pax_global_header00006660000000000000000000000064131377041610014515gustar00rootroot0000000000000052 comment=84182df1a985d45613f60fbb72f1fa0056201625 latexdiff-1.2.1/000077500000000000000000000000001313770416100134645ustar00rootroot00000000000000latexdiff-1.2.1/COPYING000066400000000000000000000773321313770416100145330ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS latexdiff-1.2.1/Makefile000066400000000000000000000051011313770416100151210ustar00rootroot00000000000000# Modify these paths to the requirements of your own system # For the current setting you will need root permission but # it is perfectly acceptable to choose user directories # INSTALLPATH = /usr/local INSTALLMANPATH = $(INSTALLPATH)/man INSTALLEXECPATH = $(INSTALLPATH)/bin default: @echo "To install stand-alone version type: make install" @echo " (Note the standard version requires prior installation" @echo " of the PERL package Algorithm::Diff available from " @echo " the PERL archive www.cpan.org)" @echo " " @echo "To install fast version (using UNIX diff) type: make install fast " @echo " " @echo "To install the version which uses the system Algorithm::Diff package type: make install-ext" @echo " " install: install-so install-ext: install-latexdiff install-latexrevise install-latexdiff-vc install-man install-so: install-latexdiff-so install-latexrevise install-latexdiff-vc install-man install-fast: install-latexdiff-fast install-latexrevise install-latexdiff-vc install-man install-man: install latexrevise.1 latexdiff.1 latexdiff-vc.1 $(INSTALLMANPATH)/man1 install-latexdiff: install latexdiff $(INSTALLEXECPATH) install-latexdiff-so: if [ -e $(INSTALLEXECPATH)/latexdiff ]; then rm $(INSTALLEXECPATH)/latexdiff; fi install latexdiff-so $(INSTALLEXECPATH) cd $(INSTALLEXECPATH); ln -s latexdiff-so latexdiff install-latexdiff-fast: if [ -e $(INSTALLEXECPATH)/latexdiff ]; then rm $(INSTALLEXECPATH)/latexdiff; fi install latexdiff-fast $(INSTALLEXECPATH) cd $(INSTALLEXECPATH); ln -s latexdiff-fast latexdiff install-latexrevise: install latexrevise $(INSTALLEXECPATH) install-latexdiff-vc: install latexdiff-vc $(INSTALLEXECPATH) cd $(INSTALLEXECPATH); for vcs in cvs rcs svn git hg ; do if [ -e latexdiff-$$vcs ]; then rm latexdiff-$$vcs; fi; ln -s latexdiff-vc latexdiff-$$vcs ; done test-ext: @echo "latexdiff example/example-draft.tex example/example-rev.tex (system Algorithm::Diff)" ./latexdiff -V example/example-draft.tex example/example-rev.tex > example/example-diff.tex @echo "Difference file created: example/example-diff.tex" test-so: @echo "latexdiff example/example-draft.tex example/example-rev.tex (stand-alone version)" ./latexdiff-so -V example/example-draft.tex example/example-rev.tex > example/example-diff.tex @echo "Difference file created: example/example-diff.tex" test-fast: @echo "latexdiff example/example-draft.tex example/example-rev.tex (stand-alone version)" ./latexdiff-fast -V example/example-draft.tex example/example-rev.tex > example/example-diff.tex @echo "Difference file created: example/example-diff.tex" latexdiff-1.2.1/README000066400000000000000000000122601313770416100143450ustar00rootroot00000000000000INTRODUCTION latexdiff is a Perl script, which compares two latex files and marks up significant differences between them (i.e. a diff for latex files). Various options are available for visual markup using standard latex packages such as "color.sty". Changes not directly affecting visible text, for example in formatting commands, are still marked in the latex source. Note that only files conforming to latex syntax will be processed correctly, not generic TeX files. Some further minor restrictions apply, see documentation. A rudimentary revision facilility is provided by another Perl script, latexrevise, which accepts or rejects all changes. Manual editing of the difference file can be used to override this default behaviour and accept or reject selected changes only. The author is F Tilmann. Project webpage: https://github.com/ftilmann/latexdiff/ CTAN page: http://www.ctan.org/pkg/latexdiff REQUIREMENTS Perl 5.8 or higher must be installed. The latexdiff script makes use of the Perl package Algorithm::Diff (available from www.cpan.org, current version 1.19). You can either install this package, or use the standalone version of latexdiff, latexdiff-so, which has version 1.15 of this package inlined and does not require external installation of the package. Because latexdiff uses internal functions of Algorithm:Diff whose calling format or availability can change without notice, the preferred method is now to use the standalone version. As an alternative, latexdiff-fast has a modified version of Algorithm::Diff inlined, which internally uses the UNIX diff command. This version is much faster but is dependent on an external "diff" command. Subtle differences in the algorithm of Algorithm::Diff and UNIX-diff mean that the resulting set of differences will generally not be the same as for the standard latexdiff. In most practical cases, these differences are minor, though. INSTALLATION UNIX/LINUX The basic installation procedure is almost trivial: 1. Copy latexdiff, latexrevise and latexdiff-vc into a directory which is in the search path and make them executable. If the Algorithm::Diff package is not installed, use latexdiff-so instead of latexdiff. 2. Copy latexdiff.1 and latexrevise.1 into the correct man directory 3. Optionally create soft links latexdiff-cvs latexdiff-rcs, latexdiff-git latexdiff-svn and latexdiff-hg for latexdiff-vc. The attached trivial Makefile contains example commands to carry out above steps as root for a typical UNIX installation. Type make install (for the stand alone version) or make install-ext (for the version using the external Algorithm::Diff) or make install-fast (for the version using the UNIX 'diff' function for fast differencing) to get it rolling. You can type make test or make test-ext or make test-fast to test the respective versions on a brief example before installation. It will often be as easy to carry out these steps manually instead of using the Makefile. DOCUMENTATION: Usage instructions are in the manual latexdiff-man.pdf as well as the man pages. CHANGELOGS: Check out the comment lines at the beginning of the perl scripts (latexdiff, latexdiff-vc, latexrevise) CONTRIBUTIONS The directory contrib contains code written by others relating to latexdiff. Currently this directory contains: latexdiff-wrap (Author: V. Kuhlmann) An alternative wrapper script which can be used instead of latexdiff-vc. Its main use is as a template for customised wrapper scripts. latexdiff.spec (Author: T. Doerges) spec file for RPM generation latexchanges (Author: Jan-Ake Larsson) Wrapper script for applying latexdiff with numbered documen version (see contrib/README.latexchanges for a more detailed description) Contributions by the following authors were incorporated into the latexdiff code, or inspired me to extend latexdiff in a similar way: J. Paisley, N. Becker, K. Huebner EXTERNAL LATEXDIFF SUPPORT PROGRAMS LATEXDIFFCITE (Author: Christer van der Meeren) is a wrapper around latexdiff to make citations diff properly. It works by expanding \cite type commands using the bbl or bib file, such that citations are treated just like normal text rather than as atomic in the plain latexdiff. https://latexdiffcite.readthedocs.org GIT-LATEXDIFF (lead author: Matthieu Moy) is a wrapper (bash scipt) around latexdiff that allows using it to diff two revisions of a LaTeX file under git revision control (similar functionality is provided by latexdiff-vc --git with --flatten option included with this distribution but git-latexdiff allows more fine-grained control on (not to be confused with latexdiff-git, which is normally installed as a soft link to latexdiff-vc) https://gitorious.org/git-latexdiff/ LICENSE (also see file COPYING) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License Version 3 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details (file LICENSE in the distribution). latexdiff-1.2.1/contrib/000077500000000000000000000000001313770416100151245ustar00rootroot00000000000000latexdiff-1.2.1/contrib/README.latexchanges000066400000000000000000000010771313770416100204560ustar00rootroot00000000000000latexchanges.py (Jan-Ake Larsson): Here's a wrapper I wrote for latexdiff, intended as a drop-in replacement for latex, when you have several numbered (or dated) versions of a manuscript. My coauthors don't as a rule know what CVS or SVN is, they simply use a number or date for the different versions. latexchanges replaces the current DVI with one that includes a latexdiff to the last version. The last version is selected as the TEX file in the same directory with the same prefix (up to a number or a dot), that has an mtime immediately preceding the given TEX file. latexdiff-1.2.1/contrib/latexchanges.py000066400000000000000000000042441313770416100201500ustar00rootroot00000000000000#! /bin/env python # latexchanges # # Wrapper for latexdiff, intended as a drop-in replacement for latex, # when you have several numbered (or dated) versions of a manuscript. # My coauthors don't as a rule know what CVS or SVN is, they simply # use a number or date for the different versions. # # latexchanges replaces the current DVI with one that includes a # latexdiff to the last version. The last version is selected as the # TEX file in the same directory with the same prefix (up to a number # or a dot), that has an mtime immediately preceding the given TEX # file. # # (I should probably add CVS version numbering too, at some point.) # # Copyright (C) 2009 by Jan-\AA{}ke Larsson # Released under the terms of the GNU General Public License (GPL) # Version 2. See http://www.gnu.org/ for details. # # Please do provide patches and bug reports, but remember: if it # breaks, you get to keep the pieces. # # Jan-\AA{}ke Larsson # Sept 16 2009 from os import listdir,system,stat from sys import argv from re import split name="" newarg=[] # Find filename argument for i in range(1,len(argv)): if argv[i][-4:]==".tex": basename=split('[0-9.]',argv[i])[0] name=argv[i][:-4] newarg.append(name+".changes.tex") else: newarg.append(argv[i]) if name: print "Filename",name+".tex" print "Prefix is",basename # Find last archived version mtime=stat(name+".tex").st_mtime old_mtime=0 ls=listdir(".") for j in ls: if j.startswith(basename) and j.endswith(".tex")\ and not j.endswith(".changes.tex"): tmptime=stat(j).st_mtime if mtime>tmptime and old_mtime0: print "Comparing with",oldname system ("/bin/cp "+name+".aux "+name+".changes.aux") system ("/bin/cp "+name+".bbl "+name+".changes.bbl") system ("latexdiff "+oldname+" "+name+".tex > "+name+".changes.tex") system ("latex "+" ".join(newarg)) system ("cp "+name+".changes.dvi "+name+".dvi") else: system ("latex "+" ".join(argv[1:])) latexdiff-1.2.1/contrib/latexdiff-wrap000077500000000000000000000105441313770416100177730ustar00rootroot00000000000000#!/bin/bash # # latexdiff-wrap # # Wrapper for latexdiff, to # * provide support for documents consiting of more than 1 latex file # * provide my common arguments # # Copyright (C) by Volker Kuhlmann # Released under the terms of the GNU General Public License (GPL) Version 2. # See http://www.gnu.org/ for details. # # Volker Kuhlmann # 5, 6, 7, 12, 16, 17 Oct 2005 # 31 Jan; 5, 7, 13, 15 Feb 2006 # VERSION="0.6, 15 Feb 2006" AUTHOR="Volker Kuhlmann " COPYRIGHT="Copyright (C) 2005-2006" #### #### Constants and initialised variables # diffcmd="latexdiff" diffrc="$HOME/texmf/latexdiff" #diffargs="-e latin1 --ignore-warnings -p latexdiff-preamble.sty" diffargs="-e latin1 --ignore-warnings" diffargs="$diffargs --append-safecmd $diffrc/safe-cmds" diffargs="$diffargs --append-textcmd $diffrc/text-cmds" # Note: Can't use multiple --append-safecmd # show current command lists: #diffcmd="$diffcmd --show-safecmd --show-textcmd --show-config" #### #### Version, Usage, Help # show_version() { echo "${0##*/} version $VERSION $COPYRIGHT by $AUTHOR" } show_usage() { echo " Usage: ${0##*/} OLDDIR NEWDIR DIFFDIR [DIFFARGS --] FILE.tex [...] ${0##*/} --show [DIFFARGS] Version $VERSION $COPYRIGHT by $AUTHOR " } show_help() { show_usage echo "\ For each FILE.tex, build a new file DIFFDIR/FILE.tex with markup of the changes which were made from OLDDIR/FILE.tex to NEWDIR/FILE.tex. Any path given with FILE.tex is stripped off. Any DIFFARGS are added to the latexdiff call, if present (remember to follow them with a double-hyphen on its own before the FILE arguments). With --show, shows the settings latexdiff would be running with, including the changes applied by the user. " } # For scripts not using function library only: Version() { show_version; exitwith ErrVersion; } Usage() { show_help; exitwith ErrUsage; } Help() { test "$1" && exitwith ErrHelp show_help; show_help; exitwith ErrOK; } #### #### Error/Exit codes # exitwith() { exec 1>&2 # write stdout on stderr instead case "$1" in ErrOK) exit 0;; ErrVersion|ErrUsage|ErrHelp) # Output generated by function (program) $2, if given test -n "$2" && "$2" exit 1;; # more codes in here # more codes in here ErrBadoption) echo "Bad option '$2'." echo "Call with -h for help." exit 9;; ErrMissingParameter) echo "A required parameter for option $2 is missing." echo "Call with -h for help." exit 9;; *) echo "Internal error: exitwith() called with illegal error code '$1'." exit 19;; esac } #### #### Parse command line parameters # # If the next arg starts with a "-", collect additional argument for latexdiff # until "--". scanextraargs() { addargs=() case "$1" in -*) while [ $# -gt 0 -a "$1" != "--" ]; do addargs=( "${addargs[@]}" "$1" ) shift done test "$1" == "--" && shift ;; esac fileargs=( "$@" ) } case "$1" in --version) Version;; --usage) Usage;; --help|-h|-help) Help;; --show) shift scanextraargs "$@" (set -x $diffcmd $diffargs "${addargs[@]}" \ --show-safecmd --show-textcmd --show-config ) | fmt exit $? ;; esac olddir="${1%/}" newdir="${2%/}" diffdir="${3%/}" if ! [ -d "$olddir" -a -d "$newdir" -a -d "$diffdir" ]; then Help 1>&2 err fi shift 3 scanextraargs "$@" set -- "${fileargs[@]}" #### #### Functions # #set -x Log() { echo 1>&2 "+ $@"; "$@"; } #### #### Main # # Create output directory, just in case. (set -x mkdir -p "$diffdir" ) while [ $# -gt 0 ]; do file="${1##*/}" echo Examining: "$file" # No point running latexdiff if both files are identical, # but run latexdiff on top-level LaTeX file in any case. if cmp --quiet "$olddir/$file" "$newdir/$file" \ && ! grep -lq '\\begin.*{document}' "$newdir/$file"; then (set -x cp -p "$olddir/$file" "$diffdir" ) else # Delete file, to make sure it's not clobbered by redirecting stdout # in case it's a symlink to te original. test -f "$diffdir/$file" && (set -x rm "$diffdir/$file" ) # Run latexdiff if both input files are present. run=1 test -f "$olddir/$file" || { echo 1>&2 "No file: $olddir/$file"; run=; } test -f "$newdir/$file" || { echo 1>&2 "No file: $newdir/$file"; run=; } test -n "$run" && \ (set -x $diffcmd $diffargs "${addargs[@]}" \ "$olddir/$file" "$newdir/$file" > "$diffdir/$file" ) fi shift done latexdiff-1.2.1/contrib/latexdiff.spec000066400000000000000000000027231313770416100177520ustar00rootroot00000000000000Summary: Diff for LaTeX files Name: latexdiff Version: 0.5 Release: 1 License: GPL Group: Productivity/Publishing/TeX/Utilities URL: http://www.tug.org/tex-archive/help/Catalogue/entries/latexdiff.html Source0: %{name}.zip BuildArch: noarch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root # only required for 'make install-ext' # Requires: perl-Algorithm-Diff %description latexdiff is a Perl script, which compares two latex files and marks up significant differences between them (i.e. a diff for latex files). Various options are available for visual markup using standard latex packages such as "color.sty". Changes not directly affecting visible text, for example in formatting commands, are still marked in the latex source. (C) 2004 Frederik Tilmann %prep %setup -n %{name} %build # quick had to adapt the Makefile %{__mv} Makefile Makefile.old %{__sed} \ -e "s;INSTALLPATH = /usr/local;INSTALLPATH = \${DESTDIR}%{_prefix};" \ -e "s;INSTALLMANPATH = \$(INSTALLPATH)/man;INSTALLMANPATH = \${DESTDIR}%{_mandir};" \ Makefile.old > Makefile %install %{__mkdir_p} $RPM_BUILD_ROOT%{_bindir} %{__mkdir_p} $RPM_BUILD_ROOT%{_mandir}/man1 %makeinstall %clean [ "${RPM_BUILD_ROOT}" != "/" ] && [ -d "${RPM_BUILD_ROOT}" ] && %{__rm} -rf "${RPM_BUILD_ROOT}" %files %defattr(-,root,root) %doc example CHANGES LICENSE README %{_bindir}/* %{_mandir}/man*/* %changelog * Thu Jan 4 2007 Till Dörges - 0.5-1 - Initial build. latexdiff-1.2.1/doc/000077500000000000000000000000001313770416100142315ustar00rootroot00000000000000latexdiff-1.2.1/doc/example-diff.tex000066400000000000000000000064451313770416100173250ustar00rootroot00000000000000\documentclass[12pt,a4paper]{article} %DIF LATEXDIFF DIFFERENCE FILE %DIF DEL example-draft.tex Thu Jun 12 00:01:26 2014 %DIF ADD example-rev.tex Thu Jun 12 00:01:26 2014 \setlength{\topmargin}{-0.2in} \setlength{\textheight}{9.5in} \setlength{\oddsidemargin}{0.0in} %DIF 7c7 %DIF < \setlength{\textwidth}{6.5in} %DIF ------- \setlength{\textwidth}{6in} %DIF > %DIF ------- \title{latexdiff Example - \DIFdelbegin \DIFdel{Draft }\DIFdelend \DIFaddbegin \DIFadd{Revised }\DIFaddend version} \author{F Tilmann} % Note how in the preamble visual markup is never used (even %DIF > % if some preamble might eventually end up as visible text.) %DIF > %DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF %DIF UNDERLINE PREAMBLE %DIF PREAMBLE \RequirePackage[normalem]{ulem} %DIF PREAMBLE \RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} %DIF PREAMBLE \providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}} %DIF PREAMBLE \providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} %DIF PREAMBLE %DIF SAFE PREAMBLE %DIF PREAMBLE \providecommand{\DIFaddbegin}{} %DIF PREAMBLE \providecommand{\DIFaddend}{} %DIF PREAMBLE \providecommand{\DIFdelbegin}{} %DIF PREAMBLE \providecommand{\DIFdelend}{} %DIF PREAMBLE %DIF FLOATSAFE PREAMBLE %DIF PREAMBLE \providecommand{\DIFaddFL}[1]{\DIFadd{#1}} %DIF PREAMBLE \providecommand{\DIFdelFL}[1]{\DIFdel{#1}} %DIF PREAMBLE \providecommand{\DIFaddbeginFL}{} %DIF PREAMBLE \providecommand{\DIFaddendFL}{} %DIF PREAMBLE \providecommand{\DIFdelbeginFL}{} %DIF PREAMBLE \providecommand{\DIFdelendFL}{} %DIF PREAMBLE %DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF \begin{document} \maketitle \section*{Introduction} This is an extremely simple document that showcases some of \DIFaddbegin \DIFadd{the }\DIFaddend latexdiff features. Type \begin{verbatim} latexdiff -t UNDERLINE example-draft.tex example-rev.tex > example-diff.tex \end{verbatim} to create the difference file. You can inspect this file directly. Then run either \begin{verbatim} pdflatex example-diff.tex xpdf example-diff.pdf \end{verbatim} or \begin{verbatim} latex example-diff.tex dvips -o example-diff.ps example-diff.dvi gv example-diff.ps \end{verbatim} to display the markup. \section*{\DIFdelbegin \DIFdel{Another }\DIFdelend \DIFaddbegin \DIFadd{Yet another }\DIFaddend section title} \DIFdelbegin \DIFdel{A paragraph with a line only in the draft document. }\DIFdelend More things could be said were it not for the constraints of time and space. \DIFaddbegin \DIFadd{A paragraph with a line only in the revised document. }\DIFaddend More things could be said were it not for the constraints of time and space. And here is a \DIFdelbegin \DIFdel{tipo}\DIFdelend \DIFaddbegin \DIFadd{typo}\DIFaddend . Here is a table: \begin{tabular}{ll} Name & Description \\ \hline Gandalf & \DIFdelbegin \DIFdel{Grey }\DIFdelend \DIFaddbegin \DIFadd{White }\DIFaddend \\ Saruman & \DIFdelbegin \DIFdel{White }\DIFdelend \DIFaddbegin \DIFadd{Evil }\DIFaddend \end{tabular} And \DIFdelbegin \DIFdel{sometimes a whole paragraph gets completely rewritten. In this case latexdiff marks up the whole paragraph even if some words in it are identical}\DIFdelend \DIFaddbegin \DIFadd{now for something completely different, with not a paragraph in sight}\DIFaddend . No change, no markup! \end{document} latexdiff-1.2.1/doc/latexdiff-man.pdf000066400000000000000000010215771313770416100174600ustar00rootroot00000000000000%PDF-1.5 % 3 0 obj << /Length 1608 /Filter /FlateDecode >> stream xڕWo6_a/2Ps"Ϸ @ 3恑hD4 Gٱu #yOo6W?Y &xFmSr1YhD5|6vZDӁ|LԃuZZ2}WL}\>gq+n;pp JS8m=@!w,ib~ ΌjFCeO+, P$hԀ(T& ߺVwL i„f֫}lt ϙ8a2~WxtڇpGv>Ǒ `b K`F%A'y믪; 81F\q)x~ŒyGL~ۜ1(OܡCAmi$+{h  2cUu,'nmeyl,@ӄ 3TlB, -5d5iCValcOmC䩎@QOy\9+?GKz!w̯I?U#rQ9tY1( P\œ .+o q&$fJ&1)L!XRϰ 1L陫uɩ-(X1Q /+hB(w//WDIOBooEp|ѽւ ~B .D,RVxoAXo`%|QKߍ?B Qk X7aCg endstream endobj 18 0 obj << /Length 2392 /Filter /FlateDecode >> stream xڍYmoܸ_a( ^HXKhCW\ J %rR!9yx/*ZD:VW+E"ӫ$BE>-) ~ӗ W%E$3Yȋ2DQlG\s,*Ԭyp̚2׸jZ~ި4p5}?U?}tW!)d(Y* BFA ]QC=N?^8Jǝ ;\DA{DN^L*EeJD}$q< 3RQ҅ku 1Y옼 !@z!X2+ZޢLX'Iw~d?_i6ݼ' ,tCѡ(hOٖDm~xnX^RC-H*QJO˳7{: Xgېgo"&pٶx(^%{nD⦇ڳ#Z'^P cu=,0{$H4 OcR"r\CczEȶkSAB=s va0+Ow@p(yjcF - ٘(̄/'3sa*R/VaطP0DLo,Fȶ8eEW4ZA_U7:<LLGq| 4 >}PWZԴF$ן>~Y*ҨE.>HS{[o:Y䝿QZNha \a!`kiG`vJy@t[BFcMrlfdܓ ay5Q *(ZϵhYÊa Œ5v'n`|@5<2 Ʈ^GViTu_Q1=:sd)0Q-N I.[Ǫ0v!{u}kn)!!QgxHaf NGe(;$'膡`ټr[,KbDlN=SQ+ƎB(oc;һ:^7,>%^ k?x<Ù|qnBU /٘887jH$ .r4sQ[٪QFL|Z_J&"TfR.U?xԡ]wurVe2B0 gyGq*igQWpM-oӭ:*Q^i@AJ*ka^0|F*6|+ Q ?cs~od5x9/)6zMxD:Yԕ/Sy@sq&ojs BK~c?;ăS#,e>-˘Tt!.vDUYS%ȷg;Vrڼ!JcTv }®5>8Jgǭ:tLiVz(0p H0kPg 2)0Qƹ1.o`BۢH.y,r.ܫa;H{ᕬkV.k[+EKo}z9kaf;wt#t`:QHI@aRḎ*,_+p <(Uh?: ڒ6L8em3mk~ӘxolNMsB ֠bkoZ}ļAPgm~̡  Ij Rx T',Jq2"qj yyU6>YgXݫ?Xs5+ ?tëC. 9.$ ɂ~0=7A{dzT`I~Yrz*%p@aSQg^v_V>_Vr^|l|a 0蘔{,GڵDԘP*'8als>{eK ]ht.yUh@ZAgAɢ6+&z?/VJpHֱXov}"ӡhKHEGVDX=B5 L|& endstream endobj 23 0 obj << /Length 2657 /Filter /FlateDecode >> stream xڽYo=BؗҀŐ3!>1(V(-$TwKcXAoͻw*Sj[ZMVľfW7*YwZ+gLy!{۬bv:=;xw<pUt:BxtZey9k\*XO]n5 xCs @lZ>x&E[6flaSJ@ 4QUyuQms^T{8^V0DhS*sr z)`t\v 8[Oȫjމ[/S!Uڭk:|\3/Cܑux;?,Ff>| Ս?+vxI DQzfSn0ڊ)\JUE-&aamSB?$zD ]@4a\*#Ja(TB'PJ<XGI羒]jmPf! kA:nryܠiB΅PQ ʚ'18B[Ժ.'H'=0<#p0:~AYr7^h;q%%^ZћN,~_7Ew82Jˊx^rM=[Ѹkmoh X DӐ2"iNr_|b疡<*H%c@(i3@ځ] y9jbZ@Uw<``%MV}%}+D۞ y-x0# 0 cs#?wFq_LPO``ќp.y]~ego'3t+t;uvT._BQd*B@CEƀl bj>fT3dp FWt9Qst0QE!9 Z+Їl?Qy P &*ŋ q@[B#qKx>raf!dyAR4u5_aP15co1k=oyd(',$krNxS,ao%#PfJX=HYV緌Y duRdqG)c#*ɮ%b Oߣ6Ǐ0_x9P?7 {f^^>]v.ex~m: 2ĩs8O|UU1鮪WZ@[/ѯ8|R뙵P$2amK [|:l*P=$6Fs%jpfՅ 98*8Td +S?>B!+[~j d ‡(Ap|ϼrFD C;)q>TTRAws$Fk_r.+ʜaPG#kҠb {LG14C{+=]F{!L`W/1M×RoJ]XHpNk kt(uj@D-;Z e_PŦOT3n5WK;%IU_€Űq;r\{Js2Le0?rq|TWv W*9d[J)!"? xIW]le;sR P4c f`_pYh7!w1|c.6@Ipwɞ=è I}>{Kx"H0٘EDr6}1#de1cPr(dU4n, i!gA&cB[,61Φ!X;Ot0yJnXY`hch0wKa^M]?ߡЉ!*K%7$݄ZX5D_{Y#}$vĶ\NECFk)cPccFVz`蟔E Yj'\7xc@J1W ZR Ě$fFz6q5jF9$86˯kc[_%J#cdk!?˜T*R4z(s:!TH]7*56H,`2Ƨ_.<1h +}$vؾ}X;ѾM7Jx@l~!z6tCI)`!V8]'b! `K>|+K+ `ߧ,Ou5O! M}-$~,Ew7?* endstream endobj 27 0 obj << /Length 2187 /Filter /FlateDecode >> stream xڭY[s۶~ϯxLrȖ/c=sNZl64!8g R'v6Xt2y52}8q[^3^jOC!osV2]h3p\uN, #D$1"gI,w3 KMB2*ro[S)VW-hEWx3G͞MsLPrə܉ޘkVh%] AlL$Q$RJ1-?l\;<joJ!)YqO#\`V3K? 1^zAJ-uk<|%6a"b?47!?erc\/Y~rc9%Sʛv~1PTdH3_i|HC!i??0_c_`\# EO<#/b[V0@6b<V!ӱt_휽 [ok3ã)lvz1q p;5zWL*8`fP,*wu=^]0 {Q.ׇ P M#ɀ{un=fMƗ1+Y)iN 3CjB;D/{tMrɦgmFU5Rx_l2@Pxgޭ{4q<?˰ dOպ%RW2U:#i^Q [ U߷Y0hFP jWx'RuED16IoT1O3ްm+4'U"_6Х ʹlk W.f/Y?3P Te773A\#K˞E8n-V,s8r*ҝ|[b7kwUJBƿ&yU%D6=;c^p .4&h0Ӭ0u2o&U[SnʰeNQ68q0g~)_k&ޘy(/.ct@ݭ*ܟꢣGFp?;;T"[#9S(L_Њmap?⛬r['ZB+hȸOw-|'AW /+ I4V:12&]|L{>8EPw`﷌ef[8ʏPYFtr_@]m c?3ņ5jDF5b3ч}m7g7$ endstream endobj 30 0 obj << /Length 2137 /Filter /FlateDecode >> stream xYK۸W*5A=I9W9e@IԌo7|H,[hk~zԓ'+DMb0!d/XN5t&0X64ZV]Vh3kagVl:SB~54ǧL$ Uh՞Y5?'d9KΝ$eOšH՚~Z(eg"bi? o6&MyKȣeQP+ٞ~cv.m=O WxYm䛲G0F(-+@UYJ"Az,K Vւ +^4֚ak(4穊дѝۆ(EYsk:hoQ˪x`گk%yS) um8g7#:"c"/d"=xjnI]feiV4 p%L_/]RM;R-C0xύ4Ktz|Eu9) >uD q#NX6YuJSTi`+"^:T!}V'`[t9'wsCJ "{f-jKKp6Do*"-\chb!rmF)SeUXVKE:)29?@ )pIK4鵓DYa/yu65χ; ݎ-ܤAr iKUC\#4A#N0n_~/D03ڹBHF`I}2P4cYXoeV(aa_F@2v;Mڦ;wn2M|NAfl6%_,+ Vo4YV2wU|XƹM"r(DBx Esm}.6m^o:neɋ!#lD̸YZG4RƏzQB#5ÌǽY)^C {m@$ͣjx}ƒǹѾ,KnԵYqYq lGRc#w hƗ GEfJ1yZN? @pK@i8+x+xǭ1[7U^c.Z!Kۜuyc,M'+,vȨ( X<@ U3ߚJl89cE\Aws{SS\v>/S*!iST;͡>W7$W ;|0Y[h?6."} ^\=t_ZmUFq~9&bЮZP;u endstream endobj 33 0 obj << /Length 1895 /Filter /FlateDecode >> stream xڥXێ6}W#^ta>CP IFmaeɑdPekî23B4ӉHV73*S&d)V.͟_g'΂3ͳU%*%ߛu&ܹ֚:O̒UD5y̦WLg|p\1!LeXj~ot̲uk=}ZV>Cۮ*[?DqT7ww*aI"!8ytK!jƥ\JU,Y--<ʚ>GӗMѫK|wT!ӡmVPCGmۦ ;|!pF 6M?VzG™ǰvaPd|no.sƒz44w SI=Є@sIwe῎;Ѝ҂  ApG!m”f )LCu&Y=ݤ(lfށg 0+'`F_ӑف#drp`h7K0L)h*z) gJy'Y{Œ.g B1(KEp9Mc7304{q*|@A)Qj[rFZ)AD X( @Pe];HgQjDNA(uu+v&%T:rAr7;`뮩,a[% Oq$x/{sR* "7 ieD)uٗAyՑ:Xv®h …cJ_MH!_!vEɸ >_:LB_9\"bBd ,{99  @D龡#*O݂>NERf :H:\Nw #;[6o/ 2EE?J#EU5RFłd7Lvw}ǖ6 .T @Мq5{c" b\OLP!Von= :;=IߡLjMdPGe}@;qyZFWVPcp[(Q $ @)e?w '2^ɸW]Ctzo:?Sn:맡x9NDXov*gpģged_h_PryngM~´|㕩Iy?G{{n 1]bgR*0yx3U;WI~R/K^d V>Up]\RR{ZGli򥵢uVasM#Ⱥف<"Z ^'J^*UyQh`~} 8J%\ϮIAqF  ` x@"\ۍbArTFSug7\pᵋ"1&Ggɷϴó,uV9PFg1ޯBe= JhDPp:RNCŷ PX'u ?j ܥ_X=]Z񢤋=r2Mo&=u?ܡW(|{\,O+@亮z{ `ئ₉®w'~5n-0diaG,hAvWHz#Hpz@a=0FR A"dB69ÌHG qãϳ(dJ%hM=(whs|vn(#6hU]GX*ŏ'_VĮLIq.h` $~h\QFG;XNݜЫZMCۚǷw7||}yLv_]_nGN]ukrr0o6]t3Yzx.?p}><;U[fR hkoݎwzzrav;tj!#B3կ*ΙBm3|?ew1&ٯFm\j=/0ycnha\,|,J endstream endobj 40 0 obj << /Length 1939 /Filter /FlateDecode >> stream xڝWKs6Whzf,L'6vfiL)E(|_}e6v{.}|շt?N~0Eŧ{3lɾQK]=;"={{Ziv& !eѲբ@Ksggd~y:w4uI(yl([l p|29IC,r 31 'q(N$$ygE/n<`դBL}H X)ȃuڝn%o!0XjIݞj?[C:+@5? \@rLImgr`/4kR=eU*͒CA8?1E$c׶qce`j:єq,t4\5R&;m;7?@Ãi!PӅ`@| +zn6r[lwؚPi|օ_ W#"jvW<C 5]ٌDGX z\d0O.M^$:]$_l]pA{[%eU9qzXpIFYFE"8WLċbqOxvǑ`lFs8ѬOpkVߍYevVO,tGD<9>HTDم5T>饢ئ.Di_5w/a..W= I!($zj=sS(TgUZvk@-vgcS^b-QOTĚ^v8KsA iQ|M !tv#%xJ2'D⣴V6 %M+;]A-d~qѦ,rsY:\/4[@ȳlYg}h84[wjHa啡 "{?bYۙ=~R ɒ;C^tp΀5͑[۱mx5uu{'/Nsd̶ti|#t vO˹|Ν= <(V\YB.bJ`^dhJYCӋu7 Y@Bd 8nA)(lS;{flq2{ฉyYDZ^UֶU.浴z- XMWEsIL#8I.,Ig.X*R_o(dc ʈ}k~a^h`}#T"`c.MH|_F?j(H ,(o1i}I`qn\@9p䭨i . &,@pyJՕK , mc^ى""> ˳FEfߌ]Fboy-%oKޕ]}[#nc ݡ$&IydqɊcDJq> stream xڽXKs6WH͘ I#;MN/I Iˇł%slw:ӃM`w,v}@_~'IB?\\o^;a, r|,7+Uioa8 TCN ?#cfigNfIhK?vʖwy+G]**EscKfx08 $06B4y6pߵP%*D5pw<"Ֆg\ v#@6Ezx qtDG]Wf1 RǏCce3K[@pf$Q>ĺ'8mB a I2aN c`'KT5m f ; j:-Ne |sm]6&~[%-Y@`9g2n ]M0o8,23J8Zc<Ңa\P;Ni#$zݗGQƸu,z0 xq4{扠]+5S.u ]BǍ16{o\٪crrsP88H36SPTmLX;dC;;[#8w|=}tKbJ=QNG-0 })C7цbn ¦)ġD!? ! tJ`@= {"B'AahVcA__47,IFh]CnF1c7⑓nzG lbt2;>F%N^إY~ &m*(= zδ\hBK2VUl7 4DlP֧ &&1juӯ_>|\] nbQm&y0Ć(; Vg`J7N.m;m.7>K.ut$"IBը7k~dN+)G,ꚺSg$L>ѽ-Ng9lNPM0~OlA3ЍZ-/NNM3 &4J;e 'suםSv%ueR8谽Qb A~N`"iJkT65$wl qSSLimٌZ- /* YR 姏'qˏ+Vޝ^4snG  8yi)oT#yUv Ac\:z JZ'i'>pý/dv:bM,UgŬ۩tƔ3 Ǝ)Cpx2Z  ƪg3@$MĄN]nsc cPp./qxa06i"u?G R?AL m*BTR ձqۦ1hEM狠j]cDmv+|i ^0)l?0 Ѳ<+4RH@!5fhUBl&1 y4̴)LMkݰR64LzWkaxѤ6p>A'ӌsx{|lo`'jsҾ6$}LO#qXv9~1c$8;T_ DQMJf$w׍ƒWbhZ{, ^_z endstream endobj 46 0 obj << /Length 1757 /Filter /FlateDecode >> stream xڭ˒6#S0 JU.rJ' *3B}-`w+9j޼}']UyD]Q*a1C}2§Hz4ڜoߕ؅IUn5è݇iO\F#|'ЦvR0 > 2%Y{A)Cܵ<Ѫ A$2N# &Ҋ0;kkMٷX7mC󍂄8Iy"qB7 4lz $aW&o=F!T>zl>l\EqNuxYe "dL-#v&8jTQ|A]mM \s=8;gؐ ysvz?ϐ@&nK#~3n#eA³i2#C {BOnPԖ~5 =b$Ŕ9"%Y.yaBBM"E@9ecoX3a#l3j&!pѨ'@N>jEv"z> om\:]rB, aI" TdVA3҉WPKf$V\nQ>؊(28:n)xl UH2AtNz$U'SA<"C+K1Ur.qAr֜"Rs@u,̃3+M)Io $㐅Z^_pKr- e bH||:$؃Ֆ r 2 u }\Ezf=Esmc^{icpI+VZbt[J1Gu;rЅ\x2Zx8a)5V^摨 zfߍЅ? {+[ @$;v4yݾYp$z%P _9-Gi a¹ӵ܏D:nrN"lWεuGCPVGB-rW=,גRyFXYl!$5/ԃ>##6 8DR\- C%r&cɍd_Vx,iht= :a=3[ǁ}w넬dQl0ֿ i5cRlH8nـ038/BTYpY]L+<." i_ւS?m0E׻m6nq"{^UoЖ[:%zޮ:`$tVP>Ȑznhił+*Ӫ B `yrZ &u,յ֌<#xs Dbܤ|IY_  [eM@YڥḺoaK!B_c&܆DMt'cQȶ7Y2e+o<@hȥ J`\A4> stream xڭWM{6Wgau:}^v{ Fi0u}g4$vOh;bvcN|4[9"Fa Y:jQT~s_tl{"f1kzב;x'ߓzeEڠ̭ܢoQ!P"Jm!yvPvURjzV 傾< '7$%EJB]ZrH='lnIHr5\rY*q-*(F/=hbIc0*qb~*r'BA[Rc3pEa"$/ӫ \ uJ7iUِ vHegQ!(V:2ʭL[j;G4NCw|{6 a& 瘵\Aa5n} dw5g '\=4 iIIeC&QigP(t*v!HQlIEMÚЋ*iH@8 GXhhT}> y.ym gܬT`D_WZUJ +Y Mx&"8H %j\d6߾Am֧ }B"cIJ WҨz")jU@zm $Фey%U贕!BM"-sô (/PI$B&~!O\גQ~PEXF}0|ΚUK=`Yw U*0/;\c!>DpFU STAaT]vCI^< +O1~2Su7RIUZ,\(jݧt{\Z9.?O8ߓ Sҵ`ƼtpoֽHgЛBjΰhwȷ)3"K9%|Wμ48YBRB"MՕu ֥T5DY*whu MO'rÃ}y!cuY Rƽ4wДD-p!~~,l{c'>B Aa(1"c1 FQdz:4{D[GJ=8O%TuEjZ6*qq 5 yGj }L~ L|\ܞ@Lu/C'T7 <1zz}j94b~|i""> stream xXKo8W(ڛ$,Ҥhu%*K^QN Pp8߼ YIW 4fIza_?ʞt s.Ҕs7"7{\)LEr%ta2GYBwY,A9M+증x AK5|qӧ^r1pU)Yvc"g9~ljr{K[ )MWW06s2 LSG^l[}Uij3 <Uq8-+2-7v 3Ma80DY:;Q_(p4n{m>f o5{@ H^ߞ'*o*@4UfsH+&Pfm$.{Hcxbh:djx+J@D4P斔Ed%M8tۃҐ & @gÒԔ!$YjGJri-ۭn^gcpv Ij#Kέk 5t MR>-A}[j| sx {5zHH+ĎH})k!wZh,oT"{YGHcm5%xH@C s3[F-0( Tnclg=4˝j/.>B 1T h~2gqݴ56*7 Wj7!5䘶c¾4*ۅY(L݂\j Uƪ^#i{Ξ.~xbrJRbf)@%Sd%ɡj x*>i[*ێR2~rJ  LF&l[96ړt^/3Ѝc =Q)qM (# @ݍP~V%3YxŕRu 1p|9p%FKĸ:FCM m'3DOɟ7gf1'fzHYN$1ptHa`r߳:H]ʸ]07,ӌ!ȔL&báIRh$2bĻ&n!N Ɖ]VPO r#/݃Q݂l91Adqw(s"rThǼlU;rR0W/7 _eH;xع@N|T?u'⟧ZYSjw(XgϠVoï[ZT(y}wRͱ>Ô :&Оeb Ľ7o1i) endstream endobj 55 0 obj << /Length 2032 /Filter /FlateDecode >> stream xڭXYo8~ ĬH: ,iEm nnd%C~g8d;Jbf7oE2JXp4], Q"&M7?^;"`&\$ ʼO|iM{%<tX837۶L/{^ZVh٫WHzAKt>Ccti1-3{ȫ^&q̤AaemS"OgK+?ӛZVg0@&t"bqJQHyӱ&{fdY:Z{ՂFm~1VQ^:1wh nShV\YHnh=fY y\rVoǼ]2`5@ْ͔'J,UMl20qz*N^˴04-ҸntW,y1$37kcyAUk%R,:eA t@RaXAa?hR[ 7zGgIbC7l /᠀OW'# A1dyZRg7/`@A2=Yڝv1|>[ˤ-TEc6aм\[е"exA h3*\0J˥q$ qO[mEg0bbr$8^%UևCrн:)pXbOȦ4kx4@wb*`e1?Hʁঘ;p"i%ea_3 $a i F4QQ'.M p\9 {fzɉ1Ekey EIvK)KB+g(۔Ewi4.x <*'EAٚy&3ڟY q@rKMgx (a*b&~)dYlY1V{Vf@.z<<L\O1w%kiCk^= !? -&ZG˘CGﴮ#6(<Spn¬O.N˫F;(ʊrKZs[qQN / t퀴 /6FQ'cԹi_]cR]~=7 ~iKUK}q{20ч!8_T[}ЕseeE# 03.d?Xj ՇvP Q'DDi+a|P5*miꈳfՏ!6>dBGR16:dyYZ2:N AJ\7MZ?njN5X {%Hv%o.r^1|5 8݅31}RR/mѾr4xBEA *38M1w0na3{x;lw'HX(mŧ/ӫ'5s |\0~KBPEkxܬ,r)jodAzk˹țFfE܉V= +><2(Z=YjOv!:8~bKc|`*ŀX8@b‡tY19{GWP6jHGZoAӠs:b1tƶ0HH𢶁X lm)5:쁊 ]vB@7@]m>jz'=!%͸7s56& 5O%`4RC|Q׸ukJص>`P_ML[NEe"dp WW<ۣ(:7znz YOf;uaao<#t[GmܻOK+&MuY Ust\7 _!l2b*``> stream xڭXIs6WHg"!3Һ$X%4T=DZ2E[~<{yHd4yQId$N hoO'o:8eqEDhLcř}Q,WUPf6'㈧ɘT -­r/ss Y]eYUiuiףR"ޗ5~*ZLE!q%ۆӐvK{m[ʣpQ#ewȈĢ㶐kp4Յ?x $bu8MB9hsn<. 9EpYjOA]kIëZZphz}1HE8Ճjm^NI?>݅V>2,!4fGYށ3C'$=K>Xz(D/KZ$XG~,Lb`-D)$9$|+]y`dD`/o6A@|A3ÃXKB;j^}D MֈC9[;Q腇"'t "Hݵ'шdY644rIPA {p ,ۊlWYJj9)L-vTܮN8={ FME8nDBm*gy/-T!cf;t 9>GLGWn6pB27Z%0ju%϶~(5 <5 P2";g6uYM~6J,xz,:p (pX檶d۹,]d?:,95^Tv31'Y^{$s݀ѿ}jJFHr ΢}"&XloD̟[0)1,v$ &T }F6Z܄cn`ӽBnyr tu>48xOHWl!YtDPin?=eBW9V*ُr/EK#ٖ_/o8ѥ^WO):tS=lfJ]Vve@1&`"Q@LycvbÄ,D,X5f;ݱXbVՐnrHMrf+pj$nw-}ƛv5g60zU,Iv5vA4 P6~/H)a^_v Wa ]ygnYLߚLnw@q掖ۿ:y{qtͥ0+ PPX7uM(s^uT7p)ݡ t*#10b ̡n^Don70e\\BjS(n;7T`sg.tJve)QǾ@0¦ KĀ.CO:GEA3VE?3F0P#cQ꥞76Wee5;KR"Dݳ3z4}3~`x`l%_oOvuvw\ B72 X9ji3|}_D l$p>)c|q2d A]%mUzfz&"SmGpYt חPG8n܋ڄ> stream xڅv8z/Ip{}p'yv3s(Hb"5饿k"_DTj/ݛO:C^A8D \ۉVp *_ΐQ.Ĝ530A KPJbfEqgjӂh6jA|y=yK:r._Wf:?a69I8=͑ d3ϼxāfóDzˆusсh9aݧӂE*ad "JϹ"_qj(sTC<7ԡSut8&IҤmq': n̋ЌE%1T :r0M$*Xڶ=`|]H8b%C5@\ DkA:i\#:Eߒ㔍EÌ<򷔹yLs`H [p.ߖ\ LpW֠00!<,?^ouZ^"dw8EBNj!CEiCsiclϘ:F.E 3O7w/"T^A8rS `g5GjY 302a QHg 0 7x$J4IWzVl( oQ4r// hςɂPfSR EI`҈JPԋ2 Tf<&ɜ(J|ǒ]bؖyGFA,œt@ c{k`rfP!ֶ{=Vs1"RF- I{* WH?b#Gye&޳*?=e87 X軮)-pwjW\ dBz-ft"ͪ ^AexyB H͖c˂Eb{x80zc,uy ͆\4lH| PPQr:M%;SɹLHZx`(h"yP-nSmI9bI>?TPQ4YHVa)z5'2tJ^T0 .ֆH!u:SpZ*U"8^++Eb|hrQO~j1|kfy2F5-tQAhkߘ|dAN䑙~} ΖgUi;j 3qToP!Or5yG5)N$/5ϏI*e5 2 Nw%ϝ-o d 48ݱyΔ/T5Q }:!XEQ 9?F3? 4&a8L^iۦ]h Exğ"}SLI2`q`F7xy?z+@q~i }i(TiTqf?ƹLZ%^|f]!MU՗(3_Q\ ɓ`m7֒ >cZ!nl9+C1<I^A%Cl5\__]3I3>t:d븊lFbd]Rd+? ^|% 36*IԼݺrݣ]HJR2QIZ x!U[zFa(kd{vPc}2'5ל-}fQ0zav}KDٯUۮ/g툂= %.ĔpzE_ڌcH l% DA#C1W$NoAG%Mg7A-e0UU4;_j*7H;3y%#1)՝x_Cs6QxmKFב sN;d,S^p2R {7 endstream endobj 65 0 obj << /Length 1701 /Filter /FlateDecode >> stream xڍWKs8 W(TD4mڴq;݃lѶ&%8ad;vf/BăM1+El6_͢8yV̲42NgzW~ 7 ȳz0KELm=X5xq'xAAS6#SI,8i$ C xeKe֒imիGb UvI22F`e3|DI2e߫u+m^" j]V=8hI֪dDpڇ>k(QmOQݲ֬o>dtOQvhn:z.r`H\dޮUeUhR[dcUնO|~􊿄xMX;'e\C_9vwjͻwCˑF E#o`и-ڊ)18\+ 6;LM_,ʲIaIPw X ikO:}332%=JŞ cP-@*h8꘱=,2iMWfAgQ"$`q,Eps+w绯)vg2QP+$"y=qb&¢yTr El=ǻ`}/ow `# NB> JjSZU&MEAr6K<j1Us{%;"Sǀk=O(dHBYmtxӁuX]6YWZA=U7˷jun!t(EZ2>0 +S P=bCĨ:tugR'ġHa`M./.Xwrs&"x?qX꜊^w.| %ТzI(^-QzgTh{ aP6_E|.!@5IXzs%G eԆ,ظb 6LL9l<`{1".鞛ʥT{?ukU1<:iN\7N_ՋvO68{(U4zM6c܀wڕGShN$;D't? ixKI ('o"4ę7-8MD༃ bzc@ Lz2~ۛf1"fӓ=۱ X1 ?e0Npqly$N;U8^} jџ,_z1ÅSF\\ +|g>*fҿ p @ Odl-ƶ sw: ڨ|K9Ȭ8-K}ȒއA-:9r;wjH zPTK qq+7KX7dUwo'o0cyrJގRZކ@˓{Ű&h Hv~0| wnY4aJzJQU9Cu 7_6 endstream endobj 69 0 obj << /Length 2181 /Filter /FlateDecode >> stream xڽYKoHWHaIX Ml'2-R6ԒT<[|I-KsRYWU߿Z TF, .%M0:fB}=ːs\-O"e?,7YW˶XR ŦXuHbBb 7 o~GfUNպBi%Kw}GOJR&~>e<26,N5|bIp3,JҞ/w^>=ٟtXNL `<6=!,% YZT~ ,2R|:7xt;X:5Gأ3%f0Sdy S<6;N1ь߈JCZ 6#ґ4˾^{:EbE걋 p֑;a@c-\[0HY]XlT7kNGAUNm /[tY[ѶeE'i(_Vɺ=h VY <,C:6½/c WʹT=?, >~z`̰$+o|#F>V)A/_?\A >& d-LD~Om䩳:jDՄ9B,F~ _H&>y^H͙(<(Ҙ55\#a)^,0 Dʢ 3xX,05<1~=GbZ (|zFL̉uB^ f"yQ,VWfnG TM7آ:u=n}ҖĆ;@mHR3%s =l0 6eUx6zlD:*M -U]nߩC`kP TR]LW^Jp(=@Ƶ_JNRFCh?j ZLfpvɽgZ؝9]Bu8 [$<./"xAzO$ψ%eDB;mk*A"XSV=-FKHwP:QxX|^_ZY' eV/D(ɄJNE'_;D-CIP;!'ʼnbn\>j{-@YWyY=g|A E`4FS]YEǧ}l/P АD-8`;l}BaΔ jʫP Hݖ%54 OO%CaTg(y~eڸRiY5NBi$U>+d=ғ)Bx,MAyQbo%0#y휡s}hApHp } QP9vdS7c{zʒP?#r:6 < Ze.0$X'zm߿<Æ;=]r H8INq -8+0qWX@2p~silصeT걨&soDZ\`S}w [bN h@ԁmtj_uPdmi} k=r:+[o_EcɨֵcOhZfODre{g9ݐBu_ CñzgɵĒ7>KhaCvIC`fW=͍i7ݩL(z7 JE %jހӽDZX.Ny ~ KEӽt`.^X$$`ic|Q?a` endstream endobj 72 0 obj << /Length 1860 /Filter /FlateDecode >> stream xXKo6WQ XЫ@ -7"[=E{g8Z: D1~͐o^]IV)K#n+.%d12\߽L׾Y-kͽ~i6k_$^~͡/M'E UQ)嚭(N-5 ?n~\+sNJx;{Yoı2aiRz]`Dz4xJX>IA/Pr;n53(!:k? י-fGfI̒8g/ nz[6I\*-;3EGƀ sXH/QDyM]f-Aoq_bi!KuZՉaΙ;,M8aw&6i!b{Vy)?zlP2:|0&iR'^7*邺zD|[IҟU cܕ=G2Jv DhM3~08z[Vwnm kQW24c&cl` `aNEIRml l9|vRG ~TĴ9*;Gys)8@F]m%XD/gӈ& = >:D_%DbGcYFpR=1CE!v5 P#gAºpzqbpY;X [ȿ5KR{൫pV aPC]ߢ:Y@%۝NW5WPԸEg:OJ@IpD/뫬XB1\Sbx:4l\\Wo ]XǕTvRP)B~Tǵ>;\q'ӬjuVXRJ&U$fH^ۇ%).fnlˇhL{ G:jPL@ZϤiC7I$R]hyOśk2cuJpO76򬪜}%[ӊnԥvhkZ-qQv}YgB-u" ٕHIriWC ,oMQtåDhYoPBк["s=F#p̾[pO/y tI9! ;㹉0tHqVg0nG10PG>w@Ӹ!3Ytlre:WPXyiD@1;/*{e} nSx^ 6詻qӶ^@` ]zS)d.Oç,΂49ۦ/r/$LAϲIͅQĒ տ > endstream endobj 75 0 obj << /Length 514 /Filter /FlateDecode >> stream xڍSMO0>v>ӂJ*+P!l&^9qƕJpN޼{~=Wgxd".%+2ʳ Eu$99lh,w7W ˨bU.r?DǎS~L wRUi)V)i%z{]?|RҌ'ӊE c 54%QS!h/$gqI!l:ԫSvl04c®G Fq0fUfoLɉri>zAuz< n}%Kbׇ^YːJNp 2/ sZZC$K.ъHKZBUV?#R#$a$!5$(aNl3 RLs^4V}g 9{uu=9f)C.H Hz&]}Εt{zI!-SX;B_*y"UJx{Mv endstream endobj 79 0 obj << /Length 1639 /Filter /FlateDecode >> stream xڽXY6~ϯ Q6I@wxHXZ-m}g8es7 1q87EIfdI.b0!X|2\_-?uXYE(8K']ޙcexZ4X/C% &?HJnCGnA&|ki8qӢiLg9N{iڲ@!vs2z LJPAR8@U`é1TwWU7z T8 9qPƤ3\ D@b,ri@H3U}ݧEi6~L3z)(7hƣPC0~μ1Q}>-RRj/4Lwj(}N4Q1u۹di^2bq6`遜,6≔\+:UB"ИDhX9҄H ruJՄJꐊW̧En7wD58 gD*Woo)H}Qwxe=Y=F /@9b ah5M6\o<9ǔ`Ns鑦8k@}n@C2)ȁzmF4Pu Lk57iۼA+mUpYGzZm 1;Ɓ[K`ztE~NѢ2Y85W+ߵ60x&M(tyJ!JǮ]:H Le#_P 3K )n9/]sHIeֳpbA RohKw6C~C?ͺ"a{Xx}uASB;6kDk4HD+M}7`vf:+8gil36FgSC?2)$,w;e,j֏!d#"C:Ä6] :0@-:CS[ڶW?n5N4-& @ʞ o̠.g.e~QۻJ 1Wd˶C۵1`aR#oʢ0.j-I'ojNGL\քSN;a;A?.QIwӘSD @2Ƒ8본<çqw]~%)HHI8Rt+QY LMӠv\qy*3ӺK>5daObcM|=*B#rWŷ 6OYA1O&j}pgO=/cj|ʣ4^U\WCpkSdi>uM'~,Y<]8h@t6*}&Fr2 oA.8gmkJF[C:< y\3 2}}pūH T endstream endobj 83 0 obj << /Length 2307 /Filter /FlateDecode >> stream xڍXI_1G50bDJlb؉  ݭZx]=<_"U,U}COmS'!2}x*~|tx/Op!Zf{ղq{U'C^:TVgwɷz MT;#VJt BE o-[n׻jf4RI6}EySҙ }|W{>bU{혥*\4ˠ4UiJR^qǪ|/'ߤl:%+a"W2<뚿0^Üٴ'y= nD#({z((z2kYq~= #1#%42۪2m,yN$pbt}) ̦KǷA5X8?N̹z;։ J0S. ugk$Rƫ6wM!/V.q=\dr>-GƲCݛHe;Ќl;C/I~y``zn`t>Yqio3^1(M8,j.Lc ax d(CeL5bʁ'I9ïX#BC1J*C11{^*怈ևq9$ջi #[EtJ^y,㊱ߙJQ=&Jӯ'XTȢ&$*GUf~m_]*ԝE ʀWIb8Su:WT jZ:VQ 'pb\6!:8 <ղafm_"nǤj7# bZ1_5_ycM@〄C`C os>ޮU{6UQf%(Yʧ@ap[J}檻$8cN4>7/|5o'pQ>Àah^?0 \5@yfC쮛DJk9_ 5k*Lrdz9`eC~7l ORB)}跖 +tw^q^0(,%H`0),,O0|?=%4'sr7BikR2VD(N(2 u .Al*/,.㔋:U&#\* $MyZɑt#_oEWIK WϚ$]SxEȓӐqpgRq@J&~GBd?\mx ϐS9 TW 6i޻3/?pyo itH¬=p;CՀt0މB@mV:Y!Zu҈@> stream xڝXK6W , v;I68Tes1$qǿO?b7F-o޼VyQT+dAU fae^=vu_8qO՟C3 lJbuh=h}#cf^u{ ~"Y gGW"Aru{P*j}p,t&3g-mK}Y@i R $Hr oQe,q8  /ߝ,< (dI8ݗOHJ0^wo@ m@u՗KcY\ގ_mK:ز{-@OE( x-믲[وYsS{I[.'5TRQoYOW|k 6EpT>Fڗ2=# $%6 ,!ȞWdb>I <@`PlePT`ʓX7J&8FAc7 j ŎE ^G7(D@2?|#0 yiaf19 0Ҧ $a~osߍgF$Px|Ǒv=R$pϵ+DQ(}>Bdumu_]i @|V;" m:Fݱ'cv_ ՜c~DN憥f}RI զ6{vpL63m8}[oW-fi #鵐;8q!'uQ">>{gfPx Nz~=<"Fg[ݮokC mS v}+~:Xwi6ύc4i7*Ȳ+69&" 6ecM[EIgFdUO\XF;t"`xUB@TxtPa7tiFJ%4ꗦR+ j@4QGӗznjriAA rr# tYF ӛOFF?*=^.[$g2 q$VJ5BR4"1ř0_ S"?~ 5 -3}K|h˹Z*KCCU ey6 Ya8Dn}d^@w}*@Rle6%6*)OlY.!T8 ĥL.=#:zQv]3k{ʡ8 ^IQAm"P*IwW*#1*NplhX@BNLVr,e׬irSN\HF!"(lVd/ ~M+h0qE4Tˋ;/!Eb1'*|"p<‹`S恸iWr!,3 e H0LA+\}!~|) C4N6X/gP9r JxU!]zLCP2MUaT,&2պ@6Ğ'/XZ>6&ʽO-}6AxN)[ΊaR)^ [-WQe?2g;lzˈk4'&Z7%~vSWG kɁ'eց y.N^J@)8D͛xC endstream endobj 89 0 obj << /Length 1231 /Filter /FlateDecode >> stream xڝVKs6W΄d{l7rf:M Ut.,J_i\ Nj: 90]6 E"M8 d߯E;z~Ed?&~1YB>ԃf;bR{gaD]%.'E!R5C??ٝEDz:|Ҹ}2 }-t-$zF  )P D,\(=`a~$Fh Fl6ok9 x4R/XL8 mXє ? )&o&  9{lYȎRT8H1YyyD/nnWPStQI n!ŧr躢;@Hs82 c%Fv4m10G)-: Jčd!Ksn($O i_P(`Q p[hvgm~*DQOӌܺEcj$4giˉ ( 6jچ96|hz2gz+\'Rv QqL~l l9tp% <%*f@qZ:/ /.oq_f\~y;߯pߊFDMΌig$e _L /R,B9ar`na4LAP9[q؇WWk=˥q9i% r/OmgOhd3ߙ qI;΁Bf'.8 { ]i7=.gDzj96.s^`p[^{G°tRq)Q;qub 5 YNmzF5C 5z`iJ38QhήVgݥ endstream endobj 92 0 obj << /Length 1380 /Filter /FlateDecode >> stream xڵWK6W=bXr&MnMP$9""Ek8;C^[n=ų/ xA$lY'" nl4rSp/,a`Χ8 8ro$@t4Fh;i k3)G8 IfF0! cIpM5ςR6rgd徫˖!Q|øLa GVY4;U5EDeRdԆ s">J۫8 @/o6TW,J(UA( (r%~PE?z [C%6:I˟$t|dWJ3QVkt% ]`gIu!-R@eR4;t ks-ƵA8`qȬ$0%TkS2Fײz8 Ga_/9CP"B p(: GGn;0}bQ#QP  VWITT!}9܂n.#ZS(}xx܈"%1zAF| b2*+[E!E|76P݉oF`Z]&S]&`epcTm \ ЄN/5… ߛ!uF` M!GGabY49ViLj6Ӏ}X}Q3*cz%KIjYe3Y55րKB^rr]AR8G"\(O_Pfz&7ʚC|vTeT[r;;d;7 Iik9|ZXwS "}U_; 8}wϖ;k(Wm{O> stream xWK6p-bm)[dM!uID[Ҥ@R5 ER&m/=kff8#zuWLJTq>Y&Qy^Ll$,ǀ,I@-UTp3K!n@Wwqy4,QRЪ#Ox22mD1y,ti~Z$3ѱڢ199* PV,/_bneatx0(.[`A1Mz(FQQ [zn8NQ%̧0Jq65S NƢT٥l0_v4 e4I2^l, *Mj;n$gI:Q9O iQ|U!\W +qQk%KM+F=6+^ҊhFZ7{3Ӣv~P\Lч}u [ Qx$Í`ֺ9Sg1MAlgoMW 7/Kք&2f>3QLD`]pwrg.(`>v[{^hbGx6)vJ7Kf̎c9hS/B+yJl860735\vCjL!]Β@>ڒ>o]0'-Ɇx7׌ֵbg VD*mD!C/v-''KfS37~}{y-Ji3?doX!U#0Mi6j+|EfrenIAtNU u!N>!wi$M+tP-QF^^y̮aȑ{&2#!T3#XFqCn31:_wTގkWTMU$l%E+%AIav*MM/^(M!ƑQ/3\m+JW>3] yI%Sv6ăwT+bqKmnS徸q`w*?&/#IGÕ]+r> stream xڵX]6}_T  fD*ͮfiypI1|AV&sν/ n>LQgd<ˎ8 ;뛶vإH׈,=õݮ!x0OT8؈8Z ,9?v5a:oRI3rTISj,gPD-s%/J9Hmzm=Cv&GQ7GHJt)Ʉ @+ףxE!9(cYTtA3G3[ baDecZv*~E? R\nf\iaAqBK F|E0 IKXj=j-bdG YaF"\ޟS#M* ĺ,;!rds v`Tym4 Gg-h+1LLӄ1W57g]CRFk+^*j~t@~Aՠ\/1JZS/̙БYD5FNAEDp GT!}T得_o]G'縪f,!L9hW}F%75HQul10E0n695̿x<7`=m9WvwM5?93 CTcDqTePŐN+|_ KRz*~OFr=}x\t gr;h~.zIij΋%b:t1Uđy[=Ѡ[8dԹTWήk"uelٓJWQZyZԅ\vb"d (2~)Dy5Vl/Z@ǯkFvuVRH2(+B*gB*,]mdU׏9xKsIoH=dG!Zϼ^U&@ ?ra^s J[d `C(m[IObnt\["]l$K!jzeQ aj\eu펜4Ze> mlZ^%_3-bZG̓9&5VvKR*"YJQNJl8ay9ݎ*,ۓ/L)4̓ endstream endobj 104 0 obj << /Length 874 /Filter /FlateDecode >> stream xڥVK0H/U,y@V^TUm&kM%fY?yPddy曇i~uęԚ'N8Zqxؚ/%DN w_xK cߵ+}~:qBq(̿Z#k?ǫ,F7<.e娖T0+d m4ؙmn$NIAb<*R^@xƶzWz$ʕ z1+Ȅ3wkT4[z5 0%b:$U+^xVLxb, 2'8ڍ4SӠYV2SBK[\o]̷Vv;d{e 5,eBϾ6XA ڶjϧ<=$ b'b͈~ؾx|;(ռ*{JUu>=bVK*GJt梬ji-j.l[uоb"?BYTz(C= '#U(|˙\sd|%_j3W9ոi1>)D6#1Ue*.y$[Jy\)M8Dl /Y=ZG숔*uzk6xS1I;ϫN".DR F *hD؉6qg&%?,Q{0flM䏗^ O"Kf=-E6mx%2CI#U{llNk=9*0\1{JRjɂ6>t!+ɡ? Qz 0DYWgcɨK?dLzf3/W endstream endobj 107 0 obj << /Length 320 /Filter /FlateDecode >> stream xڕQn {$R!`תܪ`5Nʏj7q(EŹ> /ProcSet [ /PDF /Text ] >> /Length 2716 /Filter /FlateDecode >> stream xڵZ]۸}_@R$&h4;E֖B=+{fCJE GD>ldtxxyy﹗]A7r{ǟ)8%ZsUܮ 4dq*~mSuU21_gᅱmXtHh/|y{6+q¥.7FD8[B0BpH ~Ɨ>VZEۿڇ~s=cu` +X,B("o_ n}  G0Ђ,j9/̌Sfa a0F!_>N/ayX2 ,)ք߻G"]zjj};gşV n>mOsTy!Eۯ;bs2^Ml^MpK  SǍw2fCSIB [7ŷC[ wBhzPL'_vƔc7ڧη7lsg{u<#יwzi;+R=&R  19xؖag7:1Á$E AKM-8ls":P4& 䌪O';`(OF>LuKa-O-BeTu"Ѧ08gjxAȹǏU¨٩>m|_ ndUJ Qpn$Q'>w'%Thz>d +jKIs>MyהM&B 䙤,p.{&O G)Zd!x#QFkÃoO`mTD[7J`U {SOqs,yz98~-9M`νtY90ȀTyK{ypa`y#(o)5NZ+7r q2 b.;%r1Jdǣn ژ$ u=\ AL$K06&} $΋t%|خ_wNxX'_2h%#uYZ=5r_!vSS֭)"ee[6cn^"yU's/Wo_՜ī^m6Oa ;hjD%t*|αC(BAS%Q]o3i4v)jC&1,xN)Sb43 hs. Aˬi 0 j%~&޼ԚC<O8M]ԡupܷ!!Tu+ 2;U5]Jx6 3;7;ʜbi|>I \I(dIj\b^& n1AszJmOk] B e֘e|*(*%f㲩saS9 ߬0p O/6vGG(TUI j25 TRE 3W5C] nTd4kSRѓ;DOس8АQ]Ky/wZ&\6e¦W|8xSI&|3isBbY&a|BLD%_!>e8D,dž̲T:XQBNa ]!^9D6=:P$Ov:]J>0z+!yؔʝP^9}#6ܨ[Oܬzу=۬D DXam臍שLFXWShKh2v\dz0]6 7L٠BCE&#hPjee}];*M T..:O^ "xuovS c Sh=0G#p!'_ 6 !˰oRg*ԽYyAt|(Q!;9#u;qGWN1_r`uǯX=礔<5D]wT4c} k$|#hS73W__x]jX?=A4{Q endstream endobj 136 0 obj << /Length 1997 /Filter /FlateDecode >> stream xXK6W"$ChzZ4=m%C])KE=oOoߕJTyoXJQ& lTo$ lqC0a`6/f4}'4{AIk>?$ew?]]T |-w(QA+'Tǃ|]R6a*sgR1m"+BQƶHz.@ ihā~q2!+3 Rȣw#}${c"!s![ ݊m(QqknUׯN"!{*iTޘI` X^ 'HaY(3K tĐ(•"'jݨit1G ܏:g 9*]**|`c.[F N,1 iVOjPA^=8Wx"۠zX۝-eܯ044I 6 ~(% h}Kr5]\T,},D%>X"fwLw!q0GmJ8hg1p }$2L >PgƩhS!Ӎݪu&7W8h;:`Xq]ʾr'Oj9 Wm5zxڞ%fگtެY L?r*DW !]:\N^Z˭~/Y]+eܽ}͸WAk*uADv {ItL˫W*TKkaEhxl20u)R0M4/{.{D(o9f.LϚ?.5x"RQRUBB^)\?!y))6q;gyg9lȸd@'ێNbQB&yDEZ؀'9B [Wŕ~ϔˀa$ *ۺ.zPb,TL=N_i Ԭ,STk, .7PQ3P=;1kGlA3`P3^nKٙ5u^q)L7ZhNsyYS˝k(;ۦ ~hPScI8Lz t=vD#88 B_= 91xKT)|fGYk2WKG=\eGs4BZ'*Y9np`%yVzO \Km\@d y{e{8Y,x+P Zp0FM5Z8XA9t HR=e p+!t$e ։QΎ+UdR,8(}03)UL*sy [~^+0NcRuG38J[}Gqzʗ .̃qq "r@2XTR!㛟݌ endstream endobj 153 0 obj << /Length1 2139 /Length2 16658 /Length3 0 /Length 17937 /Filter /FlateDecode >> stream xڌP] ,F{pKР%wqΕ{E>zvϵ QR63J:330DELL LL,j gk@G'-?,DF21#wCy;[5`ab#@d g(D=Ay20sss:LlF@&FU;BPY8;021819 P@h 2@oj 5 ӿvfnF@duzwq5:޳T@ˀldbbgcod5E 9gwg:_FNvFF k#wK7H+#ى dGƿ¼YThW}b G{=}Vvn^Af [Sh3ۂ\by!LLL\nbW5{J|f4> 3/'#W O"ff)` 4". #>~~>av>bF5EIa SRDEgag03s8|7;K@m"޽qdP{mA}?do:" kT2ـ=m>.!o!T6:ig 5oAN w_CSxn *9pLLGs&VY53kX;}IM6N`f׉r qE8YR+Q0A\F?_`TޣAlcjqWf|&El1߯$?/>y މf)A;!cj,m {Żޛ`?3G<~}ACNak 4s#e_k_{kBw.v@Scef~W9w|}~?{?\9޽x gL\ :}ɽ2 h4oglYv_-LF;?CFM6kpP78Ս2zذʭO_Tv['?O#H&`!C…y+^}e4t~WyC4}zn@,Eq.)3=! ƹ; FZB/_,skj,Nxxڸ7S^")28 ^%E ٜq sxJr9n&& Oup^!%fdC%YA~/d Z঴?:O;hpycmn1ڳ|9`ˌ$堓ɖ?L 9x1[BZy9"s(?+$v[ 4Tc`MsoO:&6r^Ieq ʤm0a8}TМT~4:&8'2~]pE%7ɐng09Qki6!O:KXM>Q<[*\5`܇]g9>_Jb͌r79#ns %.MeS!gzN5*/U!dN¦hmY?%/|w2O|kT;LYo!8~v]' uK;WvH?z6j5XDy$!-IZ j9 ۳C;ɛP(KGz7V*%>/(@Z- 8eȍfj7ܚQBYDs9Dfv̐ G+Gz>lst[֨ J?Li-2Kp| " )fUN1qRKv# `X '} p>g\cI'o[S=ﭣY# =˱͢ƒdJcDu3L^bH-kP]p,U%=L: tS{UP$=QL6?6{~~ЍY Vri ߃ O;4vnivmow/uI^s{D'[KGW`,oacEQ8"1_e v/eUpe)uڏxWZpl&!Ä7u_? V[`dVHQڨvY/o!&sdt_itEⱽFf)X\%<}1o #6Oݰ[_E& Tl(,m],u6Tՙ O7t amAj SXa]I]y[)8Ɍ53`T8 =D-2y.lp=!#hwpXJ bӟBih͉]9U1TQMRo`HlGsqbd3(4 |܏^8}Kv^n *u2@_Ǜ՘]RVqH5EtyK}&!0r: Ug1j*A~괲в `i|N@b<755A9l5"2"`!15rDq1%ђ*s0 -"=< wKj=/LRO0l#x$ ],AVflj:,rYaVoܷÍ"\K0LNk8m DV(wd%]]pGasM1A\a@,U%>zC1!{ !/XnJ_بqQ[brs C FGTwSy9)Fx!DD O |ŻwQuåTH%ҏNЪüW=&\|w-ʬ:\4`g r1d5gq]$ubƂ?}~_BDF8pETmT0LT, w6$[9LmLwe7 cD-Q(a#=$҇l P>;"ގ =G:%Hrhhv]MjHpyImh\獑9QdLSvI.:3cO$qFt0߮˫9~i. b*s#!Q[S#_WXl emѣrRXKE~|^Y^4,@WhyD=8{}0{ :͉44iۀ88ݍmm!ӔTW֜8eM^!5p9q<<M> pqi%v_TrǼ, i-`F6sb;sMn:n"Շ?k{3zJ1|]y_Zi΁ǰ2%kCh}g+}6)#[fG\S΅8D OI9I=8?,(N?SgB=J'.KS3on~L6EkE2T\/ot:/Ttt>7do{7>m2ܼҺi4x*DwWE!r%1͊kF%:dV&ٛޗ&jJCysirG v2Q'N:٬ԹlA ܽpuGUf2ne)-M8Z&YJwM̀opF;}l/C3IԖEF؀^#d};ܲiJn̍Ԉ2>>~+qȕWKr%VؾI:h,Y_su mw6~le HT?'S]ׅz 0Z Vcn˪2cSe~;2 FFjI=B yrjz ]l/ n.b>{7^Yo֮wl2w,&,޲r19Y1i#]|-܁x\IdV`!2q7ݐJ d#Dq*&ejjTč+Q }s(9$_3iDL)/ZLs8JJ 6q\@.dJ݋y YG 5Y;/[I#΋0]cz| AӞMIuyDۚck3Yl=0+3OǮle]2~:6ǎ($1czwӠU/EGdu 03I uC?D4$~vptv539n0УɑՆ%Kc0)8ɱ,~#r77p}@۳+j%aպw&|uו<Lb 5ץ+N*:V,(qeN{1gL:-Y,?R t,Lz_4]e W*ܵ B8c;oW6KdLxhU:ZaFPǃNzU+[z_NU< ^-GTζ-spMe]8]UdsPqt(qMr/y2M[Ѡzj7>~PV2~4msp%prL0[wn J4X[aA:Z{QGlN u36?wfMsW/<^U׹YZ/͋!K&hcf$A<~٢/$e3c8BrQƩubLbv ʗr4w PUׇF3#e߻0v:xۮ9OG$_skNW8KfS[SPƉ.X9 0j)smtoF!~VFC`ʗE[5PL~k(XC. 3C>|^:"@nD"h!ްɑQn"Bg J,_HVx%h'\PFq){1 7R|n;>l]@Br"h_+[E]6m Ib"Ee@\&& OˋHATzGg-xa}DBL מ}}BL)/6zf8#A76J w$3?k>'~@fs4&(>!=zMFJ\tb9i}V$;c06hx'# +ȳ/uSk{匕X>@ǿHtWF+qt4[ 5:912&Br.2 ߗRڶaZ^c0>n&SUδy:?ކ_3Q ȩ"81s-`& DI.v!@Fg\0$b0RySSp1<{5:^LӚܢ@\3(r%e;o&0eL(9W2d,pk b6!,Univ.h53c\+xti@«pʉPs2͊[Nseʌ 2ZgYoƎ[Q2;PV|qO$St4-g뭼[$$fHQYZ$jʣR!A2@߷5كgb}˷rHxI-_w0L۵4^sD,52xd%=l{5 R`D\N(!.K֙>1/tȺt< Ƀ. kOTwFvi*(գ^-2Iեo|U6ǥ7nz v<;M3M[R%$Jlp[MdҺS2}G]O sk+KsƄxT=5T-8#u=EJ%*tj٪kۻ3~' )z_XdAa2SmLp¨G៨SpubP?#mxk Il-;0y,:7=A@2Y< ?--{΁l#Q \y`eHI9s3`>ΏEG so^@xb f,Q@Fv+^ETW\vDQi& X-^ ,-Aj)Z asysys|CSFMɎ*NsorߨFvuǂ x}BG}(Gh_ #$Y_4ҎLk89ht } Wٿ!`s~.#W )i 0μH")Ll]pdR,LN3UqI8'`i,'|_"UqNM}ht۳9ig#|@EͻJ2|RkIk'&8-F_py3%l8.s%9ЉF՞'"Rf^  )xo4ame/bGV?ёVjjE^c*aIJǏ D-b̌Jyҿ丢$3X*?G`P2x Y*"LGv"OV&َp)ÀH%K~z1}{/}Uv>lx3Ү(Xm%99djw*!zSuVQՈ l.%rheP_&p"%L햐 wΪp8Xk!Vs!_%RWA/N">,|n%gr[/gdKS| >@Ӂ l*s9p9}pXʮXk\iq~ۗ ap)'* :Yb>ϸg1c\5c dZReiQջ5߷҂GDf>ݟ=&T:G`=Qd?Rb>Ҙ_ 4B0K)<]F6exEK>uO|7pǃCraQM@}"fT:& k$Ȕ3I3AC+Ԃ"{C39wq-n(:#+ Ij\5N F%8g>T7Ԛa! S8)N[oiV}Nf4Meo**@ Gu_gf*B@xCD W# reFTviiw eA!k7xAA>L@ۏv?=K7;m7b­"9(-_„+օ+}L() 0j;M -xdޘo,:;6 wcQʣTCJ$'Ϗd\Ē{dF{Ȭ,>7Cq0lY!!S]^> G!Xlzˀ^Ʋ"Y?jXj`}'5K'NȀ u:}q23Hrk+3Tй⤪L > ~}@*{e\۫!6$͇eKL@E%`Fk/w+FgQ/M-O38N,IDėt ӠeBX L(_[RK!r aw^Qq0 .O̊ʹSCF]1 $\?n^?r :,Y9%>{$=h:Rt#l|ĻGr`~0^uH8슲T^KmJFak2/k p_„qb\)5(H<6l?ҩuU ̺uE&[vb9e_}7kp2k)j?s1Ǥ>z #,RD=+}^![v-eC /ye_4mEh(IIy$jLYc2M#otUt[,(6Uy=:5yK3*jkƑ^5 65)oIMxj&A:?Ɗ+D{L {-,J!k][x vql U%H ڇA8xpE"nM&=אKUCPG&MuKRX5V 5< Kzk&+MD ߮Kn7_{aM_lKhP< vҕ~zr,lmF<д_LA,`_T"74;>3R xt_(3 a(1R.D}DoD;) ff]=mY+OV>eӲw^IY]$5J t| 䉾ZVM% Au|T)m[ՒGF6#=5#9ݲx0]6[ t?|39 N@.aJ? G)RDmq"hXݘGAdQ(dD)2y=_@ֺ |[0r,9{\QMV<hg#ܶ!Ak,lq㹮g5k'?͸&:ka"rXȢ}QSEUh$Ɲ]O^Ըs]a# wɃW%"X[\DFK#QBpԡui'|>_1\ *o7{³K"|5pU@ x{͝%0FprZ5dZGxfJGlkj#/oísS9V i]P[/mµ6,cz_^3w{ tM?yQ} yS!qptX/ýfXvA 2 }gQ"kYjB3 U#\D2Ğ Y"8]i9~R1Y U]9]˘O[Qx"AC(J!lxZ,)E7ج*M>M-C(s4QG^ͲG(6b) YAXÓ%JE<FG)0ěU'~Uج`:0u(7ssx J þ}V7Zs8(%4!Tđ8 oA:koϒn##mcn^slj\jz~*d[aXy.( T_qY"JȘ9*oⴐN~dl ր-Q$ ?H&D\g_ᄼLk7ܱ+ 08VazZJг=PW :CK6b??NC&ɷ:Ue'̬9m<(?e71`CI>"u&E4NXCΘ_k8`qZdzdYo0$(>|jle1 y88ߖN ^CL)+]diZp6GJ/bc"#qTth4\.o[n#߰[C8uKA mV]kS22%HZ` Ue G.ZvA(A墸Тȵi,6o e|!vM_;(9l0AN?ql{I 1A*PP)ԋ*n^@wѴ7$M8tJ@#")bQT&讴E)_̄uWoJ[%5rv5j؈,Pd56ay3zDXe8[ʼn!/k#| œK⸣pTp|1Ң ?<'xҳf^gy8}n.~s_7ZdۮwfH앤8G<$oQ^& ; Gi.*|XzdȇB#,3Pz_C4ݑcjq#`(K<~Ȗ|I8 '2f[ Gg0#4wpS *{f!STUY3Ͳ~=[HV%B|uWh($|raޯuT3Ǫ$J>"*UV7Ԯ*-U,W\ k~J2by n;ǘ'D*R_ }mr5I~ 8?1w.;8GyV4t#r58҄;B X5L"5…Qf44U-d}:w؉] bAM'.3?2&˲an3S&:c.Dsu~d>px VVfd% vK: kJ~A̻ˁg#]e6j֍X}V/nR/&p(`cX>xd\w=bIc3b֠BRtOv|~9"A|\P6YWGJ*^4?Իиy_/Q <}ROiSYD|Ÿ$=&m)AoqraH ɞOy8Qʄ0JgX1)3C4+@] ˅y:cIkXn^x%]u5K\'z1qבCC tZ7e7 F{BHHqN gj V\T+us]̒uIQ1;.)ACn\a϶99y%3$1`7! Oڬy { m?_A G7+#0w\3hia=}] CʼhJv=y?/zyLZxR` Pwx{šA<xL+Ve׿g)SHi N_ӗև?]ؗr 9'c/o^b}$#ӦK*˂y({Nzpq;8 L^2R!)PۙE0Fz@!5dqP> stream xڍPҀ apww> A{{e#{a^JReUFQ[###+ @\AL †@IfhRd`ak q{]&t|7T:YX\||,,6$&& R=hi DA@dhP59OsGG;>ff&-r;L PZ%@_ U[SG=.088٘2%;ͿeXXhllkmq1ZXJRL _@+w3 hnw@'`loa`aWy?fIq[kk_IX؃ݍߗkicb211 ';fuN ۼ@Nn.^+jlW57;Jֿ=xyLyY!x8AG{'?K cGOw1_~cwzfbkc+fVwUٺ<9lVVv^7' ReſcQ&O?8{2h6͠h> ͟ed1~aHo=Ϳ @k +[ϳn(ؾo5klLN!6fV=F ) W?l`t;glPqxUߔ6ƶ&'hotC`y06NN\m3 9/=_7 `K/0!n0K!^,X e{>?OSCK<{O=zϧ8jw?^z^Wf-K:c[[e6W c__M-Kod&f&]Z~k|oSy{/r;T{a(0?"3ޟKsNfGs{?NZG8}#{6gh\A _[+E ]wF(w4i=ۜQ`h+~ߊ& t-oI܈,x5†4}jy|62ӂ0?;{$ZQMd嫧%dx,eW'l{_Ү5gw>Vp!>O2FGLSf82aNNad~G:d^gzq_)Ucsħ#Oŝ(̏ oJ? Ԇ QEڱ P<41w`'^5miRlJ5#` S ½'l!)=VohaC{zORƾ|g3r"Cp_xIԹV|"6F4@d5'1<[f)NX9!ejMGqWybDT>.!pr6JbFå @`nbX65Acu21hDd(IILiG}P1kz f\NgU,\4@1YP= ~D4/]u.o[ϵ1=㛺Ly4gDmݍ(Ӣ—Vh]E wňQnnF#=NvQʛ1NNEQ3 Y] I;; GF>yn}s p13B21?m\㌗TL@!-5)4Z>E.ݖNc4.ok8G ([Fczv'S)ME/hm4bkOc\]`E`oÝL|]Sy4{YV?_op+#'Qie4ԋ$~I]UyƚI}/<*4ͣP&;R)1HɈxk"Tڗ^E?cAAx:)0utk[X ڌ])ӚrvuHٍYjNwyJG5KIiT{˓a释5pwWXF4?6>jY7*v!OwgPd[cϦ|yR`6/ۮ\/k^5ĘS0/\$55R>--MLO݁k%qA@?[# 1|./WFXM`2IboN}MgJ(:-]r:*<5³ nCn PH- j&,h.iEx KKPk9+Q ‰I}%S)A6Mw~ZO+ 9Cmy]0!g:F!"ۄFھy}5}V77-&)#|~3R>e,O簼OVGu`$n_7vK.'ek|Daw0ۏ,&VF4W2up&DhSg$\vKP zԑ e¬pW4ޭ6+^R6|Mk(cJgq"RϾ#>n*Ybwa$稡XlM$/iBJU8B 0ʶ!\iD$T%xRj$-ﻠg.t1ey=uYN (.Kk0JB$ą7m5kK0i;sx ;{ *M҅{:%_Eĩ<&1@ #YkqN ;bcP,@`ږFuf!lݠv@sD/?Ǣx5t{I^uTg`EE_FX"Q ݡI0Qa޷\"^v eLg!n&`""9|}VOujCOn[X\^rql Jg7 ]ZtUޏ"[gM u99Cȷu>bmz4)h=1Pp{M(^V51:|:~]r4~] Ҕh5j%.j-$X2PEcߌ=Koɸ:"QI܍P3'Nh)qLPW64ӵ16{K'$&5K+f'SHONUNXV&7uE!q8j0:|ХΣAša隑+-NML smF #țbz7miХ*)GG8 83`isR.>g N(KZNvQss1Q8jFHcߖإSm: '3g3|W}]b*$d>6>vx?7\k/WtXzDi X4\ cظ !=KZ$>V2 h,aC+Tᦖ?k!K,3fUYٸc4 e@KFr-i@y\C`So)23wί Dlf2![=JuD"Yz"]7.QnN,) Y$lskh/{Hǔ1Roқ 0†|G| ;{M޴̡w:6Ie}QGpXS<d qAKbD U舌!r"Z$eB:ނ1 ŖE·P/Z-Z/ 3dtxia!1:\/ ;ހWႡ[O/ Nyߌ֤;jtt 6f(niGc xl1˙29Td)5y@2< R-*bWtV݂үɖ mȊ֕:gR@fUgzI77`4J54]HCM"%9Wxsy#(sgK:c'H5_oUo.BtFi˵,zkrQް ai?*'݆-\KKEar]O-_^2tbcBn©JЭI| UF{zF d!rR,&F1@cUSiRXeU=FlüAߌ0vU=hOcAC^j}bcxİke;Z^F7l~ ~sH {' ;&QB0l[)cŴo$6ُs3l K)'\gp%{R7ǚĈV:fh'A_0bc-īP)^Ih)m5g~(1a) `My_im;)Z$RKs (TH{Mbȡ6g1}Q)Ϸ ᒒBV7SǴRM{ 8:T(Ý9B6!>/pƗWk{4(rdL8#_˖-!_n%qc*"G/JL;nkH+ 9Z^2&bnZ"LslN|;QN 4=G&RըzMȆ#N8oo~/\vO* 2iNA]QUV~ō_}u1Dh'ƽ!EYadqiy7zV6iB8!'hEЛ0f{\5~o^)^t}T .lZh7Zymw̒tܭٹ:rC.iClچa틂 5b4q:TYg { œt9p>B_bſq}eDn-;=w((Uj7lZI.SxxIQ SYHNATN27o,Eud|1&e%\.7JdsO>GR=$:dA,X`[/)7=׫$LxH'ϛ;:<o"`R3Xh*Ri% RZqxgڠ(}[u:in%Kb~Pʑ28ЖŠL_q'DYMؤ*h @@j<_uc#ooZ͚P7mi-&g}=}\VaЭZя9H!yݞH}0O[<[`7]\z[T㗣^Ī r{-),&6nr%Q牓jʌzʫ |38~u-*PyiQ*Epw銓gbhˋiق-KX‡~Ә:&-I/'AA M +OE\/0~R51)ڐ+8`]FVxQIEe[ P/R d<2g*L,,]ѧ]u)DžoK<-UGa;LPz]zÀ4SVK~:k!(0g_ ZM&Bt:l#O*;$ygt&1QLk D|t2о`hRsȊ>I2!RxGnze"oB) 6hfw!n5\.)kjN\*,sKzE 8O Y-]pOki\j]@f=h=USB|<<"o =p 8BS98f[l8ֿKc6I(-<䚼T$d3n@c]ӥ`wr=uմ6 v΅oe|Jo_?BۓIӍ#?9<S TQ=guf{t a&k#4Jl)s״GizXOaȉ8Qi卬Ru}Gbz8P$09wpa\ʽiUw.kZw(*fc5yz3^JkO&| s3թB}Y6ΩT\ pϘdvTEt7E֕(RYA1U" O|0HvecMɻ| kg5V-[oxn7q<cR[V)$4U&/)@xVQ(8WO}2 I'N'[*0wbP5PE19Q|ʔ,#0B bA;t\\>-_4cۣJҮ!t&ZQN n/`b]Ңwi8>@Xv/efI$*wU`4YmJ6u@K1hK&0LHr6IQY\槻*;9*Ρ=?Iz|nkNԻ^z.^sPvў's' '7b#В9 SҔ7Q٢g)zc :E`pGT֦v_k_̍7Wؤ2\~()!?j{||]<.3Aj 3&D | [s w&Ϗ5@$RS~ ~DxH6ZI\*| 4zԽ ۛhG>l |TP-厀4\ *WLF i j iY~Dzʮq[lJt#(r7 B7_L"u4Yj:<< m=ή^HfZx&iFd R L1ʂ 2?QoH& {&!QRN81z̤e<0df#-F}JSOjB):k$U@䝂m515IJɛ2=M数"Qs{'6d+/K]fvx2vFSN] {xL֑$nf>bY#?ʼQ̗%B'[nR6EWITz_ffg 36^'^&()12S$vQw6c/#DG]{j>cuW\DBVD05u{Y(7~7ܿlɠ/SX[Ƀrwu/QD؎KKdsvБco5^ ~'=i/F\nI*я>dI#/;8<'#}onxhkF 6V_q;*ok'W`ICiZ۹[Px~VCEoCl|S#f (8[9%fJ.pOv'7ߕͶ7tUçf'?뇸So?yLϱy&9ϓJeR: dġ)aj g7'$oAXl?XGп=`)ii|J8N $d?G* G.m=\Ҫ;pSu򐈢aW4nK3N\(ϴxaX~!bP%좟%g{g&[SΠIپA5GOH" ۣ0J6ճ!4#oe&>Xdew2'vpG*I}cOxqAqi/Ws!^.oDŵWމ8! 10[ӱvoJE^NV洒]Xr(۸ZwJ: l,RkHex|Ves'MEV2tzГ1ϫ[,CbmSzQ@ " z"maі L!5ִ骨@*ۆ8dWS.g ]5y ~y hjHJL \-wt-e1ob+:#=ta-|+%n\RD < ݳש-z#tg 꺊XJ:f :w}Sh%?iٵ4_ɮKF)ǨEPX C):!S_F*ņR8˞}L*jZiy1|mK*FcIRێ)Fis]TWп{g/,]Pl/u/hP,kߺ*ਃmO!Y)~21>ibL,t}<~/v ;㌧nb4c 7ož:;X<717.CWMJ`; QҢ wc3+L}]wUWY.nxb[54̆oENFե|Atcʶʪ`&EFDz]Z%-TS{ffC2Ĺt`]!ɲ1]/D3PCIuv3D;*qqG`sQ7GꋚŸ/j {EcUkcdO;0^eѿБ8tin1kL`c`NkrH<IKݞ}AP&|/ӌ^qב]yQ?glMnpD ` @;M5zr{ vKM͒k&B62VsiQךo :_φh؃<..a)6U̍"';/ 6#)G/sj6l"օ"WϖTUjS3C7~ n'I-xx\1s@q.4)2)qe`Lf[˵lb&7 [5G;xs_MOQ ;scɾ7*z20˝U$]BJ3}AF$Ad}#HPHs%ǻ.fB>o%-:W@l7o)\Y6vX>"HY5^uf!pH4ia)a.20Hŀ1;t|Be@o`-Yz]}=/0SxarPavHCW/~/n4z> Y&D[hPݤґZ4Z`jټuft_ TZthU=wXیr(LҁyƇ)lzJ%l-e!d![ڤhLetr.jľam"֖rGWJͦqL{0U^eR! _zw }Ma]J?H6!8:wUAH>KSF$lw:W7Z9 hpT5_pu5ʖnp:#$y1^ I!o‡PfT0~ WFj$TMϰ]TL?nJ\G7EXg2Źu xnR覃%!&tM*&Œq<%UAYQ@5U2{:eO{xfJ?T\Z=(iyWÚBKxLbTE[zL,N?0.Z'oʢ^UJ+@`;tC<\K~5OHSԜ\J"+𸪄Uh[JB8~ W-=]x~̍oV}5&HHG14m4"HJ4QoysvBov?T ÐrX썎BU+MXW(~:6XF( KS7cϬ"ٛ9*9VX l?`ZsJoHUZsR1k PqLezcN p{컩=x[is)G㯆hXVLG [TF,Hz['*n[~YN)Wu%4@ :KÆ@VgA %2a}zyaDj;߀Y.sYe=SNUn-"k [jlg_J/x\w2"؛VO>wkQKш\62BR2VwA/_t@.ɻϺ2S }A&W<OSV` J ?> f阑OH+Bd,0< t}=&)M[eMR'iGLJJQ }K8›&w9 }"P ID{#HSo)Swm #i85 "r` 3m\߫ ,(9!Ն 8 2x-n%1ɩx_- ;\Ny ! 3!iLMi.G d(oQ/xT"# 2NM[wN"%"Q̵u};pG TSPysͥ43j٥rHkzo6YpMbй :ŤR-- *NZrmsuTVA'8MqתL Z斑s# ,F ;xJ㐥o+LvDJ@aُ ΪH'ye~!{ )U9cBߞ6Žo0&᎓)V}|C 15/.x$+yL`܁hi9F}]$$K;G/x\ugRSu vP3 Yʜ“aV$7*SǑ?W~;>rCbtvkP3D IM*7$[k;jzß4NoK S'1QBv&^T+r&%c!7?J{=5Y:|K3d?ufPFΑĖ[jOU:~3gSbZJ}ôhxuwm+>@ӷb2r0%PaB?hU6 E6;vZYͲ q+Y0wyBHK6#LidwjMg;]Y.E &K\e$eF '*tp\<7 &D9jBfԗ8߮q3)qA(;#j<|W" eNoԤV *\Q=?tI]i`#v{IOLER f+:Ò}qiJk)vE}87gYn(KCdHj|,P(ܠ$,Ai%;oe-MPOP!@JRϭҾAQ~.$v)P;?&Gv0;sPTGg׋M:[CSk a 4\Ŝ7 zX7.`nQP{̞ >8a, lxo_B["qb)Ut1,wj:Pv)fDp,oO7砇ʽ+XtSY1b|/-h)(&J `]Leiaj-,yv {d; m o/nC~ )4T1B٣>NHTlZCGvBSX 7PӹӋJWn 81׮>dtcJkg|Vw#+  ӃJF8ahj<Cj NI,3l,0S6{9,| r'bo%Չ]ӆlϖ9h,7ć /t[-oUK`"Z+;UNJ.iB=6`42(W ,͵u"jR?YM܅|,_9+?8(q0gDfvQ4eJ 3<)bYv~:-j -kj^AdlZ'uٱNUkCBQ5 endstream endobj 156 0 obj << /Length1 1658 /Length2 9141 /Length3 0 /Length 10201 /Filter /FlateDecode >> stream xڍwuTT.] HP !8%t#)! ) wwZgγ]0ШkKZ@@rPS "R[ɍ ہ`1``(D_i 1?PU/%  dL"rbڻVH̙\BBlo@0)b yhnjЂAp`텁@7P3 hA0gWU7bh[PiA-.0A`6A  !>@KAfAV=.iX,v 20X"9BMMvfɛ$55Y9 lwpCe!7o@#֯d0C݀-[!Jp@N ?Y"dV 8S@ r\ͭhك~+,Jy-AX  `6@V`? ?C·!pf0gP? |!wvn!;7'[ {W?G% G?a7*aA M_;oNrNvvLQ/۟v?l aW KRP;)MvEb0\r`W:nn2[zذƕC-~"7?3uzzY 19 P B/%h@_W@A.-?aDWп!/Ô@ C4ؿ7|h!x.*N0ý{:}Ɂ@ s)HMy@e$ Wn^zkdΛ~Ң?OxBg$['6B.rؾ$}31TxlsծRK ŠGf˩83 d gE?8#} E'y$T,U&9>Ѭ@x,u?Rngb7J\"x9|g^4eG,a`a]:1qP=Hi+iǍx&QqEU L/M2I8±rd*:f$Gm6rM~zUl?"1q@j^_S'>kgoSf ,'`!HJ+&ECzlpZ&P5'`Uˏ',FaUb13 =yblz)&Z59/WL0'}cY9.48?={hhBNyv0M @JCˉy/P:}i ֟\Wαv\Hxפ;0bWWD(1:wmmJ,: q'>jn_ZlMt⹽(h c$X f4ӕ~KIћY'=ڨ$ۙ/_ wj79bq&E6vRJ5N|;촭n:j|XZ*2͓ЋlN+DϘI%>k#v|lϽgy̬瘝j௛1Iq>c29d?z˲l$kO3B+q3ftE}4@ 8:9Ijh+o2N3]-e yHlXJR}Zc>pX%Z*4."1נZLYw"\\M4g1^>lՂ$j4|?P Mj7G*1JA$ $rת b *T`]Yte êա)TBFPHԓsQ5=@kFWI~8uFJQ ̹˃J.31]$^a4Ї6C)pTTnOA.ni6'2/_gz 3"Wpw#b%/D)u}&!t7X2ٗ~[ !p-%g xqQU0;=9QK7IZrDUCPMˎ~W}P̭ x[ybv0.>EI5!H ϷލG LEAp::`ZJBY,j'tԎ8tdB1v'|?ȲLܬmf"B'jxR[_xʷ ̾b5J:1Y~/h7_߈;/MuI[?LW,&20}{A*+@6B69r鄲:U6AGjxF4(o۸hmٴ',D"L\%Տ*6:dE&k;uGsOW s_:Trt[EL?s)8a:|j)mZyFZ݂($[k)DF;$RV/ʺw״[TWZeGd{#xKq'P8R*[5Lz>)+b ^3 NuR`aGG{@"ֶ4f^䀷T)a-,S\R+V Y|pje}ND71eQtdj ɝS~XQ'3C5.gfL-|G>T>(.%#hVf`,k}瀼ڍWuq.NQ@XȍÔI,c24^H"U Dr`Qx";LˆCX}=zLqkܐH7&dm{iH_M&8wJ13*݂A8 ?1 /X׎ו7Ǔz CN g$GE 52kHZ\["߫{rI aA9GTK^&/̺@hwDAw ~-T~~mx$7\Y/b4Ḓzp#qE3.pHͩ/K'w~rw!"7DZ}z"fMBOQ[g_ ve:whr2[Al$CPC<(̒'e zsN=J=d ռO:+?^ FCVލɯ87@aa8&T-h!l \s'8 I2r-hHa "PiZW1yҴ6:MAWvQ,GT+׾#;3'WRXM1hOf0ILS#nʞ+Up0~!dpW;m+UfGd:ryD| u*Y(: j/ؾ=,YhzQb2gfZfg)yv<lo( 0YA9K/ ˘M~RتkH5@OhN`5dĩpFIź=3(sl~:-rn罶zG1;CjL)7UH~BrBk69E~FPfGR O1SP[ޓڒ 檝\`KiѾ[d@~R߸n8BbT1fxT#uݫsO5>[{cXȊ׷XpD ̕iNΚ 5f7(E(4LaoO#+Q&KfgesgG0[UV~Mtp{=DJ%)<]ǻύ|*t$M^=qqTsOHK fF#K1lٵOSӜ8NngE Ȗ ki MEt<^r y>,Zu܇r6ktX QɆVIDŏs1%n2Jpf*)QmVG--43z|Uv$'9:1S8@I[VA~22o zZvƯwR vk7{$zC]MԷbkkR7Ą-0:E}lr2BfBR#=+&@t+.uSf-t^qa罒$|Ӯ.坺NYJm~.{(] پ|pN搹F@Y4ۧ~`M!I4v+ p =V*_ ^|3} ~|3<]Rv՚LcWE\)J7X[}%\Ú%֋OVԓ$9vSN{VdE~〤5[)e(|RǺˢ)ӕT:kj/Yk5gƼ EiI3\UL92q=uHz`༷Spixzv[ nF5?I N1jQ6%^zG6SQK<ъD0p/eG7l tְVK7J>' څ&zjtbd?@M!Exyj-Bv_XA%W ]2q;>We\DYbgl= ?VZaVL/`'DRg5 HfF̶keij!(Nt0kе?8 aUޔMDS Ő?S jhy,1rl $̾aM2mLD,t/c ߳y FJuߨ&=e+)0Ybat38H0AQN#VLu&vUD7qMQ zJjq o3:XA͔pnag5.敊SlcpJ.1r7 e"ѽ Y?f%1AChrBGjW;+ʲRd V:V/C)G$=qXv.b /i F2+|>'VXcﹰ ai޽D"Lz;JrK%i(6ǐsQ3KGc_Yp:rujy:kDRkv[l]6wQdCQӀի,] eׅ=@|aU5%v$w475et=Ji)"+: $ ^*GytNk*ʱBD1eA˦njw7"^hӘK4p׻s/&_*fH(.Y[IR $$r$}GO!>Vʯ~zXj1 ]>{2'EWpNpY/ϒ1!#t^KW+޿"~gL H8T nCxbǎAUoO+;nœȇfQ&S]m7aFeVթ/mnJ ">;}$GGzw`Smn!9s>[͹77%Ez(7EA[5˚^xG'= %;:$~*=j_ӳ1NRz3,9w8K kz"oÞ9 WNREmu!s^j|{_ |UeO FYq06C* 5լ$俎egB3W^f#-1܈>O&|GڱtMGayM ms&JhY 3k C(c f8sI˯o' mj*nwLƓ;FUolN\wF8Y4Ċ߱lɔߛe7c'eo5x1j/6nJ:'{Zg*W!CpfLb˰ro +/ZiF'#{nL!:CԻ/ihu~%-覄~$?rN3 m{``+ I:Q2͸^XAlNvD:RMȞ$őEƞ{ endstream endobj 158 0 obj << /Length1 1413 /Length2 1162 /Length3 0 /Length 2051 /Filter /FlateDecode >> stream xڍT PSWEQ+&(SPz9 ɽ!D""kmQ 2NquXj ŊR{3{||uv20Yw>A$4&p\qtX9HpcJM1=H ,,BJiB1[@q @" 9RY4h8./ys OUI@BP&D3$YݤKYV)2220BU dPl2XP@OD 8 8dJ=fdl i5Rh<]"p>Ɵh7VoDцb$udUez !W3H'(9 o5 1jRE)Y5z<}tA4Q( ͪ9R*H7f2̉2=F[KSi8B!λXd"Ԓ<|}T2J CD`%菓&!`U~b)E &Q4]w5҂ 8R ۧHdR [*L6y"hA&.BEB57Djls e r@7#}Lcq'D0H83@m`(owpKpCPPrIZ"{HdC:8jj RŇP@6񣓐9J(L6(g69E(FM?=?!FwfHAchM(B"tL*ZD1 G|5I=ȥPL@jT*Bj!dHܔܦWl3h}V'ON|l[ϲߖFu$m0MgT蝑*ofXZ{Sm csG+!k_9\c-|ןilqmIN"C٫?_Sv:hvkxCV'-7oǼ~ 6[|Eprs SZGC]g/^ln~eRdrJ۷0d iwewܐQ/mvDlXRP †kmQpiݾom 8<5t&uܢ14x=f{;zD'4+ݤRଆȘ{ܦ5D6 4zk5> stream xڍwT}?RPIf*p)c m#TRDBR@ABBExz?s?9{v|=q޼kįh!X~H A aHi Ǻ8Mah e4 T X.z  bR`q)(IDKU p{P aH7 %% *p(ԅ``nP+ ðH-Ţ=== n$Qu00xq&;1 FH' p( <@@|uPCvpp`HG @H7 G80 {A_8B\1H|<w~)!xah8 ]/0 ^*^C`1Thނ@z"|{ P& o# I Ka@I𢀱7 P1(|0~O?% C@;#wv[ ZA=YfDz׈U2_F%%Ї_X/$ A"@q?FK{dD8 %.Po$gox,7-A ( ނ_!?_d_=pue!npW?xB?C_~o.X~IxE@"p f:&p#`wŃˆ= rgk2 jCE_줐FCxJ%Q0_ X|D.-&tǀ7ցM\(Q Ʒ&V]0 @B[+=WdHͅ ɰݪ6 FYS&jmzJ9sv|kkE&/'ܚl$xb&U&EN.omIWuDO.5qʒ,zI/ Mv}+ ~r ZH˸-zHZb x#K*Ǣ"rt鵟4>v /yR7nr';&9DXQ3tJiH0v^ig:\\'VmΑS5-{&Ȟ.|JWe *}φC}q3! 4csjarku{/=imUrBDjf|3 oBӫqn^V:nB2\ׅԏR@gm1 ʦJ J^ҿA . 97=S)ָiz0h_>@^iq!夨ԝcPXޙ i>4.cr;pqӐ6WGm`i觯ye>:\~lɥourS˵y =3al-6yD+Kk~ya)Aͷݱ ~4#I<Fc7hd0B-ATWbMC|cJ+)!W@C~OP7?8ыED^T)3صE^Ph'C] KT*u7)NNzw*ӆr?4F68.%H7bTdbn`>>i܋!yEϑy+ӎ&wE+]{mݹ+ۅbYq_lT(}wfY7q4yU59wgJ&( ҇u.5 (ӟ!GqGEC 1hȯi-6!G.<8Ǹ&sU]y3ZrT#y`=X  :˩TT4n׉k?|oZ s=6`CygvLzzbBg"!CV Uf\S^9W2S{B]$t楍a5\GQkGAmB"b^ yހjOG5v.?Uy#;Kʯ6zFd]ǃ!ߜcH툔gAtH I;k(KKC/ǮWU .$au]/2V# r 47GXmxTa@EU^TzQyۦY[!P'kCת wʣAD^D4|&ȳhɖO9J"UgD _^ĢI(7F9 S F}jTN} Pg?Yal ɾ͉U"ߕO]Z^6.f+wU)PkCv;0rq 3nɽYzҷHGJZQ-Ջ$˭|5+ ԾM]q`vYJ؀3"Nc1fˏ;JS2+w9PDe=랝>x@xNq+{!~O*+>pXҕtR'̭ç|RaSeidxrSr>OPӈq#1W LR7\gr8\n*KH3k]/>nTd6%07C(7B3G}sXR3iywd+pT_-FV>$ \'Pۊ\zjN3F~e9]ћO'0Gb3JxyE{U&HQ;.Oة't?PSSYOr~-˲[bUdq=~ Eb_)~'t*Fc(B^ےhMpeWU*5Rܬr5{?< s3ZQ8br'O;1 t6AԜ%`J/R]E9Y]ڇId4ppmYVgԎm-(zqո|FM#{<3:ְ**Pje*yU-V[ Y>#[x{F??($o'8sr"3O>ʣ }CPB:5fAX15(`YfPr))*c%<|]{!f͵ިuT46pVhmtUb P#"BsgML㦴7RGJ{n2pd69)nJu T 1^HW+^$QM>;]̚};X]/g$*=ulӭqVͅ.M'UޠB+48j7G'_3fo_- #N? LO>8n21 tY ÿG0xb~wLWy>[1'f:1]dzHV fjE|' nwL=$rƢ>rEW@,|UeVW3t ١n qx_i'煐w9I;(|+:TԹp}ԄY:Le|r#6dx_H? 6Zz={uF'<1v+h;DM7ȵa-Fƴٓ> stream xڌT  )t !04CwtwtI#ݍ yƽu9`;g$UVc1w0J:\YXb ,v&6$JJukW;?b$JM1g+X&n SpdV.>Vn> &&D)lmi G-/w=P0qڃLjf@Wruucf`2warpexXZT.@gw9WE{ߕ1!Qԭ]9Xz8`p`r<@Xo?2_A99;A k; @IRӕ`2ehb7q731 @RD`.\̜]]\~+  s1{{ W~@3p۽-[*͑Yd,B-8YXXy@'̊Wxu/G_J_bp~> p@?k ;S_ 06s-AH@1x֞=X~^ ;͗YEMWKDՉ:x|9Xl,_K 06%U6'?"ʀ,npg-h9Z ^}}N3/moBnvviM1+,ZOYhnf2&YFkIkO;)Y.ֿ6F|pf xV{/qrLM#N+B́6 vX88#('Yo`bY70KY̒+Y7b0KFf߈,sF\~#p.88̮~#0of욿]7kF`v/]78w 8on-p-gWAF̬-sa`ޱSe~N1 ;ٙ8aN;(\~7\o6RZ f`%󗹃۟ ,ࢬ~Xf`Oڟ;mG)v vwL 7{_OJ?29c:%`GK]`GM`t0Kf`iN7L 47 ;oY94G_cVVp?F ﶁ\]N_6@? b{9ؙXoZǺ{8vV -Ϣs=*|"muFHPʶ͕ɓaK=G8mH " Յw}|5l[ R8*罾_<6]eKl1Z#J?x24s Εmz3{D6(Gw-n{Bͥ O sdGt?Igާpe`E$!yi-Z5[>ɺ&xP[șL (k--hBtZ&pw `E0iuMXrPӷn?b~!BKV: +etd2Q.-t%DGXw>g[,,<#ǜ9g1~ 3v!/!\/_OO %3hr%?RfBʘO7*KH8) 9dzW E{3kVj}W!9do*|뺼\A#\t(fS;4Cj`vRH$Tl/)OuQwRX4-ۣ]E e2ԅ r}  {j?\5u(@@_]&7j<{%PS#ހ蝟&ܦ/ksFBQo]xh^_"M}%`gy#8v$ ((X/2e)|OEn͕]:B?'vW?b Eⳬ+)dTĺp~ӿ@9g; 㽽>#Ǵ"cGꛜITV12 juX/˴fr2}E3cΆ^ pt(vOndiT7 >\5Ԝ3\timtE(=(/_Jօ>alZfVR nnj]>=:v)rŚ Ɩƅ }84;FZP"r F禓0֟ :Pv_sj ;nL\HXs3!$H>5{n)(OH>AWzGI!bڕݕ Va4EcD 4i?¬}]c= Z+>Qn.h.Pd )5 TɩFQW~rɹC~cw|^qJoNp>eLo烏pTh$lŎ/l>鍧1eT=f@lg0:V~10gl1R{_S!}4|JI)kÚ|87e[dr깦)qA1v4vUݙKSѫeIOw&*85#r-'B@<tw\7|e^|7A i3rDa^Yxg7/3UȂ%&Ȏ ,bRùCoa kSvyT{ : &PuҘM{ĐxE g!r<[V]YE*2_93q-z|7+qGVRIw <<0u W9%FW0 VZn6OiE^5 oV15.|e^b(2{lҷD; Vwf{GEN9nH'`/mšItRnt5[ߗ7I$ģw323:K( %ߊ./[1PGTt9?{puJg'ya `J'qt # sƯO#f "g4 KۼCvr \IBe\MZJ&[J9~ܑN7nlۖ1VJxm? x^eJok֖_TzyoMӿ2#$SNގ9"-X*Bg6o;޿qZp>OZHtC3s'}Z5ͼ':B`t͡ݵ>Tz׷LSeT : |vpc <z.O} e{wcX4ڋ2PQ}-nPi"yiᕏA!OͪLWOԁLԣj=m#v^$ yt>W46VKqI6,=2G ?oDl"mp|e= 9ZYZQݗC(/NH]sx 8;[`XUwLMa8_]F/ëBD\1^2}dxCjRV0j5Ϋ7S+ѧ.WjMa9ШI4#Cn)_\&ekEE-ZcGN4}S.^xAE` ۭ0/L J~}ڀ1s䃱i.fWtn#bW޻&8~6j#xh5§~wIaѡV z_D&~ÌlI(?I5DX`\_BcweȥL}mP]<ܓʷESwkYdыޓ?,GMvb>KL ־Zm.kjy!fD:m4/}<Ͱ{IPMa|@E4cTkI7فx3B[^xҌI譗׋EGI_~lvM.qv-W#Þ,QM-˾/ ҆*I1;{e*=tq룛޻IsM)9=l CR^kH~;] PRWW7@̴}aAZ-+pMOMqYVm4b1爯8_E#[>AR㇍ n&SiB1I&‡FOE  FvzQHTajIC~A6WfcsU6Y[qZPAM \ IvwA]4C'^$?:"U kZEns .!u '8{/jݫ,mVZspA-MVL աh `'߁<u%& /ouUa =3קSH ?u69cq$=C5|#߇J i̡s 들\ > i=@ ɰaO7,`!k,y HfX@,R^/F+1-Q0ރu0 ߆ yaK V raF cp<w6Y{ݲsow~}j# -fۋ{DObNՐ}6oZHx_M\Ixmvx 7i:9.U5Y7" G x^nBe!3kʍZğm+ja!ݟ!˲z2>[j#-Q<*ni"Q$u.( qN1#0fCb@ry۝ a?.5F?>4UU U#n ʘ6+IE p䐫VĚ)]WF޵17ku5%7fA"C)# <%َucp{g/)$ͮ40j-F؟ a|e͌lCc+; *[WHmk{ Z&!8u%Fd=NЏ ]8Issz: "ᲷJ 7 P}ek/e~Qۓ ֨zunZ^ghP_-E%H mt(\=Ci6>MGy#d>ۓcX),cro0YfPjeօXBPйex^}׳ߝ*q ԶP]E ̻#Z#tyQQaq@nhƧE.Dg "*?c[w[naV_+fՖ|lSu_rJwN9j֬Y5-C,QM:8jYDho胑^b$K:|^b5-o0^cx5ka" @}ɡ {^|q֞>)#n2,rj&RlR 5 GaHO=1C=϶j}b(W/4ߎU؋f|;ؼ%fs ӰnT܄ځad9>Qpfw<4ew-ɴ.{$LҴ }UP{ !y+VоD85/2$Lf8ٝ, qV4lj~ࡁxZku#&6$$)ȷ~ hrvGR<Ɗ^Dڨ0o^)bYEd X}F3 *@<`\098V9CKLM_yz1Xx)c6I$E t#P3Kc2S5j7ӽoؘ뼸 #D]"v~ʯG/yETxxo;"JοtX#[#r1URŦ*dXV )9]VZ>[,e^kuN V98/޶1,s'΃8yMPV4vcn.a~&/d ttoj;b$pz ~ !PIh@JiD<4JTJͪBJ-8DHҶR76 t׳_ _@:,Sx_>TL/ {&J@uc>_*GU>$REGbK=_Ў_e?:&TAMzgB۬:ɚr8$AsSj:ۉV{NU&+QO<4{dy uxr4!Rab-1a>l@B7!b4mc^O?EiKz@0juo#{*?JzČtkaddݫ>T[3%MQrWy,8mK@]VÏ0Қqmus;oV^iwϲt>bfe۷$DT܋(DU슫NjwxZs^~Ra+s7i/El/·JAF%9qڜ)ޕJW "g%|-n9NVRb/ b1يWkfFE15)pp5~&BWW@Uܖ(&T)7JBF$-3dl9/az57-S C$ǍɰjIRy6\wO!s;҄ <3b!aZbk^p_4fߜMB)n#[2j-7,YH/' m~~u_,I#$~:h+⦕`ftkr9:"ihX JLeV6L9iȉ%OLnv~ l$hڧ0MZpRO{bo%mXwp2UF uBA6y 6`#;HlԡI{aJ2z|Y%+w[sH<ş]"鿾NȌ#n~ k-]ӴOm5S(Wh;{)ˊER'z]@83L:엯2BoNS,)=Ck)҂8ZIsnTq@a;XJ݄_@qVm|bvbW큏n:ѲxyOU6C}S<ӓڢH . C_6-=0yͲcD.T&D6#E '[tr{/ 41 "y{xa 1U(B7>'z$]\Erhjްɼ˚Pt(aɗ:TzŅu6r]9VE+k+͉|E;QjS|^53:9p$wtvQ# HͣVzT+)+f=0å.l#֫ } CQh/8taWD#6{+Xi{3uᯡѹYT"W\`{ u'wi4^w^7;1A`JGYSKFɌ줪)i+zfpA#j!aѕ7A Dw|Qf~MX,R=F̘2!Ƚ&Q HL,!d;Z˒K0)5+crop:Cۏ4Iq$~ k#B>2# E6%( f:G F)!B)5'E׹? f❃HQX3W-tHVѽӕɌJO=bY>I.Չ$0WGK\LOp}Ug+DauVj%gU?T_p)+ q-raJ 1v3+{ǒQ?8@ ~ՈlM'РhRi-0" {v"dwq޾H^'(8c#[SE`p]L yCD_|D;$\+=4fEz4ݼR~oN8Of8bɈR SZ Q\=E- i gEOP>)R^s{rC{%/uDJIB T TπY-s􉕋Q~s; ? T}g aDyLZƱ s0ׁEҬcmP1ɡMs{DQ+ÏH64͔yB+zG>}yZ7~U:jѭ>Kp QO&VőޯyAE>ܪ|nSt`&tL?xlMk8k.:*\l@85 R7ۥ'+*0M"s.0G4:|W1:`Zz8>4ILdnaFIi?$kW4Qmr)*%bbom$4]Lw*C71eBW̙Jœ߫;Q[\BP8P/|k󄞶*<@o:-)cyNZ>Y, Mk@GA7O0q_Er aXۚC*`F.5IjEK j}EWIEDA_-VL|%ȘJiOYR5SOB8zOGR1\TZ+tT?:Ge}xUk>$okA=++.x;Ciyw*ڡ9ۘ+!pM!8jxB)<|'f^Lr@ձ^8sI}r}o9e#n8ݘq`@Tbϔ1ti Wiq(O!@/VVL@u( . h?f#a}QZ i24^KA<Gi{Rr&fb kݯq?QO1gMd"kV 7}8 ϹQRv2fأ^;)252esJ&t؟z z<:H',WV_!vj4OĤVKr9Mj u8qLM.~eR*dj0G['ob!Kՠ>#!L gAޥaU2::K !Cτ`IP&Y1|d<]=;=_ct@-qKvr^6,\J ᶵ3q +p$oϣ!h7hM ӭT쵷l}A*gyd}̹tlxi=xw|꓄+KFRF}t< Fr?ڜ')\pNy!K{=^/UB]ټt#''GR,:OTq#",u~c}{fIo1#{PrvU9%HX<;(IW`:qt3U(B$+g2-9rT>noM A3 ^QLMcB9vx.:'L'bŎ6S,I[CwO.I p)L{.ᠷ'o>|G"/"Bm<Ʌp> & Zxw^_v8ά|1w8%9{, 8~3sng}jJJʥ]jɋq]ʮc~xsShhP[0nC0\2+]`lcmbE+|J5MwǰX6Ii<&"1+`#vC^Ny  ggQ5, 4,~0ǹѯ s(8qow}vcNR#4 MN[ $eWz/\O!, ǥyqtJ!l"'vGQ?XCjOϡ\z4~0ٷn+0lⴉyo Ս}鰀G_3擵#mg`㧡%ZŴGx> ~&1WMنeׄPR azVn?pZe,65:Ʀޘ-HѕZR@\w$vwVd1r]$,ɲ]W"z2h50ɻ$ yq ʨUjܒi"nb .te?F%;K'm/ SboIIaJŚwGשgs]\C%A;Dz+[<$2Mut2jUћġ*a0?g^꜈JS?RpMY^}Î)P'n|$2QDm֬lI0hX04)4 &࠰eѿn'dgݻfWgԫcw?s)DL^('AT:)b"SiO}E'n.EuHSl;=)O]C)c S1YCB::ź 6Ջvxϳ̘"OQL.̾a6"7Tbwr2rNОU2/πUЏ -X񘚴q;IN EbƉX3W@QE6%/N-)R?-$ÖT> oD E9y hOa Kt.g(71l}5cF׮1jI_z&K/_tR_kF}Brut7CSa;s@uG̋9{] X?9bDUyQ&$?)0 JM[CѭO "WQғ{_ڦ7$CVWVߟ?(E:UTj@S1١taGW!O6 0.糅ps3j<%,{oa6>XUy3|9 裼~1R7^[LD$Qu'O7Bg" e'zk9eLrQBx{:>2=E j{dT);Bii#7ߧqCˍF0>W3j$?#Nux&yXom()[&*6PIa~_c )rDF?Q]σ8\~ (-;Uzvb)Y͕$ P,0hY+?BO?pp O$1uvHȸ+vh1绎'e( H){^j{k/R6>T U#M<-i?FTjË 6~AHʔ&;ħUPJ5zv%P"'OWMG`TOA VV{ ։ >br*h~ pnem||hZXe-xS`P)tHD.D\S@HýT=ÊK4msĸH*K+SxKY8w?>Kd ;qq Y~EG Ey]&k"Ǻ /DSo"1 n\6RVyٻy g̦: ',o[M?Ɯx+0V$u^huZe|mԱ"U\bɊ+i\md[rg.ӘjHJze.RR;S}a@S'S7Xhc-G7 j$䩬 )wb;<=Zxcޕdrj9mz^&@F1빯^!c<669~2?FPu;ktMmCdL6"yD+L95ߡR_?Bq:4X|na g!9ٸa/e)әU1&1 -q)Gâޮ)8\{eG 9YA]kp=hf"N Lϰ !'i?R.Dh/>!):i3C,E<k1]쯝=25U/R2rgrkf|5f)J=t۠W*Sm (P\Gg0@%#}.;tSRgEU]49 AQ8Bt2ӡ>M \fpi_lۼd03i]>nn U

Jfy\.YU>->iGt{BL\|MΘ-j;Z)0;zXܑo{OuLU{p( {z>G>@2WϪWVq˅kBgޡ~=ʄ!l+rdRcPtPIE$!3'辈y#YwA< 8lM!۸k211\`f΅Z딑}N4I )liu^ rzJNi*}Z ? ++40'S})Ǖ j{hrS| TCz4rfmӶ&LݐwTZw +ׯKt\vm$JEƍ7ꂕPNwWS{goéoIMKoCP!!gޒ$w! :y\f̤zLך9Rx{,Kbypb =bklsd{`0lP^F52xe|zѱfǣGlyfylkUɶro(k2Nr~F 6h] "} VlŅ7m#W*٘v : sql8U4E .[!7(!#0Qۦl::a`*: q'FhGTRYKik= ZB e.[)^|sRTq Zr:- ^ؕ$ä.0 u\$G0&FxkMu(l$9u{4ٟAIWwc$_*/ *GhD-9Wp"ö8sj՗/Rm\"$S ˣ~t%eF }S04sqjnT@}i7k'x<.Yj6^dJra"yV}*W7+TL*>=~r#ڠCPi:1~vy<H쐀\$Ew'N#w!ĵv*OBB»1"v*k!4&cww]x$סx8yɚF>۝ӎkԝ~múNxn#Ht㨜BA(t'( 7Ka(>zu)b~ôq.$d)?InNoĆDFԳlb $6_ծ Y.+yi cs0}WbAI 6e~)Wd<Sfi>ʨ^DFV@1_1r@ D\aAS Hc?I{e2t$xc+8_17@d3Fx f ͯV1wW52l@yk~{fv1} {Jۙ/VCb 4fјP>P+𐗎% KjVELg$:ӛj`R z]7 FŠS U`N`%NùTlz8,>`[w4O\k6NXƌJfİ간>ӊu5lš-N9 Mij̚ p lr-Ib9^Tw4< l/]P2LE`|+NL~ EB23IѵZmZnh֘gb&w~%]nuS}?ѠWN@8Qs2ٔȼ#HMKmD5L$C:-| 5KFPd%P bI84%ёvUR*3WBhpϺ_|-,!W5a X6 αSd=W qe7oGiytQء2&m-X؋ }xl)ŰqϡBN@< 16h=3" /FAUT<8Q2SډnT+ϝor{fLB/5cJ Xv~6?h/uuq7)7 ~GRZՄ(TeŹݐ>T^mgq.uZ~,0Ah (RPM0ů',kڄBf=lBu 0,ύ"bzOm@Ŕmt~I c7΂`Ң:"1щ A? |*R --OHo-B?5*ڥeRWOSȜᎹI%Hʤb6-"2;y?H2;Dq' }x#sM]g̴,/ = ?#YO۪P_D5<لx\i;}2qȒ#IZ|/J#dRˠP"Fyܿ6y+ j<tL]FqsfIܿpTUoR& ,4Oۋ>Usm_b5[6פ2zϓʖAf 8 当M5\A gWĹk5-rLt+ە\52 ɱІڌP\= TcdlxapO4Dr_c 鹔s[5o\ױʯ6E]pUFm[2h>GzhmkVr(v}^sإ\LsM>+ qH>}вڄ&A݊{0d*5p X^=8UCQ_>_$':; Wϫ-31S~_\*IJFJBڵeo#|u'F%k% Q2C4ۦҸN!]o`tI-c![p? ,&};Na鏋IVldkp`Tv# v@he;w2qj? a*(TIU(D(Y*4J'T oE47ƅuшhhz˨0b[BOP^f_~>Sחq?t1%N0@ -e :NY-9c|6&8ӎ%uلhɨ$ P`0^?l ˗'zAr)t5 YmEvjWs-1P]! >J-(Ԋ\LQg/_Wzbsְ$ЌE[fxS}x+3[ለ7/Gn;t^Z,>Fm'WQe)jFv+.CEqF^YgҌLE}9v VԼ]+V0#f~8; ^?2ztx=~Ւʦ†Psd G[A>N`d` P1$i6pU$,*|C*(ORvI}[m[_l|fje,xSE*\5Rh62;PeqA gst!Ox[E>Azk&@2Aamgtzj{@{It:p@HңP#S/y:lXLG5s$Q۶#e&Q l8"<e x RNN?t彌^ljm_o0E4N^5>TWϽb6K{cXg. ˺径 $ N:쇷_QO!|ܼDu \ Hk5&A F4:󫕥( }&4R\_~iJaU3L[AFU؜,lʳfW'^$k). b5먞}pvݑ8íXxv8]]./*;kEzS5ht /Ѽc˄!RIJy36_+fjwBφA o0ya%i>o쑘lLx~jY $̈́1ĞMɼ*ss'K uj;wSmj{]- -boFL}M<ȈhPo2@: |sIAWBz 7F_Ւ,6h.uЁOhGr2Pީ# f e8=iv!Q%k :^SMloD}fhW1~[$*3F,Ʋ?|o˥bs}Na)$Cz[p1MQqBb] +i]F^W<ϵ{@}5yu-. %%4u&0b(16z'Fl{^,]htȌu-hc}D9fd9$S!y1쩾*m@Õ'ZC7 5A;k ,v*r#2~IK /<\X7fģkj][ȈҼ4̏VHcH .FEkvI5( Tݘ@l mω/iU} T=t[(\W0'HT^,wݒK_Gp6tERɚjC }|:+w}!#(DCfo^YaLo^Y&C28Jv잚"K1=RW@Xk:@b5q"-F5C)eP [ ek۪2Yi@"n5Wڪ"6_qE\ly68gA EyTJo7FWϊd%@[lFc9pOmk_L’8\칣 ;m0TvMCv!ߎ^YxBv{fsj5Fa PpeՕ*#30NHeL, h /҉)|U ^W%!#fUhNѨ宓r0c4dYNXn^ P:R4*7=d +'uת Ț1xؚ5WS6\:g_՗1abUs{2R hc fJv*{_Gma8M$7anѩ*;-E98$'|,I6d^ݾieO]i~ ?$\}U](Fvkm%ЏE4qӞ%_F&Iڑ*RV'Um1KRbAe|" t_^cc%ȯ|_~ro01[@b46h`;ϔWt$j!uJYmjD{gk-tRcʺ;T֜/ lCAel""Cj4yG<k$Z0 &0w:u/'DkVl= K)j4s` I{<{D%J)c~wc5ͣH"enMҖ-i[väp:ܚ^חH69[E51 ԚokMRh=^mv:?hoRq\6:"޼— i4_rS`A_@+wnI!pOb|Jc/M%x My"2P=MK=h+MBcnu;g?A!w-"T2y7"qUKݾ;S6rcQ[#ZB}~2>z[%J[>r* Knygq^sz낆4o pyXg6p+!NR$nCH)e6Kee c|CUȳ@T1mW,C"V:Hk_l֫&%8FS$&=whKw2旫s0NNv;֍g_5]EG.R`D@1܇_VaoT\%S0^˥h&YUHE=AS' `R ӘaH{A š.ryK;SD7 "|f|aoXa lE04`C}ݹ]Gu4LW3$ɲ!{U&r7dq˖&U dGoESb>Ʃ~WO5Q(N69Kch5S6N8h2{nAv},lisUI!z-f)ՌX)p0M(bQ" b)~6>?!ZePf\nl- WeOZF]_۽eDWSuL4ۈ#=4ʮLؕ4"31ɓzW?o,VNrHҨJ+9v (,yEقmxdr^IS R{"$:eߩ|dGe ;D!`QX ,ItB8'bEBR:+a,2e`#W7ǖ0DKAHo9+i ); ,TҤϻsLټn`/[Z+"YqB17Xy-2v &-)9eH endstream endobj 164 0 obj << /Length1 2079 /Length2 14826 /Length3 0 /Length 16079 /Filter /FlateDecode >> stream xڍP[ upww.3Kp \WrսwCI(j` t22TY,,L,,l֮v(5. Ĝ&6qw f`errXXxCtp[ 1 1r3:[ &V@Ljf@WIA#`dbl)Dv]@s_&)cB[Yˮ`a ̀ 79~8@MF,/߽27ݿJd ;e XXJL _D;xwk;wߕ$EU&-Յ/y\ruA>qkg{۽u Ͽ5/n k'7)&?6K+t=ͬJ]#]b:|_ 06s-Al cy=V_3x/s,QZK_`dd9Y~okcPdGC G3,,f_cWI67}\߷B}7@&+ͭW};DAvm'\_#[xOog *;X0پ?O\o}H _{0qv6B`y/6NN=l3=.`׍rqE2 ^7 Yb}? ,e  `VS/yS8?2"wzgqޛ _{??R!{3]ηi{߯wekGupf.?nw^?{i.:y{?j\=~>4=]ןbC?`y*@OʢM}h}(gZF.GdTښM[>47"$/>'m*OF3CSE' D"/NAmݲyNn<R k*5\r峌1A%_p`\/,o:/`wMlۧx+;6eĔ.d_B즧o6S$7%;NUD#XzmU+P?gxnrds,Ά:fS+/Q[WevG:KYH]:;̋k, s{I`؏W"NK!8ͧ? X( #ebyV2J|pi4ʏ;| [-V5HM/~kFɕ9O@=xnc8V%?dp9C!TU`< 0 ~Eyb'O7ݔaԬy.AW19LRjNO_EIsYOL_>%+\І rQ $`!W2wY/t=6ݲYw KNʿxk\AIOchhs7 k byIP1ߡ[y|I\'Y:9 eFhuL78Gg*,݁y"z({j ^en}jl2m˱S0g?'Yx5~1k)7d:N& Y[xc\Oprx׿fN˛܀:YI΂d7av@Zw[ d}<[,T͉ؕi͙ͥ\7QI/uyrѪqj#!:q+#uUMԓnb%*$taj&ؙV0X6K 5&0dfZ6b1ͼ4MSLn۬YJ=)tWVb{mf%GjMTo!l'sZerAl6M&nk\gu*Rj"_/U|!BG4A8ľwjDT8^\5И31=F6'"p3[:K fs %gnD704IL$9VԎ~ŸѤĉ҃ r8.wq.ڈ : d-:R3MuAN? 2^/Dթ,) 4Nq$h FřFK&!ȹB*TmiÞ'mޠݑbNZ+/!\NQtn-mt󜉭\ '؊]W.W$3H=nHΑj;$}p˶3EY@I:C5\TyYO ^?Qj!A!6L{`7GThr {nDHz% ĕ߄27kDr![j^Ʒmצ/Dk=Fιszgs]Y͉]bk(m7 4cSnBcZ}{k+e.z^/[qpX&`ahrܺd&26ԣ<|4129R0`cM\Px?ח9=sm F6tv{|#:RVtJp10L'e;cƪ\w0YNC۝f|N=gٓzI%!$lx$>]h#o 41gh!}gM^Ji `Fj_l߭)^)iP\I 5? ߾"%; NҝPs@%w̄ OSp;wK{K5a̍jasF1ECt%*Kpkl0h`Vq7:}8Cd%qzk j6CZI`U4VҊvo.=7<IJ,4Ƴ{Kt.=Z E@ ,TXwʛ܆YLJAe1Fl?m_n01N uRKI2i1],*퉷O$xY9@R_diV ;ߍMBmj角5U!1MCGpsn4G Rt(bY|1<cDE>ǜ`~[aۨ-^t瞁$,(t,4.b닸#Ye(c~rӬ΋X]F41 "weYђ(Eg9I>96DC'^rxrugbQX-.,qǤ|z?(lJWw)}EJDTB5(x~v:7&4;60? im {hW `i _ҟyq"YoD(c(V뼂)\Y4 =t[2)Htj4@Ovj$ǙnmC+q"PÇ1t&c 7&i5/Xii73t$1>\;O+YF2~G~K߁w:r:4+o0Av(-1 vn$9RmĦl QtMk5mO6ѣt z*V>LW6JPVdF_Գ:/+rrsMʵKBڡ`mB2|?d6!u 8p;pO"Z(eٶTf]f`2_} xϫ'{+L\2ZJ֑Q!&)-Ta/{M_o˨znE)Pcc)xȤh6w^n·OG{z1SgQàcrɒ Z1W[C5w3nVbYVs=wtP:'f+F]b`*z!yy=f0s>bu^JjL[dˀ !l[6,}*#`EJq;y) 9W@Se~miMsT+3t8.{KXhѥOۘdIKiLluz⫬A]r*%Ƴa=zO;Y!'#{JEi7yNrKW 2BZf397g*YrHVыo*4-49M((!`pPżōuЭ>b2II; H֬2Q g'p/Kfn ]>*6 @IBAG]}96@109f|*K))a JM0ǘUam ޚ"֘٭je]ܱ#D?Cq Nt/,3gӹ!ŇQi\OwPuUҢ{mμZ9s﮹SNKuVybO6c]![5F_ CM^3?}U.'i'GFf@hڱ涞IƗuOi7Ǘ-1s`>:U޸Q@Lc&}ZzH&z?,{A*^ч8]\$;UAx(Cۥœ_ 95F$NJ$E. QILm ԈGwΤgӽ`hٺ$̫/7,p:%Jlq&O,Es#b\]$HAE֖.;!$϶%+7B~YȎ̈́2U .CӖHA/w͓2%"޲vJ86 )K`N ;LUܣ؁]RKa?oZ-^#S~1m$%xU : }9d_bc>r#=k 楢UE{̩j EׁYR{#b;g o[g6y[563)^sb R`g(Wy>U bɡH&3 !ʳ ϊ5GE w 5tAfR?⿍"k"*NǗ#~(מfچuҠz=lLM | {hfU=;č]"3}Q*A5oi>o:13/p 2 ^YOz}1$̔3wyDEPU5=4FAc{d&)3)*s0x"g33m;84} !4usM^Ey jLX6ÏP F%#IkLw.89g[Gվ`7 qzYނ]*Lٱ/?=$!ڢ)4_>P`OvN'Y!xs89~k;u9Dtмq"vuJ|''Vja:TnGڥc)V9nw29Z%Ҙ*hVzӐ&!F9bkhJPoTH+B aǿNO:5WE޵qs cIB&Q =fIeWb{F!|&ٓ GQtx}oG0F&JPz!덻?ܻEjh&lAAkYH i}!-Q ztwZ}tTd9 2FO~<+ܝ 6\mOךv*؎l1ҫZ|IMWBJt n]0%_'i`]mQ i7MK2)p*1-v᪐^ϿQ~ kO({‡ TlD==3jn5WK c&lztiӚ2*ҁMkjg&:jqv4w<:u67M_)H7YCJ$iU:D r4#vYюJK,Y32fեz6`L.dzTS-K^tz \x \<$nK۠S o:63?$' F C13r؃jI;7գ{G* Jϗ.:SvrsCE-zR"njN`'3=_+[TJ\\n݃?A9F(@JRhH [JDM 9%.DFF{X3rkԁBZ򅭚zm. ~u@ 3T|o-)ct|{z1XO`ltrڪ g/m20w2 U[kA@\3h|;KFNEuȠFsѥ!JdzŴx:~AY0N۷4kfTn>ߦ'ZiIwvch1Cm<~GDEZie% rQFbkA,"iI 2Ѱg>ӝ֢sn$LLyc|OW ewfQjcx8ŃKh*o U c`P& Gw}'ڴm0GkbmI6hCNMi^gT=J85ܻ/3)9PڱFwS뼷 #vp<[cC1&0%'3sP : wpꭻL~Tzz 9U+t1|N`n(GK%|}a/.x,6zoDJHu8LLp#"72PVQ@mWr ;M-Y#",ahq_ݴQX%JnJJ| S{U"?QVw ! aƉIqnL(U]ি i*ͯ?0`N-7!~QS8C]ױUa5bfT i ^kѧ;W_C陭G!9Zߞ^CyE rߘqy钮 '&SyJA%u-VGg6J*yl>_x3ڴYD.\E%Ga]u Ԕ_c!uakzmm=aEl㌄왼Mֻ82g֊^ٿ y/Dd3 N 8}jn ('_Mϥȉ+= #𭧃BhK@q5rch`$5\%Z_N ($g/jwk՛gR9˳/9SQ.FF%HfMXV0NrFX︞oqh5{3H2Ӌɪ vKX,WًJUQ6p~ @XYu.2819ŗ)yytxGSCy4 KL,^\>?9rA&5\TJ/ Jq^vbQ 8MRCG$"ЫݳSap|*Lu$RFWR룥Qϧ~wⲽVb7?#U ֙N @N55k(wOp?##1$[Ҿ۩ ¾.yb^̣졚kG t¢]Q5p\PeN vOT1v|^W9pa,1K%;ZgiR,f_I^ƱN'9Џv `V,YM xxya Gf2a;fGx>Gg`QG#f-.M%>ة7c.L6n`]O\kNC)FT8^Er;4Xiλp-X(34XLjLN;imPgЖNgd#ٟmi%O'"G%~!P݌ڮ 5}v=o9 (!VKʟt c^1Yp|[Tפf9spaޡnWdT 2/a:?_?~@>׃ZiK4^uA)8v hXOU.vtAe9TmCa՛k2,34) {4NlS,? PSM\ NrFF̘VLtC%[˱"7f 4ò)F0M}z(ʖK>)KŔX_֤ٚ`tYO֢`:k+oaUk:gi!aL=̫VVܰYYO{2Q玩dΙ/4=΂?b=Ugo.6h}80qlKȱ/劁id ziT؄>Af]zD2O{xx^{Qz`G@5 R *0Nz~Oh^*$~R@jY(p|it\bFDFM Tn0*\${.m^Z "U9C?!dY{G⦒EPmZۤ aqn3xw!һ[S+[Rֈ?gfyƋZdr=?CrpE},ܵ*U(Z¶>M|\͓5A*b)æu֦j-nEp xDE ȿS!9ɳ (}9#:rt'fKdx&VoP(Z1{."&X{!z&[Fs 8%v軚_%i-pynH5: ")V r[}Y+tS?Ce pRdi_gՓ3KoHUPtl vK2>4n ̍{ ӅuNix[N~[W+ ,8 UWuxWG1k)ayޜvϡH6nk8Ejv?c,cd-b5ozh,,"uĻj,T/xnqQw4 >$E}c񬥿%yPԆd˩IJ3c(w<[O)RT>KZ+ hMjCzh!Ba~2wT.lblV*(}dzh[Fb ^/9r2Me]Lmd5+y)|ߚ*>^k L54bjG6ٹ<!{1/LU! ®O,9.NN r9ei8L:&O{ÅXq&t&QDzMېQISe (Q\L;*ܰ ?|+J'Yj<[kl6*)}Sn) :޲lׂyɟGB"G\ LK~KlwcCuWbޢW=([7xrH8o!ZKmWJNd1zxa؍lk+q anBiX!Į¯BNI% -h7?h9h0 #1*y&DɞVfX ^fʩ͔Y1vO"Is*(<]ڕJ7YSaxV(CI2 dG!XZ疘!k_["+:uFe;fi?GOkd_i\BUx'EntEi[X~hDQTCإ Dŀ>y!CtE 5=CFUO7aTjq`. Ā4k!^iPTW- KIO{rx#;G`$;lm5J4=,f" /l^<kkchfcndp ('?Fpazu dfJE&p."J=;(D R-?`+pe e80MZ'JTUQQ6K2qOE;$;u|6f 櫌227x̚Neۀ!m DGS3_f ˙ZB#;q`:k]+ȕu"JNK L2̮nƙ例M ;Ad}\XeK͑k fz>;ue3 x[!NIUz]b@nΩ)q1;8x\!z ,lVopz~wCU3y/zZH x(wYxQ vs[Q@ .'>Lzܞ݈[jD<f\އsE2`sdۏ> P+#d4H3ěDOV"(Ϗ}K 6"na17L5V-^lFq!-؁~8ogc4ĉG%0x]i|~ 2Qr[ܷ A~ ~_˽@  t9'eHBR%J6 ػ-rcnB4 ,6ޡT\ER#kȜ1l h#P8[)B<0.$rw4Rܗ22,@_qMzqfr5D$ }5$?4-eBeָ(N*h%''/0~\u ⻻fEx}D݁!VSHSUd;6p7>վ?ײhg }ޯk@J 犿igI@/|-lbE[ DnU?L{n[͎8L3=D,"s4 uV3d [+mEؽfc3Sŗrؔ3ta >>жa6OKjEPM]P+dŒ$<_m$}BFťs?SFьBiZš|Mّ1 QO6+ls)S7[pS'XE{")v(xa@Ƹ\29l-{W8ċpQ6\#/rfi4Bͨ:|> stream xڍP\- ]h=wwk݂w`-;G9XkεTIQ l932DUX,,L,,lj gfDJ l[#&f'ȸX\,,6ybƮ 3<@ltB{8,,_#Ɣg:@25;[m_W45MA@g*Aoldlve-*@'+ `-/eL5K_vU#j^3\̀rE{_r0+?dcSS`%䘜ݝvf8_]A6&27H+_-dC"e^wYLlk svBho`33C=(-wȫ _:Wdl0_]gGF33hCh~=|G;@X,|ym/3ǿ/_񉈀^F6{{WGiU2͍߂v`_^?2\ '+(_[X8XL_Xϔ͟n?-Nvq~ ylo&I\l+l:v6l#I4S9ZB96 ; ]`dea뼙Z'Ng :N)쏹c;:{ u@̀v6x0;"qf?L!? ,f0x^}*&*?T1YkY7[0;7l|vfK{K߈Wm~mRP__8_u r4\~4\4~ۂW:xSG |?o_ h86 n&tcLeZtlsy@Kx#4ԍ-Ns-DuT 9A0Nerq;NDpM;F5PM2.ܨJXwn5}%ˣs?*8eJ?GP|#uf$ qT^pEUE%wq՘īN\ X!&Ԍ-x&lVq -lrf7w?,۔N$eP6qzH q^hC(<ؘOBpic2x#m@gR(l8 ]O?FF:}[B`0HRnNܶ}F+*۶ћ`[ 'J 6Pʉ>{Nq'7҉D)f1"K5_mvYsXRV|Q.U}C`zqSN|34\d7m7 W:7Z[*?l3yJ Іɛ8zk+ғX{ƹT Ի]B\zb'$/ցh%U:㶇RBHHjU 'S,#KKu<*sX[]qm7'hqyC-IEnjkA'Τ3㖃pt x=5M%XN-WsX# dpk):~&Q+cm'n-Rf=|^ 4iѸl݁y!&+l(D]B?'QZ k `!)U6!J8TĘ#ſ?"&cP'9㎫Hr2ԧݿ-4/|a a.wLpUn=ts+o$E*wH.5Y\v)6gcK5T]JcOO;}/x5MFںx ]Դ,6mCVˑccb}.tҤ5.1*[Rq?KP`D,YoµLm'NngZe˧,ˣVP/\g-UJYͳS]pko9A d@Y3|dVǫi͟b7lq%fc+` ># A0Mȧ4 Ad$ygVD~Yӝ{-6Vf6]4FZrdũ9Pz8y7C@6{S0ZGId˄QvJ)ٸ>^, F|p{~*"G)ti\lT~[KN!>T1@V0; LUʇ ,Wa*=9Jtmvn]tR"BI*'a21uҶ&Y(}pA{TPOAݢ{r$Y`9f|S+uѩдTv7EBE~|tNnH) ͳcỴz2 ОࢵS^7-fPw}FRUFڤ};&tⶩ~w :ʂ U_cM.T <^M}Ɯ@#oq* 0wr8K3> ӋlB(,O1 p(!K2FAVMLJ/E#%OK)FB8j5?ٔJ})-q9S*D]S+4oJ7#-?{,wk4UW k5&ɣ GkX37)EKg9T%>R4Oh3葷A7s[lIAgK5_2v`x\|ѧON6>թm *H3QMI.k[c;R,qNU>K\-p!LVp( y@~5!#Uji}OF{'[7qm*?Yt˺:pbGCJam:HXj!I#ُG.eptVȍ5Ifpֽ)ZՓ­/ESI&$D]nZ'Ƚr Yuu%NV|׽p$d.4pv^@t,\QAA,/ɘc7%E8gZ/+v֕cFWVN';rα*H7vuoUz(OGE/͡q`HqAstU.:Xd)|DF\C0(?ȐIkg533݌iz'awb?[g8[֬ xֈy`7iDi.ߪrPv#sJ8 _m= Ex cmR 0d}.r.o+n=|2cruwj/$f4i_ ǏW/f0e {~v"?46.fTf^d&Qx_BN#I{19q^K"3k%Uxmŵiۥ7HUQ'Uy|ARVsh/rm$>wkX>1r7&veix,rcWpgdY*@hls3P(TS6gPhG#ʛ` FJq3ݭFQ~%%XտdFH}<@-c;pM⺰Dېa(\Rx3>ejx(=W/6 KWY3@CضmF,5{H[lM'J-k۶taJhF8&ARZwX) jY#_,Quq7ݒy^N5tf6"pߔ"ayKtǾoOZ:]ΑeV=* iGSL'O 㞒ip/9vʐJ0]ch;0H.y '\tRM6bۉHpVNαObxb$ )tZfr"QE\o,- RΪUQ[70x녯HKəƃs?Bv@眱Ss|I%|';~RrMԬL,D>K'S [:4k_-Ru u@U}x¨MO({k;Oqv,l)_EМTJIfcL}{kIⅹ$OCKB[pFA(WrS̊8k1!^y_pd82$-_QqOX[M@Bl!i#٨Jd )E3ʍN(`,Fjl&?mP-yn^AHe[Wi\I +әwTC?% FghT2jN(:N_"fMm;έ";=зp%R 9nQj ]~UҐ7",!JY^B_dTڞ',l'@WHP rtD3k0)/ ;kӻ ,ْGUԨѪ׃UJc#K1 wDmz}$G &FwFp5;!Gohj .hJf?%⋔X+]qk*EJ:e0mѕ"?FbJ[B$iQ*Y:g-QyC.>1vB]lN8ho,A}8q L0lH#1szMSwhMzubSE1^X|:2Vi{w2mmpXM+7sĻ鑢s~݈Hf|_2l+%m2 /^ȸED]om]h>cP.(BgfnH3i:"/?oQ]aÎڱM=Gs?KaWGxSHdS3[{S -[TY{[nԚlo+jDGP%rö|R%CJF|{y38ov{Ǵҟ$ R1YP*tz,tZ GH,2Acb)X(?H bsִ?i~h o|lv Զ隷 Wgjs9>n s÷^yO-wﶅ+T1}[72[Mx<=᧩XtUyl`+_r?I**2;C}FBt>` pn(e`.UH0 X7 87Usמ0a5$k 匷6R i=jw\hk*cx' axzT2ұSC><|\nPC+ڑg'b#?nRKЀxx觃"@}3F̹=#迅 =w3.=u$*Jv?i߀Ϧ-h }c-/F\>L!t)ZiM>RĕIf5ݬ(%̦ؗ/zf\,KJ|G_mUˁn#Gw V𓑮|=ַ !x׶&C%OehvfyA(dqyIy[U~%ږ C]o@p"129dY=N "'fS7/R@RBbx_fCA Łw0;їɘAh=8^wx^ ݤ ,qz&FG6$0[VhC8Ej(g)sǪ~o.xN-Uadq;N9 sL2GMvt+C.풫"ڇmXU~Xa`*]޳N1-R,>*k˃Ԩ]v{3Ǿ6(( \va6k T/wZh纜@V]( 2ul-VB'j٥M_ۚ*j#ATS\<$5KE־~RBٛ:\ֵ٬bykqU ;#|om.e^0*&ɽ[ 4@ٺڃCϙDmȖ>=F'4 H_+0"k?> FoWˑ-_V_>i 4ʕ/_ w?P8cۮEYĭ%Uf -4DC ;_ԩ,i]+1S'{&'܄O|U_"Fە]XcƔ3}nLQeZmG}0Q8$='38m'O˧CJ AzSUA$R t'-Z*u!L)wZ!K=ԭ]L$r%G4Է|5I!zw)dIw#Lم2BN^Q<4>[?0n R(/(c#q|ԁA|"{ǵ݉nl!୑"p|JJp&AۂO zgCkƓB܈S!{9 =_ޑeOCVz)w:=bn Qe `ee7Dd呸7 ]]`Xڢ\Z-5dcHw6S|D_Pm"d*v#G2;r%dMo]Q^XJv#\kI*8nTmKC efRԒnOwhtm&[9z1E@Kj{n.ժvh%i׼}:aٸ" {~.C>v+&"_WrUI$9?fѱ= ]wt89GF%̲0Mr!-R;6}!1|U63"Z;ɯ3=PYHfsV(Vu+wM G)8wC(~s$<=cOm>K!'~xkچNVf\j 22ƪp"ccnoJzpF8d^5(MMNy7GE?g"'G(z;S}nQ QWA5jd-7}g70eRUPPޕ=ReǽqoIty͓`9%˟8C,jHkL?e7ASdvrvۦ|([Qdr/ol:(5^h1-Z;@=4VP3,9̄ M nԦwUe7q0cjƮhG?1+DΑ~r8g"T@dkG*2樍k2EOK"9Pt:#3/s׼e!Ҟ!KiF ߅[t"NejG#79sK*[TF.'⒴M){u v2c d 6Qܙs g [ _ͻ\F^hX-5Pfޡ~$ (I:'\ 2UXLOk7s. 1⪊߶JSX~Fkic1ugg{[z'C2m Jݦqe> jNF鯸$ּ*i#CYe*5]!Dy[o}$Rַڬ&:>kbo/>?cԝMGvǻㅾ[fY^=o_oa#vRc/T}$ ^ah.dC`릢r0uzgDbkٹLbS16&'z|V֎p{[·쇖OcLzW& g^>DH;hQǐXVj<^Oτ{zXnj^XR4ˌטNw"t}D!T0pה#}QnGLH/T{[g3 aWsNA+NG'.hY[CLt]O&{8Re, p= jWx6~ Ƥa ʊ [q/P4@hulun+fh%{rX29G07[r )evbRI k?x&4#OPFG?چCg^pu{TR "Xf;J,$/> Z +B|G1Qȏ1iz5>l0#PdH=)\0K`3嵣7ڴ)DUHV,~֖g 2 jw~~W۬2/h1럾~ N+bgxcW/2-3O 2ᄂ,M'Ǔe'Ŷe^BgFM,5ih>7-DM![K,:"cC`2揆H{z=ڵߢg'}V7 |#w"JtF]dufe-7!EU26 `GH'mTώk'.a4*o+$&cMb>o ڛ)Krqioυ%W1)Hޤ bw>a Y0Zqҟ=G)΂5It,\tȷ,&K3x!P93ds`~ĞHqN}{Q|qԿ]Qߥ o1U%F0O4ZMw(`"kԗpl!OORI\l.Ђ=gDQ+cDžD Uq5J6 2!3}zt30'[|G~$>*( Rrkat@=#)hXIOY}%(4\tr?0mJ`3_hO,^nZ8FQ] ($0Tq-L.X59ʇ+Itxub~ T`ۇ"3ܓ0 "$w/o>R32SAhy=7BёkAuRġ9;*"nwF*FF'}k%?Y>͛؄.qqJ&N#ђ\߽%uƣXTh> stream x\k7_o.VjB`HX>xb{_[3f<쥖*X-IϹH:z0B -2(Ba-$p. wJ x&0IdFX-F,a mU6oN&$S0#UgYIqгnw@}v"_)"Q)PR"D *@@RaVڐcd@$^P: H TNQ8 (Ad ,@tpI[*PDUՐ5ȭUޠP~ vT-hLjWgmGthOT Hь @y&@A`d#iJP/%4$=e8 k)n&57,T[(H;Ji,u( (X@ b?ۀ !k|l] NQO2J} &LAtWm!Gjtb!}H~lɻUsZ #H>oaGOx #hH6oGP} }hM|!a &O$8|Ic"I0KIttFgjC SJo[hi uKJ ?Z %Pkb4Yٸ (u~\/5ej K)Yjo뺠dsZ[@? ۸ Jg&h7>tOE8-?p>{~J߸Rݨs{sWQ*Qֳv'>yUb6.~7-; Mmy-L3"DxU7e70٢) U_nЦ=ua)ƛy#mJ(Īms4 6[M_JƔ~UOVa(N低KOn~MœH^HQGGPǴE׆P5BGB|u~t|мN:[4J }MV ƀY?)'{2?`19?o@zv L1b ] ȴ&2cBGC^n:9dLćR?XY4HxW`b{2YF}1j$_MY:5'c bzҪ̆w&ˆ\AgߞΏgnH|K$lHJt$mAHIt$Ht쑴~$2hB?ĚH3 Ę.-44΅A $Ho![lAlsBu&V=%Oyb4c9wôԥJw.ƴba(sXl+54`Ia5.-8Ãv*U]I JD3r|ImMt-tmy_Ʊ ٪ԭ$n(+Ro%0ACFxIx!o PIFX&_T}1#% RlTav_fXoWۅh)EsPJks%< 8$(zMe&j )S-۶5KF]6rmR{9 ߰6G͈i8UO5:..kp9ݗ1\N%?q<%7Q7^J8S$a઺0$Ƭ`_f( BB;Ȕ$Ӑ?_@$OIpCxNfga00]ٜm,=/;8tEO;_5}[E? ޿q^~~Ҝf1C'!HF>J b~9@FYSZD)~,"? +  cK-肗Oa{č4, 52臾8]DN '-8w K8e3 C,56%m"yekMέmTrf8iQM]ʺ4Q3D$V%Ea(,of04"jR‘( a8l<IրSQƔ[KgqktZڬ(UpNt4(hPd4DZT ie>&N0C%j -ds͙/hZ+L6#uoE]^]srl9^=;m[Qx}!IÒEvHEtArm -m $]zdnN\|T*.w!4## ,]cxűz|^XC&|ZTkv U.? &6KQW4Zuyln_~})~%Ã;R8C|pLHH^%Gywr]3})$ve4>\Mfgg_ӗR vhdmyn˧ oK\pM] 5^LfnT[sy2xũ]׋9z7l&[6ʾfܟwgw}TgvRz pl^W8 NPeU^r}/I?>I?F/| guMAۭQt)ӏѓEt7жY>}{Rm~kr[oukȸs/A7'ţȟ%"?~$xpEpAn'p9TbW{1[5j:;jօJ"ԋ?z՘c*ƌfT9k5~|8֟o˩V,K`$~?_\z5L98}Gz:G ub\'es:e!k9,O.M`eao9֝$V>w'myXy$8^?PdA9-^]Z s`mgvEX]V@S⏯~tGJL= endstream endobj 167 0 obj << /Length1 1625 /Length2 8810 /Length3 0 /Length 9866 /Filter /FlateDecode >> stream xڍT6Lt 1tt# H 00Ct7HttJ--݈_֬}D%k ) p. 7@NCGˇĤC@IA.`Tz9Q&o4ӀAn xyEes[U$sr`bEE9dA.`+ (@nr|he¬ `Ýxx<<<-]a.Rl0r4-Aqc1ua6p Q[nPk 17@WEe'@`g ++ ؀! :7 Z6-- G?[e,wvC~3r0GG>y ֽx uCm~Svsy;TxaGf yyyE3ie;~?'lzqp.n ?*ak` CQ ?v 0}< 'ٲA!^1\um9}%9?z p ¼ǃG7q#ն]"@m`ѿ(<ݿh= 3h`؛ Z=~oG֣ѲV`)v?nq/kknU[.5\x0 ߢ?HH c<6CAsGP8sqx`L=>ߣ_iǻ@ +Yx}mpU,֨˷l\>.n׸)lYoV].dS?/m(,4ף$=o5OЙj:N?Vp [GIͥ'{܌ةʔ&GtѫYW8:|ZH l+EI`4{rz48 ;'ựZ,Bo|f+\()i '} ͐9&![:W.{?͘X)yUW[OTW=U~ 7[rj% µ潧uo]ķS>id7U =9TU#{ rĺ\:z]@NWfLI~POy$FJr5v'S ISUHg5=lzv EcfrxH:^)]lʫQɤwÆ4cZEX,O0ЈbzR,?[12V6Ń)-Aɮ+kAl1X 84W%LJ's}dE<_G\g"k,ă\*Jo6m7͍P&,pwqJ{dN1=IiHWE찂I}l-W>xFj>S'^ Aq( MA0.\+g8">fyzYsSotXFeWHt*JLNju"^5Hwx穣v͈@t [?L][Z6fx]|t/JN>Bhb cjAaȌ 2A$Qu P00F9Hԥ )cGEx\/B'GKY0Qw7qS+9xɓQ+{8Z]=v?u,ORD`6)ihڲ"F¤P[d4iV(uɃa8'8Umt Q.l?ó{N>0N828aٔ3C"!nOcKl+BAzF7&42H΋֙$f ?] PJiHhªPZܓKcNݖfhAE~2˷Q%r Otc(e%es] ">yQܕ rprY{4F˞_xϬ7S7ޏLRs4F0M(ٱt-I !C0 WLɞ:0{& 9As @'k#C7*Dpg@@gaۮSFJ4}7hIFw9j7.&ݘk3q̰[%7vSBBm2q-6vHG>GFŃ˜ }hs%v읿$?W/F0 qnKD{a>dYO T$Xv8jmWc$\#6%VNS#*bSӠV󉉅Dbq2ƧTQy`W9*TyKʡ}* R|Oro[J: ^{GyF u;&\(G&_)hy^c+:۱Q #iLރbϾ%^2^Zѯ%)"ȣ?YءkyPIfѺ֞\nO&%}ڈ_4"͋e|O"q|xz3މVF/mQwOf1xt{'i i%%Џ,l ϗ׸1c\ b5X-?sz~TOCͺ"7;R⮏Ίgvv c{T"̚3;2 8Hkb׎I4Lo>qadp81 \اlR4\h?9ȇFg,y2xa9LLx-]-N:q!֠ |[5}I1H+ZZ%Go1w}t0fXż9^w_>ic%"h54\͆.#="3lVKgCg 7DreN¹Iyb4˒X#܁՗dn>ХE&؂; Xb;qض#SlU3Lq~hkJx<>>Ͼ8h.ԵL&Jq6ƬfA iW?C|/ᑉf< ؁?t $Q-)ja'B(6לGx8z"x^٥^=/I/ȍݑ炨vCCZfS7EZ27@chE~L0 c=F]kLJwn$,t;')x;};k5=}xz2p0TDhs")y^q:ׁsu4 #F3H$ΟӻUr'; U1SCNzI+w69*)yϦfkjHa),s XvaQ%nI^7xX#EޘmDy!/\5XAu؆GQ}gi "t 3oK fi:آYš Xp 8J,1GSВpAo$M\ᗞx݉:KDT@_履%̑x{}>!찶Tnݗ#?OO Y{9VEtb- 69ρɐ<F~ ) mq%LG$}XZEӶ 4ڲt02Xpqleo1^GVN>.A=.3 T~n D"j}_S[-k_8uYt xS'6fO3YRj1Nqt|#qm qgCޟQMM؆X`}6?֮gNHLhYA" L&USZ)ZZR'ɞSMoalNlՂ9^n$_I9Zbp^;-YQln9ކϫCs-[8TBcQd{6{wzERmĉޯ5;9$Gh\z؜_J ެ݇E Ѭ.dFpBjĿ;2T>oz*HkmKQF;+gXvn4;5 |k*װe¯#j9mԇ,]٠xQjtPBt#W)8IN>hM8yԷm<(߷wU'6d9~KH~uAɓ$ ]&/F]Bޱ;3*x^)с_nEr?O^O⮉L:k.0=PhA*÷z- TƗپ:xe)!}xfǩSСYK=ݐʳ(z 350_*+ =H E̠CI1fB鄠!.ͻ,nʷyn/z3l6S,BJ]IAM/B=PG Wd(XQ˪TP`XJ䁝l9XcNՓ骺@n^F ClکkSl8}S{n;՚75x݁_.)/Ӫ_-X _1p?sW y=R͢Lټ(Z]LH.Ѱz `7UZ|Ls*Js"n@ 1JȨ[L&2+GLQ-$^Gt⼤KiSY.Zc'ť#FJ18֭cM$il_B|3?6'3M^CXp'~|݊wzQ *?Vzm1}Es:]F L8їzK/6˰st9zܔy*3Iw7)eF5AѹWȣ5'q 簃NC2HŞ>xw/OC/SoH('zl'1^7M&X9 ZUrq^; JOtguzV|KkX1\Ĺ 7VzaL;Bmm ˓[XEǴtʈ%G7v@^ȄO ܳZ]O;Sd (N^O=)"u\|?xUw"KgsҨzV ?G 4ʱᑕcXay?ץ"m8E DͶ"9 , GC^mG൝CljhPLz͝W_}s^Dٟ?J|uefnMQA+;_GYkڄVo 02 % V Oݟ|#0Pz[$ZÒpblMF?Hm^Šld,r-|ZG=-yq֗bMElLȉn],/JO:"- of)-(F#OQUԴrXS5 !orx˅.X!TIޜojQW^*ek3-l,wuV6DY-J^dbΞ!2-(c0zyrޅ H1% InFsnPAĘyT楃шARtJ3OT+y/b7!OQjJ9.u}_2=>]Eo| j{ Dy# 6FqE5iUEi^62Kx̙ȧVkt50'7^y2d V{1͔ FjodǢ<ӯL}'Eo 5>F|z#jO{2ɣ%VtN,<E NMzi d@8A$S&՘i2:n\-c@>_=Z/pVkegi% K̫S`siF2cR2 ,uى_F:,錼I請3\E2g}2FץNRx\分20pMM{ ̈́?&˭Sw|0OgqZB>/ȌdKPn˥_TE($jU;wx[}AzdY0CmQ #߳v^!lFW$:rܵ-SvUw+*c46S$3h#hgkE-i ɹ,C=^j# E+cvͫO۞=~r4[b *ɚڈB4AmJԯo'Bx1ӄs23x.UgbŇ*Ϡ1yZFGBH:23jn6n;KY MYs1QT.j;cC\ jj 7eEneuD6P¨+ QD>ht++`31-`?ys74z.@>Sj݄_AVb;Y+,fq[_Q9CY*oSRBb([~uo"?(:fn$=9TT(8x}"=hY[5#QN^XRȢ56|sA@.@Χv|A(OK:ō[/b/Wf ǥ[Z=N%nxk8F}R.Lߤ$+U}kZ.JIeWly>ZA٦g.ؗ~sX?Ir0)cg&̰l爺hүrM|)Z=]Pn;KUy7OPJ7XRNkōM`-Þe3@,=MGnK~tL ;^{jP mgѭ=[*h\\޼.-=h| N9ܲ/MV:狌ݏ<5R=hܞ =8_2-D!b5Bӻ^7@S'BDI oR&سq ~ZV-越!1?hߑSW[Sk+p| h* 7a\Z|ņDwn %P~|6{F;w1W &dʕjK_"t%7Jntg&7?ksY20%6Ϡ]p0'Cvf̧v7B+ػVΖ'ű(q5u.(f_$]T\~0C_wJP"/hjfbR/k X^ܖ@J%y؆x*C1#fi`™T7.4ob(ƱG^'zvkOTg#Θ L%8vp~L[VHE~!AS92nS#fo2ƐɸKo#NW;)yrq `rY̌ᘖZ~) o@~K-mIy۫sj, mIJe*ĮnwGD][W\3`c[UvG$j*'/sc0A-*mN0ni5_pLpJ}Q-P0iy'9dj:w ~ap JP͇ ; nj(sxe(:=jxVpw6i[9!/CXhʟ[骲Zo&A8cR$r; w5&7Jb,Q{fCԫA}{k @ >zyz8 "L X &?q#mkyY2k'g1)=r)!lCBG V)tD%⟬ehPC876k5lE]%"/U/N:U Ptո}!y?%2N#1yҍdv_g_Yi$I6iŇ޲dSq,k, }br7VMaq( lvKR" u%֭x\u _:l3@H<~h •u#$[RnJm_\| eƇJ#E"^|BP,YT]<( &a*l#]P%r'wP~P8ID<^9YY ,:nzˌڏ}w/5CSYc&%q2y|ŋJ(4fC-(WfDbmD ]0I fz@V@scY"o)BbN,ۧ897!*>S;Lb2͔3"+jC؜Leh̃F)Ҝ1#|!mJ+9 endstream endobj 169 0 obj << /Length1 1471 /Length2 6379 /Length3 0 /Length 7371 /Filter /FlateDecode >> stream xڍxXm> Rҥ ]c0#$A:$$.)A}ǎcUy_uo8 M!HGTLD PL%4пqNs' D'bj 4QD"2"2@ @)Py =!=$"TEz`=+c$JcS01[g"pT$ CN/44\}{ 8h~6ycIlJ~-~ʜO]]iϛ8doCSZIzf=\ꃩ:N>#IJrr$=mO >;U3I[au~.@XN'šTni;rCj"@rz!_Y=MN7[*GYã:'V쟽ciK`|=Νxq@8)^ lJoU67yvsj:>'9aѨ⁊{摴J^0?>iy7)j2Xc4Bũdpۆ#9BछyY^ZqwoCO- $bu{m-0DY],=h*JzWhi~{%b/rO"rwv`͋!B6qzanVK$wLmt]Dj9~- 䏄Jx™aNrwo| Q{vAUka: l7^L~1{lV绯^J 7gK=f`}P/RIW_Z'-/f~ -U͎/ч&n_zD(fISz#LWF  G (Of2gqJ) 2P}NyAÒ~}*#al )RCGt<5ӅR"Aw})z$5]6#S7IL-mod36:VgXH1T Z)YF+TW]1p۪G?MUEv|F]ưDPylCt2 4fp~Mdt}Q%cO.xQ(v*&GW}Χ㣦NډpR/v_čPlÐow2}i/< HM}zaRQ>kOz#8k)z}OX3]jA#f U65%IKvlE o&KXYm1YV qb[̷ߕ]qw(RPy;.bOS}Ӭ߄nux@K.k]A%GS ErRdQT%fմ7hxG݈U i/jDa4_S(<ĩc-3-^ID{X~(eGHCe":h]7Xch޿xA;gA׭ٸ~_}1R]A?lM͌^d},9:[t19u-h" >w~[;od}M,P;P阨'#]u Ye藉۠r MN[^X1v1gBw{mRQQWYn!{`2D($Wôc)c]-[oxA o8[: *O I;Q9ŹVo+R oμo2G^b)Ӷ49ݑE{vj+ܓO͢]l_i"/rp2o;l=0 <=%n`MʖZʚ%C9XV|k8@dη)Ҕ3̔ABeLL-C qRk ;ԅ0)tup^$An9#DXf CiV$WyX[E@5b{Γwdm(UR/?x1z0Dq{FȢ=NW LK]g~YTj<3i[cǝA?‹F ZFnK{YvhpV.;9TV'+}zZyfgcJ\)XuO~Tӓ[d0W8{"Tu9Y(pWoP}A즬m{S"ɤpU,14 +q.?C|@HoqZ[i`&n\f}^Qo%9 K3zˆ_6P#,)Ϊ=mwD?hţ>+ŷ10V;C.ǜ|Ekt%,3%mC w2,eQ qЙ/0sO88ln .j(_[d(}{r6ܨiZV4RnSfR?R:4F $sMu$ߍ7l>G2qcs;&R,ugu:nM_Z.]V_{B#v6U!oOENq =Vp}\M5_qtQ>^3üX~'f4lJ(+yO`&lYg7B7HٓMC 6ڃ[QD~ Nriq!w"ۮ9 (B ?/ Zus*!I= j8^<ҙ՛\S_wh{.c KK};eue*SK-i eLB7^wٮ>Kq*EuLgZ#_zY;Iٳt[~y{t&Y7o;0K;qh&XQB$]EUm?WH*Y\ Ypc)ϥ3+}ANJ qC} T ͺ5cmW;_% ʂIƹ<d2Շb7C^Uɏ>H,,'[=ˇ9oSUbč%˪%wBrQ|g{ۙB錄{CglM6R^)q<$|Ui%*7~6ǏOfͭbW@S/Y;ta ]8M1uEqeP\n(sMSF`KYOӱ:gkkEDIw{i^4I~ ݤnK>^5]= R\ҍnG B8U#ǨnVj]-c ,ZXS'_we|'/OA h3Epnhu` ΂Xݗs?uN}<?r4QSC!+1_J=R2˴%nf\^}NKXi=s㪺DžG>ğ;JXi4/\"{0$OKS]4~(/]kb%A8&;%1JӾ0V*cmW&Wr?TsNd[21S?\3YGR@ Xz&{0mr˻!a0hI:4EgUj}HD[R-c Z8uk яЛr!x!}}ڂ˕Sz-BM$ /`=p" FYfoS):,Z\}OgU| N\433J%-Ifu+8bP{Q#&]8W]L-%ԠϷ´0.sIQޔu3"gš7d^ݳ"$˾kÛdf)ӁsB |ĕRvU1ð&_2)~NsG u͔yO^:EoF?ҡ. 7</վВOgk:JQ۩3I%ڸk\aOUXEŻ~t "rmRNFc2waO} Ԩ5dMto06+_uZ[|N ]9j!["wN}_zgYF > stream xڍvTSk.ҫ4!${oR ! $"("(](MAQ{׺w333{m^.#SQe(BbE@<@UJIA q ^^38 QHPE XM QH,K˃eA 8$7AP>B0(wŗ (Ɉ(#`h# Ї`]`|EGaqJ!źˋy{{! v)(c]&0 ~@?̀38a CbH( j a?`?_gIWDp`# AHg 0b}" qà/ 9l E㈆c1@ E_i𧬎?58?v؟κ"QHNp$ 9 V 7QcsaR 9iiIqt 2Nx @`,^Q( p9ÑdǛaN>^{`xyAQH7?474?>OT *')@FV,7V#ItBP4R_#w^0?ʷI7d+K! O7n ApJB C-a&Y{"۫CW(Xcc4>0GG_ 0_|_>9?*|~`w]u# kĥ45&.% -oCx'W[%b 3/'ſ 8z|׿G9RLOB׆(y. /E&XuGHa>fjyC+M= gvCg ܬň09"D8FVP~@q) t}~Rb boHL`l%|~kд:ibKQ7l*}-jyàJ䌰E疗PQ*(W|r5a\RI*ZBZa+Y.^*h%9Y-;>G_MVmrQ6Y( %u EQӴ9aOT(%,wF{If"02kGY8H1̣,#mFP6yO=. z{ZDGYp;?->'@qa8bWb~rm c+7zR\[Z9upx}mS~&+n9K)HzZ=d"ݣ0O #fzUv؍e u jƞʾ丮VHhTM ,=H$d3~2pǧ: #ۗb(DjHnwh2~һHZV[9u}X=K5L0Pi !X~Pdܦe/J*<'`Y=͓I^f5X?*Ke88\>1RբMp;fac}\׺sƾ} }sL!Bqz} *u+uUsٳ$`wRnN:I R?Mbw^{) zNNSJPyd UӚk)#!|ږ-z])ᘔ\ϼl1H:٥rdEf5m&/ .S .i&y5)s~Aj#7\~c;;-qÞnlmk`b[q%Nk_z㜳71 M,[>iP 3@jR7uv<z/{N6gy4c1,UqR!R+ \ZP0DU%fdLLCsy ls?Aw}Q­G Ac}6畅UU?Ofx2mVӸ[AHmK$IJ>_wYyW!>a2R't,yWÒu_uW73yS  we[s`4njU)#̝O駖}7$X!2}a,dR%i fRpʼZSD/5-EԄ~d 9{۰^kvǭ0>46 gn] tN'۬א̕zr>%%e$v჌"qQg}/'iDmp=Li7roG0jL#\]Sy$_ uˤ~:QS *N5 Dd𔐸ȴ.9rAlH(=0H>ߜ0f#P7tmV5xnokb4,(kk}~(]{^r8¾0^7o|Yj/CeG{묫䓄c][r{ZrX,ݲ+hNgޱeX _H, Sn4F-T̬eC^ [fa;s+?SA H R2lD;W.- tU \{cnB셮c>"[\9a?KQg޻̻Ǐ>!&b~MDM11-V4K :;&`: 2UErhf 1yJ]m U( _rHJzWyeF2%ME,Z_~ZTp?F*s2U듢os|bV飭* \ݥbzPza ގX7e$UIPfY2Ao>̷"yZP^0~^lǪ_`ig.ֶciF:aiF%B#\`>^exYgCZ-|d$A{gdwέ4yąz_ǩef.4> Q\O+ ]3aJJ-/;;껛A.}d}>j҈\ [~'2tH%n^ޙ}6M>}'bҵUBtfU>alo|0eɝ$bN./~rKKXN/sAͿm˲hk׫|ˇHnϳO;im]+aԮjLK`/Mp#-)2GהdH*8[L:go]TgU@^[X@ʩ 'Z[ƇXMԯ;ղ;fiL¾}˼?fv& Hۧ>MAӪtwV|ߦuX}4<6ݡiW'Ρ}'2٪ɯMrrW^_qGC;9! ?LGV+/=„I2 P wȇIv[YW~j.J .)O &!zÕEk#j}aicXssѩs*׶}O4x_;*#mӉ:S8sSC*v$voy.e3w (_C̷gy3W.,c{Y!I'|lђ1'@o54 `zOF61ߖ%:!#&Xi`V 1JY4ǩP3˥yģ9kHn7$g5N;9U,\ltd+lQ6E&BZ<^yfT%rxDǛ]yֽhlyH@S_9"9,eQ$|DrAoڂ9 G;7rղ8.0; x 8mrhI[fer"NRVʛa)aӫC7 eT!v7?tmZp 2$|xSGtt]5,iTEl/MŽw5 9؉x.i_KW77£,j~`\EoL 1M _ ^)Z:7ԎJmҽ$ 픟ZJ9e$ ,qִJI(t P2C%H /M\ez'$,zJ$7L7nPsG`AQ}#C r?v9GYb:VQU޳u.D ޷+Z^Ϸ:Oքئ63*_S&[hvh%oakџQ- m*ؘs9^[7bmSʳߝwd+؀)cMIIOzʱ&5lz5uH}mi1_+τަoϤf{҂ޑzcn>:lB㠵Kknk #>J>|~#@ x93l0N RR8YɌra)MBIrFvmvɼ"o͔4s?pZ1=:_ʢ'10iqo9|sllLxT*գs&P8ԡV endstream endobj 173 0 obj << /Length1 1400 /Length2 6060 /Length3 0 /Length 7014 /Filter /FlateDecode >> stream xڍuT6-N etn;Ac0bm4Hw4JH <"! t{}y߳su eD!B 9 PDD$""2C`]. 8@!Wl,.zEŁRrr""@1ٿQh9: ($RCNX\P>tB@ MQP NX7Ў|@o h^p'`72 h43"p$ቄ@\s>;@g6@QY BQn/t@ VA~B\1(\> p~T1Bp@w,A( nH b?硫@á ެ sp@ a?A<݅͑O JJII@Igy3_w/O3A;D8q? Ģ=@TC@@{# : w}-EpG/ O kV?>UU_H\($+) JK]?/r"TA:17?#>;A C}I(K[RoYE/7/ᆸ!\}C-ῥl!<۫䡂tQ\HT$"ێh"|0#H0o\p*~8QTFC|"8X/) @aťq(4ZŁ 3ۂO'_ h4N~xp80=ʇ; o>VadskLUw${򩿓lQFS#G>6!sOxK[B}ǻ[0tFՏ7)<,'";W+W[1ֲ߀nloqVll(LO3s8Djs<81ܞ *HFZ?]^F ^K"F] B>GX ;JGdph~w]Ν&NWf{OpԪs%Ar\=pcKUV_N tÜն.Ie!Ck vJ)or޿Hb$eKG R2I}Ne:Pj3f<& Q8N˓xH-e#gymc>*~tQQ08q wLJaF]⬎g0t^d[rRmWd#>uY[%7u$iPO)Bug/0GKcvNH- ì]0cnjR>uhGՐml.A0pƍ.[[:0n`#ӏJV_HSAtC̕$ Cc}DbR#,ELըrylQTK@y7,K5/@uYRC &!U[ݶ^izZLʃSS#5VO9{f*vMBz ~Zj7”ų?Րz/ڻıQgԙܭ[^x' _hG5-boVq'pyjOcUȶd{hV piÈeDϱA PNBb1*,BΓD zUh W&˽mo;3b2J",} 'ٚD\HFcβ6OR=>X>{D@~īo-tr[2Ye\]+o^k4?0=lܮ eN~ϻD(et[̵%vǝ^Ly*όVXStNm0tlWڦ/=2ݨcĭ˦ yxc[L 9gzt;Fp&Trlqr1p󪹗]0'~Z F!T:5wʈf09 rw8 ﭸ |8v1kPaԶuJyM5ozwoJ#6&c ơ~9ԝ$d`g&li{"=Pc. =B RװW)uN]_}:jD7<MJmx7䳾=e*F+ŧA>]D7 2 ?V"aW^< ./3uziCsۀ*v9&5[4%wZ=7&b@l #Pwd H`|~؝ٍ]4#lۅq)miWDIUC/s+#5IlM3̗az0dَk{CsI辶4V<I-sH?'>[4.'$^7U,s X*E%q?X{3NJf'EG6|R\XPqRZt gngJ`%'ySm*?5!N .3 BVQ"|N O^x)>+]pAN+F e}>T 3;_{n9 ge{fcb!($:ȾI%׆}ZV#56Ot2!kz\ݞR`BG*'AZMGbDn^k=W*<"5Y]Vm~Ջgrn1̠qh y%I*m泉ÜjuOJ3zq6-v1샋Gl.#Aކliښ/OkT& ׫|3PG(V_lGGO$iX1p NνToޕ~9ϫۅL.li%}ۀaU% zc#aϔ(v{ mz(xuܽI8­Pƭ兘)d!=+3thԫlSVx$lgI96z Xrù{ ;c(&_h^Ԟmq%`qP&!FOzu``P}ƚ eԸLzY :w_$%{PFx638뿏h.(w8w G3=_o+xv~~` 3'7y=I6K%Ys  =;ĦAu(P0rzX9B` "@awG[U E8*[n$;Rd )ݯz}2ݮG+ūssZu޷7_MQdٺ{|$zGqI:B=g]f! %׮vp:$I\ ʓa./tY1ޛv,WX4]bJ.| 2])^Ƥt)>Q:ckM̓s&=JVڼ]}mp?e"/HH4#l攻A6\tl0Е&4C֥S 93%)`Φ m{SCq-V]k1co[|۲0b*VCv ^۵G1猪Kխݳ[ amF){FNj !:џUpvAm#mY@zm/ZLDPƧ[&7\B\Е F3ǟ<ߡz8lg(N?)ͯtxH?C+1t/0zZqUcblw# 6ש\ Lpz)\f~撌vkA(ε%|g'JU:ͷҚ8 ٔMC(*f]z";Ś~XX.$9ܔ{EJ7cXCϨ>:+Hj"; EØ}Xx{{HMΘ`z/}]p9@dN}qbᕨaIcF_*50k9P-e5Ϫ%u*C?4 `E*o͑_ʪNp8ؙ-3e;h^Sut5M7v#wNoO;I]{W*<7˞FnkTǭ u%nόx&N,ym7J>PblbWȪ@$G B}oZ._drBr`xq5w1J 5"Q[y:w{_^tOؘd*g1^&S%Zl]qFC P+g DS^F֐ P#]i~w_P`₦C`N*_f MT`WUwI)maGԽ|s#njd0/k1K ^cɬ ȼ:|0r Z ]m=%C)T8\ﺂ1-H)n.Su`I鬎W}rTWlPx~f^`u+6,n0sH Ը)5ay0:6ZSU-/苂@F>o n/;{M?'}^uH7/iyK_k=9',*{|!XᘋyGPrƹU7yzItݣtTR:%+^ OFB5GOlT(<_l%*Dl *FI+||>=7w ƅ W2[Nݺg kiD}ޤZ<*X!۹-ee~,@;4':`G¹1alm-r| \u\Nh*EҼ gk-odNڸcx )i Fϵ*)m%v/}8-˚GeJWvb㽇ʌXiy79HkKzghJĽxvUzZ$X*@Eڭfv[nƱql ZTF!EXg Ӿ˹AdG5YsSK}f5`2/0C3%4g|g#d䦝s 3ہ:/5ḃ\Ūg.^ NLPM He皸?uv\s8 dY(\ۛLЦ:OKHµ2w^g.4iU$Še j@B^$zW?D9cYd\Eu`(h[Jk#;SR\%W+OHƅuK9(20Ѐ*PdQx c(~ W!F*e?n&M eݟ endstream endobj 175 0 obj << /Length1 2076 /Length2 16504 /Length3 0 /Length 17758 /Filter /FlateDecode >> stream xڌP\ =и; 4N Xw  8=\DYA(` SPaa03123SP\mSh]@X9M\e& Y7[ Cg^;uS98z9,\@mF` btL\vLljf ruueb`4satpx\@;e)V ),\=Lw- hfotg2=07ܿ  do J򌮞{ Ml]MM@&nQ37?3g /LyoA@{1pm<},@0wsdҰ9em.Gf tp033srN_ Խ+YsqtpX,?>.&@O"x9` ] ~?g'@}X}d>a^}L*" t_' `aaep?ov?*]e-<"޽qdP{mhA}_o:"I7[ۿ2ћ؁lm>nﻡ!T VV}GD-省_r$h r5,0s؂.w/f{_=3V7J؛9gg/ xG]5z=&F{w;G?3_`K/`qA<&".f? $0c*c*qGQGQAuxcc-8uf.3YL? +/꿐V^V?ylߩQ;?BU?m_KkwG~F[G'Xޫu{e.&.Vpոz8~psqGc߽=\{ gܜR//8[Wx0M# ^_jJ?\E,txD?f-~kf1M^o0ݡBxP 7#"Dd .77"DpHFGh\ ˥IGÇԁQVRzpV*uƑ`A/'`bW):=3˘_ԥne懁b1p"=M hċ[× 8J{ʤ0$$2~G3TwI̜M-MhTVYd6rыv|W ˊ^5ZtoCF A x":& '<`%=1S1@c:93vX`0ڿUc.OhA17reۖebɔMq |j 4bep[p?W\ߠ$s䷐5ce~9Nf!>_F9{?m˪uՖ׹ߐ']H/j\V:[?e,+g,u/0CuWMTsӵWC6 P ch~9l߿ Ih9R9<數T}:΃s|RШx̺Z\"!_+᬴_5 Lf8 |>(zK"to$X& ?}J6,|qCܧQnGQ9Qڙ?@ W$5IѪ"xx&ݗ(Ӌ{DX[ V0D]jYfD/R:rjyd_ջ(%)2,%B!.\' XZk(qyl"16Q3ěW3LeYWYGo (6'09d7(g~[hU$?@u@^dAi"C4L} P)l@:L0~9v!ۡGO&:mkB"N$#HQ qE'̜kUU}a]S03L*URd5mlYC ± ۏ4uk^2ePXS,xN[-}"bʘג@2-Uq3i Y8Pi{~G ,_Nj4&SEbOܚ%LtEwep90]ZmxUSQV$&` )T>+>٠WL"8FC~ osGk1b8Â3λh:9޽l O^q%BU.e`.D0rsNfE)M~?WGe^U%Z><ۓ8ں:IS C> 'u֮(MF\rZ]/Mv>L'-v0),XAk/Z\19Y |#=ױP~DZ1vW@p.,|;G+:~>"(9+  故wb Uue N8b3'Q 1bq$7 l8X$:Q9WQ$.2uO(dYkj4 ܧ:|~B+/agI:#ZLWWm97P ǁs{QcvVa@. S%mrgC;QMsS|镱Nx )H;YZѮ 4dV[/Z^"j'^ Qnwj];m6uLX[줭X^ʌY}M ::fSuPht7ᶀV$Uj{\엫Hԫq{ Y#ik H K3\$ix! ߨ ]wfMkA2_@jBcN:5s75( I%SV3j+?U8IWkKAWy}[{£]غY`mH>Q8ԣOq:Or\%v$#bEBY_1S)ᅩ)Vz:2 4`c(HRxLyEP*}rCZ-₌aO[PlOYh)XAtK!wy_^ނ:Ij-,<\3ru\n(!^huRS#"`~VQ$ e7Vׅj:M>MTY7v1žP#f6!6n2F˹wX=oݝ[ܓlnFĕ,} T,Nd:oS`It['rucdFؓ}D~FOY2̓f=~pcs5x~Tid9uFlv'?ηHEg]L|#NjGXe>GXXڈDw!썶yXM[wӟyþ?;(|g)) e`2n5;A"gyt`q?on2(MԈLC ۦҦ58]S 4::qlV#vCΰ=^A{GufJU(za>2׻9ե?g6'wmoLvqnQ'#6ѥ 3\a޴^G'9hM><+n[i"ˤ]_z  V͚07M!0t`pde2^YPUE`O5@akKKIpc$ypI"GOAEnpxeM"b D3/~NqfTFsW9Hz9f0B oWkťc]AhQYBt`LC QUӑ9S>9$EX:"iG  :z?X_bQJ-zuH3`_υ7X >tCFrobtl{5y=7}ɡ|qq(Z7oESA/~GZlO?*,&u Il/q~||9msa,]Wr Pb:~?Pnfwn#-U;ϖv6{b0X !YZ߻rQ2I$N}$ZIvje =/wwpFO[ukRSGōQK5r7\3I7zGϡʿ՘AסLʏ͛or%6&MBn!(k0"!jMࠣ ( %8l)LCoжvUVK{ ]Gx<2qMXa>zP7>/R `,n# bK26z1SDֈbZ'#!sm>c, (&Lyyf%}?B^G3ĭ@@mjKI°O|;VcHٕ5i^vM4Ֆ~D7_͌a\ub)=V٩bp8>qNY r&Ol7/63Ap #?U #V#;% ƯA+^vxLy8(J -JbcZ]ӳ]GS!Jwwdo0M'c 펱VA:B|Mg 2=trvFG7g d'eeV@7+cac5(5Ѐ#HϞ>ݗۀJ,]t\sV1@wih82'qj LfrhXp[ ji\~Sˏ遛nF2!:e I۴Q5F$j1 pqӞX±thOeki398ȟI9L:6ٌ<}*03~`UnFcf}xd40=W|Ggbvҩx lmvoȓOPs>+5xq vg$;Wű.@]wqkBLVsp&$*X$II9jged}ar5Bh LxM( 055~{&Ltٗk_nw'=v03wAq݀excl r:q[gj[,0 QS!Ѯg2L"U~KĶ+7>DiQ +Dž'br#݇w4 6c9R/2 nXU)Oɡg 2 ^Y?u;jE> L;xjL< -:B+ KewLƣqI;ɖ9$P 6/~;Ar(|0 Eݍ! UNߧ(X`|/k%a8zTXŸE^S;) H'Ca~&L]1$;8r6MF"-BcmQ&1wkz>MOsϪ[C|$ YizQw\7Mߩ,`Zv8fg 4pku /gkj_S$ 4 #mz^`0G:<:i ~BpѼY Gxb P:h# K;$1v_TȜfيhm+(ޙ^[*ou#9BucY${j~+-=)TXTf<#Mcf1Oӣ~HꣲBTUe;Qڋ=T^Wq5u!_)@#3! I;~("j J&!s©#D!on?]`}~Go^nf_MͲwzlC0 N֗ro65bgyHPo%7--؁o\gO[¹ko?S4jT}L6]6PU 񄞒#бMN}|6{@{&+-?zqA¾rVgusmgVS#Y`VX5Q ԯM!ةcG߮ϑq_֙)LJ3_z .;VJP8'6!j75ŧ>侅BRǛmsym vVyxtl %=\?Z`~.XilB0)&,L.:ֿZkcXO}Zax?{{LXXg2z q kCmJ v&|xH5Dwzj|XgT1TE}|YU~9pU9š5\wdJIy"n#_phzPԺM]ӕ Y*=Rr1%2sr}N[U:VL%fޗ\+oO;W+ `x.WÍ7!iҗ ~tSεYv .^K;DϹ 򦞀BʽV1"5`Z㢸?"+r&+ƤnsAd+EA"M4ՈAӈ(HyMVl6rhP%nj~jʍv ݉TP`]'`AEMuDŽp<6P{>;IpUɬm0oWy.JFwedp /n6d'4OAn#tsАp=v%`ڸõpYI T{2mu7q/}8H߻2jU֡Z<"wm5ĉYG]I6؇gw75{uzϵxvƂ^5x ]|Yd^\,jBMrfyRR|1ҏ2/ܠF[9;S0+`>^? sH^3*v˥f3(QGfi[}gPً?/ebuvbD&+_\dpQ[gLI7#.>4&> `'1 7jE+e^N(!vd*INMyG -'ˬBiisA[bobWbA9b72H%lj,i|%NE|ݐ=wc9]VzJmHW)3ǩT#_vT0@`GQcmN1k?0YDҞј&[{pR!ŕ oOG/^0ɖ\׾tvhQS;O4y- BW9`+UI^腦weO](1,-l(w瞩&nN|QA]iΪK,q(a[\:"1qo^pH-vJ^}\zNsQ[ʱ+u5Nf "mnR1wX_r8&8ʀKq"iܔJu6>7BҵK4 *s/^ˡ!|Қg6llY~bYr]R|[Z:CLޓusV՛$Z[9ȥ!UH32^֬O(+sAmC W#Vh 7=S>ř5tPSMTQ|}4Oxa$SiBQ-*az^Vͽ9hs TaedaԨԉ=9x$AO:jfx'ԩgm#GK[*URݩ!B ~x,7f!hp*Dƭ$"]Jj0#xzKO$3Q!%bO^=LqSeaĐZ4}|(3%~_ݲ.~!-WsWrӔS߳啔ݦJdp&Sל1;>%yr6;tT͝$I:_7@jbBX7GV"ҟzk]Go45n )㭲1lF˹e" f-ľjE Wbbl|{J"a 'xH'F{X,~31V>g:xokIEg?rXqkzLMŞ 1hSp(} 65ۺP:rdIµȝg^o<DvJ/(&6_kZDЬ@;$_K!U2x*K&7b^Uf4o |%Ra. :\҇/\ Ֆ߲[V 2UdYvT89N6EOrY+}ӝ?#l:mAd~ W=5/i&'㛌Ťb{CcS7_ۼw yRპ> L)}m 4C lIuCQ R4D`U/Y/\VG~{9\v갾𒧡*/!:R=T|f,..F*9OՏrqWHJo-kTt7lB5ЃU 'F q&./id_ :%R(:a-?h3}?:.2c}H{kX|.qC=Z'-.+pRwy -\DP5[d^ՎC8BʩEϙGNDopQt̍~-KE/"C$cġ]?m /ko0x@ wTs*Y]\95|[Il@B!bJ2=RSRħ0Ş<1kx@<5sV2*p[An876w%9wGM 0P^0i)0Q MxxS=P2 ]YTKfWNPK 1b0(~̗ݪT"S&|&-'UGpI+2*S2s=#N&5H}'4cY7@`߻;7,e@wpB0t`n :+Xbs\RcF36ȣOVD/%No; ƀQCV5V:m6o}{]jN$]Td]hkELå=7|8̙wNjsͥ7!,G:~AU`*@^ 6PA'Y5PCl'ϩŐl3vm?Dh$d㑬'C!`Ys~mJI(%vP*ȟ8h4fR Ә ꋰvG܍B;o wYog|0h$eok\u>juRlH=b\"fHx/jfƚZS#]m9Pk{1Km J%«*X%z[a1yiiP, .AGT*ɒL  ro>% Z7;ő@>U@lh ʋ/rjUkKdUDV0ZdDȪHꮼ/K&4"p*8G5Ɩb(HwQA,fț{qQ=+TF=wwGZnkYJAZ/SDA-II:,>n&fuLŅVebVy-C´1^0JN}7x1R'VX&\PΡꑠ4 ~S3%ζX@nc'9u¢xb-j)(h,(`Lz ~Ŕ`>B\ an܏KfaMf!P_v"{ :qkYu6:6So= 6)n-ix z3KU@í(1y[AvWwW`^ FgHwqS01HN MNP^!F岁 <~/=sL/|UiIᮛxn _Ur L>sS\HlZvI" c`D#gs^}  k_mD^w,@WCBL&ǰ 7I}]XyNNZ'!!eN mp;:ZW՟ezGzMWێTº }oP6~u( ^$'M ,5+'ӢzSF\/GB{(QҞLтQ|}Zzx淂IZM5vRw:~[OiABI39{-=8L=T# 0ybgs v3tܸG u"_<>A=RMzyC'󈀼^oݵ(7htGlƮON[kB1=6ݛFtGR2'&e?qGE 37 GwCd,y 0y3>#^28i͜hL&l;sfh_ KCνj4.2&T^Xh?ABu)<wWG<7hP6/]2'$ZK|O%c}{!XԎsw/6ȁ5e:7F-jjN䪀SWI'˗5*[R Uq "bω|cf5L(e9f}$ʖLJ=7KgHX(Qq_y|Em%WNޯO䶂M_;#va% &L .NL7Jgsf^g/}ɐ]ȚVmo8+-Nj{Mme;B ~Y~_WlYlaUNT@ PG5"ʀ8;]zO󳭂K7gݹS]k>2 DH–߰O=8x 3XmjTtfLaӯldq9a{1;&" qdĊ!)QOT%#4/w4I+yܷÄOzP,V vzZG9\CX`_~4~s.c0m,#I'Jz;2ܸ4 /[Rp(l86ߟĕMg"aR :>;ߒQh?ےFiT![yk]61N&x`i WgE [B?pE|T ˊ b~Xk P*eROܩGzt{r3Y@5IM>EW^軷wumI H|u95^LhfZ.9<ǟcVoI[qSJGZ\𓩦e+MCȃ[xE6z;a&کuzdm6T=]UnK>̪H_y2 yg a{NF֩} ¹ql*zU*>&LGax=:uV,m?m˕cYk3.d)wx\|;I B1s=r~0ä7"˼aZ#M#5/Rp5ޘQ_ZuUjHދMDM-ճ"w9kV &T"\^nOQLpi7Ϧ8;q?]q*HYAkǖOwSBlQw[vGiVV~rR4~$[pWL mH>+Od)%6Y&;mb!5 'J*=rkTOFqk>^h}aaE#/o5 }F%H-DV& "10eUM!3%?hn:#Moc/muGU*<#. ; ybg7HjZI$1l$f?Ϭ5c;=QyL J7 7ñaWU;ģ3^L$+kS*IP`wQ}}7bJ؉8LҮ!rɜ*B," Vzg`vjW4^n,/X{T>dW))ɾ(&K^_ HW aw!`߁5SH'F,DSQ<7I o׏?f{Io(Gp~<6[l* GW@h4 Z 3`V8c?Pf#ddE?^JxX6M?½;t ~w6\R'>K'9ddFT+Zd&ȡ`NRx4;6J0zu]q(u'no]؝tKtZ6&\G !hzP 96"@"EIv\SeoM4f3.RᨩbXQ]Q`?"Gp[)@ F SC^@.vLjWGq/uS+[v5i񽒕'Ǜat Q/r?)*]P>g0g]9ة$aawyOP63Y&5`|?Y k9ͥj^Wn-`;vh[" m};ˆU֖.0|ެHw&g)0~dp;D?onqIaBi+ͦΜ`zuDRDzc]dnm3D-g?=EmzZJ~g~aeewaEw459=(oha!2+u[^+o(.dŃ5~(R1 U<7/ B0tjܡl N5sd:-lX2FKQ]A`34+:M߹m⯇[vvM? 8d]{m1L ,(o~bv:&{uM!ᕈ*qEũ1o;'Gu}NWJ!  ?Ci.ꕦ9N8Z5kb endstream endobj 177 0 obj << /Length1 1503 /Length2 7615 /Length3 0 /Length 8618 /Filter /FlateDecode >> stream xڍuTk6 ҍ 1tw4CIJ3 0tIK# ҈tҭHZ߷fg}0kq­p;7?@AS/ffև;c3?!p? n`O~ԄjN~A@O/ M4yjpͬwqC`arN9ݠ6 @;w96PϿJIA]$xyx@ ; `7O-e'5lf>#s' Oقz@ 0.O?~'ll. f:O5xܽݹ / yN {Ae96nPw#2ǬU;;a_)B6:^0,;( [^ Tsgv  W} /=? 8jC<w7p?Pw5 l}nPo)߽|>y2W-7+qI?Ayy7[P-  ]?'^m?x ?׆Z{=lߌOSUO;N>"~ 7BkmwDfsn~!>?P2l u.㾇ֆ#;Y||_=w ~J0@>|:-<0} cbE_֯ xmax?^?L1?"^M޿ov⿅vO/ `m$Z==>2P Q<,ڊ\!xшf|C+:>BC`KJfkO~N$;tή˻7UCL\̇bb(amr9mok&ځL#_iw/3{z*\rd2v>P[&7>(=~rfғz̶e+p"EUP3v;8i"Ham$ZL⒘'nD~4R}Ӵ *P]x%RvgcˇMλlף:ޒW'ŽZX47 ,Rh1QP1+h;&T" }=n]߉+@>εXye#1CX7! @eV^@Fv$6諶<|*7tH-iO+(jU:-q}5#ךԮlOf؛iʽcD=0Zza{*@JT*SaZㄊnXy +&!Kt??c{$5ńTwvPJF!!Pك׌ M{cZ"b8x_B.,pjr-y5^ 3k31h,^:O>i{HCrL^k1"C,\z>GPlP>~`MCnL'O,y,Z8 4fqpצ53PAw\5MfKW*'txB_Vcuʌ'dG~*S5)IʦzZ>&BDL/chePnu|E6˖vKYk|9W/֌;ޑ?AXnw=V*}95W!cv /Aé|]fgAk("1V èzcb㑖0KN۽j2~G"xmTpr4Pg@dlij]u7`g4-Ah(:(U`#όqתuQ*Cr6Rtޣgdu h-h~&a2o{S!!os);f& j:w|gc22lK_݊orJ{DU %? jP-ggUFcl rD׍kZ| Y8[5>xSp#C]3*}rPM@vRr)FЧYǑ [wQ?Htܡ83'6JiFB#p^5R9Ѿ*Y^8{b$Nt5˜iyVv@bOmuGnϫcTpi$C [K֫f6R* Q R$`9DSB;F!~DB;^eۡ2%f~6\#3pߒ"Q̚uPWFBE?Y&o"/˳8=58[V+"+6{Ï c]ucҟY"1{S|f 1M4gEƝ{YJM7ޓ8r^HkppBw3r<;9W&Be'@-7w$yfe 4Fv֐ ݐMN/ ;ԬO,]ӕaKmf\Ydėu==s;]P!1ټQޯr%vmoUpf`E^*_!%_ }df2/ejXV85t=Lb>!bW I]d~+TS >gJ;"L+1P)hm5]Э\[B7~ľdU:28r;1^&а|'qd-!9=|%ML84> eCL:47>inoqz[#82CZmQ%?ϫIX)HoX&O2=M99p|̲$8?hd4{ep4WuL7a Xfd$BC|pa 51Nb.1w(m_LrUu3k/~XLy?^7PQ:QznGvtZ/w_4]D6:^1zѡ(eﭹ^ٮ]_DpW$ ''T-H)d=JG32X|1"Sa~svZ2=f6i@f>5E'Nvk#wErE=ۙo䏿unG U':<0e + 2!֖O0<=ϵi%JEP !fbp>YY.F*)A^VT'v{F* #+lEս#3^ eH?Rz#I[jc+ٕ[/Y7݂mOWz$O! 9L/@)ιem<WƵŻi(Ps}ՠ`# ݰAj IHl'Ae2;`v~ݧeuΌFϿi|Y$G<&.sNI9~Fl j-qBDn=txSM] H=J?2SݙNN}XH$jly@[WZVKwq5Lj+iշ`9_0JF5&R\<LzGү,)\ֶ|G?jC:\LiCK3ѻF]p_t|aWqβn#шPJ8JT9OL6PW٪.*6% +'oGx%?~b3h_%Re̓{;X"ubsoy!5Vic5y8X(GX]jN"fh9T{ %-$)2,sH#|E_܀[^֊ӌDKOꅛn.aQ)`&|TB?:Q9=}2c*]VH&PCjy} go<# v $Mr> >g.uy!ތO7P+&ʂ[7ՉۙҦcƛ6ŏ:kuSG67&Л(Ƕ'F8_#&ƪX*Wܹϛꉾ?`o+}񔽯e,~941E׷Jƾq, >j`8BX (eݴ"N{'Xq)~kӉ+êDau:-srl“{r*-gmv,5T_ ;< $!ʔx F.ABTs'X yQFu:"^*þX}P ˝K~ZG'io$m9@ ϐ@dwOj15qa,:։W7C ZI1(9><ۏzoŪiԿC%T3VrwJ2>[(3E qG@b5ihT.wsHӹ5]1Fu|PmHJIZ"z9ݻ߁OwH- [扖I~$6vHu&Î02 dq~L͖m5qeq:VJo*{YBr!8MbWo_2 Y,Ж#Y^amգ3FKOWOemԤQsPR2:ݠA~tR˒.! ݾwre5{;UGVQ=rJG*u/a8B>a/#BSͱ\vy9_O(˅{zޛmHW#x)ԕS5][[#GBCY yɜX^j,μseyn-rAFA"2XsJOW2mͳ80xNֵii:Dv6n&M{sqJi\Yb"^U@ a:{i(T#M =>yr4у%J)؀deҼ(ZC(ekW$ h޾1Ō4~۫eך"D9O&|-ʁn)~w5wB[# :3h?袍yB_Gbmv`)sfFۢe{HFcsZS!o_a{oz!ːzy1P#Tr5yG \j'YF5SUy0=*w|&ߓ13R"KoJeY#ǭ~)CjS" GXF#";iG'nm^Jđy;N#)'j2!Qh6$:ΗP RjMr(~p~v*\vD"4Lxl6o8oDgItQm[c+)m~^)7?䶌YT]7Ys`}P/Ey`]Ob1N'J+RL|H0'alFe_T,ȯpuKfv-E2J+2a^yW^M2H0ۇ٘q EwWrBEHAEb̓lUj 2qz䑣@ Ō+R}xi #e]T1Pc@sNcdWc%J;%`<Έx"WS~X–`cni'ώ34evS~uɴ#I,N#äkbqɎ(Gf d_WmO[.!_OS6v~|`馎"9nt1#nTyrzxyRN-@/kȭhdHAEC@@ZPI}KhDUd֧Xu:sZg+{!$$9^t*h@e\d<(7[ M kbWS܄03demu[oS[x33ju!,vssRkˎkxP[&s`ԈYD7` ƧDk/{/qVmkӬ3D3ˤ V6X9'Uޤ}<|az!ixP1~ RO2grs]G51~={sh}jqNaZdn ?D>J15C+|k9Gety)j+Dk왯OäG5;ĿܕOI]rOgměyGuTmRȯP$E<>ٮ˚dHVF7 >T?-z֔pc@gʠ}R OOsZՒ[80\b'rWn˝H~AwR8l8 \6:H:}*_|Z2:&qbS_uWP'{t2%bHl׻fٍӴVyvWA7 bXhBc˵DWE. ˴Ǒ޷ig m&m:o$)KX_=5yxf]$Mr$(NXj &Z^0`"-9I!j-qj@ƪ+}e%i}4}+z!{8}uv[ō)/7rd=8Ob([Q\-u[DF[7TWЃ+KtX]L4Fn_~|>*Ryi@Q;z<~V4V,,k豳ʸ s,w-Yb/=ҚkzL5[l̓nt-u|VF2bFU[ݢH@e _rz\v铪;k[]5yyR\ P'?xAntQͦ !aP6- Ah YѴJd`ryC-%AdAkUY{Kh~&so`:ν'9<Ԫ|1#cG'Sr* lN"]Q:ɝR{AfS5&?pC endstream endobj 179 0 obj << /Length1 2696 /Length2 19071 /Length3 0 /Length 20598 /Filter /FlateDecode >> stream xڌP cݝ5gpww %;'Hps=$aV^{% Pޕ `aagbaaTrWO tvrCCh IrnVv++7 | cw+3"@O)lea W)-oshj 1L^FՑÃ΅Baj P݁fR(I ni5sWcg $2ڻL̀;@MVrdePR`rteۛhl7v756)1@J=?:[90X#_n@e7wڻ3Tw/kca_dneofWfnVNn@Yt@"2 + t=M-"Pr}#b:|<_ 02u-{;[yX@ `o 3swu%44IC11O# oKUpg.hYZ2(9=X8YLAWoI}Nsc;+[4@ E~_U-YhffOe]A"joao!\6%MZ=6N.< h89>5z=f&{W rqEq~#no`x̒"no `2;Y7F vĮؕ~#ĮT#o`V@]7kF vĮ/F ;(c0Y.(c &_)+( gcS-1?ٿNX#>/c_ 4wf*D TK0puZJ@73h0mRthכ *~׉TK/GK /? (!rrk~ G˗7'ȗ=hkw3뾴#$г;hO?XYA:>q8ni%?m$gv:?TY9.fy܀._CK 43iGWXA'hgf rVP^ fWKgc* n@P ^?d;8'o5usU7t//8Z׆Wx0MRi2,;="äVeo:ߊ J܈4Ä$o}}6LPk_,8'#dT}q lurAVq'Y_:~Kt1V#CPey\2hWF"X: OY7zxXo>[l\(tq oǦ|Sp} c62mvSEau^kcES3ru6 DA~7hjL"Ra^Э(8, O&7:A+q8w:Ƽ1BI"[yxWTj|I~xڬJpSJ\71ޤejr1n%ϡ -* #,*􆽖y~2^֏*~~ 7 L/+2$ qótvM:icBkHL{>,]\"e9G:,}'TE6 mo ֨q}^Iᯟ}O$Xf--i=>Ff*L _m}~E2|Vx1ٶ(5sI.XSpy 7S$/{\fGRWc곅-3L_閉 (EQT>"~̊ B% ν,T1}>PrcP!Pz:gS+X9~@O̚J- {c|:bTl)_cmJ.5Ur2xq@VZ)UT):ad>@бZxuq04w|^5>f%Wsq{}$?1$׈@>G zQjl"\r/ cWo,{z 6.-[Vp/2T䭁a)g1cA84> V!i<̧D`5њdvXPCcei݃'[f/ +ZxOwF A遷bbLjMdA2۲\bSwFT>4|LV_;=e1w$8< 9#r[2rR;12yᔔtqr'nYPLx:3c`qOמҁ2 tmg=s@ ;I=şrQ%2!~iCE^l0RD鞣$jO ub)x<@wjEq6S9]*Z+U{d$#LU=7؛/D˓/jD6p| [YiOPaLW9nvC*Kh锰ALtRX%t5>@2ōȫ]7әq`if3E+IBOZ̤!3dP$i7oC]e%ʼn؂Oqc `7}7z4i)1зmFCBO3 8uߜ}Zq5tx%Ks+8xW:ƙ =wR>f, wi_2 yKH>3yh?}p`&`c#kkan{[FF88dL?GqIN][(`;Lu#f}TkLA@+LbI4= 7Z4 t&RqROWYrao+X~Hn(zÖq>3uD8@l+mFYNzX-r,ƋԱ\0~ʻ ˘܉0 $#0G$g>bhʛ<71(p>a^z)L 9Up.=Fuٱ^:`FԊ /4U?G1TD cȠwiET}'l a}`\P–'LN =/JO~X?"o? mYI=J*̷֜JNܻ-L<}b }lZҦ=J"BZ3>~ ;Urv+1 7X7r^Er: DB==FË[i6B BbU;V3{w Cqшfw]Yg >½*lE$3X&>lB)4Gk!r!#oOqS}.ư曼rW$5E@2N>WSX3Ryr j}M]42c飫W,qp%oﭙEOK=M_ch92Bt]}o!Ic- !\zBNMA9b_I2X<:ۍMS>5A(m_\fTO]y֥,ͪn3|1r[Ê i(8LI5zWKTMy-Bݻ_֝i+0Z@)yʹhԫ-RK,.h3r9Vla !a ,Ȅ榍S9Ui :UAj{'f"02.[O7kX̿vZl4 -~$E/QsئL%1i6kjb?ϒW{_8M+;[AZJ189P t'J2.cYC.#mi!{˪0\hCtP@ٿ{E`+Hc_|J$,M'? GBetsד$I.|&!{3\z#8"کmdd0OZTX;Z4S2 p"fʽ#NZa *pP¸ӑ) A{-X*~x>k9!)V7C=5PiE%)\5?GVl@nXH5ޕx,o$P}F$=AuVҼ6]?MԻzB'InN.P a!Ym:W*0XxsԃRːM ּjl¿,0a;?G0tމX i%#mEN(G$ dڎݪ}`QG'[UE~ǒU>YieA"X zO8ݹc1i^4;%'aJh*bRC97eg/YQpܧ-[S] ,%/;j@)=@%x  UB~ڿuwŠ[CA@aODGMBceYν^hһ&ъ. lߟ,V&{н-IS[T3#9Uga=^ f_KȲͰӮWp3uWKjY8%;N֥#N2gk|E&rZE%3,λ`η۹J/w 2 i:*O#h@9<-GIdMi+~h͉ڣ?#؟w?}os7MlA!{gMՂYR#I.rDI]d׉,{Ϗ<(Y/LEk7R,"YYԡõ[ {QZ|cWOXVn1YN &'GlO]x&~r2)h)s<1RCL]Cw'c]XȂSH3)yIfӚ&۸J|ޖG id >̴pC<0/&<΢+PJK$y2v1Pp1cKN=˂W DwD5a1YƘ9_Æ<8Vw[ S'Njv`2#2ܽ/C.˗qFŃc2M*c ,bql,.Ϧz*Yť8+AѴCo`=?@&Դ~}ށ{Y̬1d+ZiK0oUGڈj<>?q`4_PS8gfsӆnQE+hCUN l [JONf@zہGQ &ƷJD,%m.do#s(:;_7pi1HSLoĜ&^uX"?rYcOA ןT}$-Di|A:7x_ѳLxq;Zǰ~a7^<|[Y {n#K6#;VDk07āʏ).l,rU'F=`~eEwBT#NSWU cFKyeV]5W;tZ> d]P|Z?Ȗ;h N|nsqka,{pg-q?X!N&&}F~9S{N-,]:+9٢U SKMeT=l+.q|Sog(W#z_~h:qc9@􉭤NhSF(/7{J8 EӞNO~(!oòe> +ދDw=xoʵ>?\-qRWUSWs^ۘ3c& uP= 7 YH|vzmtL+*ᡄ~JyҬmnEM+ŏ) VrHu8bn}:43x߭3A9s>tuK$G ɑL9R3p K(zN %#v{SEV28Lf$0C&fos')5fdʴ*<) .RLJU <`$r}uQf&t|] 瘜.nwe5ȄiG׍O|:\, Fh; !R\c\áa1LE4%q-<-W.-,FDv#U%%A1!/&3ZrA٦9wQܧ9\t >YA|(@MVYl 3)&1p3wg ~̝Bf#lL/ʱ->?y5j=c&jCD}eOB 3yOyXuk' \ٺLČHeS>cN"x"ObpFpvGUS[GesZ%"_dޝ*DU,dd Cd'8U c^_܄Z D%0K`U0Ź&q1˦u2_4l(0ecDC7`<'qaȄ6WMؐTIpJw 7OfS|g|t69{N*ܤI8+ӶOHlW4FuiǷ& 3_Z%A[VB'TH>꟦ҏ*_֋SB>hع`Q'/Ebۖ }9:Y$6!'EoD 0no;\` NB7Qbx3&,IIYFPh4,)_!CZ*QR(8_mmiDR/l8Fӆ0`,7?~yǸFm܏t}HT!'UBI8/fƶ{6Lp>Kzh* ^[SWw\=Aq8Q,$ '41QHS6`60X?PMۅT,Y iŷ DG2,woVQBҋ6.J&_B$aC'6K7,`? /-[0iK쎾NG8%WTivЩTB7~}JaʤiN"g>~{uqLoFByޟ?/PVQ{_xI.28lR-9 | __z,IT[}U BKd\jWj^#^j2i_Ss1q.R ]3vݥ /v)$Lxc? NOcbWPF`a>>t[Gc _zA~N78P{Ma o]0Ct8cjT}N-C\Aڊ4:9k'5}?1KzǸuGԇPLOac; |K|҂5CFAO5^Ś|8bhdűOaj%eaɢãcҍ> 噞1p"yXF OzPVB+,F|' n A:AK?p062tq#5@ V,ڦqSϖ8ၮ6lTCQw)B޿WSSuմX܆`MܖĒu=e-~=U!w?+?𝱰 ee]a۞iP?X(v_FR\f =D`h:-4KH̡9)yo[7PhKu< )pr7@Ca'SE] q`Ѡ*ϳQW$#>㵗{oA">Tx3WpTYњq+?>;Yzi6\d猾H5:LMH8+dz.9 4_Nbm" ~3h2 d"{p6O gL/՛}n ІbGM,'Re¢|(IJ]aIAiNƚ,:zuyx{jsGZb,^ ~epns上 9i3@I'9קӛ뛌 H cޤH$ [B~$l8m4޹mq$u5i5Ī~Hu!)Ywt۱kiD'KzXX`4(.Nb>Au-ej۩i_ȦN%TTK%G#v%{2^8^50%bݣ# c!m2jHca늏/*MyJ|^L-rK'wnޑɾר6y~`A֤#PL[us2rb̟<*B>EO0ڈ$K? ,oySV_OHr_ C-)e-PL){hg}VՖ1 y~KIĥe7@>'wvX-mti?H@kۨ]xek[K]bd3͑,g:Y8.+_( j͡=e SԎB!cP!Ŏp<obT_MCȳBT_"<7s_3Dd,ZuN;Ǽ)&K%SR{{U" x* p"^BTf"|.[=gkڷ,So廘mtO!v)άn2aqAXL^}г,(BH Seԁ4Ib9fl' _cHg)b(D2O/y:OJPu i}]+ ҈w6FQJ~Q~S)PƱȌިfa[@k3d !P3h>3VtCOUC{hFoˁ+Cts ;"3t [r Zl{W^<9m(rx j G+3!jUN)P.=EBĘ^6 y6vyʆo7૿e9%x0iŏul։Ǭ\"0C/A).:ˈUnF@4ߍ1K5(fJ{yۉqP+#(~_27𳙻.CK2 c3.ӴxDo #K$ư,U'N˹@,EP!JUݧ G[:qN^L@ j3yuy>oU-i8diNMܩ3{ڦ> W]&Ȕn3:w$VBf1]&ouX*bZ@K3>^kS,G$a))ItIS^:]VCѱA+9oڑdS< L$2V$huwP;T 38{HŀؒD$಴UP>Xdn}'bkE&%,=v{$+XssTGO#QTQ߫T9eZ3JH-],|Kpb*hO^vfP~6l>N;B e[u'ꉀSI 1]}|RF ̞pCLɌEMgLvY*=J"[ #Q:~b_e6G/#d A _NF yx诡|7E2 JaIN;9Õ+6bmF0J.@Qd:,]F}l0jP5RVyQz\Ö67Z|c3eV%ƌ`ꛁ&//BL}.G $(׭XFV #7ͫ}3܃ 40klA#FÁ:ʍНRA3cΙ#:qYr JlT6patKK]%/]SItb!Yb^0oH6zm:^}=z3蔣}'WVMh]6)CmѼy$ѤmЉ\OA9֊UB~x1DCВ6;ֲ8X0T{ ]J Lr1x/JÛƠuI2uU!VRk4=:U6ϙSu #e.^jg`lty!Ѣ>yq =hJpya0c `خʗ>Mvq jHBYJBJء=,O6;sY!{u;du[xfe|OiYK$X4 ~Xl(kB6,Toy!xVcy{_YukaqբV_ESK<;{ TnQݨ4H^,ߜ# Klz)Ցmܻb+xG(jE_5Duم44}qeQ{]\ 0^Y>HZj*-(2sq=g5Uo TMG-I\Um>55bm&{yˣ&, ty\*ymOA=޴ O S1SY |u2ṻlK.}X?aYt~9H(]84y.,]$8G^ϛD&!J=LBrQo~ eFԦGR8rDsKʕ:MC't@Ui$7/Ww,V›µٞ+ شcF]h7^U=c᧝VH)O||;Dv2|"^ >9İw6plyCo$i!F%;KPViOtR5&xmЫѩ*g]|}3@PψE'>9ͤE]&~, lXXIxwE[2c7e}dVȧdsfoR7Aꟍ(-SOaYe'ʪ6G1ؒ' \MRn594lKrϮ&\HPZU 42P.WO൹ߟh l(4ٌ%J97w.d>\'(Q1CTeY ,qΊy2%x&1?HQS yC>L%fjrc4I-'$հgϯdlpVd<ׯ?KRC&@MUܯFk l0zq#&6 UȽ?jC3c{N1Q>p6=ykk\4aؔ-#gnB(j)S)v+S,QpJt &%ݻB*'3,33[FENµ<)sPTuE Z&lHb.5=T $I@}ŬIk}Sx(IO.PNw-/XAAX[ Bt7(:r>$Q{>Zێ22fd0A{ =ں# 5cos~2޷׃XA"\, Ȅ4%5wDdy 4WЄ,!ee&?Ym$xν+,?{mKetvQUb1R:,q's20D?\ P9)T*ۂ$0iDH;Qz(W ˦"F/Uk͑E]5}<>y4Ssx`^d+#RznehYz.Xb.un sXA 7ł~0? .H4k%Mҡy3[ڍ53wӱpo"+†OXX7_tF!'Rڧ?|3: RyoebŞ+ O=`&3rf6>7V!}~X#+9 'ycl~%uczB}s?O(`/iQP^]Y( 6JV\QJuD{UT0%%2-4vZȾC*[%Lj7 gH Mx$)B}E"8|Q>'йމR zmOͻۨUpOv3AO@FHU]Լk-1+D;D}hr>#1I[M[KIԮFv ?~2&዁8@U)j\> یsB s QR] :Xn ]ݫ } csȻNG\suGʸz\Te0u3W mi/jc!+;uDR 9|Y9V[LRlg#F7~fۺ|a[\ܕ:vqW&w]V@}cL$ft<ܥ'~_v̈́1d}R:}4Fn{wsa\=ڼsw NqfD7`v3}oۯ2^.$eoz]% sHf:/XCt) egi ͕=Q3d5SVÄ?ZV|ERpхt IMC=vF:Xn/V[#II(NH n)v%:\ e~>4DBwa*lxi@[W&k9ng/)F bg!OՁp6ö*pwf߽'5x3.CLuO[h[/EӴ#.$]"VqoiKǹƿ{(0{IJh ÉiAhPkJ+adyY qenIΘ؆*ctOZ/O+}p ұȾm4oz[@2dwR_Bș|nl7߽#K:9cr/+Groʑamo0+^[™\&Nxxfs+2i&4lZly8,+ZR8x%7nQ]C*kT!s6c^Wc2.9&si# b,ӌ endstream endobj 181 0 obj << /Length1 1756 /Length2 4696 /Length3 0 /Length 5768 /Filter /FlateDecode >> stream xڍt<(>=ޜJ93;$#&$legK)w=2﴿xยo$C"T(D,(C0XX 0F\ FIeAp2 G0AM" @Ĥ R`0 K2Dce'4(C A:8y~<DRR;uE`p Ёp `#8qܤ@ ///A+Vq8GE`<v1e@IM0vDb(8/.H8%x0? @!>D}whW7r.@OU[0ݱ!&nh7@ዴG~(|0Ox |}VQ@ lHş1&V C\o1HYWo"@!a@TH|7_ܿKaȟ@٣oϹ4<3 ӌ %X '|A+7QoE..? =ӂ08f : j` \~?$#8Bt$ " #ܙpSf}W!*(8xDKHTv>H\;_8naE?$Rą$ o$! QdI otd _/HOu%4L͑pxdȿ T HXQ/H':aJU @ !/H =@!yw&=0}gߏ)G)> ANAK^sB"/6¶fU=?*m gA&i? U;_;ߘOԅ$3zhe?c=浚,lQvVk ;x.ϽO&YSSJU$Hu;2ABBdP4X ߨqнǬiN!OS\Z\vJ^K\hcҲ8f[Ubm]1"L՟=؂05o fo.:\?'H3HV\7"算&s[ѡ͗lykXt u.Ana_HyQepdVJf)IHЭ 7MU3i6 dc{T8;4D*kNfhȂt)Ǽ²o/X\A݃@we olLX!9WD5c>j'CxY[{-⧸ 䨨/eMl5 R 3j.nm Y%}j?e4ɼҽ #o[8eO|Q|R7s&# sh0coKڞײV!k~^RvU->.d(ȝi4.@#e+6L/|c|׭\SvKQj耭 OSk|a|(c#+<CA Uo>ٞOO)ƻxuNr^z'6V%C_­}:=CƔgRڢU[38b6%ρ@c42WR^\)-{s/%vϞ>;=N{Xg>=f.v@YxVa¢rJ+j((knEf>:B,4ħS~-펎.v Q+ hR[ 4 ![i` n:&pXsǶs^SGE3 "ҭTgߺ_0,33$64&~н:U@jϖizCT" / Wj *aoRאj-|6S)@\ 6N\_.HN6cM~]n*tkxwBp 9eˠy7L%eU{eeqM"+yӇ蓩'qnE IA^mp8(lUÃRH?1q).&bMO %?dkF6(sX^ "z -m(Oft63.#>jNjM$G!iq:LIM YU¤'7 E`"nzԖⲠ8ښd&5-iQP =X[y,SJF@z9}Oou;@kn؄$M֒x^L۩RKTmѨl캕yiܛǫ}eBJWZ!!U{.onqƗ C:R,m0>>ij<o (خva> BTԤ\[ S:E8XQ1^Pv{@$)I7JǫѪ 6@};sFPo6PS`Gm"VѴnm߱%Ahw^O( zMފAaoe^/Ť uk;rά[rgQ^SOnd c*^n#n/Zi]bN#}!ӌ:[W;"k]W~@*t4[Ibu6f%]7S^ʗ\ȇ]\ꓪ?Ħ-bȣ.!KSjt^?8<I_6zD,=I)#b9--_ܓ5wXسr.?!뢏 ,x<}Mbr * -}֘SHDe\̙B*̓∯lS>$ڨ|U[ b=V.T1Z\r@{wnH"&yW68C}kY)gҎoWAn}y/%~yIl9|vQ1v?Mp3u!5NEinUD0l75VJI:~+k͍0 v9BuTm(Xh]l] BvmZYL35b*Q|å/ ]o7C/*sZТą!O/7:)fT ݌#ΧKrʩZ]x< r߲I\HsC!S;BU`nyR{]|L|1"C\fCEh0#ۖ+H4 yj>;8sf"U|8Ԏ{qư!oވ'f"+ %=D 2ơO3?=6S[f[b[-oYrv .%\#9W6 F[ Uu9vm#Z:M6- O2Ri3-Ql.: .WZj< >oKɼ%RTW"ڀwZ93^\!vE4Ne)(G}_s|OW 2BQڳm[Aey}ɶBtotLRҹr::: y9&fE葾%S EWcl2H-',dƲj@1DvH#B$7P.w ^Hhv렏*ͫ_v6]dqWY*+@J3^9OP7LuI5|'1PpV$?GwJS4cR՟ؑ|2|^ށ2KJsj bse⎡kpwOs֙ dewWnXRżzzԕ_ސ'YWl!==6Mi09$"[&#{рfqJ ~ާhػ4yʽ~R;eyrډ!5CՍOMHLͭ 5zptIyiop]ĸzhԢ'#^91O{-9׿>$<0 iAŕ%]|R.̸!š{_yâZT3O3>}Lwge.C+toe /_0@˻.A`y)9abWmU 3g>2%UEVL\#L||̵T!+owӥijt嘞XIvRo\ endstream endobj 182 0 obj << /Length1 2549 /Length2 11488 /Length3 0 /Length 12942 /Filter /FlateDecode >> stream xڍT6LI H3 ҂t0 0-ݝJ ){_k<- X!RpppqppjBi[R`L& t)BNn''C?Bi il N4`18YrH؀ t2 [_!D,]]]ـ6l梌,W@vp~(m3cChZ@kؚ9CaPS!PC6VۀOolw /g dkcC35"BMma@ h3r @FB #bMwX_AMlmlP'GIC X>Y++`&alǮ;1e`'/7l,t-1H!f`tOG  S` 9L(ctl7 =N?-eWx 7unOV^+7'( @?q<ƓfkX3 , #3(& `x|^7 qK@1 l)la_Sߋ68V [ m8@'_CE@7 tmYnGQÖ3lMo/tG //`u`f.[7K>"#se']q_?"n#eP|DvG˧`TE|A2h<"#zDڏ]>"X7"A%_ v)&#lp V0SG31J9x~8A`kbԿQ9[^_8EAְ o#ߓn?6b@?,`Ts, ..նp怙?Loeim &af1~Ld{Af [Gְ\PgW5.|v*a1m1{Trd?>7nX %q:o)@X"'GҼ&aѣ,cBEjVd? # #4#uˁ`p]} J RW1._:]DN"%:"Vpt 9 "ֶ>13Yg}y̵ѡg 55'xs&sWV! }O6 "n 6̶r*v9rݫ.޵o,4?0~eM#Q0Lnt"e`8pEƂ\ЊMI͡ =PU1b%Xlά8_碸 hFHɴhJntj$})(g`5 />0[x*%x+ahz1NeHyG ZUț ě¼Ξ1_ih ZKCrdU $-#a'M ZL>alWtP|CMh!:nBg&ؓLd^~%{{'7Z*0I# V]hV'XGVo0ޡp٠R3Oku뒹qC=J&F춯f{Uo{HYXCM ~s;U`S{gr,(ۏ(~ < i]'ie/sni^bぷrl5щ$fZHV L$ھcxTl-,}Ѕ>B~t@2krzZ Gt+_(1#fKPMmɅ$jHը J^*4x-~ [3E1q&6|n A /V⼤ eG"BZkP~ ҁH/qxQ>kIlnhL76uJ,"6.qL!(iIB*ýtbF?k5YJ^-K 9>U>'˔~py/ &T ha\#+f& _%3dD}d.WsY[qu?ZK)-u1,}pnm4dWqECE ׮ewюT6D6_ϭO(,8Vq]zLԀӻQJ&InJZuSl]yoWxq.#:rh&&12pRFzѭzyWy+}'Gċ2K˨3mz"vY,_l 7{3Px-5𡄭/E>Lf=oV,# ?ꉏRVStO MtT՚w\vv=Vy6M=3݂=e%WѦ%k /_o Rr>];ט\l^Yb2(0lf+Y\ 2}?pS*[ɼrBDsi04:Px?K: JL&ebK C瑮߭s.q̶J|{6?`Ĝ6GH v|mzQ䌽:zp!u_HhDΌЄB]kͳ( ݑ(JEoUf2Ssf KfO LœeY^/ wۏϽ#-.ߦ {5Qh7OSйV| WE _8U Fl jQMőDծ|~`Dx}ICd+?HZpYy9Ar2l5):a$V j촐,91*SNBY>,^ 'BJqq_ 2t3$_)CܗaLSQ$Fu&3OŘ@U[bcOF'XC"OI ='D^.qI( ?B(v,.Ԧtn.5i*$p accYKE`P2*6hýJ?41F1jq{:&oҾR+\ G8K @+NKάQ| NohkǙ.o =^nlXlD4z=D\THSmQ:!̄uGzQp\i;zx> =jF ܂O,5 C>.Ruӡw`Mi.;Ө̩H$zg7 {/XH?Qc n}["l\fˋ3@)BޚĔET| Z9VOj>iTb|0{ ױ YM٤,?}NF/[[f=52jE5( _h+.l7pK68ʎqMQ%&N>'2*W;SE_T+D31LlfSm|E|/v>K(}j͈4q>*;՞my.3z6ڴ|³B4ěaҥu(,9ע詪ZC_TD~ssJ 3YC!׋lP`y'Yla5?}K'"vTd/x < ~ 9?3-kB4 w@֡/;+,F(d>' 8 +yVGa ,ǴB7*bsfW {ġcHÿaJpvLmEzNkjUQ4y ذUogx m,OKXv]= Dá,vEW0ZG&:#m;ԜMHsl+wive^3&Y.~:uR'"5]bz2cy`%M/B 豫ѸQ}R|/TjmrDD&JCih*3U dxYvS0;21`Fy Ga4wEבVxVON@zA .DQL^}b)(@:3RlL4f/(jDMӔKowh|NJq:A(wqsR n+AZ%vRI49\3s?\Z8ڏ&p[@'!yז?,od,VGmd-E(}-ҞLcӦ4ʎV !d>s4 Bi;f)#TrL+zXF< Hy/Hͦ L'ͶOjImWR d?wL~fP:*vAB1H(Z?H3,a\/e[n,\y޵{l#;äcv;Bʔ.ϛBb{X޽YĜ\cWzmEXwLa"D?|rt@"RaﮍW?uja9Dyii"ŹBN T+5kHf ksK` ;W$-\Z84"wˌyW֜ lZww!()ֆ_1}Ls#j5 xj ob%MへO$BG'p!#wa.WZcƹ C O4OG+MXO7CjR?G/T7 2h\>2_3 k¾du4 R,dL d+WKh7IOc>Ǽ rI>AmXDμAG-"vYb "<z# [c_qR^}&/CY  Ԛj7؜]G&V=<\UP,~pghINmIBY:4FcKBݡHO&x%< L^yۢi>7iѵ$ `Sp8GgYQ S93뺭- 'buj.i~Q,J+/ O\7:Q$X&̥yc;4AX:S^3`"z D&Es|b:E:dlI0H*"z?E-YF׸.NR_'~Aݘ?p"PJzNs$T `|( 0Oh55:32/iE ;gS2(?!N# " e4wqs}]+c5p' 9%ASOA(1BF:b9TSghFԞ>Ykǡ"WJ౏Y{L9kOF͂~*{T15O)+ BFbt~)0lo>nq#aCJTOĈj&ZTRWDx7(5 cp)Ŵ,ѭ9*w57W患R?vŦZ֫@ ea>^o84mV4i~0OL=}MF][+$jJÃ6=T-{t>ARٔ6uiT1af{x6E5oV 8l@ C,'%^4FTǥX 7rvKNlNECgq.mϜ ́?3LYZ$%g6Ett$j1T"e x#A}_b+Z Rd|sONg ꚩO[ގ Er2|-MLxM(F{QHU \s ,JNvޙ%zD7^5YQdo7j+v&#췣{r; )'L2Hi%Lq4PaF1Yͺ` gcHtn=RFWue6w)YӤue(|"x4y|϶8k;g\X2dqۧ{8N.PI~`ᒵ noO\oR{6δc޼Bg;^Ffy)19DP[-%‡[$L4;>dWj dI[K pM>=aO Q dG 92V,.ȪY#M9#v$b=(^[hq0W|5cʀ&OiY9LemK೤c Ng"B 7A0XV huqΧ8Nտd9T|V^wF̛j~y§Zh.%L>?^_)oIմ0ϥEL(^zA!F'Hoxy+)-vajr +r|9`zd#ݖf<%5/un;fnI$+' wv ][!/b_d$;זh|!DV];&[WaW2 4%hg`s0yj.KF  BZ "BMa i8!Ѝ t)*uт2Wvx&Z'?0X>)|6$}Ⱦ{mωge+$;zX'عY&| kyd W,20P&fPxOJkL=̀=~>bW_<ҟ7XgR-z^|F9j6 4|O @>칆YIѮm5fh%Iqaj*y1 bEҞG0ٖ*~ޗǡML]VA@!MkNKԫn)5'$vcf I<("9rg=Okp9g&~+Rǖm8] k?$Jvp"`Q@"WOOx}4{zԌs8ՖVyV~|r#&4X' Nv t1!x}S; [CBv_ g1 3{ҭSQ= UX6 A!Lp}SGOXbO@G)Qh3o_F62`$46T d.Hq[rT޶4b ;V*(^lFwz%1MgyH/}TKD?2j "JS nʷTwL|rw2 @j *S۰a k~-%&Ag]jV"/nq*I`e]2d컻jѫ6;8_r5 yo q cY҉|_xMS~VK壢8Pri(^; =&'1ȔȌ|5/7D4%YKu(PM{&Vou KDOsIt(h`grkd361B*O)e_PLmuukrH(,gp'Fa3Wwp,HU6Vފŧ:P]`Jyܲ sg,)dL[7?aڛ` [!(%5!qh۵{qZ[?9Wk WκYswƗ_گ >1nhl581mE7; 202<'> wQ\5w8|f9p{zW, 8jwR[\zskv8rSR$PuEu % 71NjuOE=#Ƶ{oqt/ǃT1WkA$fUMOuZkĊh=ް=Eud㠉p O96>]G$sWr3TkwJC&R]%6ޕs'/s#m5.#u:wؖ˱ vL_0aOt,5XVoMX0p_& gGbhGޔ''5#MpZQ0s؟A~f!"ع~gdqrE'{C|-<"혢4Oe_4JkkyOFv0}nHD%":8aiDtIwڗ Q`ܩSoӘ\F9/G ֛+rƏ\>&9։ 8B#lLt׫_]Ui]1_Uc,k0P^A|*Ͼ^{׽mEEl_Z\ $؇ςjMܙt+{2Կ>~1O34ɅA| N,UW b1WعHu'ዿ+M8Zk"{Rr}GTmg[ F,]xo}'ϻK6}z٪w"`6.fI!=DcۇayR4&K7]Dr5'.۴~=I5YF|#|ϞpJzہ/80v+\X<8ёa5¦z#:1cw7rwP*ި>:@:L،[վdZUs!gD2!}zw\m4e z5G8kV5^ϷΝiuc%}@ n:-M2W8jC'=U_]—Ř2=1_MSesdE_6}tIY-~sW({6"Ϳ:2DGpO@tE?N&`> stream xڍS TW(eA$3@D "* 䒌IfdB" ZQAŷ"Z⃇V *Ee}P@; Q9gfw;] T0$@P6+ HAY^^8698IIAf01F3y @"@C&@e XzW$3SRE _#(o-B-p9F FQi6 WѴNFsHJ83RP,A<8,/̠hp9$LP@ 0YL џןl(}KgᄵI#8it6#DL'z,5X:`=9 c=HZh.GHRgY')(gn߬ Dm AM"#04!(8@\ŵ'uD-0 ;KG@#fX&4eY \P(p9 ҡ'Xf˧pHA1-1D~L? 14 P2@9H>7Atc!39LO /`Yc@d̘)O$͔$Ų\ ob̋Ybz̮o_HyXz =w[Ci finsԻl={\[xs쉪/cg;W=xS;b0^n),tYBǛOjM>nwҿbYUVe!*2mՠ҈SΎ7V Qؤ>{A?D-,V /&'X [;T? +Y}l25Oޡ.qXq7^Y.vRyٟhMw{txhI|I Zz~K#Z$r+wlrymLdUz uGxU.Isz7K˒Vwg{j?msR7].^2}c5-=]g]{P.x/:X7ž1穪f7oWL?ͼ/|ͯʔ<ͣ]-`nVsR6<|}6W~=jCtZn ^ZqHћlh*)t?8TvHC$i_=Q]>.]*!5gőg3~/wRlK1;|[lO_~ fW nknZluQYj ]{ND<,+>4gz)i5Ӧt2#J/y}`|uOJzW1uo{kG5˯(cyk*qw64rV]۪jΞq8E߸]p+>=CSx䧡L T}9Hum 2v{ pNf7g&4\rͪTO9"p}"1?O2Mj2-м!!4:4TpR(D$*61]64y kU2GGkc'-ٚWwKؗOv|%9'M60Z}ZjaM7VG^"rJp&KU>-YW5Q36S#7 endstream endobj 187 0 obj << /Producer (pdfTeX-1.40.14) /Creator (TeX) /CreationDate (D:20170622104526+02'00') /ModDate (D:20170622104526+02'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013/Debian) kpathsea version 6.1.1) >> endobj 166 0 obj << /Type /ObjStm /N 36 /First 290 /Length 1574 /Filter /FlateDecode >> stream xڭX]o:}W^*ǟJ@R e[ mv86l%NHpĄp$R0.XJeƕs _~P(xL¨;|O+̟Ĉ}?/S\z<֋tj?`2]u ygfIςq}1in7@fM>_9>1{xxq8xxC#/O ?kzqU].709q@\p6ԥYcļIݕ5.QWKLJV3;EBH8di,9F$DX̘\ nG\ īt*)S$OFx@Ou|R̘FGyl@d UA YFe;D>0@l q䋪nY,܄y7סrt7[O^r2y^xy:|rar]3i6o`U?:6iK5(N 222= ~pLc͓ nýOKf¯ʟ"8=0NMu:`j_ 3 Pн=lN񥓁:_?Mˢ=v8S]EtγF:_tG=#R=!8ւ5dkd=ьe!HXCTBl۰CVV~<;޴.ʬ+kHYϘzXǽf)rBa-5HoiPH52%J endstream endobj 188 0 obj << /Type /XRef /Index [0 189] /Size 189 /W [1 3 1] /Root 186 0 R /Info 187 0 R /ID [<56F5B2A8B237534A76202775651B1951> <56F5B2A8B237534A76202775651B1951>] /Length 518 /Filter /FlateDecode >> stream x%;LQs"ԂO|b} DE'P ELH:` 1QHLqr{/sJD @*ԈzFE$DX'֊ZS?m" U+1"b+V2"ձB*$rnШ{?$Gumw5णNߎ[&ݾIQ[?l qNq^ bH\İ,b^%&@8^'<980cuߋdB󒫐b ]0*SW f,g,9YdK/6g endstream endobj startxref 270457 %%EOF latexdiff-1.2.1/doc/latexdiff-man.tex000066400000000000000000000274201313770416100174770ustar00rootroot00000000000000\documentclass[a4]{article} \usepackage{graphicx} %\def\C++{{\rm C\kern-.05em\raise.3ex\hbox{\footnotesize ++}}} %\def\underscore{\leavevmode\kern.04em\vbox{\hrule width 0.4em height 0.3pt}} \setlength{\parindent}{0pt} %\setlength{\textwidth}{6.5in} %\setlength{\oddsidemargin}{0.0in} \title{Marking up differences between latex files with {\em latexdiff}} \author{F.J. Tilmann\thanks{tilmann@gfz-potsdam.de}} \date{\today} \begin{document} \maketitle \section*{Preamble} {\em latexdiff} is a Perl script, which compares two latex files and marks up significant differences between them. Various options are available for visual markup using standard latex packages such as {\em color.sty}. Changes not directly affecting visible text, for example in formatting commands, are still marked in the latex source. A rudimentary revision facilility is provided by another Perl script, {\em latexrevise}, which accepts or rejects all changes. Manual editing of the difference file can be used to override this default behaviour and accept or reject selected changes only. There is no explicit support for annotations as these are trivial to implement. For example, I include the following command definition in the preamble \begin{verbatim} \newcommand{\remark}[1]{{ \bf [ \footnotesize #1 ]}} \end{verbatim} and mark up annotations as follows \begin{verbatim} ... The roadrunner is the fastest running bird \remark{Check this again with a zoologist!}. The most famous roadrunner ... \end{verbatim} Alternatively, instead of a command like \verb#\remark# in the example just given, an equivalent annotation environment could be defined. {\em latexrevise} can remove such comments or environments from the text body. %It is planned that the revision capabilities of this system will be %further expanded, dependent on the amount of feedback received. On the following pages you find the {\em man} pages for {\em latexdiff} and {\em latexrevise} and a simple example. \include{latexdiff} \setcounter{section}{0} \include{latexrevise} \setcounter{section}{0} \include{latexdiff-vc} \setcounter{section}{0} \section*{A simple example} We start with a draft text, \verb|example-draft.tex|, listed here in full but also included in the distribution (except that the ``verbatim'' environment had to be renamed to ``Verbatim'' for the listing). {\scriptsize \begin{verbatim} \documentclass[12pt,a4paper]{article} \setlength{\topmargin}{-0.2in} \setlength{\textheight}{9.5in} \setlength{\oddsidemargin}{0.0in} \setlength{\textwidth}{6.5in} \title{latexdiff Example - Draft version} \author{F Tilmann} \begin{document} \maketitle \section*{Introduction} This is an extremely simple document that showcases some of latexdiff features. Type \begin{Verbatim} latexdiff -t UNDERLINE example-draft.tex example-rev.tex > example-diff.tex \end{Verbatim} to create the difference file. You can inspect this file directly. Then run either \begin{Verbatim} pdflatex example-diff.tex xpdf example-diff.pdf \end{Verbatim} or \begin{Verbatim} latex example-diff.tex dvips -o example-diff.ps example-diff.dvi gv example-diff.ps \end{Verbatim} to display the markup. Of course, instead of \verb|xpdf| you can use \verb|okular, evince, acroread| or any other pdf or postscript viewer. \section*{Another section title} A paragraph with a line only in the draft document. More things could be said were it not for the constraints of time and space. More things could be said were it not for the constraints of time and space. And here is a tipo. Here is a table: \begin{tabular}{ll} Name & Description \\ \hline Gandalf & Grey \\ Saruman & White \end{tabular} And sometimes a whole paragraph gets completely rewritten. In this case latexdiff marks up the whole paragraph even if some words in it are identical. No change, no markup! \end{document} \end{verbatim} } We can now edit this text as we would do with any other latex file to create a new revision of the text, \verb|example-rev.tex|. We should run \begin{verbatim} latex example-rev.tex \end{verbatim} and look at the resulting \verb|.dvi| file to make sure that all changes are valid. An example revision is listed here: {\scriptsize \begin{verbatim} \documentclass[12pt,a4paper]{article} \setlength{\topmargin}{-0.2in} \setlength{\textheight}{9.5in} \setlength{\oddsidemargin}{0.0in} \setlength{\textwidth}{6in} \title{latexdiff Example - Revised version} \author{F Tilmann} % Note how in the preamble visual markup is never used (even % if some preamble might eventually end up as visible text.) \begin{document} \maketitle \section*{Introduction} This is an extremely simple document that showcases some of the latexdiff features. Type \begin{Verbatim} latexdiff -t UNDERLINE example-draft.tex example-rev.tex > example-diff.tex \end{Verbatim} to create the difference file. You can inspect this file directly. Then run either \begin{Verbatim} pdflatex example-diff.tex xpdf example-diff.pdf \end{Verbatim} or \begin{Verbatim} latex example-diff.tex dvips -o example-diff.ps example-diff.dvi gv example-diff.ps \end{Verbatim} to display the markup. \section*{Yet another section title} More things could be said were it not for the constraints of time and space. A paragraph with a line only in the revised document. More things could be said were it not for the constraints of time and space. And here is a typo. Here is a table: \begin{tabular}{ll} Name & Description \\ \hline Gandalf & White \\ Saruman & Evil \end{tabular} And now for something completely different, with not a paragraph in sight. No change, no markup! \end{document} \end{verbatim} } To compare both revisions, type \begin{verbatim} latexdiff -t UNDERLINE example-draft.tex example-rev.tex > example-diff.tex \end{verbatim} This results in the following difference file (a few newlines have been added in this listing for legibility reasosn): {\scriptsize \begin{verbatim} \documentclass[12pt,a4paper]{article} \setlength{\topmargin}{-0.2in} \setlength{\textheight}{9.5in} \setlength{\oddsidemargin}{0.0in} %DIF 7c7 %DIF < \setlength{\textwidth}{6.5in} %DIF ------- \setlength{\textwidth}{6in} %DIF > %DIF ------- %DIF 9c9 %DIF < \title{latexdiff Example - Draft version} %DIF ------- \title{latexdiff Example - Revised version} %DIF > %DIF ------- \author{F Tilmann} % Note how in the preamble visual markup is never used (even %DIF > % if some preamble might eventually end up as visible text.) %DIF > %DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF %DIF UNDERLINE PREAMBLE %DIF PREAMBLE \RequirePackage[normalem]{ulem} %DIF PREAMBLE \RequirePackage{color} %DIF PREAMBLE \providecommand{\DIFadd}[1]{{\color{blue}\uline{#1}}} %DIF PREAMBLE \providecommand{\DIFdel}[1]{{\color{red}\sout{#1}}} %DIF PREAMBLE %DIF SAFE PREAMBLE %DIF PREAMBLE \providecommand{\DIFaddbegin}{} %DIF PREAMBLE \providecommand{\DIFaddend}{} %DIF PREAMBLE \providecommand{\DIFdelbegin}{} %DIF PREAMBLE \providecommand{\DIFdelend}{} %DIF PREAMBLE %DIF FLOATSAFE PREAMBLE %DIF PREAMBLE \providecommand{\DIFaddFL}[1]{\DIFadd{#1}} %DIF PREAMBLE \providecommand{\DIFdelFL}[1]{\DIFdel{#1}} %DIF PREAMBLE \providecommand{\DIFaddbeginFL}{} %DIF PREAMBLE \providecommand{\DIFaddendFL}{} %DIF PREAMBLE \providecommand{\DIFdelbeginFL}{} %DIF PREAMBLE \providecommand{\DIFdelendFL}{} %DIF PREAMBLE %DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF \begin{document} \maketitle \section*{Introduction} This is an extremely simple document that showcases some of latexdiff features. Type \begin{Verbatim} latexdiff -t UNDERLINE example-draft.tex example-rev.tex > example-diff.tex \end{Verbatim} to create the difference file. You can inspect this file directly. Then run either \begin{Verbatim} pdflatex example-diff.tex xpdf example-diff.pdf \end{Verbatim} or \begin{Verbatim} latex example-diff.tex dvips -o example-diff.ps example-diff.dvi gv example-diff.ps \end{Verbatim} to display the markup. \section*{\DIFaddbegin \DIFadd{Yet another }\DIFaddend \DIFdelbegin \DIFdel{Another }\DIFdelend section title} \DIFdelbegin \DIFdel{A paragraph with a line only in the draft document. }\DIFdelend More things could be said were it not for the constraints of time and space. \DIFaddbegin \DIFadd{A paragraph with a line only in the revised document. }\DIFaddend More things could be said were it not for the constraints of time and space. And here is a \DIFaddbegin \DIFadd{typo}\DIFaddend \DIFdelbegin \DIFdel{tipo}\DIFdelend . Here is a table: \begin{tabular}{ll} Name & Description \\ \hline Gandalf & \DIFaddbegin \DIFadd{White }\DIFaddend \DIFdelbegin \DIFdel{Grey }\DIFdelend \\ Saruman & \DIFaddbegin \DIFadd{Evil }\DIFaddend \DIFdelbegin \DIFdel{White }\DIFdelend \end{tabular} And \DIFaddbegin \DIFadd{now for something completely different, with not a paragraph in sight}\DIFaddend \DIFdelbegin \DIFdel{sometimes a whole paragraph gets completely rewritten. In this case latexdiff marks up the whole paragraph even if some words in it are identical}\DIFdelend . No change, no markup! \end{document} \end{verbatim} } Type \begin{verbatim} pdflatex example-diff.tex xpdf example-diff.pdf \end{verbatim} to make the markup visible. This is what it looks like: \vspace{1cm} \framebox[\textwidth]{\includegraphics[width=\textwidth]{example-diff}} \vspace{1cm} If you approve of all the changes in the revision, just continue with \verb|example-rev.tex| for the next revision. If you like to adopt most but not all changes you can use \verb|latexrevise| in the following manner. Simply edit \verb|example-diff.tex| to remove the \verb|\DIFdelbegin| and \verb|\DIFdelend| tags around the text you would like to keep and simply remove the text between \verb|\DIFaddbegin| and \verb|\DIFaddend| tags, if you do not wish to keep them. Say you are happy with all proposed changes for the example above except in the last paragraph where you prefer the original draft. You have to change {\scriptsize \begin{verbatim} ... And \DIFaddbegin \DIFadd{now for something completely different, with not a paragraph in sight}\DIFaddend \DIFdelbegin \DIFdel{sometimes a whole paragraph gets completely rewritten. In this case latexdiff marks up the whole paragraph even if some words in it are identical}\DIFdelend . ... \end{verbatim} } into {\scriptsize \begin{verbatim} ... And \DIFdel{sometimes a whole paragraph gets completely rewritten. In this case latexdiff marks up the whole paragraph even if some words in it are identical}. ... \end{verbatim} } and run \begin{verbatim} latexrevise -a example-diff.tex > example-final.tex \end{verbatim} \verb|example-final.tex| is then almost identical to \verb|example-rev.tex| except for the last paragraph. \section*{External tools} The following is an incomplete list of wrappers written by others providing some added functionality. These are not included with the distribution but need to be downloaded and installed separately. \begin{description} \item[latexdiffcite] (Author: Christer van der Meeren) is a wrapper around latexdiff to make citations diff properly. It works by expanding \verb|\cite| type commands using the bbl or bib file, such that citations are treated just like normal text rather than as atomic in the plain latexdiff. \\ \verb|https://latexdiffcite.readthedocs.org| \item[git-latexdiff] (lead author: Matthieu Moy) is a wrapper (bash scipt) around latexdiff that allows using it to diff two revisions of a LaTeX file under git revision control Similar functionality is provided by \verb|latexdiff-vc --git| with \verb|--flatten| option included with this distribution but git-latexdiff allows more fine-grained control on varous aspects. (Not to be confused with latexdiff-git, which is normally installed as a soft link to latexdiff-vc) \\ \verb|https://gitorious.org/git-latexdiff/| \end{description} \end{document} latexdiff-1.2.1/example/000077500000000000000000000000001313770416100151175ustar00rootroot00000000000000latexdiff-1.2.1/example/example-draft.tex000066400000000000000000000025141313770416100203740ustar00rootroot00000000000000\documentclass[12pt,a4paper]{article} \setlength{\topmargin}{-0.2in} \setlength{\textheight}{9.5in} \setlength{\oddsidemargin}{0.0in} \setlength{\textwidth}{6.5in} \title{latexdiff Example - Draft version} \author{F Tilmann} \begin{document} \maketitle \section*{Introduction} This is an extremely simple document that showcases some of latexdiff features. Type \begin{verbatim} latexdiff -t UNDERLINE example-draft.tex example-rev.tex > example-diff.tex \end{verbatim} to create the difference file. You can inspect this file directly. Then run either \begin{verbatim} pdflatex example-diff.tex xpdf example-diff.pdf \end{verbatim} or \begin{verbatim} latex example-diff.tex dvips -o example-diff.ps example-diff.dvi gv example-diff.ps \end{verbatim} to display the markup. \section*{Another section title} A paragraph with a line only in the draft document. More things could be said were it not for the constraints of time and space. More things could be said were it not for the constraints of time and space. And here is a tipo. Here is a table: \begin{tabular}{ll} Name & Description \\ \hline Gandalf & Grey \\ Saruman & White \end{tabular} And sometimes a whole paragraph gets completely rewritten. In this case latexdiff marks up the whole paragraph even if some words in it are identical. No change, no markup! \end{document} latexdiff-1.2.1/example/example-rev.tex000066400000000000000000000026061313770416100200720ustar00rootroot00000000000000\documentclass[12pt,a4paper]{article} \setlength{\topmargin}{-0.2in} \setlength{\textheight}{9.5in} \setlength{\oddsidemargin}{0.0in} \setlength{\textwidth}{6in} \title{latexdiff Example - Revised version} \author{F Tilmann} % Note how in the preamble visual markup is never used (even % if some preamble might eventually end up as visible text.) \begin{document} \maketitle \section*{Introduction} This is an extremely simple document that showcases some of the latexdiff features. Type \begin{verbatim} latexdiff -t UNDERLINE example-draft.tex example-rev.tex > example-diff.tex \end{verbatim} to create the difference file. You can inspect this file directly. Then run either \begin{verbatim} pdflatex example-diff.tex xpdf example-diff.pdf \end{verbatim} or \begin{verbatim} latex example-diff.tex dvips -o example-diff.ps example-diff.dvi gv example-diff.ps \end{verbatim} to display the markup. \section*{Yet another section title} More things could be said were it not for the constraints of time and space. A paragraph with a line only in the revised document. More things could be said were it not for the constraints of time and space. And here is a typo. Here is a table: \begin{tabular}{ll} Name & Description \\ \hline Gandalf & White \\ Saruman & Evil \end{tabular} And now for something completely different, with not a paragraph in sight. No change, no markup! \end{document} latexdiff-1.2.1/latexdiff000077500000000000000000005534541313770416100154000ustar00rootroot00000000000000#!/usr/bin/env perl ##!/usr/bin/perl -w # latexdiff - differences two latex files on the word level # and produces a latex file with the differences marked up. # # Copyright (C) 2004-16 F J Tilmann (tilmann@gfz-potsdam.de) # # Repository/issue tracker: https://github.com/ftilmann/latexdiff # CTAN page: http://www.ctan.org/pkg/latexdiff # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Detailed usage information at the end of the file # # ToDo: # # Version 1.2.1 (22 June 2017) # - add "DeclareOldFontCommand" to styles using \bf or \sf old style font commands (fixies issue #92 ) # - improved markup: process lstinline commands in listings package correctly # for styles using colour, \verb and \lstinline arguments are marked up with colour (blue for added, red for deleted) # - bug fix: protecting inline math expressions for mbox did not work as intended (see stack exchange question: http://tex.stackexchange.com/questions/359412/compiling-the-latexdiff-when-adding-a-subscript-before-a-pmatrix-environment-cau) # - bug fix: when deleted \item commands are followed immediately by unsafe commands, they were not restored properly # (thanks to J. Protze for pull request) (pull request #89) # - treat lstlisting and comment as equivalent to verbatim environment # make environments that are treated like verbatim environments configurable (config variable VERBATIMENV) # treat lstinlne as equivalent to verb command # partially addresses issue #38 # - refactoring: set default configuration variables in a hash, and those that correspond to lists # - feature: option --add-to-config used to amend configuration variables, which are regex pattern lists # - bug fix: deleted figures when endfloat package is activated # - bug fix: alignat environment now always processed correctly (fix issues #65) # - bug fix: avoid processing of commands as potential files in routine init_regex_arr (fix issue #70 ) # - minimal feature enhancement: treat '@' as allowed character in commands (strictly speaking requires prior \makeatletter statement, but always assuming it to be # @ a letter if it is part of a command name will usually lead to the correct behaviour (see http://tex.stackexchange.com/questions/346651/latexdiff-and-let) # - new feature/bug fix: --flatten option \endinput in included files now respected but only if \endinput stands right at the beginning of the line (issue #77) # - bug fix: flatten would incorrectly attempt to process commented out \include commands (from discussion in issue #77 ) # - introduce an invisible space (\hspace{0pt} after \mbox{..} auxiliary commands (not in math mode), to allow line breaks between added and deleted citations (change should not cause adverse behaviour otherwise) # # Version 1.2.0: # - highlight new and deleted figures # - bug fix in title mark-up. Previously deleted commands in title (such as \title, \author or \date) were marked up erroneously # - (minor) bug fixes in new 1.1.1 features: disabled label was commented out twice, additional spaces were introduced before list environment begin and end commands # - depracation fix: left brace in RegEx now needs to be escaped # - add type PDFCOMMENT based on issue #49 submitted by github user peci1 (Martin Pecka) # - make utf8 the default encoding # # Version 1.1.1 # - patch mhchem: allow ce in equations # - flatten now also expands \input etc. in the preamble (but not \usepackage!) # - Better support for Japanese ( contributed by github user kshramt ) # - prevent duplicated verbatim hashes (patch contributed by github user therussianjig, issue #36) # - disable deleted label commands (fixes issue #31) # - introduce post-processing to reinstate most deleted environments and all needed item commands (fixes issue #1) # # Version 1.1.0 # - treat diacritics (\",\', etc) as safe commands # - treat \_ and \& correctly as safe commands, even if used without spacing to the next word # - Add a BOLD markup type that sets added text in bold face (Contribution by Victor Zabalza via pull request ) # - add append-mboxsafecmd list option to be able to specify special safe commands which need to be surrounded by mbox to avoid breaking (mostly this is needed with ulem package) # - support for siunitx and cleveref packages: protect \SI command in siunitx package and \cref,\Cref{range}{*} in cleveref packages (thanks to Stefan Pinnow for testing) # - experimental support for chemformula, mhchem packages: define \ch and \ce in packages as safe (but not \ch,\cee in equation array environments) - these unfortunately will not be marked up (thanks to Stefan Pinnow for testing) # - bug fix: packages identified correctly even if \usepackage command options extend over several lines (previously \usepackage command needed to be fully contained in one line) # - new subtype ONLYCHANGEDPAGE outputs only changed pages (might not work well for floating material) # - new subtype ZLABEL operates similarly to LABEL but uses absolute page numbers (needs zref package) # - undocumented option --debug/--nodebug to override default setting for debug mode (Default: 0 for release version, 1: for development version # # Version 1.0.4 # - introduce list UNSAFEMATHCMD, which holds list of commands which cannot be marked up with \DIFadd or \DIFdel commands (only relevant for WHOLE and COARSE math markup modes) # - new subtype LABEL which gives each change a label. This can later be used to only display pages where changes # have been made (instructions for that are put as comments into the diff'ed file) inspired by answer on http://tex.stackexchange.com/questions/166049/invisible-markers-in-pdfs-using-pdflatex # - Configuration variables take into accout some commands from additional packages: # tikzpicture environment now treated as PICTUREENV, and \smallmatrix in ARRENV (amsmath) # - --flatten: support for \subfile command (subfiles package) (in response to http://tex.stackexchange.com/questions/167620/latexdiff-with-subfiles ) # - --flatten: \bibliography commands expand if corresponding bbl file present # - angled bracket optional commands now parsed correctly (patch #3570) submitted by Dave Kleinschmidt (thanks) # - \RequirePackage now treated as synonym of \usepackage with respect to setting packages # - special rules for apacite package (redefine citation commands) # - recognise /dev/null as 'file-like' arguments for --preamble and --config options # - fix units package incompatibility with ulem for text maths statements $ ..$ (thanks to Stuart Prescott for reporting this) # - amsmath environment cases treated correctly (Bug fix #19029) (thanks to Jalar) # - {,} in comments no longer confuse latexdiff (Bug fix #19146) # - \% in one-letter sub/Superscripts was not converted correctly # # Version 1.0.3 # - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator # command in preamble # - \(..\) inline math expressions were not parsed correctly, if they contained a linebreak # - applied patch contributed by tomflannaghan via Berlios: [ Patch #3431 ] Adds correct handling of \left< and \right> # - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug # and sketching out the solution) # - \^ and \_ are correctly interpreted as accent and underlined space, respectively, not as superscript of subscript # (thanks to Wail Yahyaoui for pointing out this bug) # # Version 1.0.1 - treat \big,\bigg etc. equivalently to \left and # \right - include starred version in MATHENV - apply # - flatten recursively and --flatten expansion is now # aware of comments (thanks to Tim Connors for patch) # - Change to post-processing for more reliability for # deleted math environments # - On linux systems, recognise and remove DOS style newlines # - Provide markup for some special preamble commands (\title, # \author,\date, # - configurable by setting context2cmd # - for styles using ulem package, remove \emph and \text.. from list of # safe commands in order to allow linebreaks within the # highlighted sections. # - for ulem style, now show citations by enclosing them in \mbox commands. # This unfortunately implies linebreaks within citations no longer function, # so this functionality can be turned off (Option --disable-citation-markup). # With --enable-citation-markup, the mbox markup is forced for other styles) # - new substyle COLOR. This is particularly useful for marking up citations # and some special post-processing is implemented to retain cite # commands in deleted blocks. # - four different levels of math-markup # - Option --driver for choosing driver for modes employing changebar package # - accept \\* as valid command (and other commands of form \.*). Also accept # \ (backslashed newline) # - some typo fixes, include commands defined in preamble as safe commands # (Sebastian Gouezel) # - include compared filenames as comments as line 2 and 3 of # the preamble (can be modified with option --label, and suppressed with # --no-label), option --visible-label to show files in generated pdf or dvi # at the beginning of main document # # Version 0.5 A number of minor improvements based on feedback # Deleted blocks are now shown before added blocks # Package specific processing # # Version 0.43 unreleased typo in list of styles at the end # Add protect to all \cbstart, \cbend commands # More robust substitution of deleted math commands # # Version 0.42 November 06 Bug fixes only # # Version 0.4 March 06 option for fast differencing using UNIX diff command, several minor bug fixes (\par bug, improved highlighting of textcmds) # # Version 0.3 August 05 improved parsing of displayed math, --allow-spaces # option, several minor bug fixes # # Version 0.25 October 04 Fix bug with deleted equations, add math mode commands to safecmd, add | to allowed interpunctuation signs # Version 0.2 September 04 extension to utf-8 and variable encodings # Version 0.1 August 04 First public release use Algorithm::Diff qw(traverse_sequences); use Getopt::Long ; use strict ; use warnings; use utf8 ; my ($algodiffversion)=split(/ /,$Algorithm::Diff::VERSION); my ($versionstring)=< 3, # minimum number of tokens to form an independent block # shorter identical blocks will be merged to the previous word SCALEDELGRAPHICS => 0.5, # factor with which deleted figures will be scaled down (i.e. 0.5 implies they are shown at half linear size) # this is only used for --graphics-markup=BOTH option FLOATENV => undef , # Environments in which FL variants of defined commands are used PICTUREENV => undef , # Environments in which all change markup is removed MATHENV => undef , # Environments turning on display math mode (code also knows about \[ and \]) MATHREPL => 'displaymath', # Environment introducing deleted maths blocks MATHARRENV => undef , # Environments turning on eqnarray math mode MATHARRREPL => 'eqnarray*', # Environment introducing deleted maths blocks ARRENV => undef , # Environments making arrays in math mode. The underlining style does not cope well with those - as a result in-text math environments are surrounded by \mbox{ } if any of these commands is used in an inline math block COUNTERCMD => undef, # COUNTERCMD textcmds which are associated with a counter # If any of these commands occur in a deleted block # they will be succeeded by an \addtocounter{...}{-1} # for the associated counter such that the overall numbers # should be the same as in the new file LISTENV => undef , # list making environments - they will generally be kept VERBATIMENV => undef, # Environments whose content should be treated as verbatim text ITEMCMD => 'item' # command marking item in a list environment ); # Configuration variables: these have to be visible from the subroutines my ($ARRENV, $COUNTERCMD, $FLOATENV, $ITEMCMD, $LISTENV, $MATHARRENV, $MATHARRREPL, $MATHENV, $MATHREPL, $MINWORDSBLOCK, $PICTUREENV, $SCALEDELGRAPHICS, $VERBATIMENV ); # my $MINWORDSBLOCK=3; # minimum number of tokens to form an independent block # # shorter identical blocks will be merged to the previous word # my $SCALEDELGRAPHICS=0.5; # factor with which deleted figures will be scaled down (i.e. 0.5 implies they are shown at half linear size) # # this is only used for --graphics-markup=BOTH option # my $FLOATENV='(?:figure|table|plate)[\w\d*@]*' ; # Environments in which FL variants of defined commands are used # my $PICTUREENV='(?:picture|tikzpicture|DIFnomarkup)[\w\d*@]*' ; # Environments in which all change markup is removed # my $MATHENV='(?:equation[*]?|displaymath|DOLLARDOLLAR)[*]?' ; # Environments turning on display math mode (code also knows about \[ and \]) # my $MATHREPL='displaymath'; # Environment introducing deleted maths blocks # my $MATHARRENV='(?:eqnarray|align|alignat|gather|multline|flalign)[*]?' ; # Environments turning on eqnarray math mode # my $MATHARRREPL='eqnarray*'; # Environment introducing deleted maths blocks # my $ARRENV='(?:aligned|array|[pbvBV]?matrix|smallmatrix|cases|split)'; # Environments making arrays in math mode. The underlining style does not cope well with those - as a result in-text math environments are surrounded by \mbox{ } if any of these commands is used in an inline math block # my $COUNTERCMD='(?:footnote|part|chapter|section|subsection|subsubsection|paragraph|subparagraph)'; # textcmds which are associated with a counter # # If any of these commands occur in a deleted block # # they will be succeeded by an \addtocounter{...}{-1} # # for the associated counter such that the overall numbers # # should be the same as in the new file # my $LISTENV='(?:itemize|description|enumerate)'; # list making environments - they will generally be kept # my $ITEMCMD='item'; # command marking item in a list environment my $LABELCMD='(?:label)'; # matching commands are disabled within deleted blocks - mostly useful for maths mode, as otherwise it would be fine to just not add those to SAFECMDLIST my @UNSAFEMATHCMD=('qedhere'); # Commands which are definitely unsafe for marking up in math mode (amsmath qedhere only tested to not work with UNDERLINE markup) (only affects WHOLE and COARSE math markup modes). Note that unlike text mode (or FINE math mode0 deleted unsafe commands are not deleted but simply taken outside \DIFdel my $MBOXINLINEMATH=0; # if set to 1 then surround marked-up inline maths expression with \mbox ( to get around compatibility # problems between some maths packages and ulem package # Markup strings # If at all possible, do not change these as parts of the program # depend on the actual name (particularly post-processing) # At the very least adapt subroutine postprocess to new tokens. my $ADDMARKOPEN='\DIFaddbegin '; # Token to mark begin of appended text my $ADDMARKCLOSE='\DIFaddend '; # Token to mark end of appended text my $ADDOPEN='\DIFadd{'; # To mark begin of added text passage my $ADDCLOSE='}'; # To mark end of added text passage my $ADDCOMMENT='DIF > '; # To mark added comment line my $DELMARKOPEN='\DIFdelbegin '; # Token to mark begin of deleted text my $DELMARKCLOSE='\DIFdelend '; # Token to mark end of deleted text my $DELOPEN='\DIFdel{'; # To mark begin of deleted text passage my $DELCLOSE='}'; # To mark end of deleted text passage my $DELCMDOPEN='%DIFDELCMD < '; # To mark begin of deleted commands (must begin with %, i.e., be a comment my $DELCMDCLOSE="%%%\n"; # To mark end of deleted commands (must end with a new line) my $AUXCMD='%DIFAUXCMD' ; # follows auxiliary commands put in by latexdiff to make difference file legal # auxiliary commands must be on a line of their own my $DELCOMMENT='DIF < '; # To mark deleted comment line # main local variables: my @TEXTCMDLIST=(); # array containing patterns of commands with text arguments my @TEXTCMDEXCL=(); # array containing patterns of commands without text arguments (if a pattern # matches both TEXTCMDLIST and TEXTCMDEXCL it is excluded) my @CONTEXT1CMDLIST=(); # array containing patterns of commands with text arguments (subset of text commands), # but which cause confusion if used out of context (e.g. \caption). # In deleted passages, the command will be disabled but its argument is marked up # Otherwise they behave exactly like TEXTCMD's my @CONTEXT1CMDEXCL=(); # exclude list for above, but always empty my @CONTEXT2CMDLIST=(); # array containing patterns of commands with text arguments, but which fail or cause confusion # if used out of context (e.g. \title). They and their arguments will be disabled in deleted # passages my @CONTEXT2CMDEXCL=(); # exclude list for above, but always empty my @MATHTEXTCMDLIST=(); # treat like textcmd. If a textcmd is in deleted or added block, just wrap the # whole content with \DIFadd or \DIFdel irrespective of content. This functionality # is useful for pseudo commands \MATHBLOCK.. into which math environments are being # transformed my @MATHTEXTCMDEXCL=(); # # Note I need to declare this with "our" instead of "my" because later in the code I have to "local"ise these our @SAFECMDLIST=(); # array containing patterns of safe commands (which do not break when in the argument of DIFadd or DIFDEL) our @SAFECMDEXCL=(); my @MBOXCMDLIST=(); # patterns for commands which are in principle safe but which need to be surrounded by an \mbox my @MBOXCMDEXCL=(); # all the patterns in MBOXCMDLIST will be appended to SAFECMDLIST my ($i,$j,$l); my ($old,$new); my ($line,$key); my (@dumlist); my ($newpreamble,$oldpreamble); my (@newpreamble,@oldpreamble,@diffpreamble,@diffbody); my ($latexdiffpreamble); my ($oldbody, $newbody, $diffbo); my ($oldpost, $newpost); my ($diffall); # Option names my ($type,$subtype,$floattype,$config,$preamblefile,$encoding,$nolabel,$visiblelabel, $showpreamble,$showsafe,$showtext,$showconfig,$showall, $replacesafe,$appendsafe,$excludesafe, $replacetext,$appendtext,$excludetext, $replacecontext1,$appendcontext1, $replacecontext2,$appendcontext2, $help,$verbose,$driver,$version,$ignorewarnings, $enablecitmark,$disablecitmark,$allowspaces,$flatten,$debug,$earlylatexdiffpreamble); ###$disablemathmark, my ($mboxsafe); # MNEMNONICS for mathmarkup my $mathmarkup; use constant { OFF => 0, WHOLE => 1, COARSE => 2, FINE => 3 }; # MNEMNONICS for graphicsmarkup my $graphicsmarkup; use constant { NONE => 0, NEWONLY => 1, BOTH => 2 }; my ($mboxcmd); my (@configlist,@addtoconfiglist,@labels, @appendsafelist,@excludesafelist, @appendmboxsafelist,@excludemboxsafelist, @appendtextlist,@excludetextlist, @appendcontext1list,@appendcontext2list, @packagelist); my ($assign,@config); # Hash where keys corresponds to the names of all included packages (including the documentclass as another package # the optional arguments to the package are the values of the hash elements my ($pkg,%packages); # Defaults $mathmarkup=COARSE; $verbose=0; # output debug and intermediate files, set to 0 in final distribution $debug=0; # insert preamble directly after documentclass - experimental feature, set to 0 in final distribution # Note that this failed with mini example (or other files, where packages used in latexdiff preamble # are called again with incompatible options in preamble of resulting file) $earlylatexdiffpreamble=0; # define character properties sub IsNonAsciiPunct { return <<'END' # Unicode punctuation but excluding ASCII punctuation +utf8::IsPunct -utf8::IsASCII END } sub IsNonAsciiS { return <<'END' # Unicode symbol but excluding ASCII +utf8::IsS -utf8::IsASCII END } my %verbhash; Getopt::Long::Configure('bundling'); GetOptions('type|t=s' => \$type, 'subtype|s=s' => \$subtype, 'floattype|f=s' => \$floattype, 'config|c=s' => \@configlist, 'add-to-config|c=s' => \@addtoconfiglist, 'preamble|p=s' => \$preamblefile, 'encoding|e=s' => \$encoding, 'label|L=s' => \@labels, 'no-label' => \$nolabel, 'visible-label' => \$visiblelabel, 'exclude-safecmd|A=s' => \@excludesafelist, 'replace-safecmd=s' => \$replacesafe, 'append-safecmd|a=s' => \@appendsafelist, 'exclude-textcmd|X=s' => \@excludetextlist, 'replace-textcmd=s' => \$replacetext, 'append-textcmd|x=s' => \@appendtextlist, 'replace-context1cmd=s' => \$replacecontext1, 'append-context1cmd=s' => \@appendcontext1list, 'replace-context2cmd=s' => \$replacecontext2, 'append-context2cmd=s' => \@appendcontext2list, 'exclude-mboxsafecmd=s' => \@excludemboxsafelist, 'append-mboxsafecmd=s' => \@appendmboxsafelist, 'show-preamble' => \$showpreamble, 'show-safecmd' => \$showsafe, 'show-textcmd' => \$showtext, 'show-config' => \$showconfig, 'show-all' => \$showall, 'packages=s' => \@packagelist, 'allow-spaces' => \$allowspaces, 'math-markup=s' => \$mathmarkup, 'graphics-markup=s' => \$graphicsmarkup, 'enable-citation-markup|enforce-auto-mbox' => \$enablecitmark, 'disable-citation-markup|disable-auto-mbox' => \$disablecitmark, 'verbose|V' => \$verbose, 'ignore-warnings' => \$ignorewarnings, 'driver=s'=> \$driver, 'flatten' => \$flatten, 'version' => \$version, 'help|h' => \$help, 'debug!' => \$debug ); if ( $help ) { usage() ; } if ( $version ) { die $versionstring ; } print STDERR $versionstring if $verbose; if (defined($showall)){ $showpreamble=$showsafe=$showtext=$showconfig=1; } # Default types $type='UNDERLINE' unless defined($type); $subtype='SAFE' unless defined($subtype); # set floattype to IDENTICAL for LABEL and ONLYCHANGEDPAGE subtype, unless it has been set explicitly on the command line $floattype=($subtype eq 'LABEL' || $subtype eq 'ONLYCHANGEDPAGE') ? 'IDENTICAL' : 'FLOATSAFE' unless defined($floattype); if ( $subtype eq 'LABEL' ) { print STDERR "Note that LABEL subtype is deprecated. If possible, use ZLABEL instead (requires zref package)"; } if (defined($mathmarkup)) { $mathmarkup=~tr/a-z/A-Z/; if ( $mathmarkup eq 'OFF' ){ $mathmarkup=OFF; } elsif ( $mathmarkup eq 'WHOLE' ){ $mathmarkup=WHOLE; } elsif ( $mathmarkup eq 'COARSE' ){ $mathmarkup=COARSE; } elsif ( $mathmarkup eq 'FINE' ){ $mathmarkup=FINE; } elsif ( $mathmarkup !~ m/^[0123]$/ ) { die "latexdiff Illegal value: ($mathmarkup) for option--math-markup. Possible values: OFF,WHOLE,COARSE,FINE,0-3\n"; } # else use numerical value } # setting extra preamble commands if (defined($preamblefile)) { $latexdiffpreamble=join "\n",(extrapream($preamblefile),""); } else { $latexdiffpreamble=join "\n",(extrapream($type,$subtype,$floattype),""); } if ( defined($driver) ) { # for changebar only $latexdiffpreamble=~s/\[dvips\]/[$driver]/sg; } # setting up @SAFECMDLIST and @SAFECMDEXCL if (defined($replacesafe)) { init_regex_arr_ext(\@SAFECMDLIST,$replacesafe); } else { init_regex_arr_data(\@SAFECMDLIST, "SAFE COMMANDS"); } foreach $appendsafe ( @appendsafelist ) { init_regex_arr_ext(\@SAFECMDLIST, $appendsafe); } foreach $excludesafe ( @excludesafelist ) { init_regex_arr_ext(\@SAFECMDEXCL, $excludesafe); } # setting up @MBOXCMDLIST and @MBOXCMDEXCL foreach $mboxsafe ( @appendmboxsafelist ) { init_regex_arr_ext(\@MBOXCMDLIST, $mboxsafe); } foreach $mboxsafe ( @excludemboxsafelist ) { init_regex_arr_ext(\@MBOXCMDEXCL, $mboxsafe); } # setting up @TEXTCMDLIST and @TEXTCMDEXCL if (defined($replacetext)) { init_regex_arr_ext(\@TEXTCMDLIST,$replacetext); } else { init_regex_arr_data(\@TEXTCMDLIST, "TEXT COMMANDS"); } foreach $appendtext ( @appendtextlist ) { init_regex_arr_ext(\@TEXTCMDLIST, $appendtext); } foreach $excludetext ( @excludetextlist ) { init_regex_arr_ext(\@TEXTCMDEXCL, $excludetext); } # setting up @CONTEXT1CMDLIST ( @CONTEXT1CMDEXCL exist but is always empty ) if (defined($replacecontext1)) { init_regex_arr_ext(\@CONTEXT1CMDLIST,$replacecontext1); } else { init_regex_arr_data(\@CONTEXT1CMDLIST, "CONTEXT1 COMMANDS"); } foreach $appendcontext1 ( @appendcontext1list ) { init_regex_arr_ext(\@CONTEXT1CMDLIST, $appendcontext1); } # setting up @CONTEXT2CMDLIST ( @CONTEXT2CMDEXCL exist but is always empty ) if (defined($replacecontext2)) { init_regex_arr_ext(\@CONTEXT2CMDLIST,$replacecontext2); } else { init_regex_arr_data(\@CONTEXT2CMDLIST, "CONTEXT2 COMMANDS"); } foreach $appendcontext2 ( @appendcontext2list ) { init_regex_arr_ext(\@CONTEXT2CMDLIST, $appendcontext2); } # setting configuration variables @config=(); foreach $config ( @configlist ) { if (-f $config || lc $config eq '/dev/null' ) { open(FILE,$config) or die ("Couldn't open configuration file $config: $!"); while () { chomp; next if /^\s*#/ || /^\s*%/ || /^\s*$/ ; push (@config,$_); } close(FILE); } else { # foreach ( split(",",$config) ) { # push @config,$_; # } push @config,split(",",$config) } } foreach $assign ( @config ) { $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; exists $CONFIG{$1} or die "Unknown configuration variable $1."; $CONFIG{$1}=$2; } my @addtoconfig=(); foreach $config ( @addtoconfiglist ) { if (-f $config || lc $config eq '/dev/null' ) { open(FILE,$config) or die ("Couldn't open addd-to-config file $config: $!"); while () { chomp; next if /^\s*#/ || /^\s*%/ || /^\s*$/ ; push (@addtoconfig,$_); } close(FILE); } else { # foreach ( split(",",$config) ) { # push @addtoconfig,$_; # } push @addtoconfig,split(",",$config) } } # initialise default lists from DATA # for those configuration variables, which have not been set explicitly, initiate from list in document foreach $key ( keys(%CONFIG) ) { if (!defined $CONFIG{$key}) { @dumlist=(); init_regex_arr_data(\@dumlist,"$key CONFIG"); $CONFIG{$key}=join(";",@dumlist) } } foreach $assign ( @addtoconfig ) { $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; exists $CONFIG{$1} or die "Unknown configuration variable $1."; $CONFIG{$1}.=";$2"; } # Map from hash to variables (we do this to have more concise code later, change from comma-separeted list) foreach ( keys(%CONFIG) ) { if ( $_ eq "MINWORDSBLOCK" ) { $MINWORDSBLOCK = $CONFIG{$_}; } elsif ( $_ eq "FLOATENV" ) { $FLOATENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "ITEMCMD" ) { $ITEMCMD = $CONFIG{$_} ; } elsif ( $_ eq "LISTENV" ) { $LISTENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "PICTUREENV" ) { $PICTUREENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "MATHENV" ) { $MATHENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "MATHREPL" ) { $MATHREPL = $CONFIG{$_} ; } elsif ( $_ eq "MATHARRENV" ) { $MATHARRENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "MATHARRREPL" ) { $MATHARRREPL = $CONFIG{$_} ; } elsif ( $_ eq "ARRENV" ) { $ARRENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "VERBATIMENV" ) { $VERBATIMENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "COUNTERCMD" ) { $COUNTERCMD = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "SCALEDELGRAPHICS" ) { $SCALEDELGRAPHICS = $CONFIG{$_} ; } else { die "Unknown configuration variable $_.";} } if ( $mathmarkup == COARSE || $mathmarkup == WHOLE ) { push(@MATHTEXTCMDLIST,qr/^MATHBLOCK(?:$MATHENV|$MATHARRENV|SQUAREBRACKET)$/); } foreach $pkg ( @packagelist ) { map { $packages{$_}="" } split(/,/,$pkg) ; } if ($showconfig || $showtext || $showsafe || $showpreamble) { show_configuration(); exit 0; } if ( @ARGV != 2 ) { print STDERR "2 and only 2 non-option arguments required. Write latexdiff -h to get help\n"; exit(2); } # Are extra spaces between command arguments permissible? my $extraspace; if ($allowspaces) { $extraspace='\s*'; } else { $extraspace=''; } # append context lists to text lists (as text property is implied) push @TEXTCMDLIST, @CONTEXT1CMDLIST; push @TEXTCMDLIST, @CONTEXT2CMDLIST; push @TEXTCMDLIST, @MATHTEXTCMDLIST if $mathmarkup==COARSE; # internal additions to SAFECMDLIST push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # Patterns. These are used by some of the subroutines, too # I can only define them down here because value of extraspace depends on an option my $pat0 = '(?:[^{}])*'; my $pat_n = $pat0; # if you get "undefined control sequence MATHBLOCKmath" error, increase the maximum value in this loop for (my $i_pat = 0; $i_pat < 20; ++$i_pat){ $pat_n = '(?:[^{}]|\{'.$pat_n.'\})*'; } my $brat0 = '(?:[^\[\]]|\\\[|\\\])*'; my $abrat0 = '(?:[^<>])*'; my $quotemarks = '(?:\'\')|(?:\`\`)'; my $punct='[0.,\/\'\`:;\"\?\(\)\[\]!~\p{IsNonAsciiPunct}\p{IsNonAsciiS}]'; my $number='-?\d*\.\d*'; my $mathpunct='[+=<>\-\|]'; my $and = '&'; my $coords= '[\-.,\s\d]*'; # quoted underscore - this needs special treatment as perl treats _ as a letter (\w) but latex does not # such that a\_b is interpreted as a{\_}b by latex but a{\_b} by perl my $quotedunderscore='\\\\_'; # word: sequence of letters or accents followed by letter my $word_ja='\p{Han}+|\p{InHiragana}+|\p{InKatakana}+'; my $word='(?:' . $word_ja . '|(?:(?:[-\w\d*]|\\\\[\"\'\`~^][A-Za-z\*])(?!(?:' . $word_ja . ')))+)'; my $cmdleftright='\\\\(?:left|right|[Bb]igg?[lrm]?|middle)\s*(?:[<>()\[\]|\.]|\\\\(?:[|{}]|\w+))'; my $cmdoptseq='\\\\[\w\d@\*]+'.$extraspace.'(?:(?:<'.$abrat0.'>|\['.$brat0.'\]|\{'. $pat_n . '\}|\(' . $coords .'\))'.$extraspace.')*'; my $backslashnl='\\\\\n'; my $oneletcmd='\\\\.\*?(?:\['.$brat0.'\]|\{'. $pat_n . '\})*'; my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]'; ## the current maths command cannot cope with newline within the math expression my $comment='%.*?\n'; my $pat=qr/(?:\A\s*)?(?:${and}|${quotemarks}|${number}|${word}|$quotedunderscore|$cmdleftright|${cmdoptseq}|${math}|${backslashnl}|${oneletcmd}|${comment}|${punct}|${mathpunct}|\{|\})\s*/ ; # now we are done setting up and can start working my ($oldfile, $newfile) = @ARGV; # check for existence of input files if ( ! -e $oldfile ) { die "Input file $oldfile does not exist"; } if ( ! -e $newfile ) { die "Input file $newfile does not exist"; } # set the labels to be included into the file # first find out which file name is longer for correct alignment my ($diff,$oldlabel_n_spaces,$newlabel_n_spaces); $oldlabel_n_spaces = 0; $newlabel_n_spaces = 0; $diff = length($newfile) - length($oldfile); if ($diff > 0) { $oldlabel_n_spaces = $diff; } if ($diff < 0) { $newlabel_n_spaces = abs($diff); } my ($oldtime,$newtime,$oldlabel,$newlabel); if (defined($labels[0])) { $oldlabel=$labels[0] ; } else { $oldtime=localtime((stat($oldfile))[9]); $oldlabel="$oldfile " . " "x($oldlabel_n_spaces) . $oldtime; } if (defined($labels[1])) { $newlabel=$labels[1] ; } else { $newtime=localtime((stat($newfile))[9]); $newlabel="$newfile " . " "x($newlabel_n_spaces) . $newtime; } $encoding=guess_encoding($newfile) unless defined($encoding); $encoding = "utf8" if $encoding =~ m/^utf8/i ; if (lc($encoding) eq "utf8" ) { binmode(STDOUT, ":utf8"); binmode(STDERR, ":utf8"); } $old=read_file_with_encoding($oldfile,$encoding); $new=read_file_with_encoding($newfile,$encoding); # reset time exetime(1); ($oldpreamble,$oldbody,$oldpost)=splitdoc($old,'\\\\begin\{document\}','\\\\end\{document\}'); ($newpreamble,$newbody,$newpost)=splitdoc($new,'\\\\begin\{document\}','\\\\end\{document\}'); if ($flatten) { $oldbody=flatten($oldbody,$oldpreamble,$oldfile,$encoding); $newbody=flatten($newbody,$newpreamble,$newfile,$encoding); # flatten preamble $oldpreamble=flatten($oldpreamble,$oldpreamble,$oldfile,$encoding); $newpreamble=flatten($newpreamble,$newpreamble,$newfile,$encoding); } my @auxlines; # boolean variab my ($ulem)=0; if ( length $oldpreamble && length $newpreamble ) { # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) # and marking up content with latexdiff markup @auxlines=preprocess_preamble($oldpreamble,$newpreamble); @oldpreamble = split /\n/, $oldpreamble; @newpreamble = split /\n/, $newpreamble; # If a command is defined in the preamble of the new file, and only uses safe commands, then it can be considered to be safe) (contribution S. Gouezel) # Base this assessment on the new preamble add_safe_commands($newpreamble); # get a list of packages from preamble if not predefined %packages=list_packages($newpreamble) unless %packages; if ( %packages && $debug ) { my $key ; foreach $key (keys %packages) { print STDERR "DEBUG \\usepackage[",$packages{$key},"]{",$key,"}\n" ;} } } # have to return to all processing to properly add preamble additions based on packages found if (defined($graphicsmarkup)) { $graphicsmarkup=~tr/a-z/A-Z/; if ( $graphicsmarkup eq 'OFF' or $graphicsmarkup eq 'NONE' ) { $graphicsmarkup=NONE; } elsif ( $graphicsmarkup eq 'NEWONLY' or $graphicsmarkup eq 'NEW-ONLY' ) { $graphicsmarkup=NEWONLY; } elsif ( $graphicsmarkup eq 'BOTH' ) { $graphicsmarkup=BOTH; } elsif ( $graphicsmarkup !~ m/^[012]$/ ) { die "latexdiff Illegal value: ($graphicsmarkup) for option --highlight-graphics. Possible values: OFF,WHOLE,COARSE,FINE,0-2\n"; } # else use numerical value } else { # Default: no explicit setting in menu if ( defined $packages{"graphicx"} or defined $packages{"graphics"} ) { $graphicsmarkup=NEWONLY; } else { $graphicsmarkup=NONE; } } if (defined $packages{"hyperref"} ) { # deleted lines should not generate or appear in link names: print STDERR "hyperref package detected.\n" if $verbose ; $latexdiffpreamble =~ s/\{\\DIFadd\}/{\\DIFaddtex}/g; $latexdiffpreamble =~ s/\{\\DIFdel\}/{\\DIFdeltex}/g; $latexdiffpreamble .= join "\n",(extrapream("HYPERREF"),""); ### $latexdiffpreamble .= '%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF FOR HYPERREF PACKAGE' . "\n"; ### $latexdiffpreamble .= '\providecommand{\DIFadd}[1]{\texorpdfstring{\DIFaddtex{#1}}{#1}}' . "\n"; ### $latexdiffpreamble .= '\providecommand{\DIFdel}[1]{\texorpdfstring{\DIFdeltex{#1}}{}}' . "\n"; ### $latexdiffpreamble .= '%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF FOR HYPERREF PACKAGE' . "\n"; } # add commands for figure highlighting to preamble if ($graphicsmarkup != NONE ) { my @matches; # Check if \DIFaddbeginFL definition calls \DIFaddbegin - if so we will issue an error message that graphics highlighting is # is not compatible with this. # (A more elegant solution would be to suppress the redefinitions of the \DIFaddbeginFL etc commands, but for this narrow use case # I currently don't see this as an efficient use of time) ### The foreach loop does not make sense here. I don't know why I put this in - (F Tilmann) ###foreach my $cmd ( "DIFaddbegin","DIFaddend","DIFdelbegin","DIFdelend" ) { @matches=( $latexdiffpreamble =~ m/command\{\\DIFaddbeginFL}\{($pat_n)}/sg ) ; # we look at the last one of the list to take into account possible redefinition but almost always matches should have exactly one element if ( $matches[$#matches] =~ m/\\DIFaddbegin/ ) { die "Cannot combine graphics markup with float styles defining \\DIFaddbeginFL in terms of \\DIFaddbegin. Use --graphics-markup=none option or choose a different float style."; exit 10; } ###} $latexdiffpreamble .= join "\n",("\\newcommand{\\DIFscaledelfig}{$SCALEDELGRAPHICS}",extrapream("HIGHLIGHTGRAPHICS"),""); # only change required for highlighting both is to declare \includegraphics safe, as preamble already contains commands for deleted environment if ( $graphicsmarkup == BOTH ) { init_regex_arr_list(\@SAFECMDLIST,'includegraphics'); } } # If listings is being used and latexdiffpreamble uses color markup if (defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{color\}/)) { $latexdiffpreamble .= join "\n",(extrapream("LISTINGS"),""); } # adding begin and end marker lines to preamble $latexdiffpreamble = "%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF\n" . $ latexdiffpreamble . "%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF\n"; # and return to preamble specific processing if ( length $oldpreamble && length $newpreamble ) { print STDERR "Differencing preamble.\n" if $verbose; # insert dummy first line such that line count begins with line 1 (rather than perl's line 0) - just so that line numbers inserted by linediff are correct unshift @newpreamble,''; unshift @oldpreamble,''; @diffpreamble = linediff(\@oldpreamble, \@newpreamble); # remove dummy line again shift @diffpreamble; # add filenames, modification time and latexdiff mark defined($nolabel) or splice @diffpreamble,1,0, "%DIF LATEXDIFF DIFFERENCE FILE", ,"%DIF DEL $oldlabel", "%DIF ADD $newlabel"; if ( @auxlines ) { push @diffpreamble,"%DIF DELETED TITLE COMMANDS FOR MARKUP"; push @diffpreamble,join("\n",@auxlines); } if ( $earlylatexdiffpreamble) { # insert latexdiff command directly after documentclass at beginning of preamble # note that grep is only run for its side effect ( grep { s/^([^%]*\\documentclass.*)$/$1$latexdiffpreamble/ } @diffpreamble )==1 or die "Could not find documentclass statement in preamble"; } else { # insert latexdiff commands at the end of preamble (default behaviour) push @diffpreamble,$latexdiffpreamble; } push @diffpreamble,'\begin{document}'; } elsif ( !length $oldpreamble && !length $newpreamble ) { @diffpreamble=(); } else { print STDERR "Either both texts must have preamble or neither text must have the preamble.\n"; exit(2); } # Special: treat all cite commands as safe except in UNDERLINE and FONTSTRIKE mode # (there is a conflict between citation and ulem package, see # package documentation) # Use post-processing # and $packages{"apacite"}!~/natbibpapa/ $ulem = ($latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{ulem\}/ || defined $packages{"ulem"}); if (defined $packages{"units"} && $ulem ) { # protect inlined maths environments by surrounding with an \mbox # this is done to get around an incompatibility between the ulem and units package # where spaces in the argument to underlined or crossed-out \unit commands cause an error message print STDERR "units package detected at the same time as style using ulem.\n" if $verbose ; $MBOXINLINEMATH=1; } if (defined $packages{"siunitx"} ) { # protect SI command by surrounding them with an \mbox # this is done to get around an incompatibility between the ulem and siunitx package print STDERR "siunitx package detected.\n" if $verbose ; my $mboxcmds='SI,ang,numlist,numrange,SIlist,SIrange'; init_regex_arr_list(\@SAFECMDLIST,'num,si'); if ( $enablecitmark || ( $ulem && ! $disablecitmark )) { init_regex_arr_list(\@MBOXCMDLIST,$mboxcmds); } else { init_regex_arr_list(\@SAFECMDLIST,$mboxcmds); } } if (defined $packages{"cleveref"} ) { # protect selected command by surrounding them with an \mbox # this is done to get around an incompatibility between ulem and cleveref package print STDERR "cleveref package detected.\n" if $verbose ; my $mboxcmds='[Cc]ref(?:range)?\*?,labelcref,(?:lc)?name[cC]refs?' ; if ( $enablecitmark || ( $ulem && ! $disablecitmark )) { init_regex_arr_list(\@MBOXCMDLIST,$mboxcmds); } else { init_regex_arr_list(\@SAFECMDLIST,$mboxcmds); } } if (defined $packages{"glossaries"} ) { # protect selected command by surrounding them with an \mbox # this is done to get around an incompatibility between ulem and glossaries package print STDERR "glossaries package detected.\n" if $verbose ; my $mboxcmds='[gG][lL][sS](?:|pl|disp|link|first|firstplural|desc|user[iv][iv]?[iv]?),[aA][cC][rR](?:long|longpl|full|fullpl),[aA][cC][lfp]?[lfp]?'; init_regex_arr_list(\@SAFECMDLIST,'[gG][lL][sS](?:(?:entry)?(?:text|plural|name|symbol)|displaynumberlist|entryfirst|entryfirstplural|entrydesc|entrydescplural|entrysymbolplural|entryuser[iv][iv]?[iv]?|entrynumberlist|entrydisplaynumberlist|entrylong|entrylongpl|entryshort|entryshortpl|entryfull|entryfullpl),[gG]lossentry(?:name|desc|symbol),[aA][cC][rR](?:short|shortpl),[aA]csp?'); if ( $enablecitmark || ( $ulem && ! $disablecitmark )) { init_regex_arr_list(\@MBOXCMDLIST,$mboxcmds); } else { init_regex_arr_list(\@SAFECMDLIST,$mboxcmds); } } if (defined $packages{"chemformula"} or defined $packages{"chemmacros"} ) { print STDERR "chemformula package detected.\n" if $verbose ; init_regex_arr_list(\@SAFECMDLIST,'ch'); push(@UNSAFEMATHCMD,'ch'); # The next command would be needed to allow highlighting the interior of \ch commands in math environments # but the redefinitions in chemformula are too deep to make this viable # push(@MATHTEXTCMDLIST,'ch'); } if (defined $packages{"mhchem"} ) { print STDERR "mhchem package detected.\n" if $verbose ; init_regex_arr_list(\@SAFECMDLIST,'ce'); push(@UNSAFEMATHCMD,'ce','cee'); # The next command would be needed to allow highlighting the interior of \cee commands in math environments # but the redefinitions in chemformula are too deep to make this viable # push(@MATHTEXTCMDLIST,'cee'); } my ( $citpat); if ( defined $packages{"apacite"} ) { print STDERR "apacite package detected.\n" if $verbose ; $citpat='(?:mask)?(?:full|short|no)?cite(?:A|author|year|meta)?(?:NP)?'; } else { # citation command pattern for all other citation schemes $citpat='(?:cite\w*|nocite)'; }; if ( ! $ulem ) { # modes not using ulem: citation is safe push (@SAFECMDLIST, $citpat); } else { ### Experimental: disable text and emph commands push(@SAFECMDEXCL, qr/^emph$/, qr/^text..$/); # replace \cite{..} by \mbox{\cite{..}} in added or deleted blocks in post-processing push(@MBOXCMDLIST,$citpat) unless $disablecitmark; if ( uc($subtype) eq "COLOR" or uc($subtype) eq "DVIPSCOL" ) { # remove \cite command again from list of safe commands pop @MBOXCMDLIST; # deleted cite commands } } push(@MBOXCMDLIST,$citpat) if $enablecitmark ; if (defined $packages{"amsmath"} or defined $packages{"amsart"} or defined $packages{"amsbook"} ) { print STDERR "amsmath package detected.\n" if $verbose ; $MATHARRREPL='align*'; } # add commands in MBOXCMDLIST to SAFECMDLIST foreach $mboxcmd ( @MBOXCMDLIST ) { init_regex_arr_list(\@SAFECMDLIST, $mboxcmd); } # check if \label is in SAFECMDLIST, and if yes replace "label" in $LABELCMD by something that never matches (we hope!) if ( iscmd("label",\@SAFECMDLIST,\@SAFECMDEXCL) ) { $LABELCMD=~ s/label/NEVERMATCHLABEL/; } print STDERR "Preprocessing body. " if $verbose; preprocess($oldbody,$newbody); # run difference algorithm @diffbody=bodydiff($oldbody, $newbody); $diffbo=join("",@diffbody); if ( $debug ) { open(RAWDIFF,">","latexdiff.debug.bodydiff"); print RAWDIFF $diffbo; close(RAWDIFF); } print STDERR "(",exetime()," s)\n","Postprocessing body. \n" if $verbose; postprocess($diffbo); $diffall =join("\n",@diffpreamble) ; # add visible labels if (defined($visiblelabel)) { # Give information right after \begin{document} (or at the beginning of the text for files without preamble ### if \date command is used, add information to \date argument, otherwise give right after \begin{document} ### $diffall=~s/(\\date$extraspace(?:\[$brat0\])?$extraspace)\{($pat_n)\}/$1\{$2 \\ LATEXDIFF comparison \\ Old: $oldlabel \\ New: $newlabel \}/ or $diffbo = "\\begin{verbatim}LATEXDIFF comparison\nOld: $oldlabel\nNew: $newlabel\\end{verbatim}\n$diffbo" ; } $diffall .= "$diffbo" ; $diffall .= "\\end{document}$newpost" if length $newpreamble ; if ( lc($encoding) ne "utf8" && lc($encoding) ne "ascii" ) { print STDERR "Encoding output file to $encoding\n" if $verbose; $diffall=Encode::encode($encoding,$diffall); binmode STDOUT; } print $diffall; print STDERR "(",exetime()," s)\n","Done.\n" if $verbose; # liststringtoregex(liststring) # expands string with semi-colon separated list into a regular expression corresponding # matching any of the elements sub liststringtoregex { my ($liststring)=@_; my @elements=grep /\S/,split(";",$liststring); if ( @elements) { return('(?:(?:' . join(')|(?:',@elements) .'))'); } else { return ""; } } # show_configuration # note that this is not encapsulated but uses variables from the main program # It is provided for convenience because in the future it is planned to allow output # to be modified based on what packages are read etc - this works only if the input files are actually red # whether or not additional files are provided sub show_configuration { if ($showpreamble) { print "\nPreamble commands:\n"; print $latexdiffpreamble ; } if ($showsafe) { print "\nsafecmd: Commands safe within scope of $ADDOPEN $ADDCLOSE and $DELOPEN $DELCLOSE (unless excluded):\n"; print_regex_arr(@SAFECMDLIST); print "\nsafecmd-exlude: Commands not safe within scope of $ADDOPEN $ADDCLOSE and $DELOPEN $DELCLOSE :\n"; print_regex_arr(@SAFECMDEXCL); print "\nmboxsafecmd: Commands safe only if they are surrounded by \\mbox command:\n"; print_regex_arr(@MBOXCMDLIST); print "\nnmboxsafecmd: Commands not safe:\n"; print_regex_arr(@MBOXCMDEXCL); } if ($showtext) { print "\nCommands with last argument textual (unless excluded) and safe in every context:\n"; print_regex_arr(@TEXTCMDLIST); print "\nContext1 commands (last argument textual, command will be disabled in deleted passages, last argument will be shown as plain text):\n"; print_regex_arr(@CONTEXT1CMDLIST); print "\nContext2 commands (last argument textual, command and its argument will be disabled in deleted passages):\n"; print_regex_arr(@CONTEXT2CMDLIST); print "\nExclude list of Commands with last argument not textual (overrides patterns above):\n"; print_regex_arr(@TEXTCMDEXCL); } if ($showconfig) { print "Configuration variables:\n"; print "ARRENV=$ARRENV\n"; print "COUNTERCMD=$COUNTERCMD\n"; print "FLOATENV=$FLOATENV\n"; print "ITEMCMD=$ITEMCMD\n"; print "LISTENV=$LISTENV\n"; print "MATHARRENV=$MATHARRENV\n"; print "MATHARRREPL=$MATHARRREPL\n"; print "MATHENV=$MATHENV\n"; print "MATHREPL=$MATHREPL\n"; print "MINWORDSBLOCK=$MINWORDSBLOCK\n"; print "PICTUREENV=$PICTUREENV\n"; } } ## guess_encoding(filename) ## reads the first 20 lines of filename and looks for call of inputenc package ## if found, return the option of this package (encoding), otherwise return utf8 sub guess_encoding { my ($filename)=@_; my ($i,$enc); open (FH, $filename) or die("Couldn't open $filename: $!"); $i=0; while () { next if /^\s*%/; # skip comment lines if (m/\\usepackage\[(\w*?)\]\{inputenc\}/) { close(FH); return($1); } last if (++$i > 20 ); # scan at most 20 non-comment lines } close(FH); ### return("ascii"); return("utf8"); } sub read_file_with_encoding { my ($output); my ($filename, $encoding) = @_; if (lc($encoding) eq "utf8" ) { open (FILE, "<:utf8",$filename) or die("Couldn't open $filename: $!"); local $/ ; # locally set record operator to undefined, ie. enable whole-file mode $output=; } elsif ( lc($encoding) eq "ascii") { open (FILE, $filename) or die("Couldn't open $filename: $!"); local $/ ; # locally set record operator to undefined, ie. enable whole-file mode $output=; } else { require Encode; open (FILE, "<",$filename) or die("Couldn't open $filename: $!"); local $/ ; # locally set record operator to undefined, ie. enable whole-file mode $output=; print STDERR "Converting $filename from $encoding to utf8\n" if $verbose; $output=Encode::decode($encoding,$output); } close FILE; if ($^O eq "linux" ) { $output =~ s/\r\n/\n/g ; } return $output; } ## %packages=list_packages(@preamble) ## scans the arguments for \documentclass,\RequirePackage and \usepackage statements and constructs a hash ## whose keys are the included packages, and whose values are the associated optional arguments #sub list_packages { # my (@preamble)=@_; # my %packages=(); # foreach $line ( @preamble ) { # # get rid of comments # $line=~s/(?catfile($dirname,$fname), "\n" if $debug; # content of file becomes replacement value (use recursion), add \newpage if the command was include ###$replacement=read_file_with_encoding(File::Spec->catfile($dirname,$fname), $encoding) or die "Couldn't find file ",File::Spec->catfile($dirname,$fname),": $!"; $replacement=flatten(read_file_with_encoding(File::Spec->catfile($dirname,$fname), $encoding), $preamble,$filename,$encoding) or die "Couldn't find file ",File::Spec->catfile($dirname,$fname),": $!"; $replacement = remove_endinput($replacement); # \include always starts a new page; use explicit \newpage command to simulate this $newpage=(defined($3)? " \\newpage " : "") ; "$begline$newpage$replacement$newpage"; }/exgm; # replace bibliography with bbl file if it exists $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography\{(.*?)\}/{ if ( -f $bblfile ){ $replacement=read_file_with_encoding(File::Spec->catfile($bblfile), $encoding); } else { warn "Bibliography file $bblfile cannot be found. No flattening of \\bibliography done. Run bibtex on old and new files first"; $replacement="\\bibliography{$2}"; } $begline=(defined($1)? $1 : "") ; "$begline$replacement"; }/exgm; # replace subfile with contents (subfile package) $text=~s/(^(?:[^%\n]|\\%)*)\\subfile\{(.*?)\}/{ $begline=(defined($1)? $1 : "") ; $fname = $2; # # add tex extension unless there is a three letter extension already $fname .= ".tex" unless $fname =~ m|\.\w{3}|; print STDERR "Include file as subfile $fname\n" if $verbose; # content of file becomes replacement value (use recursion) # now strip away everything outside and including \begin{document} and \end{document} pair# # # note: no checking for comments is made $subfile=read_file_with_encoding(File::Spec->catfile($dirname,$fname), $encoding) or die "Couldn't find file ",File::Spec->catfile($dirname,$fname),": $!"; ($subpreamble,$subbody,$subpost)=splitdoc($subfile,'\\\\begin\{document\}','\\\\end\{document\}'); $replacement=flatten($subbody, $preamble,$filename,$encoding); $replacement = remove_endinput($replacement); "$begline$replacement"; }/exgm; return($text); } # print_regex_arr(@arr) # prints regex array without x-ism expansion put in by pearl to stdout sub print_regex_arr { my $dumstring; $dumstring = join(" ",@_); # PERL generates string (?-xism:^ref$) for quoted refex ^ref$ $dumstring =~ s/\(\?-xism:\^(.*?)\$\)/$1/g; # remove string and ^,$ marks before output print $dumstring,"\n"; } # @lines=extrapream($type) # reads line from appendix (end of file after __END__ token) sub extrapream { my $type; ###my @retval=("%DIF PREAMBLE EXTENSION ADDED BY LATEXDIFF") ; my @retval=(); my ($copy); while (@_) { $copy=0; $type=shift ; if ( -f $type || lc $type eq '/dev/null' ) { open (FILE,$type) or die "Cannot open preamble file $type: $!"; print STDERR "Reading preamble file $type\n" if $verbose ; while () { chomp ; if ( $_ =~ m/%DIF PREAMBLE/ ) { push (@retval,"$_"); } else { push (@retval,"$_ %DIF PREAMBLE"); } } } else { # not (-f $type) $type=uc($type); # upcase argument print STDERR "Preamble Internal Type $type\n" if $verbose; while () { if ( m/^%DIF $type/ ) { $copy=1; } elsif ( m/^%DIF END $type/ ) { last; } chomp; push (@retval,"$_ %DIF PREAMBLE") if $copy; } if ( $copy == 0 ) { print STDERR "\nPreamble style $type not implemented.\n"; print STDERR "Write latexdiff -h to get help with available styles\n"; exit(2); } seek DATA,0,0; # rewind DATA handle to file begin } } ###push (@retval,"%DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF") ; return @retval; } # ($part1,$part2,$part3)=splitdoc($text,$word1,$word2) # splits $text into 3 parts at $word1 and $word2. # if neither $word1 nor $word2 exist, $part1 and $part3 are empty, $part2 is $text # If only $word1 or $word2 exist but not the other, output an error message. # NB this version avoids $` and $' for performance reason although it only makes a tiny difference # (in one test gain a tenth of a second for a 30s run) sub splitdoc { my ($text,$word1,$word2)=@_; my ($part1,$part2,$part3)=("","",""); my ($rest,$pos); if ( $text =~ m/(^[^%]*)($word1)/mg ) { $pos=pos $text; $part1=substr($text,0,$pos-length($2)); $rest=substr($text,$pos); if ( $rest =~ m/(^[^%]*)($word2)/mg ) { $pos=pos $rest; $part2=substr($rest,0,$pos-length($2)); $part3=substr($rest,$pos); } else { die "$word1 and $word2 not in the correct order or not present as a pair." ; } } else { $part2=$text; die "$word2 present but not $word1." if ( $text =~ m/(^[^%]*)$word2/ms ); } return ($part1,$part2,$part3); } # bodydiff($old,$new) sub bodydiff { my ($oldwords, $newwords) = @_; my @retwords; print STDERR "(",exetime()," s)\n","Splitting into latex tokens \n" if $verbose; print STDERR "Parsing $oldfile \n" if $verbose; my @oldwords = splitlatex($oldwords); print STDERR "Parsing $newfile \n" if $verbose; my @newwords = splitlatex($newwords); if ( $debug ) { open(TOKENOLD,">","latexdiff.debug.tokenold"); print TOKENOLD join("***\n",@oldwords); close(TOKENOLD); open(TOKENNEW,">","latexdiff.debug.tokennew"); print TOKENNEW join("***\n",@newwords); close(TOKENNEW); } print STDERR "(",exetime()," s)\n","Pass 1: Expanding text commands and merging isolated identities with changed blocks " if $verbose; pass1(\@oldwords, \@newwords); print STDERR "(",exetime()," s)\n","Pass 2: inserting DIF tokens and mark up. " if $verbose; if ( $debug ) { open(TOKENOLD,">","latexdiff.debug.tokenold2"); print TOKENOLD join("***\n",@oldwords); close(TOKENOLD); open(TOKENNEW,">","latexdiff.debug.tokennew2"); print TOKENNEW join("***\n",@newwords); close(TOKENNEW); } @retwords=pass2(\@oldwords, \@newwords); return(@retwords); } # @words=splitlatex($string) # split string according to latex rules # Each element of words is either # a word (including trailing spaces and punctuation) # a latex command # if there is white space in the beginning return that as first token sub splitlatex { my ($inputstring) = @_ ; my $string=$inputstring ; # if input is empty, return empty list length($string)>0 or return (); $string=~s/^(\s*)//s; my $leadin=$1; length($string)>0 or return ($leadin); my @retval=($string =~ m/$pat/osg); if (length($string) != length(join("",@retval))) { print STDERR "\nWARNING: Inconsistency in length of input string and parsed string:\n This often indicates faulty or non-standard latex code.\n In many cases you can ignore this and the following warning messages.\n Note that character numbers in the following are counted beginning after \\begin{document} and are only approximate." unless $ignorewarnings; print STDERR "DEBUG Original length ",length($string)," Parsed length ",length(join("",@retval)),"\n" if $debug; print STDERR "DEBUG Input string: |$string|\n" if (length($string)<500) && $debug; print STDERR "DEBUG Token parsing: |",join("+",@retval),"|\n" if (length($string)<500) && $debug ; @retval=(); # slow way only do this if other m//sg method fails my $last = 0; while ( $string =~ m/$pat/osg ) { my $match=$&; if ($last + length $& != pos $string ) { my $pos=pos($string); my $offset=30<$last ? 30 : $last; my $dum=substr($string,$last-$offset,$pos-$last+2*$offset); my $dum1=$dum; my $cnt=$#retval; my $i; $dum1 =~ s/\n/ /g; unless ($ignorewarnings) { print STDERR "\n$dum1\n"; print STDERR " " x 30,"^" x ($pos-$last)," " x 30,"\n"; print STDERR "Missing characters near word " . (scalar @retval) . " character index: " . $last . "-" . pos($string) . " Length: " . length($match) . " Match: |$match| (expected match marked above).\n"; } # put in missing characters `by hand' push (@retval, substr($dum,$offset,$pos-$last-length($match))); # Note: there seems to be a bug in substr with utf8 that made the following line output substr which were too long, # using dum instead appears to work # push (@retval, substr($string,$last, pos($string)-$last-length($match))); } push (@retval, $match); $last=pos $string; } } unshift(@retval,$leadin) if (length($leadin)>0); return @retval; } # pass1( \@seq1,\@seq2) # Look for differences between seq1 and seq2. # Where an common-subsequence block is flanked by deleted or appended blocks, # and is shorter than $MINWORDSBLOCK words it is appended # to the last deleted or appended word. If the block contains tokens other than words # or punctuation it is not merged. # Deleted or appended block consisting of words and safe commands only are # also merged, to prevent break-up in pass2 (after previous isolated words have been removed) # If there are commands with textual arguments (e.g. \caption) both in corresponding # appended and deleted blocks split them such that the command and opening bracket # are one token, then the rest is split up following standard rules, and the closing # bracket is a separate token, ie. turn # "\caption{This is a textual argument}" into # ("\caption{","This ","is ","a ","textual ","argument","}") # No return value. Destructively changes sequences sub pass1 { my $seq1 = shift ; my $seq2 = shift ; my $len1 = scalar @$seq1; my $len2 = scalar @$seq2; my $wpat=qr/^(?:[a-zA-Z.,'`:;?()!]*)[\s~]*$/; #' my ($last1,$last2)=(-1,-1) ; my $cnt=0; my $block=[]; my $addblock=[]; my $delblock=[]; my $todo=[]; my $instruction=[]; my $i; my (@delmid,@addmid,@dummy); my ($addcmds,$delcmds,$matchindex); my ($addtextblocks,$deltextblocks); my ($addtokcnt,$deltokcnt,$mattokcnt)=(0,0,0); my ($addblkcnt,$delblkcnt,$matblkcnt)=(0,0,0); my $adddiscard = sub { if ($cnt > 0 ) { $matblkcnt++; # just after an unchanged block # print STDERR "Unchanged block $cnt, $last1,$last2 \n"; if ($cnt < $MINWORDSBLOCK && $cnt==scalar ( grep { /^$wpat/ || ( /^\\((?:[`'^"~=.]|[\w\d@*]+))((?:\[$brat0\]|\{$pat_n\})*)/o && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) && scalar(@dummy=split(" ",$2))<3 ) } @$block) ) { # merge identical blocks shorter than $MINWORDSBLOCK # and only containing ordinary words # with preceding different word # We cannot carry out this merging immediately as this # would change the index numbers of seq1 and seq2 and confuse # the algorithm, instead we store in @$todo where we have to merge push(@$todo, [ $last1,$last2,$cnt,@$block ]); } $block = []; $cnt=0; $last1=-1; $last2=-1; } }; my $discard=sub { $deltokcnt++; &$adddiscard; #($_[0],$_[1]); push(@$delblock,[ $seq1->[$_[0]],$_[0] ]); $last1=$_[0] }; my $add = sub { $addtokcnt++; &$adddiscard; #($_[0],$_[1]); push(@$addblock,[ $seq2->[$_[1]],$_[1] ]); $last2=$_[1] }; my $match = sub { $mattokcnt++; if ($cnt==0) { # first word of matching sequence after changed sequence or at beginning of word sequence $deltextblocks = extracttextblocks($delblock); $delblkcnt++ if scalar @$delblock; $addtextblocks = extracttextblocks($addblock); $addblkcnt++ if scalar @$addblock; $delcmds = extractcommands($delblock); $addcmds = extractcommands($addblock); # keygen(third argument of _longestCommonSubsequence) implies to sort on command (0th elements of $addcmd elements) # the calling format for longestCommonSubsequence has changed between versions of # Algorithm::Diff so we need to check which one we are using if ( $algodiffversion > 1.15 ) { ### Algorithm::Diff 1.19 $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, 0, sub { $_[0]->[0] } ); } else { ### Algorithm::Diff 1.15 $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, sub { $_[0]->[0] } ); } for ($i=0 ; $i<=$#$matchindex ; $i++) { if (defined($matchindex->[$i])){ $j=$matchindex->[$i]; @delmid=splitlatex($delcmds->[$i][3]); @addmid=splitlatex($addcmds->[$j][3]); while (scalar(@$deltextblocks) && $deltextblocks->[0][0]<$delcmds->[$i][1]) { my ($index,$block,$cnt)=@{ shift(@$deltextblocks) }; push(@$todo, [$index,-1,$cnt,@$block]); } push(@$todo, [ $delcmds->[$i][1],-1,-1,$delcmds->[$i][2],@delmid,$delcmds->[$i][4]]); while (scalar(@$addtextblocks) && $addtextblocks->[0][0]<$addcmds->[$j][1]) { my ($index,$block,$cnt)=@{ shift(@$addtextblocks) }; push(@$todo, [-1,$index,$cnt,@$block]); } push(@$todo, [ -1,$addcmds->[$j][1],-1,$addcmds->[$j][2],@addmid,$addcmds->[$j][4]]); } } # mop up remaining textblocks while (scalar(@$deltextblocks)) { my ($index,$block,$cnt)=@{ shift(@$deltextblocks) } ; push(@$todo, [$index,-1,$cnt,@$block]); } while (scalar(@$addtextblocks)) { my ($index,$block,$cnt)=@{ shift(@$addtextblocks) }; push(@$todo, [-1,$index,$cnt,@$block]); } $addblock=[]; $delblock=[]; } push(@$block,$seq2->[$_[1]]); $cnt++ }; my $keyfunc = sub { join(" ",split(" ",shift())) }; traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); # now carry out the merging/splitting. Refer to elements relative from # the end (with negative indices) as these offsets don't change before the instruction is executed # cnt>0: merged small unchanged groups with previous changed blocks # cnt==-1: split textual commands into components foreach $instruction ( @$todo) { ($last1,$last2,$cnt,@$block)=@$instruction ; if ($cnt>=0) { splice(@$seq1,$last1-$len1,1+$cnt,join("",$seq1->[$last1-$len1],@$block)) if $last1>=0; splice(@$seq2,$last2-$len2,1+$cnt,join("",$seq2->[$last2-$len2],@$block)) if $last2>=0; } else { splice(@$seq1,$last1-$len1,1,@$block) if $last1>=0; splice(@$seq2,$last2-$len2,1,@$block) if $last2>=0; } } if ($verbose) { print STDERR "\n"; print STDERR " $mattokcnt matching tokens in $matblkcnt blocks.\n"; print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n"; print STDERR " $addtokcnt appended tokens in $addblkcnt blocks.\n"; } } # extracttextblocks(\@blockindex) # $blockindex has the following format # [ [ token1, index1 ], [token2, index2],.. ] # where index refers to the index in the original old or new word sequence # Returns: reference to an array of the form # [[ $index, $textblock, $cnt ], .. # where $index index of block to be merged # $textblock contains all the words to be merged with the word at $index (but does not contain this word) # $cnt is length of block # # requires: iscmd # sub extracttextblocks { my $block=shift; my ($i,$token,$index); my $textblock=[]; my $last=-1; my $wpat=qr/^(?:[a-zA-Z.,'`:;?()!]*)[\s~]*$/; #' my $retval=[]; for ($i=0;$i< scalar @$block;$i++) { ($token,$index)=@{ $block->[$i] }; # store pure text blocks if ($token =~ /$wpat/ || ( $token =~/^\\((?:[`'^"~=.]|[\w\d@\*]+))((?:${extraspace}\[$brat0\]${extraspace}|${extraspace}\{$pat_n\})*)/o && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) && !iscmd($1,\@TEXTCMDLIST,\@TEXTCMDEXCL))) { # we have text or a command which can be treated as text if ($last<0) { # new pure-text block $last=$index; } else { # add to pure-text block push(@$textblock, $token); } } else { # it is not text if (scalar(@$textblock)) { push(@$retval,[ $last, $textblock, scalar(@$textblock) ]); } $textblock=[]; $last=-1; } } # finish processing a possibly unfinished block before returning if (scalar(@$textblock)) { push(@$retval,[ $last, $textblock, scalar(@$textblock) ]); } return($retval) } # extractcommands( \@blockindex ) # $blockindex has the following format # [ [ token1, index1 ], [token2, index2],.. ] # where index refers to the index in the original old or new word sequence # Returns: reference to an array of the form # [ [ "\cmd1", index, "\cmd1[optarg]{arg1}{", "arg2" ,"} " ],.. # where index is just taken from input array # command must have a textual argument as last argument # # requires: iscmd # sub extractcommands { my $block=shift; my ($i,$token,$index,$cmd,$open,$mid,$closing); my $retval=[]; for ($i=0;$i< scalar @$block;$i++) { ($token,$index)=@{ $block->[$i] }; # check if token is an alphanumeric command sequence with at least one non-optional argument # \cmd[...]{...}{last argument} # Capturing in the following results in these associations # $1: \cmd[...]{...}{ # $2: \cmd # $3: last argument # $4: } + trailing spaces if ( ( $token =~ m/^(\\([\w\d\*]+)(?:${extraspace}\[$brat0\]|${extraspace}\{$pat_n\})*${extraspace}\{)($pat_n)(\}\s*)$/so ) && iscmd($2,\@TEXTCMDLIST,\@TEXTCMDEXCL) ) { # push(@$retval,[ $2,$index,$1,$3,$4 ]); ($cmd,$open,$mid,$closing) = ($2,$1,$3,$4) ; $closing =~ s/\}/\\RIGHTBRACE/ ; push(@$retval,[ $cmd,$index,$open,$mid,$closing ]); } } return $retval; } # iscmd($cmd,\@regexarray,\@regexexcl) checks # return 1 if $cmd matches any of the patterns in the # array $@regexarray, and none of the patterns in \@regexexcl, otherwise return 0 sub iscmd { my ($cmd,$regexar,$regexexcl)=@_; my ($ret)=0; foreach $pat ( @$regexar ) { if ( $cmd =~ m/^${pat}$/ ) { $ret=1 ; last; } } return 0 unless $ret; foreach $pat ( @$regexexcl ) { return 0 if ( $cmd =~ m/^${pat}$/ ); } return 1; } # pass2( \@seq1,\@seq2) # Look for differences between seq1 and seq2. # Mark begin and end of deleted and appended sequences with tags $DELOPEN and $DELCLOSE # and $ADDOPEN and $ADDCLOSE, respectively, however exclude { } & and all comands, unless # they match an element of the whitelist (SAFECMD) # For words in TEXTCMD but not in SAFECMD, enclose interior with $ADDOPEN and $ADDCLOSE brackets # Deleted comment lines are marked with %DIF < # Added comment lines are marked with %DIF > sub pass2 { my $seq1 = shift ; my $seq2 = shift ; my ($addtokcnt,$deltokcnt,$mattokcnt)=(0,0,0); my ($addblkcnt,$delblkcnt,$matblkcnt)=(0,0,0); my $retval = []; my $delhunk = []; my $addhunk = []; my $discard = sub { $deltokcnt++; push ( @$delhunk, $seq1->[$_[0]]) }; my $add = sub { $addtokcnt++; push ( @$addhunk, $seq2->[$_[1]]) }; my $match = sub { $mattokcnt++; if ( scalar @$delhunk ) { $delblkcnt++; # mark up changes, but comment out commands push @$retval,marktags($DELMARKOPEN,$DELMARKCLOSE,$DELOPEN,$DELCLOSE,$DELCMDOPEN,$DELCMDCLOSE,$DELCOMMENT,$delhunk); $delhunk = []; } if ( scalar @$addhunk ) { $addblkcnt++; # we mark up changes, but simply quote commands push @$retval,marktags($ADDMARKOPEN,$ADDMARKCLOSE,$ADDOPEN,$ADDCLOSE,"","",$ADDCOMMENT,$addhunk); $addhunk = []; } push(@$retval,$seq2->[$_[1]]) }; my $keyfunc = sub { join(" ",split(" ",shift())) }; traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); # clear up unprocessed hunks push @$retval,marktags($DELMARKOPEN,$DELMARKCLOSE,$DELOPEN,$DELCLOSE,$DELCMDOPEN,$DELCMDCLOSE,$DELCOMMENT,$delhunk) if scalar @$delhunk; push @$retval,marktags($ADDMARKOPEN,$ADDMARKCLOSE,$ADDOPEN,$ADDCLOSE,"","",$ADDCOMMENT,$addhunk) if scalar @$addhunk; if ($verbose) { print STDERR "\n"; print STDERR " $mattokcnt matching tokens. \n"; print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n"; print STDERR " $addtokcnt appended tokens in $addblkcnt blocks.\n"; } return(@$retval); } # marktags($openmark,$closemark,$open,$close,$opencmd,$closecmd,$comment,\@block) # returns ($openmark,$open,$block,$close,$closemark) if @block contains no commands (except white-listed ones), # braces, ampersands, or comments # mark comments with $comment # exclude all other exceptions from scope of open, close like this # ($openmark, $open,...,$close, $opencmd,command, command,$closecmd, $open, ..., $close, $closemark) # If $opencmd begins with "%" marktags assumes it is operating on a deleted block, otherwise on an added block sub marktags { my ($openmark,$closemark,$open,$close,$opencmd,$closecmd,$comment,$block)=@_; my $word; my (@argtext); my $retval=[]; my $noncomment=0; my $cmd=-1; # -1 at beginning 0: last token written is a ordinary word # 1: last token written is a command # for keeping track whether we are just in a command sequence or in a word sequence my $cmdcomment= ($opencmd =~ m/^%/); # Flag to indicate whether opencmd is a comment (i.e. if we intend to simply comment out changed commands) my ($command,$commandword,$closingbracket) ; # temporary variables needed below to remember sub-pattern matches # split this block to flatten out sequences joined in pass1 @$block=splitlatex(join "",@$block); ### print STDERR "DEBUG: marktags $openmark,$closemark,$open,$close,$opencmd,$closecmd,$comment\n" if $debug; ### print STDERR "DEBUG: marktags blocksplit ",join("|",@$block),"\n" if $debug; foreach (@$block) { $word=$_; ### print STDERR "DEBUG MARKTAGS: |$word|\n" if $debug; if ( $word =~ s/^%/%$comment/ ) { # a comment if ($cmd==1) { push (@$retval,$closecmd) ; $cmd=-1; } push (@$retval,$word); next; } if ( $word =~ m/^\s*$/ ) { ### print STDERR "DEBUG MARKTAGS: whitespace detected |$word| cmdcom |$cmdcomment| |$opencmd|\n" if $debug; # a sequence of white-space characters - this should only ever happen for the first element of block. # in deleted block, omit, otherwise just copy it in if ( ! $cmdcomment) { # ignore in deleted blocks push(@$retval,$word); } next; } if (! $noncomment) { push (@$retval,$openmark); $noncomment=1; } # negative lookahead pattern (?!) in second clause is put in to avoid matching \( .. \) patterns # also note that second pattern will match \\ ### print STDERR "DEBUG marktags: Considering word |$word|\n"; if ( $word =~ /^[&{}\[\]]/ || ( $word =~ /^\\(?!\()(\\|[`'^"~=.]|[\w*@]+)/ && !iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL)) ) { ###print STDERR "DEBUG MARKTAGS is a non-safe command ($1)\n" if $debug; ### if ( $word =~ /^[&{}\[\]]/ || ( $word =~ /^\\([\w*@\\% ]+)/ && !iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL)) ) { # word is a command or other significant token (not in SAFECMDLIST) ## same conditions as in subroutine extractcommand: # check if token is an alphanumeric command sequence with at least one non-optional argument # \cmd[...]{...}{last argument} # Capturing in the following results in these associations # $1: \cmd[...]{...}{ # $2: cmd # $3: last argument # $4: } + trailing spaces ### pre-0.3 if ( ( $token =~ m/^(\\([\w\d\*]+)(?:\[$brat0\]|\{$pat_n\})*\{)($pat_n)(\}\s*)$/so ) if ( ( $word =~ m/^(\\([\w\d\*]+)(?:${extraspace}\[$brat0\]|${extraspace}\{$pat_n\})*${extraspace}\{)($pat_n)(\}\s*)$/so ) && (iscmd($2,\@TEXTCMDLIST,\@TEXTCMDEXCL)|| iscmd($2,\@MATHTEXTCMDLIST,\@MATHTEXTCMDEXCL)) && ( !$cmdcomment || !iscmd($2,\@CONTEXT2CMDLIST, \@CONTEXT2CMDEXCL) ) ) { # Condition 1: word is a command? - if yes, $1,$2,.. will be set as above # Condition 2: word is a text command - we mark up the interior of the word. There is a separate check for MATHTEXTCMDLIST # because for $mathmarkup=WHOLE, the commands should not be split in pass1 (ie. math mode commands are not in # TEXTCMDLIST, but the interior of MATHTEXT commands should be highlighted in both deleted and added blocks # Condition 3: But if we are in a deleted block ($cmdcomment=1) and # $2 (the command) is in context2, just treat it as an ordinary command (i.e. comment it open with $opencmd) # Because we do not want to disable this command # here we do not use $opencmd and $closecmd($opencmd is empty) if ($cmd==1) { push (@$retval,$closecmd) ; } elsif ($cmd==0) { push (@$retval,$close) ; } $command=$1; $commandword=$2; $closingbracket=$4; @argtext=splitlatex($3); # split textual argument into tokens # and mark it up (but we do not need openmark and closemark) # insert command with initial arguments, marked-up final argument, and closing bracket if ( $cmdcomment && iscmd($commandword,\@CONTEXT1CMDLIST, \@CONTEXT1CMDEXCL) ) { # context1cmd in a deleted environment; delete command itself but keep last argument, marked up push (@$retval,$opencmd); $command =~ s/\n/\n${opencmd}/sg ; # repeat opencmd at the beginning of each line # argument, note that the additional comment character is included # to suppress linebreak after opening parentheses, which is important # for latexrevise push (@$retval,$command,"%\n{$AUXCMD\n",marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); } elsif ( iscmd($commandword,,\@MATHTEXTCMDLIST, \@MATHTEXTCMDEXCL) ) { # MATHBLOCK pseudo command: consider all commands safe, except & and \\ # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to # "" local @SAFECMDLIST=(".*"); local @SAFECMDEXCL=('\\','\\\\',@UNSAFEMATHCMD); push(@$retval,$command,marktags("","",$open,$close,"","",$comment,\@argtext)#@argtext ,$closingbracket); } else { # normal textcmd or context1cmd in an added block push (@$retval,$command,marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); } push (@$retval,$AUXCMD,"\n") if $cmdcomment ; $cmd=-1 ; } else { # ordinary command push (@$retval,$opencmd) if $cmd==-1 ; push (@$retval,$close,$opencmd) if $cmd==0 ; $word =~ s/\n/\n${opencmd}/sg if $cmdcomment ; # if opencmd is a comment, repeat this at the beginning of every line ### print STDERR "MARKTAGS: Add command |$word|\n"; push (@$retval,$word); $cmd=1; } } else { ###print STDERR "DEBUG MARKTAGS is an ordinary word or SAFECMD command \n" if $debug; # just an ordinary word or command in SAFECMD push (@$retval,$open) if $cmd==-1 ; push (@$retval,$closecmd,$open) if $cmd==1 ; ###TODO: check here if it is a command in MBOXCMD list, and surround it with \mbox{...} ### $word =~ /^\\(?!\()(\\|[`'^"~=.]|[\w*@]+)/ && iscmd($1,\@MBOXCMDLIST,\@MBOXCMDEXCL)) ### but actually this check has been carried out already so can simply check if word begins with backslash if ( $word =~ /^\\(?!\()(\\|[`'^"~=.]|[\w*@]+)(.*?)(\s*)$/s && iscmd($1,\@MBOXCMDLIST,\@MBOXCMDEXCL)) { # $word is a safe command in MBOXCMDLIST ###print STDERR "DEBUG Mboxsafecmd detected:$word:\n" if $debug ; push(@$retval,"\\mbox{$AUXCMD\n\\" . $1 . $2 . $3 ."}\\hspace{0pt}$AUXCMD\n" ); } else { # $word is a normal word or a safe command (not in MBOXCMDLIST) push (@$retval,$word); } $cmd=0; } } push (@$retval,$close) if $cmd==0; push (@$retval,$closecmd) if $cmd==1; push (@$retval,$closemark) if ($noncomment); return @$retval; } #used in preprocess sub take_comments_and_enter_from_frac() { #*************take the \n and % between frac and {}*********** #notice all of the substitution are made none global while( m/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)}(.*?)\\frac(([\s]*%[^\n]*?)*[\r\n|\r|\n])+\{(.*?)\\end\{\1}/s ) { # if there isn't any % or \n in the pattern $2 then there should be an \\end{...} in $2 ### print STDERR "Match the following in take_comments and_enter_from_frac(1):\n****$&****\n" if $debug; if( $2 !~ m/\\end\{$1}/s ) { # take out % and \n from the next match only (none global) s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)}(.*?)\\frac(([\s]*%[^\n]*?)*[\r\n|\r|\n])+\{(.*?)\\end\{\1}/\\begin{$1}$2\\frac{$5\\end{$1}/s; } else{ #there are no more % and \n in $2, we want to find the next one so we clear the begin-end from the pattern s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)}(.*?)\\end\{\1}/MATHBLOCK$1\{$2\}MATHBLOCKEND/s; } } ###cleaning up while( s/MATHBLOCK($MATHENV|$MATHARRENV|SQUAREBRACKET)\{(.*?)\}MATHBLOCKEND/\\begin{$1}$2\\end{$1}/s ){} ###*************take the \n and % between frac and {}*********** ###**********take the \n and % between {} and {} of the frac*************** while( m/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}(.*?)\\frac\{(.*?)\\end\{\1\}/s ) { # if there isn't any more //frac before the first //end in the pattern $2 then there should be an \\end{...} in $2 ###print STDERR "Match the following in take_comments and_enter_from_frac(2):\n****$&****\n" if $debug; if( $2 !~ m/\\end\{$1\}/s ) { # from now on CURRFRAC is the frac we are looking at s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}(.*?)\\frac\{(.*?)\\end\{\1\}/\\begin\{$1\}$2CURRFRAC\{$3\\end\{$1\}/s; while( m/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}(.*?)CURRFRAC\{(.*?)\\end\{\1\}/s ) { if( m/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}(.*?)CURRFRAC\{($pat_n)\}([\s]*(%[^\n]*?)*[\r\n|\r|\n])+[\s]*\{(.*?)\\end\{\1}/s ) { s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}(.*?)CURRFRAC\{($pat_n)\}([\s]*(%[^\n]*?)*[\r\n|\r|\n])+[\s]*\{(.*?)\\end\{\1\}/\\begin\{$1\}$2CURRFRAC\{$3\}\{$6\\end\{$1\}/s; } else { # there is no comment or \n between the two brackets {}{} # change CURRFRAC to FRACSTART so we can change them all back to //frac{ when we finish s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)}(.*?)CURRFRAC\{(.*?)\\end\{\1}/\\begin{$1}$2FRACSTART\{$3\\end{$1}/s; } } } else{ ###there are no more frac in $2, we want to find the next one so we clear the begin-end from the pattern s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)}(.*?)\\end\{\1}/MATHBLOCK$1\{$2\}MATHBLOCKEND/s; } } ###cleaning up while( s/MATHBLOCK($MATHENV|$MATHARRENV|SQUAREBRACKET)\{(.*?)\}MATHBLOCKEND/\\begin{$1}$2\\end{$1}/s ){} s/FRACSTART/\\frac/g; ###***************take the \n and % between {} and {} of the frac********************* } # preprocess($string, ..) # carry out the following pre-processing steps for all arguments: # 1. Remove leading white-space # Change \{ to \QLEFTBRACE and \} to \QRIGHTBRACE and \& to \AMPERSAND # #. Change {,} in comments to \CLEFTBRACE, \CRIGHTBRACE # 2. mark all first empty line (in block of several) with \PAR tokens # 3. Convert all '\%' into '\PERCENTAGE ' and all '\$' into \DOLLAR to make parsing regular expressions easier # 4. Convert all \verb|some verbatim text| commands (where | can be an arbitrary character) # into \verb{hash} (also lstinline) # 5. Convert \begin{verbatim} some verbatim text \end{verbatim} into \verbatim{hash} (not only verbatim, all patterns matching VERBATIMENV) # 6. Convert _n into \SUBSCRIPTNB{n} and _{nnn} into \SUBSCRIPT{nn} # 7. Convert ^n into \SUPERSCRIPTNB{n} and ^{nnn} into \SUPERSCRIPT{nn} # 8. a. Convert $$ $$ into \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR} # b. Convert \[ \] into \begin{SQUAREBRACKET} \end{SQUAREBRACKET} # 9. Convert all picture environmentent (\begin{PICTUREENV} .. \end{PICTUREENV} \PICTUREBLOCKenv # For --block-math-markup option -convert all \begin{MATH} .. \end{MATH} # into \MATHBLOCKmath{...} commands, where MATH/math is any valid math environment # 10. Add final token STOP to the very end. This is put in because the algorithm works better if the last token is identical. This is removed again in postprocessing. # # NB: step 6 and 7 is likely to convert some "_" inappropriately, e.g. in file # names or labels but it does not matter because they are converted back in the postprocessing step # Returns: leading white space removed in step 1 sub preprocess { for (@_) { # change in \verb and similar commands - note that I introduce an extra space here so that the # already hashed variants do not trigger again # transform \lstinline{...} # s/\\lstinline(\[$brat0\])?(\{(?:.*?)\})/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg; # s/\\lstinline(\[$brat0\])?((\S).*?\2)/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg; s/\\lstinline((?:\[$brat0\])?)(\{(?:.*?)\})/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg; s/\\lstinline((?:\[$brat0\])?)((\S).*?\3)/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg; s/\\(verb\*?|lstinline)(\S)(.*?)\2/"\\DIF${1}{". tohash(\%verbhash,"${2}${3}${2}") ."}"/esg; # Change \{ to \QLEFTBRACE, \} to \QRIGHTBRACE, and \& to \AMPERSAND s/(?{$hstr}) && $string ne $hash->{$hstr}); # else found a duplicate HASH need to repeat for a higher hash value } $hash->{$hstr}=$string; ### print STDERR "Hash:$hstr: Content:$string:\n"; return($hstr); } #string=fromhash(\%hash,$fromstring) # restores string value stored in hash #string=fromhash(\%hash,$fromstring,$prependstring) # additionally begins each line with prependstring sub fromhash { my ($hash,$hstr)=($_[0],$_[1]); my $retstr=$hash->{$hstr}; if ( $#_ >= 2) { $retstr =~ s/^/$_[2]/mg; } return $retstr; } # postprocess($string, ..) # carry out the following post-processing steps for all arguments: # * Remove STOP token from the end # * Replace \RIGHTBRACE by } # * change citation commands within comments to protect from processing (using marker CITEDIF) # 1. Check all deleted blocks: # a.where a deleted block contains a matching \begin and # \end environment (these will be disabled by a %DIFDELCMD statements), for selected environments enable # these commands again (such that for example displayed math in a deleted equation # is properly within math mode. For math mode environments replace numbered equation # environments with their display only variety (so that equation numbers in new file and # diff file are identical). Where the correct type of math environment cannot be determined # use a place holder MATHMODE # b.where one of the commands matching $COUNTERCMD is used as a DIFAUXCMD, add a statement # subtracting one from the respective counter to keep numbering consistent with new file # Replace all MATHMODE environment commands by the correct environment to achieve matching # pairs # c. Convert MATHBLOCKmath commands to their uncounted numbers (e.g. convert equation -> displaymath # (environments defined in $MATHENV will be replaced by $MATHREPL, and environments in $MATHARRENV # will be replaced by $MATHARRREPL # d. If in-line math mode contains array environment, enclose the whole environment in \mbox'es # d. place \cite commands in mbox'es (for UNDERLINE style) # # For added blocks: # c. If in-line math mode contains array environment, enclose the whole environment in \mbox'es # d. place \cite commands in mbox'es (for UNDERLINE style) # # 2. If --block-math-markup option set: Convert \MATHBLOCKmath{..} commands back to environments # # Convert all PICTUREblock{..} commands back to the appropriate environments # 3. Convert DIFadd, DIFdel, DIFaddbegin , ... into FL varieties # within floats (currently recognised float environments: plate,table,figure # plus starred varieties). # 4. Remove empty %DIFDELCMD < lines # 4. Convert \begin{SQUAREBRACKET} \end{SQUAREBRACKET} into \[ \] # Convert \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR} into $$ $$ # 5. Convert \SUPERSCRIPTNB{n} into ^n and \SUPERSCRIPT{nn} into ^{nnn} # 6. Convert \SUBSCRIPTNB{n} into _n and \SUBCRIPT{nn} into _{nnn} # 7. Expand hashes of verb and verbatim environments # 8. Convert '\PERCENTAGE ' back into '\%' and '\DOLLAR ' into '\$' # 9.. remove all \PAR tokens # 10. package specific processing: endfloat: make sure \begin{figure} and \end{figure} are always # on a line by themselves, similarly for table environment # 4, undo renaming of the \begin, \end,{,} in comments # Change \QLEFTBRACE, \QRIGHTBRACE,\AMPERSAND to \{,\},\& # # Note have to manually synchronize substitution commands below and # DIF.. command names in the header sub postprocess { my ($begin,$len,$cnt,$float,$delblock,$addblock); # second level blocks my ($begin2,$cnt2,$len2,$eqarrayblock,$mathblock); my (@textparts,@newtextparts,@liststack,$listtype,$listlast); for (@_) { # change $'s in comments to something harmless 1 while s/(%.*)\$/$1DOLLARDIF/mg ; # Remove final STOP token s/ STOP$//; # Replace \RIGHTBRACE by } s/\\RIGHTBRACE/}/g; # Check all deleted blocks: where a deleted block contains a matching \begin and # \end environment (these will be disabled by a %DIFDELCMD statements), enable # these commands again (such that for example displayed math in a deleted equation # is properly within math mode. For math mode environments replace numbered equation # environments with their display only variety (so that equation numbers in new file and # diff file are identical while ( m/\\DIFdelbegin.*?\\DIFdelend/sg ) { $cnt=0; $len=length($&); $begin=pos($_) - $len; $delblock=$&; ### (.*?[^\n]?)\n? construct is necessary to avoid empty lines in math mode, which result in ### an error # displayed math environments if ($mathmarkup == FINE ) { $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{((?:$MATHENV)|SQUAREBRACKET)\}.*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(\%DIFDELCMD < \s*\\end\{\2\})/\\begin{$MATHREPL}$AUXCMD\n$1$3\n\\end{$MATHREPL}$AUXCMD\n$4/sg; # also transform the opposite pair \end{displaymath} .. \begin{displaymath} but we have to be careful not to interfere with the results of the transformation in the line directly above ### pre-0.42 obsolete version which did not work on eqnarray test $delblock=~ s/(? displaymath # (environments defined in $MATHENV will be replaced by $MATHREPL, and environments in $MATHARRENV # will be replaced by $MATHARRREPL $delblock=~ s/\\MATHBLOCK($MATHENV)\{($pat_n)\}/\\MATHBLOCK$MATHREPL\{$2\}/sg; $delblock=~ s/\\MATHBLOCK($MATHARRENV)\{($pat_n)\}/\\MATHBLOCK$MATHARRREPL\{$2\}/sg; } # Reinstate completely deleted list environments. note that items within the # environment will still be commented out. They will be restored later $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{($LISTENV)\}\s*?(?:\n|$DELCMDCLOSE))(.*?)(\%DIFDELCMD < \s*\\end\{\2\})/{ ### # block within the search; replacement environment ### "$1\\begin{$2}$AUXCMD\n". restore_item_commands($3). "\n\\end{$2}$AUXCMD\n$4"; "$1\\begin{$2}$AUXCMD\n$3\n\\end{$2}$AUXCMD\n$4"; }/esg; # b.where one of the commands matching $COUNTERCMD is used as a DIFAUXCMD, add a statement # subtracting one from the respective counter to keep numbering consistent with new file $delblock=~ s/\\($COUNTERCMD)((?:${extraspace}\[$brat0\]${extraspace}|${extraspace}\{$pat_n\})*\s*${AUXCMD}\n)/\\$1$2\\addtocounter{$1}{-1}${AUXCMD}\n/sg ; # bb. disable active labels within deleted blocks (as these are not safe commands, this should normally only # happen within deleted maths blocks $delblock=~ s/(?>>\n" if $debug; # make the array modification in added blocks while ( m/\\DIFaddbegin.*?\\DIFaddend/sg ) { $cnt=0; $len=length($&); $begin=pos($_) - $len; $addblock=$&; while ( $addblock =~ m/($math)(\s*)/sg ) { $cnt2=0; $len2=length($&); $begin2=pos($addblock) - $len2; $mathblock="%\n\\mbox{$AUXCMD\n$1\n}$AUXCMD\n"; next unless ( $mathblock =~ /ARRAYBLOCK/ or $mathblock =~ m/\{$ARRENV\}/) ; substr($addblock,$begin2,$len2)=$mathblock; pos($addblock) = $begin2 + length($mathblock); } # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox if ( $MBOXINLINEMATH ) { ##$addblock=~s/($math)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; $addblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; } ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{color\}/)) { # mark added verbatim commands $addblock =~ s/\\DIFverb/\\DIFDIFaddverb/g; $addblock =~ s/\\DIFlstinline/\\DIFDIFaddlstinline/g; ###} # splice in modified addblock substr($_,$begin,$len)=$addblock; pos = $begin + length($addblock); } # Go through whole text, and by counting list environment commands, find out when we are within a list environment. # Within those restore deleted \item commands @textparts=split /(? 0) { $listlast=pop(@liststack); ($listtype eq $listlast) or warn "Invalid nesting of list environments: $listlast environment closed by \\end{$listtype}."; } else { warn "Invalid nesting of list environments: \\end{$listtype} encountered without matching \\begin{$listtype}."; } } else { print STDERR "DEBUG: postprocess \@liststack=(",join(",",@liststack),")\n" if $debug; if (scalar @liststack > 0 ) { # we are within a list environment and should replace all item commands $_=restore_item_commands($_); } # else: we are outside a list environment and do not need to do anything } $_ } @textparts; # end of map command # replace the main text with the modified version $_= join("",@newtextparts); # Replace MATHMODE environments from step 1a above by the correct Math environment # The next line is complicated. The negative look-ahead insertion makes sure that no \end{$MATHENV} (or other mathematical # environments) are between the \begin{$MATHENV} and \end{MATHMODE} commands. This is necessary as the minimal matching # is not globally minimal but only 'locally' (matching is beginning from the left side of the string) if ( $mathmarkup == FINE ) { 1 while s/\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}((?:.(?!(?:\\end\{(?:(?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}|\\begin\{MATHMODE})))*?)\\end\{MATHMODE}/\\begin{$1}$2\\end{$1}/s; 1 while s/\\begin\{MATHMODE}((?:.(?!\\end\{MATHMODE}))*?)\\end\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}/\\begin{$2}$1\\end{$2}/s; # convert remaining \begin{MATHMODE} \end{MATHMODE} (and not containing & or \\ )into MATHREPL environments s/\\begin\{MATHMODE\}((?:(.(?!(?)?)((?:\[$brat0\])?)\s*((?:${cmdoptseq}\s*?)*)(?:\n|$DELCMDCLOSE))/ # if \item has an []argument, then mark up the argument as deleted) if (length($4)>0) { # use substr to exclude square brackets at end points @itemargs=splitlatex(substr($4,1,length($4)-2)); $itemarg="[".join("",marktags("","",$DELOPEN,$DELCLOSE,$DELCMDOPEN,$DELCMDCLOSE,$DELCOMMENT,\@itemargs))."]"; } else { $itemarg=""; } "$1$2$3$itemarg$AUXCMD\n"; ###.((length($5)>0) ? "%DIFDELCMD $5 $DELCMDCLOSE\n" : "") /sge; return($string); } # @auxlines=preprocess_preamble($oldpreamble,$newpreamble); # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) # if found then use a bodydiff to mark up content, and replace the corresponding commands # in both preambles by marked up version to 'fool' the linediff (such that only body is marked # up. # A special case are e.g. author commands being added (or removed) # 1. If commands are added, then the entire content is marked up as new, but also the lines are marked as new in the linediff # 2. If commands are removed, then the linediff will mark the line as deleted. The program returns # with $auxlines a text to be appended at the end of the preamble, which shows the respective fields as deleted sub preprocess_preamble { my ($oldpreambleref,$newpreambleref)=(\$_[0],\$_[1]) ; my @auxlines=(); # Remember to use $$oldpreambleref to refer to oldpreamble my ($titlecmd,$titlecmdpat); my (@oldtitlecommands,@newtitlecommands ); my %oldhash = (); my %newhash = (); my ($line,$cmd,$optarg,$arg,$optargnew,$optargold,$optargdiff,$argold,$argnew,$argdiff,$auxline); # resuse context2cmdlist to define these commands to look out for in preamble $titlecmd = "(?:".join("|",@CONTEXT2CMDLIST).")"; # as context2cmdlist is stored as regex, e.g. ((?-xism:^title$), we need to remove ^- fo # resue in a more complex regex $titlecmd =~ s/[\$\^]//g; # make sure to not match on comment lines: $titlecmdpat=qr/^(?:[^%\n]|\\%)*(\\($titlecmd)$extraspace(?:\[($brat0)\])?(?:\{($pat_n)\}))/ms; ###print STDERR "DEBUG:",$titlecmdpat,"\n"; @oldtitlecommands= ( $$oldpreambleref =~ m/$titlecmdpat/g ); @newtitlecommands= ( $$newpreambleref =~ m/$titlecmdpat/g ); while ( @oldtitlecommands ) { $line=shift @oldtitlecommands; $cmd=shift @oldtitlecommands; $optarg=shift @oldtitlecommands; $arg=shift @oldtitlecommands; if ( defined($oldhash{$cmd})) { warn "$cmd is used twice in preamble of old file. Reverting to pure line diff mode for preamble.\n"; return; } $oldhash{$cmd}=[ $line, $optarg, $arg ]; } while ( @newtitlecommands ) { $line=shift @newtitlecommands; $cmd=shift @newtitlecommands; $optarg=shift @newtitlecommands; $arg=shift @newtitlecommands; if ( defined($newhash{$cmd})) { warn "$cmd is used twice in preamble of new file. Reverting to pure line diff mode for preamble.\n"; return; } $newhash{$cmd}=[ $line, $optarg, $arg ]; } foreach $cmd ( keys %newhash ) { if ( defined($newhash{$cmd}->[1])) { $optargnew=$newhash{$cmd}->[1]; } else { $optargnew=""; } if ( defined($oldhash{$cmd}->[1])) { $optargold=$oldhash{$cmd}->[1]; } else { $optargold=""; } if ( defined($oldhash{$cmd}->[2]) ) { $argold=$oldhash{$cmd}->[2]; } else { $argold=""; } $argnew=$newhash{$cmd}->[2]; $argdiff="{" . join("",bodydiff($argold,$argnew)) ."}"; if ( length $optargnew ) { $optargdiff="[".join("",bodydiff($optargold,$optargnew))."]" ; $optargdiff =~ s/\\DIFaddbegin /\\DIFaddbeginFL /g; $optargdiff =~ s/\\DIFaddend /\\DIFaddendFL /g; $optargdiff =~ s/\\DIFadd\{/\\DIFaddFL{/g; $optargdiff =~ s/\\DIFdelbegin /\\DIFdelbeginFL /g; $optargdiff =~ s/\\DIFdelend /\\DIFdelendFL /g; $optargdiff =~ s/\\DIFdel\{/\\DIFdelFL{/g; } else { $optargdiff=""; } ### print STDERR "DEBUG s/\\Q$newhash{$cmd}->[0]\\E/\\$cmd$optargdiff$argdiff/s\n"; # Note: \Q and \E force literal interpretation of what it between them but allow # variable interpolation, such that e.g. \title matches just that and not TAB-itle $$newpreambleref=~s/\Q$newhash{$cmd}->[0]\E/\\$cmd$optargdiff$argdiff/s; # replace this in old preamble if necessary if ( defined($oldhash{$cmd}->[0])) { $$oldpreambleref=~s/\Q$oldhash{$cmd}->[0]\E/\\$cmd$optargdiff$argdiff/s ; } ### print STDERR "DEBUG NEW PRE ".$$newpreambleref."\n"; } foreach $cmd ( keys %oldhash ) { # if this has already been dealt with above can just skip next if defined($newhash{$cmd}) ; $argold=$oldhash{$cmd}->[2]; $argdiff="{" . join("",bodydiff($argold,"")) ."}"; if ( defined($oldhash{$cmd}->[1])) { $optargold=$oldhash{$cmd}->[1]; $optargdiff="[".join("",bodydiff($optargold,""))."]" ; $optargdiff =~ s/\\DIFdelbegin /\\DIFdelbeginFL /g; $optargdiff =~ s/\\DIFdelend /\\DIFdelendFL /g; $optargdiff =~ s/\\DIFdel\{/\\DIFdelFL{/g; } else { $optargdiff=""; } $auxline = "\\$cmd$optargdiff$argdiff"; $auxline =~s/$/$AUXCMD/sg; push @auxlines,$auxline; } # add auxcmd comment to highlight added lines return(@auxlines); } # @diffs=linediff(\@seq1, \@seq2) # mark up lines like this #%DIF mm-mmdnn #%< old deleted line(s) #%DIF ------- #%DIF mmann-nn #new appended line %< #%DIF ------- # Future extension: mark change explicitly # Assumes: traverse_sequence traverses deletions before insertions in changed sequences # all line numbers relative to line 0 (first line of real file) sub linediff { my $seq1 = shift ; my $seq2 = shift ; my $block = []; my $retseq = []; my @begin=('','',''); # dummy initialisation my $instring ; my $discard = sub { @begin=('d',$_[0],$_[1]) unless scalar @$block ; push(@$block, "%DIF < " . $seq1->[$_[0]]) }; my $add = sub { if (! scalar @$block) { @begin=('a',$_[0],$_[1]) ;} elsif ( $begin[0] eq 'd' ) { $begin[0]='c'; $begin[2]=$_[1]; push(@$block, "%DIF -------") } push(@$block, $seq2->[$_[1]] . " %DIF > " ) }; my $match = sub { if ( scalar @$block ) { if ( $begin[0] eq 'd' && $begin[1]!=$_[0]-1) { $instring = sprintf "%%DIF %d-%dd%d",$begin[1],$_[0]-1,$begin[2]; } elsif ( $begin[0] eq 'a' && $begin[2]!=$_[1]-1) { $instring = sprintf "%%DIF %da%d-%d",$begin[1],$begin[2],$_[1]-1; } elsif ( $begin[0] eq 'c' ) { $instring = sprintf "%%DIF %sc%s", ($begin[1]==$_[0]-1) ? "$begin[1]" : $begin[1]."-".($_[0]-1) , ($begin[2]==$_[1]-1) ? "$begin[2]" : $begin[2]."-".($_[1]-1) ; } else { $instring = sprintf "%%DIF %d%s%d",$begin[1],$begin[0],$begin[2]; } push @$retseq, $instring,@$block, "%DIF -------" ; $block = []; } push @$retseq, $seq2->[$_[1]] }; # key function: remove multiple spaces (such that insertion or deletion of redundant white space is not reported) my $keyfunc = sub { join(" ",split(" ",shift())) }; traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); push @$retseq, @$block if scalar @$block; return wantarray ? @$retseq : $retseq ; } # init_regex_arr_data(\@array,"TOKEN INIT") # scans DATA file handel for line "%% TOKEN INIT" line # then appends each line not beginning with % into array (as a quoted regex) # This is used for command lists and configuration variables, but the processing is slightly # different: # For lists, the regular expression is extended to include beginning (^) and end ($) markers, to require full-string matching # For configuration variables (and all others), simply an unadorned list is copied sub init_regex_arr_data { my ($arr,$token)=@_; my $copy=0; my ($mode); if ($token =~ m/COMMANDS/ ) { $mode=0; } else { $mode=1; } while () { if ( m/^%%BEGIN $token\s*$/ ) { $copy=1; next; } elsif ( m/^%%END $token\s*$/ ) { last; } chomp; if ( $mode==0 ) { push (@$arr,qr/^$_$/) if ( $copy && !/^%/ ) ; } elsif ($mode==1) { push (@$arr,"$_") if ( $copy && !/^%/ ) ; } } seek DATA,0,0; # rewind DATA handle to file begin } # init_regex_arr_ext(\@array,$arg) # appends array with regular expressions. # if arg is a file name, then read in list of regular expressions from that file # (one expression per line) # Otherwise treat arg as a comma separated list of regular expressions sub init_regex_arr_ext { my ($arr,$arg)=@_; if ( -f $arg ) { init_regex_arr_file($arr,$arg); } else { init_regex_arr_list($arr,$arg); } } # init_regex_arr_file(\@array,$fname) # appends array with regular expressions. # Read in list of regular expressions from $fname # (one expression per line) sub init_regex_arr_file { my ($arr,$fname)=@_; open(FILE,"$fname") or die ("Couldn't open $fname: $!"); while () { chomp; next if /^\s*#/ || /^\s*%/ || /^\s*$/ ; push (@$arr,qr/^$_$/); } close(FILE); } # init_regex_arr_list(\@array,$arg) # appends array with regular expressions. # read from comma separated list of regular expressions ($arg) sub init_regex_arr_list { my ($arr,$arg)=@_; my $regex; ### print STDERR "DEBUG init_regex_arr_list arg >$arg<\n" if $debug; foreach $regex (split(qr/(?=1) { $reset=shift; } if ($reset) { $lasttime=times(); } else { $retval=times()-$lasttime; $lasttime=$lasttime+$retval; return($retval); } } sub usage { die <<"EOF"; Usage: $0 [options] old.tex new.tex > diff.tex Compares two latex files and writes tex code to stdout, which has the same format as new.tex but has all changes relative to old.tex marked up or commented. --type=markupstyle -t markupstyle Add code to preamble for selected markup style Available styles: UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCBHBAR BOLD PDFCOMMENT [ Default: UNDERLINE ] --subtype=markstyle -s markstyle Add code to preamble for selected style for bracketing commands (e.g. to mark changes in margin) Available styles: SAFE MARGIN DVIPSCOL COLOR ZLABEL ONLYCHANGEDPAGE (LABEL)* [ Default: SAFE ] * LABEL subtype is deprecated --floattype=markstyle -f markstyle Add code to preamble for selected style which replace standard marking and markup commands within floats (e.g., marginal remarks cause an error within floats so marginal marking can be disabled thus) Available styles: FLOATSAFE IDENTICAL [ Default: FLOATSAFE ] --encoding=enc -e enc Specify encoding of old.tex and new.tex. Typical encodings are ascii, utf8, latin1, latin9. A list of available encodings can be obtained by executing perl -MEncode -e 'print join ("\\n",Encode->encodings( ":all" )) ;' [Default encoding is utf8 unless the first few lines of the preamble contain an invocation "\\usepackage[..]{inputenc} in which case the encoding chosen by this command is asssumed. Note that ASCII (standard latex) is a subset of utf8] --preamble=file -p file Insert file at end of preamble instead of auto-generating preamble. The preamble must define the following commands \\DIFaddbegin,\\DIFaddend,\\DIFadd{..}, \\DIFdelbegin,\\DIFdelend,\\DIFdel{..}, and varieties for use within floats \\DIFaddbeginFL,\\DIFaddendFL,\\DIFaddFL{..}, \\DIFdelbeginFL,\\DIFdelendFL,\\DIFdelFL{..} (If this option is set -t, -s, and -f options are ignored.) --exclude-safecmd=exclude-file --exclude-safecmd="cmd1,cmd2,..." -A exclude-file --replace-safecmd=replace-file --append-safecmd=append-file --append-safecmd="cmd1,cmd2,..." -a append-file Exclude from, replace or append to the list of regex matching commands which are safe to use within the scope of a \\DIFadd or \\DIFdel command. The file must contain one Perl-RegEx per line (Comment lines beginning with # or % are ignored). A literal comma within the comma-separated list must be escaped thus "\\,", Note that the RegEx needs to match the whole of the token, i.e., /^regex\$/ is implied and that the initial "\\" of the command is not included. The --exclude-safecmd and --append-safecmd options can be combined with the --replace-safecmd option and can be used repeatedly to add cumulatively to the lists. --exclude-textcmd=exclude-file --exclude-textcmd="cmd1,cmd2,..." -X exclude-file --replace-textcmd=replace-file --append-textcmd=append-file --append-textcmd="cmd1,cmd2,..." -x append-file Exclude from, replace or append to the list of regex matching commands whose last argument is text. See entry for --exclude-safecmd directly above for further details. --replace-context1cmd=replace-file --append-context1cmd=append-file --append-context1cmd="cmd1,cmd2,..." Replace or append to the list of regex matching commands whose last argument is text but which require a particular context to work, e.g. \\caption will only work within a figure or table. These commands behave like text commands, except when they occur in a deleted section, when they are disabled, but their argument is shown as deleted text. --replace-context2cmd=replace-file --append-context2cmd=append-file --append-context2cmd="cmd1,cmd2,..." As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. --exclude-mboxsafecmd=exclude-file --exclude-mboxsafecmd="cmd1,cmd2,..." --append-mboxsafecmd=append-file --append-mboxsafecmd="cmd1,cmd2,..." Define safe commands, which additionally need to be protected by encapsulating in an \\mbox{..}. This is sometimes needed to get around incompatibilities between external packages and the ulem package, which is used for highlighting in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE --config var1=val1,var2=val2,... -c var1=val1,.. Set configuration variables. -c configfile Available variables: ARRENV (RegEx) COUNTERCMD (RegEx) FLOATENV (RegEx) ITEMCMD (RegEx) LISTENV (RegEx) MATHARRENV (RegEx) MATHARRREPL (String) MATHENV (RegEx) MATHREPL (String) MINWORDSBLOCK (Integer) PICTUREENV (RegEx) SCALEDELGRAPHICS (Float) This option can be repeated. --add-to-config varenv1=pattern1,varenv2=pattern2 For configuration variables containing a regular expression (essentially those ending in ENV, and COUNTERCMD) this provides an alternative way to modify the configuration variables. Instead of setting the complete pattern, with this option it is possible to add an alternative pattern. varenv must be one of the variables listed above that take a regular expression as argument, and pattern is any regular expression (which might need to be protected from the shell by quotation). Several patterns can be added at once by using semi-colons to separate them, e.g. --add-to-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote" --packages=pkg1,pkg2,.. Tell latexdiff that .tex file is processed with the packages in list loaded. This is normally not necessary if the .tex file includes the preamble, as the preamble is automatically scanned for \\usepackage commands. Use of the --packages option disables automatic scanning, so if for any reason package specific parsing needs to be switched off, use --packages=none. The following packages trigger special behaviour: endfloat hyperref amsmath apacite siunitx cleveref glossaries mhchem chemformula/chemmacros [ Default: scan the preamble for \\usepackage commands to determine loaded packages.] --show-preamble Print generated or included preamble commands to stdout. --show-safecmd Print list of regex matching and excluding safe commands. --show-textcmd Print list of regex matching and excluding commands with text argument. --show-config Show values of configuration variables --show-all Show all of the above NB For all --show commands, no old.tex or new.tex file needs to be given, and no differencing takes place. Other configuration options: --allow-spaces Allow spaces between bracketed or braced arguments to commands [Default requires arguments to directly follow each other without intervening spaces] --math-markup=level Determine granularity of markup in displayed math environments: Possible values for level are (both numerical and text labels are acceptable): off or 0: suppress markup for math environments. Deleted equations will not appear in diff file. This mode can be used if all the other modes cause invalid latex code. whole or 1: Differencing on the level of whole equations. Even trivial changes to equations cause the whole equation to be marked changed. This mode can be used if processing in coarse or fine mode results in invalid latex code. coarse or 2: Detect changes within equations marked up with a coarse granularity; changes in equation type (e.g.displaymath to equation) appear as a change to the complete equation. This mode is recommended for situations where the content and order of some equations are still being changed. [Default] fine or 3: Detect small change in equations and mark up and fine granularity. This mode is most suitable, if only minor changes to equations are expected, e.g. correction of typos. --graphics-markup=level Change highlight style for graphics embedded with \\includegraphics commands Possible values for level: none,off or 0: no highlighting for figures new-only or 1: surround newly added or changed figures with a blue frame [Default] both or 2: highlight new figures with a blue frame and show deleted figures at reduced scale, and crossed out with a red diagonal cross. Use configuration variable SCALEDELGRAPHICS to set size of deleted figures. Note that changes to the optional parameters will make the figure appear as changed to latexdiff, and this figure will thus be highlighted. --disable-citation-markup --disable-auto-mbox Suppress citation markup and markup of other vulnerable commands in styles using ulem (UNDERLINE,FONTSTRIKE, CULINECHBAR) (the two options are identical and are simply aliases) --enable-citation-markup --enforce-auto-mbox Protect citation commands and other vulnerable commands in changed sections with \\mbox command, i.e. use default behaviour for ulem package for other packages (the two options are identical and are simply aliases) Miscelleneous options --label=label -L label Sets the labels used to describe the old and new files. The first use of this option sets the label describing the old file and the second use of the option sets the label for the new file. [Default: use the filename and modification dates for the label] --no-label Suppress inclusion of old and new file names as comment in output file --visible-label Include old and new filenames (or labels set with --label option) as visible output --flatten Replace \\input and \\include commands within body by the content of the files in their argument. If \\includeonly is present in the preamble, only those files are expanded into the document. However, no recursion is done, i.e. \\input and \\include commands within included sections are not expanded. The included files are assumed to be located in the same directories as the old and new master files, respectively, making it possible to organise files into old and new directories. --flatten is applied recursively, so inputted files can contain further \\input statements. --help -h Show this help text. --ignore-warnings Suppress warnings about inconsistencies in length between input and parsed strings and missing characters. --verbose -V Output various status information to stderr during processing. Default is to work silently. --version Show version number. EOF } =head1 NAME latexdiff - determine and markup differences between two latex files =head1 SYNOPSIS B [ B ] F F > F =head1 DESCRIPTION Briefly, I is a utility program to aid in the management of revisions of latex documents. It compares two valid latex files, here called C and C, finds significant differences between them (i.e., ignoring the number of white spaces and position of line breaks), and adds special commands to highlight the differences. Where visual highlighting is not possible, e.g. for changes in the formatting, the differences are nevertheless marked up in the source. The program treats the preamble differently from the main document. Differences between the preambles are found using line-based differencing (similarly to the Unix diff command, but ignoring white spaces). A comment, "S>>" is appended to each added line, i.e. a line present in C but not in C. Discarded lines are deactivated by prepending "S>>". Changed blocks are preceded by comment lines giving information about line numbers in the original files. Where there are insignificant differences, the resulting file C will be similar to C. At the end of the preamble, the definitions for I markup commands are inserted. In differencing the main body of the text, I attempts to satisfy the following guidelines (in order of priority): =over 3 =item 1 If both C and C are valid LaTeX, then the resulting C should also be valid LateX. (NB If a few plain TeX commands are used within C or C then C is not guaranteed to work but usually will). =item 2 Significant differences are determined on the level of individual words. All significant differences, including differences between comments should be clearly marked in the resulting source code C. =item 3 If a changed passage contains text or text-producing commands, then running C through LateX should produce output where added and discarded passages are highlighted. =item 4 Where there are insignificant differences, e.g. in the positioning of line breaks, C should follow the formatting of C =back For differencing the same algorithm as I is used but words instead of lines are compared. An attempt is made to recognize blocks which are completely changed such that they can be marked up as a unit. Comments are differenced line by line but the number of spaces within comments is ignored. Commands including all their arguments are generally compared as one unit, i.e., no mark-up is inserted into the arguments of commands. However, for a selected number of commands (for example, C<\caption> and all sectioning commands) the last argument is known to be text. This text is split into words and differenced just as ordinary text (use options to show and change the list of text commands, see below). As the algorithm has no detailed knowledge of LaTeX, it assumes all pairs of curly braces immediately following a command (i.e. a sequence of letters beginning with a backslash) are arguments for that command. As a restriction to condition 1 above it is thus necessary to surround all arguments with curly braces, and to not insert extraneous spaces. For example, write \section{\textem{This is an emphasized section title}} and not \section {\textem{This is an emphasized section title}} or \section\textem{This is an emphasized section title} even though all varieties are the same to LaTeX (but see B<--allow-spaces> option which allows the second variety). For environments whose content does not conform to standard LaTeX or where graphical markup does not make sense all markup commands can be removed by setting the PICTUREENV configuration variable, set by default to C and C environments; see B<--config> option). The latter environment (C) can be used to protect parts of the latex file where the markup results in illegal markup. You have to surround the offending passage in both the old and new file by C<\begin{DIFnomarkup}> and C<\end{DIFnomarkup}>. You must define the environment in the preambles of both old and new documents. I prefer to define it as a null-environment, C<\newenvironment{DIFnomarkup}{}{}> but the choice is yours. Any markup within the environment will be removed, and generally everything within the environment will just be taken from the new file. It is also possible to difference files which do not have a preamble. In this case, the file is processed in the main document mode, but the definitions of the markup commands are not inserted. All markup commands inserted by I begin with "C<\DIF>". Added blocks containing words, commands or comments which are in C but not in C are marked by C<\DIFaddbegin> and C<\DIFaddend>. Discarded blocks are marked by C<\DIFdelbegin> and C<\DIFdelend>. Within added blocks all text is highlighted with C<\DIFadd> like this: C<\DIFadd{Added text block}> Selected `safe' commands can be contained in these text blocks as well (use options to show and change the list of safe commands, see below). All other commands as well as braces "{" and "}" are never put within the scope of C<\DIFadd>. Added comments are marked by prepending "S >>". Within deleted blocks text is highlighted with C<\DIFdel>. Deleted comments are marked by prepending "S >>". Non-safe command and curly braces within deleted blocks are commented out with "S >>". =head1 OPTIONS =head2 Preamble The following options determine the visual markup style by adding the appropriate command definitions to the preamble. See the end of this section for a description of available styles. =over 4 =item B<--type=markupstyle> or B<-t markupstyle> Add code to preamble for selected markup style. This option defines C<\DIFadd> and C<\DIFdel> commands. Available styles: C [ Default: C ] =item B<--subtype=markstyle> or B<-s markstyle> Add code to preamble for selected style for bracketing commands (e.g. to mark changes in margin). This option defines C<\DIFaddbegin>, C<\DIFaddend>, C<\DIFdelbegin> and C<\DIFdelend> commands. Available styles: C [ Default: C ] * Subtype C