summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-15 18:23:18 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-15 18:23:18 +0000
commit3133bbc63a2d32dac638db58fa13e966488e88b5 (patch)
tree326595b5fefc87fd7cf5ab3905bc00883fe3c919 /lib
downloadkchmviewer-3133bbc63a2d32dac638db58fa13e966488e88b5.tar.gz
kchmviewer-3133bbc63a2d32dac638db58fa13e966488e88b5.zip
Added abandoned KDE3 version of kchmviewer
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kchmviewer@1090662 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am17
-rw-r--r--lib/chmlib/AUTHORS18
-rw-r--r--lib/chmlib/COPYING510
-rw-r--r--lib/chmlib/INSTALL236
-rw-r--r--lib/chmlib/Makefile.am3
-rw-r--r--lib/chmlib/NEWS68
-rw-r--r--lib/chmlib/README141
-rw-r--r--lib/chmlib/chm_lib.c1917
-rw-r--r--lib/chmlib/chm_lib.h144
-rw-r--r--lib/chmlib/lzx.c812
-rw-r--r--lib/chmlib/lzx.h62
-rw-r--r--lib/kio-msits/Makefile.am14
-rw-r--r--lib/kio-msits/kchmviewer.desktop11
-rwxr-xr-xlib/kio-msits/msits.cpp320
-rwxr-xr-xlib/kio-msits/msits.h79
-rwxr-xr-xlib/kio-msits/msits.protocol24
-rw-r--r--lib/libchmfile/Makefile.am10
-rw-r--r--lib/libchmfile/bitfiddle.h155
-rw-r--r--lib/libchmfile/lchmurlhandler.cpp32
-rw-r--r--lib/libchmfile/lchmurlhandler.h36
-rw-r--r--lib/libchmfile/libchmfile.cpp125
-rw-r--r--lib/libchmfile/libchmfile.h290
-rw-r--r--lib/libchmfile/libchmfile_search.cpp289
-rw-r--r--lib/libchmfile/libchmfileimpl.cpp1271
-rw-r--r--lib/libchmfile/libchmfileimpl.h286
-rw-r--r--lib/libchmfile/libchmtextencoding.cpp197
-rw-r--r--lib/libchmfile/libchmtextencoding.h40
-rw-r--r--lib/libchmfile/libchmtocimage.cpp2112
-rw-r--r--lib/libchmfile/libchmtocimage.h32
-rw-r--r--lib/libchmfile/libchmurlfactory.h122
-rw-r--r--lib/libchmfile/qt34.cpp259
-rw-r--r--lib/libchmfile/qt34.h123
32 files changed, 9755 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 0000000..0a215da
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,17 @@
+if AMC_USE_KDE
+SUBDIR_KIO = kio-msits
+endif
+
+if AMC_BUILD_CHMLIB
+SUBDIR_CHMLIB = chmlib
+endif
+
+SUBDIRS = $(SUBDIR_CHMLIB) $(SUBDIR_KIO) libchmfile
+DIST_SUBDIRS = chmlib kio-msits libchmfile
+
+package-messages:
+ $(MAKE) -f admin/Makefile.common package-messages
+ $(MAKE) -C po merge
+
+# Uncomment this line before opening the project in kdevelop for the first time!
+#SUBDIRS = chmlib kio-msits libchmfile
diff --git a/lib/chmlib/AUTHORS b/lib/chmlib/AUTHORS
new file mode 100644
index 0000000..431ecc3
--- /dev/null
+++ b/lib/chmlib/AUTHORS
@@ -0,0 +1,18 @@
+Jed Wing <jedwin@ugcs.caltech.edu>
+includes modified LZX code from cabextract-0.5 by Stuart Caie.
+
+Thanks to:
+ iDEFENSE for reporting the stack overflow vulnerability.
+ Palasik Sandor for reporting and fixing the LZX buffer overrun vulnerability.
+ David Huseby for enhancements to the chm_enumerate functionality.
+ Vitaly Bursov for compilation fixes for x86-64.
+ Vadim Zeitlin for a patch to clean up and fix some deficiencies in the
+ configure script.
+ Stan Tobias for bugfixes and index-page improvement to chm_http.
+ Andrew Hodgetts for major portability improvement.
+ Rich Erwin for his work towards Windows CE support.
+ Pabs for bug fixes and suggestions.
+ Antony Dovgal for setting up autoconf/automake based build process.
+ Ragnar Hojland Espinosa for patches to make chm_http more useful.
+ Razvan Cojocaru for forwarding along information regarding building on OS X.
+ Anyone else I've forgotten.
diff --git a/lib/chmlib/COPYING b/lib/chmlib/COPYING
new file mode 100644
index 0000000..cc6f365
--- /dev/null
+++ b/lib/chmlib/COPYING
@@ -0,0 +1,510 @@
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+^L
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must
+be allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+^L
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+^L
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+^L
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+^L
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+^L
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+^L
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+^L
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James
+ Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/lib/chmlib/INSTALL b/lib/chmlib/INSTALL
new file mode 100644
index 0000000..23e5f25
--- /dev/null
+++ b/lib/chmlib/INSTALL
@@ -0,0 +1,236 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script). Here is a another example:
+
+ /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/lib/chmlib/Makefile.am b/lib/chmlib/Makefile.am
new file mode 100644
index 0000000..bcbe427
--- /dev/null
+++ b/lib/chmlib/Makefile.am
@@ -0,0 +1,3 @@
+noinst_LTLIBRARIES = libchm.la
+noinst_HEADERS = chm_lib.h lzx.h
+libchm_la_SOURCES = chm_lib.c lzx.c
diff --git a/lib/chmlib/NEWS b/lib/chmlib/NEWS
new file mode 100644
index 0000000..332fd9a
--- /dev/null
+++ b/lib/chmlib/NEWS
@@ -0,0 +1,68 @@
+Changes from 0.37 to 0.38
+ - Fix for reading some chm files. Running over a large directory of chm
+ files, about 1% of them turned out to be unreadable. This resulted from
+ an incomplete understanding of one of the header fields (index_root).
+ Apparently, this can take negative values other than -1.
+
+ - Security fix for extract_chmLib. Pathnames containing a ".." element
+ will not be extracted. There doesn't seem to be a legitimate reason to
+ use ".." as a path element in a chm file.
+
+Changes from 0.36 to 0.37
+ - Major security fix for stack overflow vulnerability:
+ http://www.sven-tantau.de/public_files/chmlib/chmlib_20051126.txt
+ - Corrected the broken Makefile.in.
+
+Changes from 0.35 to 0.36
+ - Major security fix (iDEFENSE Security Advisory IDEF1099 - Stack Overflow
+ Vulnerability)
+ - Major security fix from Palasik Sandor (LZX decompression buffer overrun)
+ - Bugfix/enhancement from David Huseby to make the "what" flags to
+ chm_enumerate work correctly, and to pass the flags along to the callback
+ function (via the chmUnitInfo structure) so that the callback doesn't
+ need to re-parse the filename.
+ - Compilation fixes for x86-64 from Vitaly V. Bursov.
+ - Miscellaneous fixes to the configure script, including some significant
+ cleanup by Vadim Zeitlin. The changes from Vadim should also allow the
+ configure script to correctly configure the build on OS X, where it was
+ previously failing to note that pread64 doesn't work.
+ - Minor update to the Makefile.in to do a mkdir before the install, in case
+ the specified INSTALLPREFIX directory is non-existent
+
+Changes from 0.32 to 0.35
+ - UTF-8 filenames, while still not handled correctly, are handled a little
+ more gracefully. That is to say, the library doesn't fail to open files
+ with filenames using characters outside the ASCII subset. I'm very
+ interested in any information as to the "right" way to handle filenames
+ of this sort.
+ - Files not containing a compressed section are handled properly, such as
+ .chw files. These files seem to contain information about compression,
+ but the information is invalid or empty. The library deals gracefully
+ with this now.
+ - Files compressed with different options were not being decompressed
+ properly. In particular, if the "reset interval" for the compressed
+ section was other than 2 block sizes, it could fail to read some of the
+ files.
+ - The caching system was improved slightly, in conjunction with this
+ previous bugfix.
+
+Changes from 0.3 to 0.32:
+ - [Rich Erwin] Minor portability fixes for Windows CE.
+ - [Pabs] Minor bugfix regarding detecting directory entries versus empty files.
+ - [Antony Dovgal] autoconf-based build process
+ - [Ragnar Hojland Espinosa] Feature additions for chm_http:
+ * Use SO_REUSEADDR
+ * Allow --bind= and --port= command line arguments
+ - Simple makefile has been fixed (finally) to use gcc instead of gcc-3.2. (Sorry, everybody!)
+
+Changes from 0.2 to 0.3:
+
+ - initial attempt at portability to Win32.
+ - bugfixes from Stan Tobias:
+ * memory corruption error with caching system
+ * case insensitivity, to match with the Windows semantics
+ - modification to chm_http by Stan Tobias:
+ * when the user requests the page '/', they get a page with links to
+ all of the files in the archive
+ - Andrew Hodgetts has ported the library to Solaris and Irix. See README for details.
+ - Stuart Caie has granted permission to relicense under the LGPL.
diff --git a/lib/chmlib/README b/lib/chmlib/README
new file mode 100644
index 0000000..d39924b
--- /dev/null
+++ b/lib/chmlib/README
@@ -0,0 +1,141 @@
+CHMLIB 0.38
+===========
+
+-------
+SUMMARY
+-------
+chmlib is a small library designed for accessing MS ITSS files. The ITSS file
+format is used for Microsoft Html Help files (.chm), which have been the
+predominant medium for software documentation from Microsoft during the past
+several years, having superceded the previously used .hlp file format.
+
+Note that this is NOT the same as the OLE structured storage file format used
+by MS Excel, Word, and so on. Instead, it is a different file format which
+fulfills a similar purpose. Both file formats may be accessed via instances
+of the IStorage COM interface, which is essentially an "acts like a
+filesystem" interface.
+
+-------
+FILE FORMAT SUPPORT
+-------
+
+Lookup of files in the archive is supported, and should be relatively quick.
+Reading of files in the archive is also supported.
+Writing is not supported, but may be added in the future.
+
+In terms of support for the ITSS file format, there are a few places in which
+the support provided by this library is not fully general:
+
+1. ITSS files whose names contain UTF-8 characters which are not part of the
+ ASCII subset will not currently be dealt with gracefully. Currently, the
+ filenames are not converted from UTF-8, but are instead returned as-is. I'm
+ very interested in hearing any suggestions as to the "right" way to handle
+ this.
+
+2. Only version 3 ITSS files are supported at present, though some work has
+ gone towards divining the differences between different versions of the
+ file format. It is possible that version 2 ITSS files might work properly
+ with this library, but unconfirmed.
+
+3. Archives larger than 4 GB should be supported just fine, but if they
+ contain files larger than 4GB, this library may break. Fortunately, this
+ seems somewhat unlikely.
+
+If you run into .chm files (or files you suspect are ITSS files) that this
+library doesn't work with, please contact me so I can fix the library.
+
+-------
+PORTABILITY
+-------
+
+This software was originally developed on a Intel x86 Debian Linux machine,
+using gcc 3.0. It has since been compiled on various flavors of RedHat as
+well, and using versions of gcc from 2.95 through 3.2. Basic Win32 support
+should be in this release. (While a port to Win32 may _seem_ like a funny
+idea, given that Windows ships with libraries for CHM access, it turns out that
+Win CE does not; I've gotten a request for a port to Windows CE.)
+
+Chmlib apparently works on OS X, with some tweaks. In particular, disabling
+pread and io64 apparently works.
+
+Finally, Andrew Hodgetts has ported to Solaris and IRIX:
+
+On Monday, 7 Oct 2002, Andrew Hodgetts wrote:
+> Solaris(Sun):
+>
+> I used both SunProC and GCC on the solaris machines to compile. They
+> both worked ok.
+> However, both required -lsocket on the link line of the Makefile or you
+> recieve linking errors.
+>
+> I have this working on CPUs ranging from Sun4m (Sparc5) through to
+> UltraSparcIII (SunFireV880).
+>
+> Irix (SGI):
+>
+> I only testing with the MIPS compiler (not GCC). All worked ok - lots of
+> warning messages, but it always does that.
+
+He further noted that:
+
+> ... for NON GCC compilers, a little tweaking may be required, but nothing too
+> complex. ie SunProC doesn't understand -fPIC for library building. Irix
+> required -n32 (new 32bit libraries) etc. These are things that someone who
+> uses the OS and compiler should be used to dealing with.
+
+-------
+CREDITS
+-------
+
+* Stuart Caie: the LZX decompression code, and for granting permission to
+ re-license under the LGPL.
+
+* Sven Tantau: identification of a stack-overflow security flaw and a quick fix
+ for the problem; identification of a possible security danger in the example
+ program "extract_chmLib"
+
+* iDEFENSE Labs: identification of a nasty stack-overflow security flaw
+
+* Palasik Sandor: identification of a potential security flaw in lzx.c as well
+ as a quick fix for the problem
+
+* David Huseby: An excellent patch to the chm_enumerate functionality, relating
+ to the "what" flags, which didn't work entirely correctly before
+
+* Vadim Zeitlin: Configure script cleanup, including an important update to
+ allow detection of platforms where pread64 doesn't work. (OS X)
+
+* Vitaly V. Bursov: Compilation on x86-64.
+
+* mc: A suggestion to add a "mkdir" to the install step.
+
+* Stan Tobias: bugfixes and the added 'index page' feature of chm_http.
+
+* Andrew Hodgetts: porting to Solaris and IRIX, as well as fixing some
+ little-endian biases in the code.
+
+* Rich Erwin: Windows CE support.
+
+* Pabs: bug fixes and suggestions.
+
+* Antony Dovgal: setting up autoconf/automake based build process.
+
+* Ragnar Hojland Espinosa: patches to make chm_http more useful.
+
+* Razvan Cojocaru: forwarding along information regarding building on OS X.
+
+* Julien Lemoine: creating and maintaining the Debian package of chmlib.
+
+* Prarit Bhargava: Compilation on ia64
+
+* Jean-Marc Vanel: elimination of compilation warnings in extract_chmLib
+
+* Sisyphus & Matej Spiller-Muys: Compilation under MinGW32
+
+* Kyle Davenport: helper script for using chm_http with mozilla
+
+* Matthew Daniel & Mark Rosenstand: help to sort out issues with the build
+ system.
+
+* Anyone else I've forgotten. (?)
+
diff --git a/lib/chmlib/chm_lib.c b/lib/chmlib/chm_lib.c
new file mode 100644
index 0000000..e7da0b0
--- /dev/null
+++ b/lib/chmlib/chm_lib.c
@@ -0,0 +1,1917 @@
+/* $Id: chm_lib.c 148 2007-03-07 09:22:36Z gyunaev $ */
+/***************************************************************************
+ * chm_lib.c - CHM archive manipulation routines *
+ * ------------------- *
+ * *
+ * author: Jed Wing <jedwin@ugcs.caltech.edu> *
+ * version: 0.3 *
+ * notes: These routines are meant for the manipulation of microsoft *
+ * .chm (compiled html help) files, but may likely be used *
+ * for the manipulation of any ITSS archive, if ever ITSS *
+ * archives are used for any other purpose. *
+ * *
+ * Note also that the section names are statically handled. *
+ * To be entirely correct, the section names should be read *
+ * from the section names meta-file, and then the various *
+ * content sections and the "transforms" to apply to the data *
+ * they contain should be inferred from the section name and *
+ * the meta-files referenced using that name; however, all of *
+ * the files I've been able to get my hands on appear to have *
+ * only two sections: Uncompressed and MSCompressed. *
+ * Additionally, the ITSS.DLL file included with Windows does *
+ * not appear to handle any different transforms than the *
+ * simple LZX-transform. Furthermore, the list of transforms *
+ * to apply is broken, in that only half the required space *
+ * is allocated for the list. (It appears as though the *
+ * space is allocated for ASCII strings, but the strings are *
+ * written as unicode. As a result, only the first half of *
+ * the string appears.) So this is probably not too big of *
+ * a deal, at least until CHM v4 (MS .lit files), which also *
+ * incorporate encryption, of some description. *
+ * *
+ * switches: CHM_MT: compile library with thread-safety *
+ * *
+ * switches (Linux only): *
+ * CHM_USE_PREAD: compile library to use pread instead of *
+ * lseek/read *
+ * CHM_USE_IO64: compile library to support full 64-bit I/O *
+ * as is needed to properly deal with the *
+ * 64-bit file offsets. *
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of the *
+ * License, or (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "chm_lib.h"
+
+#ifdef CHM_MT
+#define _REENTRANT
+#endif
+
+#include "lzx.h"
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef CHM_DEBUG
+#include <stdio.h>
+#endif
+
+#if __sun || __sgi
+#include <strings.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#include <malloc.h>
+#ifdef _WIN32_WCE
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+#else
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#endif
+#else
+/* basic Linux system includes */
+#define _XOPEN_SOURCE 500
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+/* #include <dmalloc.h> */
+#endif
+
+/* includes/defines for threading, if using them */
+#ifdef CHM_MT
+#ifdef WIN32
+#define CHM_ACQUIRE_LOCK(a) do { \
+ EnterCriticalSection(&(a)); \
+ } while(0)
+#define CHM_RELEASE_LOCK(a) do { \
+ EnterCriticalSection(&(a)); \
+ } while(0)
+
+#else
+#include <pthread.h>
+
+#define CHM_ACQUIRE_LOCK(a) do { \
+ pthread_mutex_lock(&(a)); \
+ } while(0)
+#define CHM_RELEASE_LOCK(a) do { \
+ pthread_mutex_unlock(&(a)); \
+ } while(0)
+
+#endif
+#else
+#define CHM_ACQUIRE_LOCK(a) /* do nothing */
+#define CHM_RELEASE_LOCK(a) /* do nothing */
+#endif
+
+#ifdef WIN32
+#define CHM_NULL_FD (INVALID_HANDLE_VALUE)
+#define CHM_USE_WIN32IO 1
+#define CHM_CLOSE_FILE(fd) CloseHandle((fd))
+#else
+#define CHM_NULL_FD (-1)
+#define CHM_CLOSE_FILE(fd) close((fd))
+#endif
+
+/*
+ * defines related to tuning
+ */
+#ifndef CHM_MAX_BLOCKS_CACHED
+#define CHM_MAX_BLOCKS_CACHED 5
+#endif
+
+/*
+ * architecture specific defines
+ *
+ * Note: as soon as C99 is more widespread, the below defines should
+ * probably just use the C99 sized-int types.
+ *
+ * The following settings will probably work for many platforms. The sizes
+ * don't have to be exactly correct, but the types must accommodate at least as
+ * many bits as they specify.
+ */
+
+/* i386, 32-bit, Windows */
+#ifdef WIN32
+typedef unsigned char UChar;
+typedef __int16 Int16;
+typedef unsigned __int16 UInt16;
+typedef __int32 Int32;
+typedef unsigned __int32 UInt32;
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+
+/* I386, 32-bit, non-Windows */
+/* Sparc */
+/* MIPS */
+/* PPC */
+#elif __i386__ || __sun || __sgi || __ppc__
+typedef unsigned char UChar;
+typedef short Int16;
+typedef unsigned short UInt16;
+typedef long Int32;
+typedef unsigned long UInt32;
+typedef long long Int64;
+typedef unsigned long long UInt64;
+
+/* x86-64 */
+/* Note that these may be appropriate for other 64-bit machines. */
+#elif __x86_64__ || __ia64__
+typedef unsigned char UChar;
+typedef short Int16;
+typedef unsigned short UInt16;
+typedef int Int32;
+typedef unsigned int UInt32;
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+/* yielding an error is preferable to yielding incorrect behavior */
+#error "Please define the sized types for your platform in chm_lib.c"
+#endif
+
+/* GCC */
+#ifdef __GNUC__
+#define memcmp __builtin_memcmp
+#define memcpy __builtin_memcpy
+#define strlen __builtin_strlen
+
+#elif defined(WIN32)
+static int ffs(unsigned int val)
+{
+ int bit=1, idx=1;
+ while (bit != 0 && (val & bit) == 0)
+ {
+ bit <<= 1;
+ ++idx;
+ }
+ if (bit == 0)
+ return 0;
+ else
+ return idx;
+}
+
+#endif
+
+/* utilities for unmarshalling data */
+static int _unmarshal_char_array(unsigned char **pData,
+ unsigned int *pLenRemain,
+ char *dest,
+ int count)
+{
+ if (count <= 0 || (unsigned int)count > *pLenRemain)
+ return 0;
+ memcpy(dest, (*pData), count);
+ *pData += count;
+ *pLenRemain -= count;
+ return 1;
+}
+
+static int _unmarshal_uchar_array(unsigned char **pData,
+ unsigned int *pLenRemain,
+ unsigned char *dest,
+ int count)
+{
+ if (count <= 0 || (unsigned int)count > *pLenRemain)
+ return 0;
+ memcpy(dest, (*pData), count);
+ *pData += count;
+ *pLenRemain -= count;
+ return 1;
+}
+
+#if 0
+static int _unmarshal_int16(unsigned char **pData,
+ unsigned int *pLenRemain,
+ Int16 *dest)
+{
+ if (2 > *pLenRemain)
+ return 0;
+ *dest = (*pData)[0] | (*pData)[1]<<8;
+ *pData += 2;
+ *pLenRemain -= 2;
+ return 1;
+}
+
+static int _unmarshal_uint16(unsigned char **pData,
+ unsigned int *pLenRemain,
+ UInt16 *dest)
+{
+ if (2 > *pLenRemain)
+ return 0;
+ *dest = (*pData)[0] | (*pData)[1]<<8;
+ *pData += 2;
+ *pLenRemain -= 2;
+ return 1;
+}
+#endif
+
+static int _unmarshal_int32(unsigned char **pData,
+ unsigned int *pLenRemain,
+ Int32 *dest)
+{
+ if (4 > *pLenRemain)
+ return 0;
+ *dest = (*pData)[0] | (*pData)[1]<<8 | (*pData)[2]<<16 | (*pData)[3]<<24;
+ *pData += 4;
+ *pLenRemain -= 4;
+ return 1;
+}
+
+static int _unmarshal_uint32(unsigned char **pData,
+ unsigned int *pLenRemain,
+ UInt32 *dest)
+{
+ if (4 > *pLenRemain)
+ return 0;
+ *dest = (*pData)[0] | (*pData)[1]<<8 | (*pData)[2]<<16 | (*pData)[3]<<24;
+ *pData += 4;
+ *pLenRemain -= 4;
+ return 1;
+}
+
+static int _unmarshal_int64(unsigned char **pData,
+ unsigned int *pLenRemain,
+ Int64 *dest)
+{
+ Int64 temp;
+ int i;
+ if (8 > *pLenRemain)
+ return 0;
+ temp=0;
+ for(i=8; i>0; i--)
+ {
+ temp <<= 8;
+ temp |= (*pData)[i-1];
+ }
+ *dest = temp;
+ *pData += 8;
+ *pLenRemain -= 8;
+ return 1;
+}
+
+static int _unmarshal_uint64(unsigned char **pData,
+ unsigned int *pLenRemain,
+ UInt64 *dest)
+{
+ UInt64 temp;
+ int i;
+ if (8 > *pLenRemain)
+ return 0;
+ temp=0;
+ for(i=8; i>0; i--)
+ {
+ temp <<= 8;
+ temp |= (*pData)[i-1];
+ }
+ *dest = temp;
+ *pData += 8;
+ *pLenRemain -= 8;
+ return 1;
+}
+
+static int _unmarshal_uuid(unsigned char **pData,
+ unsigned int *pDataLen,
+ unsigned char *dest)
+{
+ return _unmarshal_uchar_array(pData, pDataLen, dest, 16);
+}
+
+/* names of sections essential to decompression */
+static const char _CHMU_RESET_TABLE[] =
+ "::DataSpace/Storage/MSCompressed/Transform/"
+ "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/"
+ "InstanceData/ResetTable";
+static const char _CHMU_LZXC_CONTROLDATA[] =
+ "::DataSpace/Storage/MSCompressed/ControlData";
+static const char _CHMU_CONTENT[] =
+ "::DataSpace/Storage/MSCompressed/Content";
+static const char _CHMU_SPANINFO[] =
+ "::DataSpace/Storage/MSCompressed/SpanInfo";
+
+/*
+ * structures local to this module
+ */
+
+/* structure of ITSF headers */
+#define _CHM_ITSF_V2_LEN (0x58)
+#define _CHM_ITSF_V3_LEN (0x60)
+struct chmItsfHeader
+{
+ char signature[4]; /* 0 (ITSF) */
+ Int32 version; /* 4 */
+ Int32 header_len; /* 8 */
+ Int32 unknown_000c; /* c */
+ UInt32 last_modified; /* 10 */
+ UInt32 lang_id; /* 14 */
+ UChar dir_uuid[16]; /* 18 */
+ UChar stream_uuid[16]; /* 28 */
+ UInt64 unknown_offset; /* 38 */
+ UInt64 unknown_len; /* 40 */
+ UInt64 dir_offset; /* 48 */
+ UInt64 dir_len; /* 50 */
+ UInt64 data_offset; /* 58 (Not present before V3) */
+}; /* __attribute__ ((aligned (1))); */
+
+static int _unmarshal_itsf_header(unsigned char **pData,
+ unsigned int *pDataLen,
+ struct chmItsfHeader *dest)
+{
+ /* we only know how to deal with the 0x58 and 0x60 byte structures */
+ if (*pDataLen != _CHM_ITSF_V2_LEN && *pDataLen != _CHM_ITSF_V3_LEN)
+ return 0;
+
+ /* unmarshal common fields */
+ _unmarshal_char_array(pData, pDataLen, dest->signature, 4);
+ _unmarshal_int32 (pData, pDataLen, &dest->version);
+ _unmarshal_int32 (pData, pDataLen, &dest->header_len);
+ _unmarshal_int32 (pData, pDataLen, &dest->unknown_000c);
+ _unmarshal_uint32 (pData, pDataLen, &dest->last_modified);
+ _unmarshal_uint32 (pData, pDataLen, &dest->lang_id);
+ _unmarshal_uuid (pData, pDataLen, dest->dir_uuid);
+ _unmarshal_uuid (pData, pDataLen, dest->stream_uuid);
+ _unmarshal_uint64 (pData, pDataLen, &dest->unknown_offset);
+ _unmarshal_uint64 (pData, pDataLen, &dest->unknown_len);
+ _unmarshal_uint64 (pData, pDataLen, &dest->dir_offset);
+ _unmarshal_uint64 (pData, pDataLen, &dest->dir_len);
+
+ /* error check the data */
+ /* XXX: should also check UUIDs, probably, though with a version 3 file,
+ * current MS tools do not seem to use them.
+ */
+ if (memcmp(dest->signature, "ITSF", 4) != 0)
+ return 0;
+ if (dest->version == 2)
+ {
+ if (dest->header_len < _CHM_ITSF_V2_LEN)
+ return 0;
+ }
+ else if (dest->version == 3)
+ {
+ if (dest->header_len < _CHM_ITSF_V3_LEN)
+ return 0;
+ }
+ else
+ return 0;
+
+ /* now, if we have a V3 structure, unmarshal the rest.
+ * otherwise, compute it
+ */
+ if (dest->version == 3)
+ {
+ if (*pDataLen != 0)
+ _unmarshal_uint64(pData, pDataLen, &dest->data_offset);
+ else
+ return 0;
+ }
+ else
+ dest->data_offset = dest->dir_offset + dest->dir_len;
+
+ return 1;
+}
+
+/* structure of ITSP headers */
+#define _CHM_ITSP_V1_LEN (0x54)
+struct chmItspHeader
+{
+ char signature[4]; /* 0 (ITSP) */
+ Int32 version; /* 4 */
+ Int32 header_len; /* 8 */
+ Int32 unknown_000c; /* c */
+ UInt32 block_len; /* 10 */
+ Int32 blockidx_intvl; /* 14 */
+ Int32 index_depth; /* 18 */
+ Int32 index_root; /* 1c */
+ Int32 index_head; /* 20 */
+ Int32 unknown_0024; /* 24 */
+ UInt32 num_blocks; /* 28 */
+ Int32 unknown_002c; /* 2c */
+ UInt32 lang_id; /* 30 */
+ UChar system_uuid[16]; /* 34 */
+ UChar unknown_0044[16]; /* 44 */
+}; /* __attribute__ ((aligned (1))); */
+
+static int _unmarshal_itsp_header(unsigned char **pData,
+ unsigned int *pDataLen,
+ struct chmItspHeader *dest)
+{
+ /* we only know how to deal with a 0x54 byte structures */
+ if (*pDataLen != _CHM_ITSP_V1_LEN)
+ return 0;
+
+ /* unmarshal fields */
+ _unmarshal_char_array(pData, pDataLen, dest->signature, 4);
+ _unmarshal_int32 (pData, pDataLen, &dest->version);
+ _unmarshal_int32 (pData, pDataLen, &dest->header_len);
+ _unmarshal_int32 (pData, pDataLen, &dest->unknown_000c);
+ _unmarshal_uint32 (pData, pDataLen, &dest->block_len);
+ _unmarshal_int32 (pData, pDataLen, &dest->blockidx_intvl);
+ _unmarshal_int32 (pData, pDataLen, &dest->index_depth);
+ _unmarshal_int32 (pData, pDataLen, &dest->index_root);
+ _unmarshal_int32 (pData, pDataLen, &dest->index_head);
+ _unmarshal_int32 (pData, pDataLen, &dest->unknown_0024);
+ _unmarshal_uint32 (pData, pDataLen, &dest->num_blocks);
+ _unmarshal_int32 (pData, pDataLen, &dest->unknown_002c);
+ _unmarshal_uint32 (pData, pDataLen, &dest->lang_id);
+ _unmarshal_uuid (pData, pDataLen, dest->system_uuid);
+ _unmarshal_uchar_array(pData, pDataLen, dest->unknown_0044, 16);
+
+ /* error check the data */
+ if (memcmp(dest->signature, "ITSP", 4) != 0)
+ return 0;
+ if (dest->version != 1)
+ return 0;
+ if (dest->header_len != _CHM_ITSP_V1_LEN)
+ return 0;
+
+ return 1;
+}
+
+/* structure of PMGL headers */
+static const char _chm_pmgl_marker[4] = "PMGL";
+#define _CHM_PMGL_LEN (0x14)
+struct chmPmglHeader
+{
+ char signature[4]; /* 0 (PMGL) */
+ UInt32 free_space; /* 4 */
+ UInt32 unknown_0008; /* 8 */
+ Int32 block_prev; /* c */
+ Int32 block_next; /* 10 */
+}; /* __attribute__ ((aligned (1))); */
+
+static int _unmarshal_pmgl_header(unsigned char **pData,
+ unsigned int *pDataLen,
+ struct chmPmglHeader *dest)
+{
+ /* we only know how to deal with a 0x14 byte structures */
+ if (*pDataLen != _CHM_PMGL_LEN)
+ return 0;
+
+ /* unmarshal fields */
+ _unmarshal_char_array(pData, pDataLen, dest->signature, 4);
+ _unmarshal_uint32 (pData, pDataLen, &dest->free_space);
+ _unmarshal_uint32 (pData, pDataLen, &dest->unknown_0008);
+ _unmarshal_int32 (pData, pDataLen, &dest->block_prev);
+ _unmarshal_int32 (pData, pDataLen, &dest->block_next);
+
+ /* check structure */
+ if (memcmp(dest->signature, _chm_pmgl_marker, 4) != 0)
+ return 0;
+
+ return 1;
+}
+
+/* structure of PMGI headers */
+static const char _chm_pmgi_marker[4] = "PMGI";
+#define _CHM_PMGI_LEN (0x08)
+struct chmPmgiHeader
+{
+ char signature[4]; /* 0 (PMGI) */
+ UInt32 free_space; /* 4 */
+}; /* __attribute__ ((aligned (1))); */
+
+static int _unmarshal_pmgi_header(unsigned char **pData,
+ unsigned int *pDataLen,
+ struct chmPmgiHeader *dest)
+{
+ /* we only know how to deal with a 0x8 byte structures */
+ if (*pDataLen != _CHM_PMGI_LEN)
+ return 0;
+
+ /* unmarshal fields */
+ _unmarshal_char_array(pData, pDataLen, dest->signature, 4);
+ _unmarshal_uint32 (pData, pDataLen, &dest->free_space);
+
+ /* check structure */
+ if (memcmp(dest->signature, _chm_pmgi_marker, 4) != 0)
+ return 0;
+
+ return 1;
+}
+
+/* structure of LZXC reset table */
+#define _CHM_LZXC_RESETTABLE_V1_LEN (0x28)
+struct chmLzxcResetTable
+{
+ UInt32 version;
+ UInt32 block_count;
+ UInt32 unknown;
+ UInt32 table_offset;
+ UInt64 uncompressed_len;
+ UInt64 compressed_len;
+ UInt64 block_len;
+}; /* __attribute__ ((aligned (1))); */
+
+static int _unmarshal_lzxc_reset_table(unsigned char **pData,
+ unsigned int *pDataLen,
+ struct chmLzxcResetTable *dest)
+{
+ /* we only know how to deal with a 0x28 byte structures */
+ if (*pDataLen != _CHM_LZXC_RESETTABLE_V1_LEN)
+ return 0;
+
+ /* unmarshal fields */
+ _unmarshal_uint32 (pData, pDataLen, &dest->version);
+ _unmarshal_uint32 (pData, pDataLen, &dest->block_count);
+ _unmarshal_uint32 (pData, pDataLen, &dest->unknown);
+ _unmarshal_uint32 (pData, pDataLen, &dest->table_offset);
+ _unmarshal_uint64 (pData, pDataLen, &dest->uncompressed_len);
+ _unmarshal_uint64 (pData, pDataLen, &dest->compressed_len);
+ _unmarshal_uint64 (pData, pDataLen, &dest->block_len);
+
+ /* check structure */
+ if (dest->version != 2)
+ return 0;
+
+ return 1;
+}
+
+/* structure of LZXC control data block */
+#define _CHM_LZXC_MIN_LEN (0x18)
+#define _CHM_LZXC_V2_LEN (0x1c)
+struct chmLzxcControlData
+{
+ UInt32 size; /* 0 */
+ char signature[4]; /* 4 (LZXC) */
+ UInt32 version; /* 8 */
+ UInt32 resetInterval; /* c */
+ UInt32 windowSize; /* 10 */
+ UInt32 windowsPerReset; /* 14 */
+ UInt32 unknown_18; /* 18 */
+};
+
+static int _unmarshal_lzxc_control_data(unsigned char **pData,
+ unsigned int *pDataLen,
+ struct chmLzxcControlData *dest)
+{
+ /* we want at least 0x18 bytes */
+ if (*pDataLen < _CHM_LZXC_MIN_LEN)
+ return 0;
+
+ /* unmarshal fields */
+ _unmarshal_uint32 (pData, pDataLen, &dest->size);
+ _unmarshal_char_array(pData, pDataLen, dest->signature, 4);
+ _unmarshal_uint32 (pData, pDataLen, &dest->version);
+ _unmarshal_uint32 (pData, pDataLen, &dest->resetInterval);
+ _unmarshal_uint32 (pData, pDataLen, &dest->windowSize);
+ _unmarshal_uint32 (pData, pDataLen, &dest->windowsPerReset);
+
+ if (*pDataLen >= _CHM_LZXC_V2_LEN)
+ _unmarshal_uint32 (pData, pDataLen, &dest->unknown_18);
+ else
+ dest->unknown_18 = 0;
+
+ if (dest->version == 2)
+ {
+ dest->resetInterval *= 0x8000;
+ dest->windowSize *= 0x8000;
+ }
+ if (dest->windowSize == 0 || dest->resetInterval == 0)
+ return 0;
+
+ /* for now, only support resetInterval a multiple of windowSize/2 */
+ if (dest->windowSize == 1)
+ return 0;
+ if ((dest->resetInterval % (dest->windowSize/2)) != 0)
+ return 0;
+
+ /* check structure */
+ if (memcmp(dest->signature, "LZXC", 4) != 0)
+ return 0;
+
+ return 1;
+}
+
+/* the structure used for chm file handles */
+struct chmFile
+{
+#ifdef WIN32
+ HANDLE fd;
+#else
+ int fd;
+#endif
+
+#ifdef CHM_MT
+#ifdef WIN32
+ CRITICAL_SECTION mutex;
+ CRITICAL_SECTION lzx_mutex;
+ CRITICAL_SECTION cache_mutex;
+#else
+ pthread_mutex_t mutex;
+ pthread_mutex_t lzx_mutex;
+ pthread_mutex_t cache_mutex;
+#endif
+#endif
+
+ UInt64 dir_offset;
+ UInt64 dir_len;
+ UInt64 data_offset;
+ Int32 index_root;
+ Int32 index_head;
+ UInt32 block_len;
+
+ UInt64 span;
+ struct chmUnitInfo rt_unit;
+ struct chmUnitInfo cn_unit;
+ struct chmLzxcResetTable reset_table;
+
+ /* LZX control data */
+ int compression_enabled;
+ UInt32 window_size;
+ UInt32 reset_interval;
+ UInt32 reset_blkcount;
+
+ /* decompressor state */
+ struct LZXstate *lzx_state;
+ int lzx_last_block;
+
+ /* cache for decompressed blocks */
+ UChar **cache_blocks;
+ UInt64 *cache_block_indices;
+ Int32 cache_num_blocks;
+};
+
+/*
+ * utility functions local to this module
+ */
+
+/* utility function to handle differences between {pread,read}(64)? */
+static Int64 _chm_fetch_bytes(struct chmFile *h,
+ UChar *buf,
+ UInt64 os,
+ Int64 len)
+{
+ Int64 readLen=0, oldOs=0;
+ if (h->fd == CHM_NULL_FD)
+ return readLen;
+
+ CHM_ACQUIRE_LOCK(h->mutex);
+#ifdef CHM_USE_WIN32IO
+ /* NOTE: this might be better done with CreateFileMapping, et cetera... */
+ {
+ DWORD origOffsetLo=0, origOffsetHi=0;
+ DWORD offsetLo, offsetHi;
+ DWORD actualLen=0;
+
+ /* awkward Win32 Seek/Tell */
+ offsetLo = (unsigned int)(os & 0xffffffffL);
+ offsetHi = (unsigned int)((os >> 32) & 0xffffffffL);
+ origOffsetLo = SetFilePointer(h->fd, 0, &origOffsetHi, FILE_CURRENT);
+ offsetLo = SetFilePointer(h->fd, offsetLo, &offsetHi, FILE_BEGIN);
+
+ /* read the data */
+ if (ReadFile(h->fd,
+ buf,
+ (DWORD)len,
+ &actualLen,
+ NULL) == TRUE)
+ readLen = actualLen;
+ else
+ readLen = 0;
+
+ /* restore original position */
+ SetFilePointer(h->fd, origOffsetLo, &origOffsetHi, FILE_BEGIN);
+ }
+#else
+#ifdef CHM_USE_PREAD
+#ifdef CHM_USE_IO64
+ readLen = pread64(h->fd, buf, (long)len, os);
+#else
+ readLen = pread(h->fd, buf, (long)len, (unsigned int)os);
+#endif
+#else
+#ifdef CHM_USE_IO64
+ oldOs = lseek64(h->fd, 0, SEEK_CUR);
+ lseek64(h->fd, os, SEEK_SET);
+ readLen = read(h->fd, buf, len);
+ lseek64(h->fd, oldOs, SEEK_SET);
+#else
+ oldOs = lseek(h->fd, 0, SEEK_CUR);
+ lseek(h->fd, (long)os, SEEK_SET);
+ readLen = read(h->fd, buf, len);
+ lseek(h->fd, (long)oldOs, SEEK_SET);
+#endif
+#endif
+#endif
+ CHM_RELEASE_LOCK(h->mutex);
+ return readLen;
+}
+
+/* open an ITS archive */
+#ifdef PPC_BSTR
+/* RWE 6/12/2003 */
+struct chmFile *chm_open(BSTR filename)
+#else
+struct chmFile *chm_open(const char *filename)
+#endif
+{
+ unsigned char sbuffer[256];
+ unsigned int sremain;
+ unsigned char *sbufpos;
+ struct chmFile *newHandle=NULL;
+ struct chmItsfHeader itsfHeader;
+ struct chmItspHeader itspHeader;
+#if 0
+ struct chmUnitInfo uiSpan;
+#endif
+ struct chmUnitInfo uiLzxc;
+ struct chmLzxcControlData ctlData;
+
+ /* allocate handle */
+ newHandle = (struct chmFile *)malloc(sizeof(struct chmFile));
+ if (newHandle == NULL)
+ return NULL;
+ newHandle->fd = CHM_NULL_FD;
+ newHandle->lzx_state = NULL;
+ newHandle->cache_blocks = NULL;
+ newHandle->cache_block_indices = NULL;
+ newHandle->cache_num_blocks = 0;
+
+ /* open file */
+#ifdef WIN32
+#ifdef PPC_BSTR
+ if ((newHandle->fd=CreateFile(filename,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL)) == CHM_NULL_FD)
+ {
+ free(newHandle);
+ return NULL;
+ }
+#else
+ if ((newHandle->fd=CreateFileA(filename,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL)) == CHM_NULL_FD)
+ {
+ free(newHandle);
+ return NULL;
+ }
+#endif
+#else
+ if ((newHandle->fd=open(filename, O_RDONLY)) == CHM_NULL_FD)
+ {
+ free(newHandle);
+ return NULL;
+ }
+#endif
+
+ /* initialize mutexes, if needed */
+#ifdef CHM_MT
+#ifdef WIN32
+ InitializeCriticalSection(&newHandle->mutex);
+ InitializeCriticalSection(&newHandle->lzx_mutex);
+ InitializeCriticalSection(&newHandle->cache_mutex);
+#else
+ pthread_mutex_init(&newHandle->mutex, NULL);
+ pthread_mutex_init(&newHandle->lzx_mutex, NULL);
+ pthread_mutex_init(&newHandle->cache_mutex, NULL);
+#endif
+#endif
+
+ /* read and verify header */
+ sremain = _CHM_ITSF_V3_LEN;
+ sbufpos = sbuffer;
+ if (_chm_fetch_bytes(newHandle, sbuffer, (UInt64)0, sremain) != sremain ||
+ !_unmarshal_itsf_header(&sbufpos, &sremain, &itsfHeader))
+ {
+ chm_close(newHandle);
+ return NULL;
+ }
+
+ /* stash important values from header */
+ newHandle->dir_offset = itsfHeader.dir_offset;
+ newHandle->dir_len = itsfHeader.dir_len;
+ newHandle->data_offset = itsfHeader.data_offset;
+
+ /* now, read and verify the directory header chunk */
+ sremain = _CHM_ITSP_V1_LEN;
+ sbufpos = sbuffer;
+ if (_chm_fetch_bytes(newHandle, sbuffer,
+ (UInt64)itsfHeader.dir_offset, sremain) != sremain ||
+ !_unmarshal_itsp_header(&sbufpos, &sremain, &itspHeader))
+ {
+ chm_close(newHandle);
+ return NULL;
+ }
+
+ /* grab essential information from ITSP header */
+ newHandle->dir_offset += itspHeader.header_len;
+ newHandle->dir_len -= itspHeader.header_len;
+ newHandle->index_root = itspHeader.index_root;
+ newHandle->index_head = itspHeader.index_head;
+ newHandle->block_len = itspHeader.block_len;
+
+ /* if the index root is -1, this means we don't have any PMGI blocks.
+ * as a result, we must use the sole PMGL block as the index root
+ */
+ if (newHandle->index_root <= -1)
+ newHandle->index_root = newHandle->index_head;
+
+ /* By default, compression is enabled. */
+ newHandle->compression_enabled = 1;
+
+/* Jed, Sun Jun 27: 'span' doesn't seem to be used anywhere?! */
+#if 0
+ /* fetch span */
+ if (CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle,
+ _CHMU_SPANINFO,
+ &uiSpan) ||
+ uiSpan.space == CHM_COMPRESSED)
+ {
+ chm_close(newHandle);
+ return NULL;
+ }
+
+ /* N.B.: we've already checked that uiSpan is in the uncompressed section,
+ * so this should not require attempting to decompress, which may
+ * rely on having a valid "span"
+ */
+ sremain = 8;
+ sbufpos = sbuffer;
+ if (chm_retrieve_object(newHandle, &uiSpan, sbuffer,
+ 0, sremain) != sremain ||
+ !_unmarshal_uint64(&sbufpos, &sremain, &newHandle->span))
+ {
+ chm_close(newHandle);
+ return NULL;
+ }
+#endif
+
+ /* prefetch most commonly needed unit infos */
+ if (CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle,
+ _CHMU_RESET_TABLE,
+ &newHandle->rt_unit) ||
+ newHandle->rt_unit.space == CHM_COMPRESSED ||
+ CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle,
+ _CHMU_CONTENT,
+ &newHandle->cn_unit) ||
+ newHandle->cn_unit.space == CHM_COMPRESSED ||
+ CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle,
+ _CHMU_LZXC_CONTROLDATA,
+ &uiLzxc) ||
+ uiLzxc.space == CHM_COMPRESSED)
+ {
+ newHandle->compression_enabled = 0;
+ }
+
+ /* read reset table info */
+ if (newHandle->compression_enabled)
+ {
+ sremain = _CHM_LZXC_RESETTABLE_V1_LEN;
+ sbufpos = sbuffer;
+ if (chm_retrieve_object(newHandle, &newHandle->rt_unit, sbuffer,
+ 0, sremain) != sremain ||
+ !_unmarshal_lzxc_reset_table(&sbufpos, &sremain,
+ &newHandle->reset_table))
+ {
+ newHandle->compression_enabled = 0;
+ }
+ }
+
+ /* read control data */
+ if (newHandle->compression_enabled)
+ {
+ sremain = (unsigned int)uiLzxc.length;
+ if (uiLzxc.length > sizeof(sbuffer))
+ {
+ chm_close(newHandle);
+ return NULL;
+ }
+
+ sbufpos = sbuffer;
+ if (chm_retrieve_object(newHandle, &uiLzxc, sbuffer,
+ 0, sremain) != sremain ||
+ !_unmarshal_lzxc_control_data(&sbufpos, &sremain,
+ &ctlData))
+ {
+ newHandle->compression_enabled = 0;
+ }
+
+ newHandle->window_size = ctlData.windowSize;
+ newHandle->reset_interval = ctlData.resetInterval;
+
+/* Jed, Mon Jun 28: Experimentally, it appears that the reset block count */
+/* must be multiplied by this formerly unknown ctrl data field in */
+/* order to decompress some files. */
+#if 0
+ newHandle->reset_blkcount = newHandle->reset_interval /
+ (newHandle->window_size / 2);
+#else
+ newHandle->reset_blkcount = newHandle->reset_interval /
+ (newHandle->window_size / 2) *
+ ctlData.windowsPerReset;
+#endif
+ }
+
+ /* initialize cache */
+ chm_set_param(newHandle, CHM_PARAM_MAX_BLOCKS_CACHED,
+ CHM_MAX_BLOCKS_CACHED);
+
+ return newHandle;
+}
+
+/* close an ITS archive */
+void chm_close(struct chmFile *h)
+{
+ if (h != NULL)
+ {
+ if (h->fd != CHM_NULL_FD)
+ CHM_CLOSE_FILE(h->fd);
+ h->fd = CHM_NULL_FD;
+
+#ifdef CHM_MT
+#ifdef WIN32
+ DeleteCriticalSection(&h->mutex);
+ DeleteCriticalSection(&h->lzx_mutex);
+ DeleteCriticalSection(&h->cache_mutex);
+#else
+ pthread_mutex_destroy(&h->mutex);
+ pthread_mutex_destroy(&h->lzx_mutex);
+ pthread_mutex_destroy(&h->cache_mutex);
+#endif
+#endif
+
+ if (h->lzx_state)
+ LZXteardown(h->lzx_state);
+ h->lzx_state = NULL;
+
+ if (h->cache_blocks)
+ {
+ int i;
+ for (i=0; i<h->cache_num_blocks; i++)
+ {
+ if (h->cache_blocks[i])
+ free(h->cache_blocks[i]);
+ }
+ free(h->cache_blocks);
+ h->cache_blocks = NULL;
+ }
+
+ if (h->cache_block_indices)
+ free(h->cache_block_indices);
+ h->cache_block_indices = NULL;
+
+ free(h);
+ }
+}
+
+/*
+ * set a parameter on the file handle.
+ * valid parameter types:
+ * CHM_PARAM_MAX_BLOCKS_CACHED:
+ * how many decompressed blocks should be cached? A simple
+ * caching scheme is used, wherein the index of the block is
+ * used as a hash value, and hash collision results in the
+ * invalidation of the previously cached block.
+ */
+void chm_set_param(struct chmFile *h,
+ int paramType,
+ int paramVal)
+{
+ switch (paramType)
+ {
+ case CHM_PARAM_MAX_BLOCKS_CACHED:
+ CHM_ACQUIRE_LOCK(h->cache_mutex);
+ if (paramVal != h->cache_num_blocks)
+ {
+ UChar **newBlocks;
+ UInt64 *newIndices;
+ int i;
+
+ /* allocate new cached blocks */
+ newBlocks = (UChar **)malloc(paramVal * sizeof (UChar *));
+ if (newBlocks == NULL) return;
+ newIndices = (UInt64 *)malloc(paramVal * sizeof (UInt64));
+ if (newIndices == NULL) { free(newBlocks); return; }
+ for (i=0; i<paramVal; i++)
+ {
+ newBlocks[i] = NULL;
+ newIndices[i] = 0;
+ }
+
+ /* re-distribute old cached blocks */
+ if (h->cache_blocks)
+ {
+ for (i=0; i<h->cache_num_blocks; i++)
+ {
+ int newSlot = (int)(h->cache_block_indices[i] % paramVal);
+
+ if (h->cache_blocks[i])
+ {
+ /* in case of collision, destroy newcomer */
+ if (newBlocks[newSlot])
+ {
+ free(h->cache_blocks[i]);
+ h->cache_blocks[i] = NULL;
+ }
+ else
+ {
+ newBlocks[newSlot] = h->cache_blocks[i];
+ newIndices[newSlot] =
+ h->cache_block_indices[i];
+ }
+ }
+ }
+
+ free(h->cache_blocks);
+ free(h->cache_block_indices);
+ }
+
+ /* now, set new values */
+ h->cache_blocks = newBlocks;
+ h->cache_block_indices = newIndices;
+ h->cache_num_blocks = paramVal;
+ }
+ CHM_RELEASE_LOCK(h->cache_mutex);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * helper methods for chm_resolve_object
+ */
+
+/* skip a compressed dword */
+static void _chm_skip_cword(UChar **pEntry)
+{
+ while (*(*pEntry)++ >= 0x80)
+ ;
+}
+
+/* skip the data from a PMGL entry */
+static void _chm_skip_PMGL_entry_data(UChar **pEntry)
+{
+ _chm_skip_cword(pEntry);
+ _chm_skip_cword(pEntry);
+ _chm_skip_cword(pEntry);
+}
+
+/* parse a compressed dword */
+static UInt64 _chm_parse_cword(UChar **pEntry)
+{
+ UInt64 accum = 0;
+ UChar temp;
+ while ((temp=*(*pEntry)++) >= 0x80)
+ {
+ accum <<= 7;
+ accum += temp & 0x7f;
+ }
+
+ return (accum << 7) + temp;
+}
+
+/* parse a utf-8 string into an ASCII char buffer */
+static int _chm_parse_UTF8(UChar **pEntry, UInt64 count, char *path)
+{
+ /* XXX: implement UTF-8 support, including a real mapping onto
+ * ISO-8859-1? probably there is a library to do this? As is
+ * immediately apparent from the below code, I'm presently not doing
+ * any special handling for files in which none of the strings contain
+ * UTF-8 multi-byte characters.
+ */
+ while (count != 0)
+ {
+ *path++ = (char)(*(*pEntry)++);
+ --count;
+ }
+
+ *path = '\0';
+ return 1;
+}
+
+/* parse a PMGL entry into a chmUnitInfo struct; return 1 on success. */
+static int _chm_parse_PMGL_entry(UChar **pEntry, struct chmUnitInfo *ui)
+{
+ UInt64 strLen;
+
+ /* parse str len */
+ strLen = _chm_parse_cword(pEntry);
+ if (strLen > CHM_MAX_PATHLEN)
+ return 0;
+
+ /* parse path */
+ if (! _chm_parse_UTF8(pEntry, strLen, ui->path))
+ return 0;
+
+ /* parse info */
+ ui->space = (int)_chm_parse_cword(pEntry);
+ ui->start = _chm_parse_cword(pEntry);
+ ui->length = _chm_parse_cword(pEntry);
+ return 1;
+}
+
+/* find an exact entry in PMGL; return NULL if we fail */
+static UChar *_chm_find_in_PMGL(UChar *page_buf,
+ UInt32 block_len,
+ const char *objPath)
+{
+ /* XXX: modify this to do a binary search using the nice index structure
+ * that is provided for us.
+ */
+ struct chmPmglHeader header;
+ unsigned int hremain;
+ UChar *end;
+ UChar *cur;
+ UChar *temp;
+ UInt64 strLen;
+ char buffer[CHM_MAX_PATHLEN+1];
+
+ /* figure out where to start and end */
+ cur = page_buf;
+ hremain = _CHM_PMGL_LEN;
+ if (! _unmarshal_pmgl_header(&cur, &hremain, &header))
+ return NULL;
+ end = page_buf + block_len - (header.free_space);
+
+ /* now, scan progressively */
+ while (cur < end)
+ {
+ /* grab the name */
+ temp = cur;
+ strLen = _chm_parse_cword(&cur);
+ if (strLen > CHM_MAX_PATHLEN)
+ return NULL;
+ if (! _chm_parse_UTF8(&cur, strLen, buffer))
+ return NULL;
+
+ /* check if it is the right name */
+ if (! strcasecmp(buffer, objPath))
+ return temp;
+
+ _chm_skip_PMGL_entry_data(&cur);
+ }
+
+ return NULL;
+}
+
+/* find which block should be searched next for the entry; -1 if no block */
+static Int32 _chm_find_in_PMGI(UChar *page_buf,
+ UInt32 block_len,
+ const char *objPath)
+{
+ /* XXX: modify this to do a binary search using the nice index structure
+ * that is provided for us
+ */
+ struct chmPmgiHeader header;
+ unsigned int hremain;
+ int page=-1;
+ UChar *end;
+ UChar *cur;
+ UInt64 strLen;
+ char buffer[CHM_MAX_PATHLEN+1];
+
+ /* figure out where to start and end */
+ cur = page_buf;
+ hremain = _CHM_PMGI_LEN;
+ if (! _unmarshal_pmgi_header(&cur, &hremain, &header))
+ return -1;
+ end = page_buf + block_len - (header.free_space);
+
+ /* now, scan progressively */
+ while (cur < end)
+ {
+ /* grab the name */
+ strLen = _chm_parse_cword(&cur);
+ if (strLen > CHM_MAX_PATHLEN)
+ return -1;
+ if (! _chm_parse_UTF8(&cur, strLen, buffer))
+ return -1;
+
+ /* check if it is the right name */
+ if (strcasecmp(buffer, objPath) > 0)
+ return page;
+
+ /* load next value for path */
+ page = (int)_chm_parse_cword(&cur);
+ }
+
+ return page;
+}
+
+/* resolve a particular object from the archive */
+int chm_resolve_object(struct chmFile *h,
+ const char *objPath,
+ struct chmUnitInfo *ui)
+{
+ /*
+ * XXX: implement caching scheme for dir pages
+ */
+
+ Int32 curPage;
+
+ /* buffer to hold whatever page we're looking at */
+ /* RWE 6/12/2003 */
+ UChar *page_buf = malloc(h->block_len);
+ if (page_buf == NULL)
+ return CHM_RESOLVE_FAILURE;
+
+ /* starting page */
+ curPage = h->index_root;
+
+ /* until we have either returned or given up */
+ while (curPage != -1)
+ {
+
+ /* try to fetch the index page */
+ if (_chm_fetch_bytes(h, page_buf,
+ (UInt64)h->dir_offset + (UInt64)curPage*h->block_len,
+ h->block_len) != h->block_len)
+ {
+ free(page_buf);
+ return CHM_RESOLVE_FAILURE;
+ }
+
+ /* now, if it is a leaf node: */
+ if (memcmp(page_buf, _chm_pmgl_marker, 4) == 0)
+ {
+ /* scan block */
+ UChar *pEntry = _chm_find_in_PMGL(page_buf,
+ h->block_len,
+ objPath);
+ if (pEntry == NULL)
+ {
+ free(page_buf);
+ return CHM_RESOLVE_FAILURE;
+ }
+
+ /* parse entry and return */
+ _chm_parse_PMGL_entry(&pEntry, ui);
+ free(page_buf);
+ return CHM_RESOLVE_SUCCESS;
+ }
+
+ /* else, if it is a branch node: */
+ else if (memcmp(page_buf, _chm_pmgi_marker, 4) == 0)
+ curPage = _chm_find_in_PMGI(page_buf, h->block_len, objPath);
+
+ /* else, we are confused. give up. */
+ else
+ {
+ free(page_buf);
+ return CHM_RESOLVE_FAILURE;
+ }
+ }
+
+ /* didn't find anything. fail. */
+ free(page_buf);
+ return CHM_RESOLVE_FAILURE;
+}
+
+/*
+ * utility methods for dealing with compressed data
+ */
+
+/* get the bounds of a compressed block. return 0 on failure */
+static int _chm_get_cmpblock_bounds(struct chmFile *h,
+ UInt64 block,
+ UInt64 *start,
+ Int64 *len)
+{
+ UChar buffer[8], *dummy;
+ unsigned int remain;
+
+ /* for all but the last block, use the reset table */
+ if (block < h->reset_table.block_count-1)
+ {
+ /* unpack the start address */
+ dummy = buffer;
+ remain = 8;
+ if (_chm_fetch_bytes(h, buffer,
+ (UInt64)h->data_offset
+ + (UInt64)h->rt_unit.start
+ + (UInt64)h->reset_table.table_offset
+ + (UInt64)block*8,
+ remain) != remain ||
+ !_unmarshal_uint64(&dummy, &remain, start))
+ return 0;
+
+ /* unpack the end address */
+ dummy = buffer;
+ remain = 8;
+ if (_chm_fetch_bytes(h, buffer,
+ (UInt64)h->data_offset
+ + (UInt64)h->rt_unit.start
+ + (UInt64)h->reset_table.table_offset
+ + (UInt64)block*8 + 8,
+ remain) != remain ||
+ !_unmarshal_int64(&dummy, &remain, len))
+ return 0;
+ }
+
+ /* for the last block, use the span in addition to the reset table */
+ else
+ {
+ /* unpack the start address */
+ dummy = buffer;
+ remain = 8;
+ if (_chm_fetch_bytes(h, buffer,
+ (UInt64)h->data_offset
+ + (UInt64)h->rt_unit.start
+ + (UInt64)h->reset_table.table_offset
+ + (UInt64)block*8,
+ remain) != remain ||
+ !_unmarshal_uint64(&dummy, &remain, start))
+ return 0;
+
+ *len = h->reset_table.compressed_len;
+ }
+
+ /* compute the length and absolute start address */
+ *len -= *start;
+ *start += h->data_offset + h->cn_unit.start;
+
+ return 1;
+}
+
+/* decompress the block. must have lzx_mutex. */
+static Int64 _chm_decompress_block(struct chmFile *h,
+ UInt64 block,
+ UChar **ubuffer)
+{
+ UChar *cbuffer = malloc(((unsigned int)h->reset_table.block_len + 6144));
+ UInt64 cmpStart; /* compressed start */
+ Int64 cmpLen; /* compressed len */
+ int indexSlot; /* cache index slot */
+ UChar *lbuffer; /* local buffer ptr */
+ UInt32 blockAlign = (UInt32)(block % h->reset_blkcount); /* reset intvl. aln. */
+ UInt32 i; /* local loop index */
+
+ if (cbuffer == NULL)
+ return -1;
+
+ /* let the caching system pull its weight! */
+ if (block - blockAlign <= h->lzx_last_block &&
+ block >= h->lzx_last_block)
+ blockAlign = (block - h->lzx_last_block);
+
+ /* check if we need previous blocks */
+ if (blockAlign != 0)
+ {
+ /* fetch all required previous blocks since last reset */
+ for (i = blockAlign; i > 0; i--)
+ {
+ UInt32 curBlockIdx = block - i;
+
+ /* check if we most recently decompressed the previous block */
+ if (h->lzx_last_block != curBlockIdx)
+ {
+ if ((curBlockIdx % h->reset_blkcount) == 0)
+ {
+#ifdef CHM_DEBUG
+ fprintf(stderr, "***RESET (1)***\n");
+#endif
+ LZXreset(h->lzx_state);
+ }
+
+ indexSlot = (int)((curBlockIdx) % h->cache_num_blocks);
+ if (! h->cache_blocks[indexSlot])
+ h->cache_blocks[indexSlot] = (UChar *)malloc((unsigned int)(h->reset_table.block_len));
+ if (! h->cache_blocks[indexSlot])
+ {
+ free(cbuffer);
+ return -1;
+ }
+ h->cache_block_indices[indexSlot] = curBlockIdx;
+ lbuffer = h->cache_blocks[indexSlot];
+
+ /* decompress the previous block */
+#ifdef CHM_DEBUG
+ fprintf(stderr, "Decompressing block #%4d (EXTRA)\n", curBlockIdx);
+#endif
+ if (!_chm_get_cmpblock_bounds(h, curBlockIdx, &cmpStart, &cmpLen) ||
+ cmpLen < 0 ||
+ cmpLen > h->reset_table.block_len + 6144 ||
+ _chm_fetch_bytes(h, cbuffer, cmpStart, cmpLen) != cmpLen ||
+ LZXdecompress(h->lzx_state, cbuffer, lbuffer, (int)cmpLen,
+ (int)h->reset_table.block_len) != DECR_OK)
+ {
+#ifdef CHM_DEBUG
+ fprintf(stderr, " (DECOMPRESS FAILED!)\n");
+#endif
+ free(cbuffer);
+ return (Int64)0;
+ }
+
+ h->lzx_last_block = (int)curBlockIdx;
+ }
+ }
+ }
+ else
+ {
+ if ((block % h->reset_blkcount) == 0)
+ {
+#ifdef CHM_DEBUG
+ fprintf(stderr, "***RESET (2)***\n");
+#endif
+ LZXreset(h->lzx_state);
+ }
+ }
+
+ /* allocate slot in cache */
+ indexSlot = (int)(block % h->cache_num_blocks);
+ if (! h->cache_blocks[indexSlot])
+ h->cache_blocks[indexSlot] = (UChar *)malloc(((unsigned int)h->reset_table.block_len));
+ if (! h->cache_blocks[indexSlot])
+ {
+ free(cbuffer);
+ return -1;
+ }
+ h->cache_block_indices[indexSlot] = block;
+ lbuffer = h->cache_blocks[indexSlot];
+ *ubuffer = lbuffer;
+
+ /* decompress the block we actually want */
+#ifdef CHM_DEBUG
+ fprintf(stderr, "Decompressing block #%4d (REAL )\n", block);
+#endif
+ if (! _chm_get_cmpblock_bounds(h, block, &cmpStart, &cmpLen) ||
+ _chm_fetch_bytes(h, cbuffer, cmpStart, cmpLen) != cmpLen ||
+ LZXdecompress(h->lzx_state, cbuffer, lbuffer, (int)cmpLen,
+ (int)h->reset_table.block_len) != DECR_OK)
+ {
+#ifdef CHM_DEBUG
+ fprintf(stderr, " (DECOMPRESS FAILED!)\n");
+#endif
+ free(cbuffer);
+ return (Int64)0;
+ }
+ h->lzx_last_block = (int)block;
+
+ /* XXX: modify LZX routines to return the length of the data they
+ * decompressed and return that instead, for an extra sanity check.
+ */
+ free(cbuffer);
+ return h->reset_table.block_len;
+}
+
+/* grab a region from a compressed block */
+static Int64 _chm_decompress_region(struct chmFile *h,
+ UChar *buf,
+ UInt64 start,
+ Int64 len)
+{
+ UInt64 nBlock, nOffset;
+ UInt64 nLen;
+ UInt64 gotLen;
+ UChar *ubuffer;
+
+ if (len <= 0)
+ return (Int64)0;
+
+ /* figure out what we need to read */
+ nBlock = start / h->reset_table.block_len;
+ nOffset = start % h->reset_table.block_len;
+ nLen = len;
+ if (nLen > (h->reset_table.block_len - nOffset))
+ nLen = h->reset_table.block_len - nOffset;
+
+ /* if block is cached, return data from it. */
+ CHM_ACQUIRE_LOCK(h->lzx_mutex);
+ CHM_ACQUIRE_LOCK(h->cache_mutex);
+ if (h->cache_block_indices[nBlock % h->cache_num_blocks] == nBlock &&
+ h->cache_blocks[nBlock % h->cache_num_blocks] != NULL)
+ {
+ memcpy(buf,
+ h->cache_blocks[nBlock % h->cache_num_blocks] + nOffset,
+ (unsigned int)nLen);
+ CHM_RELEASE_LOCK(h->cache_mutex);
+ CHM_RELEASE_LOCK(h->lzx_mutex);
+ return nLen;
+ }
+ CHM_RELEASE_LOCK(h->cache_mutex);
+
+ /* data request not satisfied, so... start up the decompressor machine */
+ if (! h->lzx_state)
+ {
+ int window_size = ffs(h->window_size) - 1;
+ h->lzx_last_block = -1;
+ h->lzx_state = LZXinit(window_size);
+ }
+
+ /* decompress some data */
+ gotLen = _chm_decompress_block(h, nBlock, &ubuffer);
+ if (gotLen < nLen)
+ nLen = gotLen;
+ memcpy(buf, ubuffer+nOffset, (unsigned int)nLen);
+ CHM_RELEASE_LOCK(h->lzx_mutex);
+ return nLen;
+}
+
+/* retrieve (part of) an object */
+LONGINT64 chm_retrieve_object(struct chmFile *h,
+ const struct chmUnitInfo *ui,
+ unsigned char *buf,
+ LONGUINT64 addr,
+ LONGINT64 len)
+{
+ /* must be valid file handle */
+ if (h == NULL)
+ return (Int64)0;
+
+ /* starting address must be in correct range */
+ if ( addr >= ui->length)
+ return (Int64)0;
+
+ /* clip length */
+ if (addr + len > ui->length)
+ len = ui->length - addr;
+
+ /* if the file is uncompressed, it's simple */
+ if (ui->space == CHM_UNCOMPRESSED)
+ {
+ /* read data */
+ return _chm_fetch_bytes(h,
+ buf,
+ (UInt64)h->data_offset + (UInt64)ui->start + (UInt64)addr,
+ len);
+ }
+
+ /* else if the file is compressed, it's a little trickier */
+ else /* ui->space == CHM_COMPRESSED */
+ {
+ Int64 swath=0, total=0;
+
+ /* if compression is not enabled for this file... */
+ if (! h->compression_enabled)
+ return total;
+
+ do {
+
+ /* swill another mouthful */
+ swath = _chm_decompress_region(h, buf, ui->start + addr, len);
+
+ /* if we didn't get any... */
+ if (swath == 0)
+ return total;
+
+ /* update stats */
+ total += swath;
+ len -= swath;
+ addr += swath;
+ buf += swath;
+
+ } while (len != 0);
+
+ return total;
+ }
+}
+
+/* enumerate the objects in the .chm archive */
+int chm_enumerate(struct chmFile *h,
+ int what,
+ CHM_ENUMERATOR e,
+ void *context)
+{
+ Int32 curPage;
+
+ /* buffer to hold whatever page we're looking at */
+ /* RWE 6/12/2003 */
+ UChar *page_buf = malloc((unsigned int)h->block_len);
+ struct chmPmglHeader header;
+ UChar *end;
+ UChar *cur;
+ unsigned int lenRemain;
+ UInt64 ui_path_len;
+
+ /* the current ui */
+ struct chmUnitInfo ui;
+ int type_bits = (what & 0x7);
+ int filter_bits = (what & 0xF8);
+
+ if (page_buf == NULL)
+ return 0;
+
+ /* starting page */
+ curPage = h->index_head;
+
+ /* until we have either returned or given up */
+ while (curPage != -1)
+ {
+
+ /* try to fetch the index page */
+ if (_chm_fetch_bytes(h,
+ page_buf,
+ (UInt64)h->dir_offset + (UInt64)curPage*h->block_len,
+ h->block_len) != h->block_len)
+ {
+ free(page_buf);
+ return 0;
+ }
+
+ /* figure out start and end for this page */
+ cur = page_buf;
+ lenRemain = _CHM_PMGL_LEN;
+ if (! _unmarshal_pmgl_header(&cur, &lenRemain, &header))
+ {
+ free(page_buf);
+ return 0;
+ }
+ end = page_buf + h->block_len - (header.free_space);
+
+ /* loop over this page */
+ while (cur < end)
+ {
+ ui.flags = 0;
+
+ if (! _chm_parse_PMGL_entry(&cur, &ui))
+ {
+ free(page_buf);
+ return 0;
+ }
+
+ /* get the length of the path */
+ ui_path_len = strlen(ui.path)-1;
+
+ /* check for DIRS */
+ if (ui.path[ui_path_len] == '/')
+ ui.flags |= CHM_ENUMERATE_DIRS;
+
+ /* check for FILES */
+ if (ui.path[ui_path_len] != '/')
+ ui.flags |= CHM_ENUMERATE_FILES;
+
+ /* check for NORMAL vs. META */
+ if (ui.path[0] == '/')
+ {
+
+ /* check for NORMAL vs. SPECIAL */
+ if (ui.path[1] == '#' || ui.path[1] == '$')
+ ui.flags |= CHM_ENUMERATE_SPECIAL;
+ else
+ ui.flags |= CHM_ENUMERATE_NORMAL;
+ }
+ else
+ ui.flags |= CHM_ENUMERATE_META;
+
+ if (! (type_bits & ui.flags))
+ continue;
+
+ if (filter_bits && ! (filter_bits & ui.flags))
+ continue;
+
+ /* call the enumerator */
+ {
+ int status = (*e)(h, &ui, context);
+ switch (status)
+ {
+ case CHM_ENUMERATOR_FAILURE:
+ free(page_buf);
+ return 0;
+ case CHM_ENUMERATOR_CONTINUE:
+ break;
+ case CHM_ENUMERATOR_SUCCESS:
+ free(page_buf);
+ return 1;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* advance to next page */
+ curPage = header.block_next;
+ }
+
+ free(page_buf);
+ return 1;
+}
+
+int chm_enumerate_dir(struct chmFile *h,
+ const char *prefix,
+ int what,
+ CHM_ENUMERATOR e,
+ void *context)
+{
+ /*
+ * XXX: do this efficiently (i.e. using the tree index)
+ */
+
+ Int32 curPage;
+
+ /* buffer to hold whatever page we're looking at */
+ /* RWE 6/12/2003 */
+ UChar *page_buf = malloc((unsigned int)h->block_len);
+ struct chmPmglHeader header;
+ UChar *end;
+ UChar *cur;
+ unsigned int lenRemain;
+
+ /* set to 1 once we've started */
+ int it_has_begun=0;
+
+ /* the current ui */
+ struct chmUnitInfo ui;
+ int type_bits = (what & 0x7);
+ int filter_bits = (what & 0xF8);
+ UInt64 ui_path_len;
+
+ /* the length of the prefix */
+ char prefixRectified[CHM_MAX_PATHLEN+1];
+ int prefixLen;
+ char lastPath[CHM_MAX_PATHLEN+1];
+ int lastPathLen;
+
+ if (page_buf == NULL)
+ return 0;
+
+ /* starting page */
+ curPage = h->index_head;
+
+ /* initialize pathname state */
+ strncpy(prefixRectified, prefix, CHM_MAX_PATHLEN);
+ prefixRectified[CHM_MAX_PATHLEN] = '\0';
+ prefixLen = strlen(prefixRectified);
+ if (prefixLen != 0)
+ {
+ if (prefixRectified[prefixLen-1] != '/')
+ {
+ prefixRectified[prefixLen] = '/';
+ prefixRectified[prefixLen+1] = '\0';
+ ++prefixLen;
+ }
+ }
+ lastPath[0] = '\0';
+ lastPathLen = -1;
+
+ /* until we have either returned or given up */
+ while (curPage != -1)
+ {
+
+ /* try to fetch the index page */
+ if (_chm_fetch_bytes(h,
+ page_buf,
+ (UInt64)h->dir_offset + (UInt64)curPage*h->block_len,
+ h->block_len) != h->block_len)
+ {
+ free(page_buf);
+ return 0;
+ }
+
+ /* figure out start and end for this page */
+ cur = page_buf;
+ lenRemain = _CHM_PMGL_LEN;
+ if (! _unmarshal_pmgl_header(&cur, &lenRemain, &header))
+ {
+ free(page_buf);
+ return 0;
+ }
+ end = page_buf + h->block_len - (header.free_space);
+
+ /* loop over this page */
+ while (cur < end)
+ {
+ ui.flags = 0;
+
+ if (! _chm_parse_PMGL_entry(&cur, &ui))
+ {
+ free(page_buf);
+ return 0;
+ }
+
+ /* check if we should start */
+ if (! it_has_begun)
+ {
+ if (ui.length == 0 && strncasecmp(ui.path, prefixRectified, prefixLen) == 0)
+ it_has_begun = 1;
+ else
+ continue;
+
+ if (ui.path[prefixLen] == '\0')
+ continue;
+ }
+
+ /* check if we should stop */
+ else
+ {
+ if (strncasecmp(ui.path, prefixRectified, prefixLen) != 0)
+ {
+ free(page_buf);
+ return 1;
+ }
+ }
+
+ /* check if we should include this path */
+ if (lastPathLen != -1)
+ {
+ if (strncasecmp(ui.path, lastPath, lastPathLen) == 0)
+ continue;
+ }
+ strncpy(lastPath, ui.path, CHM_MAX_PATHLEN);
+ lastPath[CHM_MAX_PATHLEN] = '\0';
+ lastPathLen = strlen(lastPath);
+
+ /* get the length of the path */
+ ui_path_len = strlen(ui.path)-1;
+
+ /* check for DIRS */
+ if (ui.path[ui_path_len] == '/')
+ ui.flags |= CHM_ENUMERATE_DIRS;
+
+ /* check for FILES */
+ if (ui.path[ui_path_len] != '/')
+ ui.flags |= CHM_ENUMERATE_FILES;
+
+ /* check for NORMAL vs. META */
+ if (ui.path[0] == '/')
+ {
+
+ /* check for NORMAL vs. SPECIAL */
+ if (ui.path[1] == '#' || ui.path[1] == '$')
+ ui.flags |= CHM_ENUMERATE_SPECIAL;
+ else
+ ui.flags |= CHM_ENUMERATE_NORMAL;
+ }
+ else
+ ui.flags |= CHM_ENUMERATE_META;
+
+ if (! (type_bits & ui.flags))
+ continue;
+
+ if (filter_bits && ! (filter_bits & ui.flags))
+ continue;
+
+ /* call the enumerator */
+ {
+ int status = (*e)(h, &ui, context);
+ switch (status)
+ {
+ case CHM_ENUMERATOR_FAILURE:
+ free(page_buf);
+ return 0;
+ case CHM_ENUMERATOR_CONTINUE:
+ break;
+ case CHM_ENUMERATOR_SUCCESS:
+ free(page_buf);
+ return 1;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* advance to next page */
+ curPage = header.block_next;
+ }
+
+ free(page_buf);
+ return 1;
+}
diff --git a/lib/chmlib/chm_lib.h b/lib/chmlib/chm_lib.h
new file mode 100644
index 0000000..2fb87a4
--- /dev/null
+++ b/lib/chmlib/chm_lib.h
@@ -0,0 +1,144 @@
+/* $Id: chm_lib.h 148 2007-03-07 09:22:36Z gyunaev $ */
+/***************************************************************************
+ * chm_lib.h - CHM archive manipulation routines *
+ * ------------------- *
+ * *
+ * author: Jed Wing <jedwin@ugcs.caltech.edu> *
+ * version: 0.3 *
+ * notes: These routines are meant for the manipulation of microsoft *
+ * .chm (compiled html help) files, but may likely be used *
+ * for the manipulation of any ITSS archive, if ever ITSS *
+ * archives are used for any other purpose. *
+ * *
+ * Note also that the section names are statically handled. *
+ * To be entirely correct, the section names should be read *
+ * from the section names meta-file, and then the various *
+ * content sections and the "transforms" to apply to the data *
+ * they contain should be inferred from the section name and *
+ * the meta-files referenced using that name; however, all of *
+ * the files I've been able to get my hands on appear to have *
+ * only two sections: Uncompressed and MSCompressed. *
+ * Additionally, the ITSS.DLL file included with Windows does *
+ * not appear to handle any different transforms than the *
+ * simple LZX-transform. Furthermore, the list of transforms *
+ * to apply is broken, in that only half the required space *
+ * is allocated for the list. (It appears as though the *
+ * space is allocated for ASCII strings, but the strings are *
+ * written as unicode. As a result, only the first half of *
+ * the string appears.) So this is probably not too big of *
+ * a deal, at least until CHM v4 (MS .lit files), which also *
+ * incorporate encryption, of some description. *
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of the *
+ * License, or (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef INCLUDED_CHMLIB_H
+#define INCLUDED_CHMLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* RWE 6/12/1002 */
+#ifdef PPC_BSTR
+#include <wtypes.h>
+#endif
+
+#ifdef WIN32
+#ifdef __MINGW32__
+#define __int64 long long
+#endif
+typedef unsigned __int64 LONGUINT64;
+typedef __int64 LONGINT64;
+#else
+typedef unsigned long long LONGUINT64;
+typedef long long LONGINT64;
+#endif
+
+/* the two available spaces in a CHM file */
+/* N.B.: The format supports arbitrarily many spaces, but only */
+/* two appear to be used at present. */
+#define CHM_UNCOMPRESSED (0)
+#define CHM_COMPRESSED (1)
+
+/* structure representing an ITS (CHM) file stream */
+struct chmFile;
+
+/* structure representing an element from an ITS file stream */
+#define CHM_MAX_PATHLEN (512)
+struct chmUnitInfo
+{
+ LONGUINT64 start;
+ LONGUINT64 length;
+ int space;
+ int flags;
+ char path[CHM_MAX_PATHLEN+1];
+};
+
+/* open an ITS archive */
+#ifdef PPC_BSTR
+/* RWE 6/12/2003 */
+struct chmFile* chm_open(BSTR filename);
+#else
+struct chmFile* chm_open(const char *filename);
+#endif
+
+/* close an ITS archive */
+void chm_close(struct chmFile *h);
+
+/* methods for ssetting tuning parameters for particular file */
+#define CHM_PARAM_MAX_BLOCKS_CACHED 0
+void chm_set_param(struct chmFile *h,
+ int paramType,
+ int paramVal);
+
+/* resolve a particular object from the archive */
+#define CHM_RESOLVE_SUCCESS (0)
+#define CHM_RESOLVE_FAILURE (1)
+int chm_resolve_object(struct chmFile *h,
+ const char *objPath,
+ struct chmUnitInfo *ui);
+
+/* retrieve part of an object from the archive */
+LONGINT64 chm_retrieve_object(struct chmFile *h,
+ const struct chmUnitInfo *ui,
+ unsigned char *buf,
+ LONGUINT64 addr,
+ LONGINT64 len);
+
+/* enumerate the objects in the .chm archive */
+typedef int (*CHM_ENUMERATOR)(struct chmFile *h,
+ struct chmUnitInfo *ui,
+ void *context);
+#define CHM_ENUMERATE_NORMAL (1)
+#define CHM_ENUMERATE_META (2)
+#define CHM_ENUMERATE_SPECIAL (4)
+#define CHM_ENUMERATE_FILES (8)
+#define CHM_ENUMERATE_DIRS (16)
+#define CHM_ENUMERATE_ALL (31)
+#define CHM_ENUMERATOR_FAILURE (0)
+#define CHM_ENUMERATOR_CONTINUE (1)
+#define CHM_ENUMERATOR_SUCCESS (2)
+int chm_enumerate(struct chmFile *h,
+ int what,
+ CHM_ENUMERATOR e,
+ void *context);
+
+int chm_enumerate_dir(struct chmFile *h,
+ const char *prefix,
+ int what,
+ CHM_ENUMERATOR e,
+ void *context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDED_CHMLIB_H */
diff --git a/lib/chmlib/lzx.c b/lib/chmlib/lzx.c
new file mode 100644
index 0000000..7a5545b
--- /dev/null
+++ b/lib/chmlib/lzx.c
@@ -0,0 +1,812 @@
+/* $Id: lzx.c 148 2007-03-07 09:22:36Z gyunaev $ */
+/***************************************************************************
+ * lzx.c - LZX decompression routines *
+ * ------------------- *
+ * *
+ * maintainer: Jed Wing <jedwin@ugcs.caltech.edu> *
+ * source: modified lzx.c from cabextract v0.5 *
+ * notes: This file was taken from cabextract v0.5, which was, *
+ * itself, a modified version of the lzx decompression code *
+ * from unlzx. *
+ * *
+ * platforms: In its current incarnation, this file has been tested on *
+ * two different Linux platforms (one, redhat-based, with a *
+ * 2.1.2 glibc and gcc 2.95.x, and the other, Debian, with *
+ * 2.2.4 glibc and both gcc 2.95.4 and gcc 3.0.2). Both were *
+ * Intel x86 compatible machines. *
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. Note that an exemption to this *
+ * license has been granted by Stuart Caie for the purposes of *
+ * distribution with chmlib. This does not, to the best of my *
+ * knowledge, constitute a change in the license of this (the LZX) code *
+ * in general. *
+ * *
+ ***************************************************************************/
+
+#include "lzx.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __GNUC__
+#define memcpy __builtin_memcpy
+#endif
+
+/* sized types */
+typedef unsigned char UBYTE; /* 8 bits exactly */
+typedef unsigned short UWORD; /* 16 bits (or more) */
+typedef unsigned int ULONG; /* 32 bits (or more) */
+typedef signed int LONG; /* 32 bits (or more) */
+
+/* some constants defined by the LZX specification */
+#define LZX_MIN_MATCH (2)
+#define LZX_MAX_MATCH (257)
+#define LZX_NUM_CHARS (256)
+#define LZX_BLOCKTYPE_INVALID (0) /* also blocktypes 4-7 invalid */
+#define LZX_BLOCKTYPE_VERBATIM (1)
+#define LZX_BLOCKTYPE_ALIGNED (2)
+#define LZX_BLOCKTYPE_UNCOMPRESSED (3)
+#define LZX_PRETREE_NUM_ELEMENTS (20)
+#define LZX_ALIGNED_NUM_ELEMENTS (8) /* aligned offset tree #elements */
+#define LZX_NUM_PRIMARY_LENGTHS (7) /* this one missing from spec! */
+#define LZX_NUM_SECONDARY_LENGTHS (249) /* length tree #elements */
+
+/* LZX huffman defines: tweak tablebits as desired */
+#define LZX_PRETREE_MAXSYMBOLS (LZX_PRETREE_NUM_ELEMENTS)
+#define LZX_PRETREE_TABLEBITS (6)
+#define LZX_MAINTREE_MAXSYMBOLS (LZX_NUM_CHARS + 50*8)
+#define LZX_MAINTREE_TABLEBITS (12)
+#define LZX_LENGTH_MAXSYMBOLS (LZX_NUM_SECONDARY_LENGTHS+1)
+#define LZX_LENGTH_TABLEBITS (12)
+#define LZX_ALIGNED_MAXSYMBOLS (LZX_ALIGNED_NUM_ELEMENTS)
+#define LZX_ALIGNED_TABLEBITS (7)
+
+#define LZX_LENTABLE_SAFETY (64) /* we allow length table decoding overruns */
+
+#define LZX_DECLARE_TABLE(tbl) \
+ UWORD tbl##_table[(1<<LZX_##tbl##_TABLEBITS) + (LZX_##tbl##_MAXSYMBOLS<<1)];\
+ UBYTE tbl##_len [LZX_##tbl##_MAXSYMBOLS + LZX_LENTABLE_SAFETY]
+
+struct LZXstate
+{
+ UBYTE *window; /* the actual decoding window */
+ ULONG window_size; /* window size (32Kb through 2Mb) */
+ ULONG actual_size; /* window size when it was first allocated */
+ ULONG window_posn; /* current offset within the window */
+ ULONG R0, R1, R2; /* for the LRU offset system */
+ UWORD main_elements; /* number of main tree elements */
+ int header_read; /* have we started decoding at all yet? */
+ UWORD block_type; /* type of this block */
+ ULONG block_length; /* uncompressed length of this block */
+ ULONG block_remaining; /* uncompressed bytes still left to decode */
+ ULONG frames_read; /* the number of CFDATA blocks processed */
+ LONG intel_filesize; /* magic header value used for transform */
+ LONG intel_curpos; /* current offset in transform space */
+ int intel_started; /* have we seen any translatable data yet? */
+
+ LZX_DECLARE_TABLE(PRETREE);
+ LZX_DECLARE_TABLE(MAINTREE);
+ LZX_DECLARE_TABLE(LENGTH);
+ LZX_DECLARE_TABLE(ALIGNED);
+};
+
+/* LZX decruncher */
+
+/* Microsoft's LZX document and their implementation of the
+ * com.ms.util.cab Java package do not concur.
+ *
+ * In the LZX document, there is a table showing the correlation between
+ * window size and the number of position slots. It states that the 1MB
+ * window = 40 slots and the 2MB window = 42 slots. In the implementation,
+ * 1MB = 42 slots, 2MB = 50 slots. The actual calculation is 'find the
+ * first slot whose position base is equal to or more than the required
+ * window size'. This would explain why other tables in the document refer
+ * to 50 slots rather than 42.
+ *
+ * The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode
+ * is not defined in the specification.
+ *
+ * The LZX document does not state the uncompressed block has an
+ * uncompressed length field. Where does this length field come from, so
+ * we can know how large the block is? The implementation has it as the 24
+ * bits following after the 3 blocktype bits, before the alignment
+ * padding.
+ *
+ * The LZX document states that aligned offset blocks have their aligned
+ * offset huffman tree AFTER the main and length trees. The implementation
+ * suggests that the aligned offset tree is BEFORE the main and length
+ * trees.
+ *
+ * The LZX document decoding algorithm states that, in an aligned offset
+ * block, if an extra_bits value is 1, 2 or 3, then that number of bits
+ * should be read and the result added to the match offset. This is
+ * correct for 1 and 2, but not 3, where just a huffman symbol (using the
+ * aligned tree) should be read.
+ *
+ * Regarding the E8 preprocessing, the LZX document states 'No translation
+ * may be performed on the last 6 bytes of the input block'. This is
+ * correct. However, the pseudocode provided checks for the *E8 leader*
+ * up to the last 6 bytes. If the leader appears between -10 and -7 bytes
+ * from the end, this would cause the next four bytes to be modified, at
+ * least one of which would be in the last 6 bytes, which is not allowed
+ * according to the spec.
+ *
+ * The specification states that the huffman trees must always contain at
+ * least one element. However, many CAB files contain blocks where the
+ * length tree is completely empty (because there are no matches), and
+ * this is expected to succeed.
+ */
+
+
+/* LZX uses what it calls 'position slots' to represent match offsets.
+ * What this means is that a small 'position slot' number and a small
+ * offset from that slot are encoded instead of one large offset for
+ * every match.
+ * - position_base is an index to the position slot bases
+ * - extra_bits states how many bits of offset-from-base data is needed.
+ */
+static const UBYTE extra_bits[51] = {
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
+ 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17
+};
+
+static const ULONG position_base[51] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
+ 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
+ 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360, 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
+ 1835008, 1966080, 2097152
+};
+
+struct LZXstate *LZXinit(int window)
+{
+ struct LZXstate *pState=NULL;
+ ULONG wndsize = 1 << window;
+ int i, posn_slots;
+
+ /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
+ /* if a previously allocated window is big enough, keep it */
+ if (window < 15 || window > 21) return NULL;
+
+ /* allocate state and associated window */
+ pState = (struct LZXstate *)malloc(sizeof(struct LZXstate));
+ if (!(pState->window = (UBYTE *)malloc(wndsize)))
+ {
+ free(pState);
+ return NULL;
+ }
+ pState->actual_size = wndsize;
+ pState->window_size = wndsize;
+
+ /* calculate required position slots */
+ if (window == 20) posn_slots = 42;
+ else if (window == 21) posn_slots = 50;
+ else posn_slots = window << 1;
+
+ /** alternatively **/
+ /* posn_slots=i=0; while (i < wndsize) i += 1 << extra_bits[posn_slots++]; */
+
+ /* initialize other state */
+ pState->R0 = pState->R1 = pState->R2 = 1;
+ pState->main_elements = LZX_NUM_CHARS + (posn_slots << 3);
+ pState->header_read = 0;
+ pState->frames_read = 0;
+ pState->block_remaining = 0;
+ pState->block_type = LZX_BLOCKTYPE_INVALID;
+ pState->intel_curpos = 0;
+ pState->intel_started = 0;
+ pState->window_posn = 0;
+
+ /* initialise tables to 0 (because deltas will be applied to them) */
+ for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) pState->MAINTREE_len[i] = 0;
+ for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++) pState->LENGTH_len[i] = 0;
+
+ return pState;
+}
+
+void LZXteardown(struct LZXstate *pState)
+{
+ if (pState)
+ {
+ if (pState->window)
+ free(pState->window);
+ free(pState);
+ }
+}
+
+int LZXreset(struct LZXstate *pState)
+{
+ int i;
+
+ pState->R0 = pState->R1 = pState->R2 = 1;
+ pState->header_read = 0;
+ pState->frames_read = 0;
+ pState->block_remaining = 0;
+ pState->block_type = LZX_BLOCKTYPE_INVALID;
+ pState->intel_curpos = 0;
+ pState->intel_started = 0;
+ pState->window_posn = 0;
+
+ for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY; i++) pState->MAINTREE_len[i] = 0;
+ for (i = 0; i < LZX_LENGTH_MAXSYMBOLS + LZX_LENTABLE_SAFETY; i++) pState->LENGTH_len[i] = 0;
+
+ return DECR_OK;
+}
+
+
+/* Bitstream reading macros:
+ *
+ * INIT_BITSTREAM should be used first to set up the system
+ * READ_BITS(var,n) takes N bits from the buffer and puts them in var
+ *
+ * ENSURE_BITS(n) ensures there are at least N bits in the bit buffer
+ * PEEK_BITS(n) extracts (without removing) N bits from the bit buffer
+ * REMOVE_BITS(n) removes N bits from the bit buffer
+ *
+ * These bit access routines work by using the area beyond the MSB and the
+ * LSB as a free source of zeroes. This avoids having to mask any bits.
+ * So we have to know the bit width of the bitbuffer variable. This is
+ * sizeof(ULONG) * 8, also defined as ULONG_BITS
+ */
+
+/* number of bits in ULONG. Note: This must be at multiple of 16, and at
+ * least 32 for the bitbuffer code to work (ie, it must be able to ensure
+ * up to 17 bits - that's adding 16 bits when there's one bit left, or
+ * adding 32 bits when there are no bits left. The code should work fine
+ * for machines where ULONG >= 32 bits.
+ */
+#define ULONG_BITS (sizeof(ULONG)<<3)
+
+#define INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0)
+
+#define ENSURE_BITS(n) \
+ while (bitsleft < (n)) { \
+ bitbuf |= ((inpos[1]<<8)|inpos[0]) << (ULONG_BITS-16 - bitsleft); \
+ bitsleft += 16; inpos+=2; \
+ }
+
+#define PEEK_BITS(n) (bitbuf >> (ULONG_BITS - (n)))
+#define REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n)))
+
+#define READ_BITS(v,n) do { \
+ ENSURE_BITS(n); \
+ (v) = PEEK_BITS(n); \
+ REMOVE_BITS(n); \
+} while (0)
+
+
+/* Huffman macros */
+
+#define TABLEBITS(tbl) (LZX_##tbl##_TABLEBITS)
+#define MAXSYMBOLS(tbl) (LZX_##tbl##_MAXSYMBOLS)
+#define SYMTABLE(tbl) (pState->tbl##_table)
+#define LENTABLE(tbl) (pState->tbl##_len)
+
+/* BUILD_TABLE(tablename) builds a huffman lookup table from code lengths.
+ * In reality, it just calls make_decode_table() with the appropriate
+ * values - they're all fixed by some #defines anyway, so there's no point
+ * writing each call out in full by hand.
+ */
+#define BUILD_TABLE(tbl) \
+ if (make_decode_table( \
+ MAXSYMBOLS(tbl), TABLEBITS(tbl), LENTABLE(tbl), SYMTABLE(tbl) \
+ )) { return DECR_ILLEGALDATA; }
+
+
+/* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the
+ * bitstream using the stated table and puts it in var.
+ */
+#define READ_HUFFSYM(tbl,var) do { \
+ ENSURE_BITS(16); \
+ hufftbl = SYMTABLE(tbl); \
+ if ((i = hufftbl[PEEK_BITS(TABLEBITS(tbl))]) >= MAXSYMBOLS(tbl)) { \
+ j = 1 << (ULONG_BITS - TABLEBITS(tbl)); \
+ do { \
+ j >>= 1; i <<= 1; i |= (bitbuf & j) ? 1 : 0; \
+ if (!j) { return DECR_ILLEGALDATA; } \
+ } while ((i = hufftbl[i]) >= MAXSYMBOLS(tbl)); \
+ } \
+ j = LENTABLE(tbl)[(var) = i]; \
+ REMOVE_BITS(j); \
+} while (0)
+
+
+/* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols
+ * first to last in the given table. The code lengths are stored in their
+ * own special LZX way.
+ */
+#define READ_LENGTHS(tbl,first,last) do { \
+ lb.bb = bitbuf; lb.bl = bitsleft; lb.ip = inpos; \
+ if (lzx_read_lens(pState, LENTABLE(tbl),(first),(last),&lb)) { \
+ return DECR_ILLEGALDATA; \
+ } \
+ bitbuf = lb.bb; bitsleft = lb.bl; inpos = lb.ip; \
+} while (0)
+
+
+/* make_decode_table(nsyms, nbits, length[], table[])
+ *
+ * This function was coded by David Tritscher. It builds a fast huffman
+ * decoding table out of just a canonical huffman code lengths table.
+ *
+ * nsyms = total number of symbols in this huffman tree.
+ * nbits = any symbols with a code length of nbits or less can be decoded
+ * in one lookup of the table.
+ * length = A table to get code lengths from [0 to syms-1]
+ * table = The table to fill up with decoded symbols and pointers.
+ *
+ * Returns 0 for OK or 1 for error
+ */
+
+static int make_decode_table(ULONG nsyms, ULONG nbits, UBYTE *length, UWORD *table) {
+ register UWORD sym;
+ register ULONG leaf;
+ register UBYTE bit_num = 1;
+ ULONG fill;
+ ULONG pos = 0; /* the current position in the decode table */
+ ULONG table_mask = 1 << nbits;
+ ULONG bit_mask = table_mask >> 1; /* don't do 0 length codes */
+ ULONG next_symbol = bit_mask; /* base of allocation for long codes */
+
+ /* fill entries for codes short enough for a direct mapping */
+ while (bit_num <= nbits) {
+ for (sym = 0; sym < nsyms; sym++) {
+ if (length[sym] == bit_num) {
+ leaf = pos;
+
+ if((pos += bit_mask) > table_mask) return 1; /* table overrun */
+
+ /* fill all possible lookups of this symbol with the symbol itself */
+ fill = bit_mask;
+ while (fill-- > 0) table[leaf++] = sym;
+ }
+ }
+ bit_mask >>= 1;
+ bit_num++;
+ }
+
+ /* if there are any codes longer than nbits */
+ if (pos != table_mask) {
+ /* clear the remainder of the table */
+ for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
+
+ /* give ourselves room for codes to grow by up to 16 more bits */
+ pos <<= 16;
+ table_mask <<= 16;
+ bit_mask = 1 << 15;
+
+ while (bit_num <= 16) {
+ for (sym = 0; sym < nsyms; sym++) {
+ if (length[sym] == bit_num) {
+ leaf = pos >> 16;
+ for (fill = 0; fill < bit_num - nbits; fill++) {
+ /* if this path hasn't been taken yet, 'allocate' two entries */
+ if (table[leaf] == 0) {
+ table[(next_symbol << 1)] = 0;
+ table[(next_symbol << 1) + 1] = 0;
+ table[leaf] = next_symbol++;
+ }
+ /* follow the path and select either left or right for next bit */
+ leaf = table[leaf] << 1;
+ if ((pos >> (15-fill)) & 1) leaf++;
+ }
+ table[leaf] = sym;
+
+ if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
+ }
+ }
+ bit_mask >>= 1;
+ bit_num++;
+ }
+ }
+
+ /* full table? */
+ if (pos == table_mask) return 0;
+
+ /* either erroneous table, or all elements are 0 - let's find out. */
+ for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
+ return 0;
+}
+
+struct lzx_bits {
+ ULONG bb;
+ int bl;
+ UBYTE *ip;
+};
+
+static int lzx_read_lens(struct LZXstate *pState, UBYTE *lens, ULONG first, ULONG last, struct lzx_bits *lb) {
+ ULONG i,j, x,y;
+ int z;
+
+ register ULONG bitbuf = lb->bb;
+ register int bitsleft = lb->bl;
+ UBYTE *inpos = lb->ip;
+ UWORD *hufftbl;
+
+ for (x = 0; x < 20; x++) {
+ READ_BITS(y, 4);
+ LENTABLE(PRETREE)[x] = y;
+ }
+ BUILD_TABLE(PRETREE);
+
+ for (x = first; x < last; ) {
+ READ_HUFFSYM(PRETREE, z);
+ if (z == 17) {
+ READ_BITS(y, 4); y += 4;
+ while (y--) lens[x++] = 0;
+ }
+ else if (z == 18) {
+ READ_BITS(y, 5); y += 20;
+ while (y--) lens[x++] = 0;
+ }
+ else if (z == 19) {
+ READ_BITS(y, 1); y += 4;
+ READ_HUFFSYM(PRETREE, z);
+ z = lens[x] - z; if (z < 0) z += 17;
+ while (y--) lens[x++] = z;
+ }
+ else {
+ z = lens[x] - z; if (z < 0) z += 17;
+ lens[x++] = z;
+ }
+ }
+
+ lb->bb = bitbuf;
+ lb->bl = bitsleft;
+ lb->ip = inpos;
+ return 0;
+}
+
+int LZXdecompress(struct LZXstate *pState, unsigned char *inpos, unsigned char *outpos, int inlen, int outlen) {
+ UBYTE *endinp = inpos + inlen;
+ UBYTE *window = pState->window;
+ UBYTE *runsrc, *rundest;
+ UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
+
+ ULONG window_posn = pState->window_posn;
+ ULONG window_size = pState->window_size;
+ ULONG R0 = pState->R0;
+ ULONG R1 = pState->R1;
+ ULONG R2 = pState->R2;
+
+ register ULONG bitbuf;
+ register int bitsleft;
+ ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
+ struct lzx_bits lb; /* used in READ_LENGTHS macro */
+
+ int togo = outlen, this_run, main_element, aligned_bits;
+ int match_length, length_footer, extra, verbatim_bits;
+
+ INIT_BITSTREAM;
+
+ /* read header if necessary */
+ if (!pState->header_read) {
+ i = j = 0;
+ READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
+ pState->intel_filesize = (i << 16) | j; /* or 0 if not encoded */
+ pState->header_read = 1;
+ }
+
+ /* main decoding loop */
+ while (togo > 0) {
+ /* last block finished, new block expected */
+ if (pState->block_remaining == 0) {
+ if (pState->block_type == LZX_BLOCKTYPE_UNCOMPRESSED) {
+ if (pState->block_length & 1) inpos++; /* realign bitstream to word */
+ INIT_BITSTREAM;
+ }
+
+ READ_BITS(pState->block_type, 3);
+ READ_BITS(i, 16);
+ READ_BITS(j, 8);
+ pState->block_remaining = pState->block_length = (i << 8) | j;
+
+ switch (pState->block_type) {
+ case LZX_BLOCKTYPE_ALIGNED:
+ for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
+ BUILD_TABLE(ALIGNED);
+ /* rest of aligned header is same as verbatim */
+
+ case LZX_BLOCKTYPE_VERBATIM:
+ READ_LENGTHS(MAINTREE, 0, 256);
+ READ_LENGTHS(MAINTREE, 256, pState->main_elements);
+ BUILD_TABLE(MAINTREE);
+ if (LENTABLE(MAINTREE)[0xE8] != 0) pState->intel_started = 1;
+
+ READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS);
+ BUILD_TABLE(LENGTH);
+ break;
+
+ case LZX_BLOCKTYPE_UNCOMPRESSED:
+ pState->intel_started = 1; /* because we can't assume otherwise */
+ ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
+ if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
+ R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
+ R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
+ R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
+ break;
+
+ default:
+ return DECR_ILLEGALDATA;
+ }
+ }
+
+ /* buffer exhaustion check */
+ if (inpos > endinp) {
+ /* it's possible to have a file where the next run is less than
+ * 16 bits in size. In this case, the READ_HUFFSYM() macro used
+ * in building the tables will exhaust the buffer, so we should
+ * allow for this, but not allow those accidentally read bits to
+ * be used (so we check that there are at least 16 bits
+ * remaining - in this boundary case they aren't really part of
+ * the compressed data)
+ */
+ if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
+ }
+
+ while ((this_run = pState->block_remaining) > 0 && togo > 0) {
+ if (this_run > togo) this_run = togo;
+ togo -= this_run;
+ pState->block_remaining -= this_run;
+
+ /* apply 2^x-1 mask */
+ window_posn &= window_size - 1;
+ /* runs can't straddle the window wraparound */
+ if ((window_posn + this_run) > window_size)
+ return DECR_DATAFORMAT;
+
+ switch (pState->block_type) {
+
+ case LZX_BLOCKTYPE_VERBATIM:
+ while (this_run > 0) {
+ READ_HUFFSYM(MAINTREE, main_element);
+
+ if (main_element < LZX_NUM_CHARS) {
+ /* literal: 0 to LZX_NUM_CHARS-1 */
+ window[window_posn++] = main_element;
+ this_run--;
+ }
+ else {
+ /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
+ main_element -= LZX_NUM_CHARS;
+
+ match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
+ if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
+ READ_HUFFSYM(LENGTH, length_footer);
+ match_length += length_footer;
+ }
+ match_length += LZX_MIN_MATCH;
+
+ match_offset = main_element >> 3;
+
+ if (match_offset > 2) {
+ /* not repeated offset */
+ if (match_offset != 3) {
+ extra = extra_bits[match_offset];
+ READ_BITS(verbatim_bits, extra);
+ match_offset = position_base[match_offset] - 2 + verbatim_bits;
+ }
+ else {
+ match_offset = 1;
+ }
+
+ /* update repeated offset LRU queue */
+ R2 = R1; R1 = R0; R0 = match_offset;
+ }
+ else if (match_offset == 0) {
+ match_offset = R0;
+ }
+ else if (match_offset == 1) {
+ match_offset = R1;
+ R1 = R0; R0 = match_offset;
+ }
+ else /* match_offset == 2 */ {
+ match_offset = R2;
+ R2 = R0; R0 = match_offset;
+ }
+
+ rundest = window + window_posn;
+ runsrc = rundest - match_offset;
+ window_posn += match_length;
+ if (window_posn > window_size) return DECR_ILLEGALDATA;
+ this_run -= match_length;
+
+ /* copy any wrapped around source data */
+ while ((runsrc < window) && (match_length-- > 0)) {
+ *rundest++ = *(runsrc + window_size); runsrc++;
+ }
+ /* copy match data - no worries about destination wraps */
+ while (match_length-- > 0) *rundest++ = *runsrc++;
+
+ }
+ }
+ break;
+
+ case LZX_BLOCKTYPE_ALIGNED:
+ while (this_run > 0) {
+ READ_HUFFSYM(MAINTREE, main_element);
+
+ if (main_element < LZX_NUM_CHARS) {
+ /* literal: 0 to LZX_NUM_CHARS-1 */
+ window[window_posn++] = main_element;
+ this_run--;
+ }
+ else {
+ /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
+ main_element -= LZX_NUM_CHARS;
+
+ match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
+ if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
+ READ_HUFFSYM(LENGTH, length_footer);
+ match_length += length_footer;
+ }
+ match_length += LZX_MIN_MATCH;
+
+ match_offset = main_element >> 3;
+
+ if (match_offset > 2) {
+ /* not repeated offset */
+ extra = extra_bits[match_offset];
+ match_offset = position_base[match_offset] - 2;
+ if (extra > 3) {
+ /* verbatim and aligned bits */
+ extra -= 3;
+ READ_BITS(verbatim_bits, extra);
+ match_offset += (verbatim_bits << 3);
+ READ_HUFFSYM(ALIGNED, aligned_bits);
+ match_offset += aligned_bits;
+ }
+ else if (extra == 3) {
+ /* aligned bits only */
+ READ_HUFFSYM(ALIGNED, aligned_bits);
+ match_offset += aligned_bits;
+ }
+ else if (extra > 0) { /* extra==1, extra==2 */
+ /* verbatim bits only */
+ READ_BITS(verbatim_bits, extra);
+ match_offset += verbatim_bits;
+ }
+ else /* extra == 0 */ {
+ /* ??? */
+ match_offset = 1;
+ }
+
+ /* update repeated offset LRU queue */
+ R2 = R1; R1 = R0; R0 = match_offset;
+ }
+ else if (match_offset == 0) {
+ match_offset = R0;
+ }
+ else if (match_offset == 1) {
+ match_offset = R1;
+ R1 = R0; R0 = match_offset;
+ }
+ else /* match_offset == 2 */ {
+ match_offset = R2;
+ R2 = R0; R0 = match_offset;
+ }
+
+ rundest = window + window_posn;
+ runsrc = rundest - match_offset;
+ window_posn += match_length;
+ if (window_posn > window_size) return DECR_ILLEGALDATA;
+ this_run -= match_length;
+
+ /* copy any wrapped around source data */
+ while ((runsrc < window) && (match_length-- > 0)) {
+ *rundest++ = *(runsrc + window_size); runsrc++;
+ }
+ /* copy match data - no worries about destination wraps */
+ while (match_length-- > 0) *rundest++ = *runsrc++;
+
+ }
+ }
+ break;
+
+ case LZX_BLOCKTYPE_UNCOMPRESSED:
+ if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
+ memcpy(window + window_posn, inpos, (size_t) this_run);
+ inpos += this_run; window_posn += this_run;
+ break;
+
+ default:
+ return DECR_ILLEGALDATA; /* might as well */
+ }
+
+ }
+ }
+
+ if (togo != 0) return DECR_ILLEGALDATA;
+ memcpy(outpos, window + ((!window_posn) ? window_size : window_posn) - outlen, (size_t) outlen);
+
+ pState->window_posn = window_posn;
+ pState->R0 = R0;
+ pState->R1 = R1;
+ pState->R2 = R2;
+
+ /* intel E8 decoding */
+ if ((pState->frames_read++ < 32768) && pState->intel_filesize != 0) {
+ if (outlen <= 6 || !pState->intel_started) {
+ pState->intel_curpos += outlen;
+ }
+ else {
+ UBYTE *data = outpos;
+ UBYTE *dataend = data + outlen - 10;
+ LONG curpos = pState->intel_curpos;
+ LONG filesize = pState->intel_filesize;
+ LONG abs_off, rel_off;
+
+ pState->intel_curpos = curpos + outlen;
+
+ while (data < dataend) {
+ if (*data++ != 0xE8) { curpos++; continue; }
+ abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
+ if ((abs_off >= -curpos) && (abs_off < filesize)) {
+ rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
+ data[0] = (UBYTE) rel_off;
+ data[1] = (UBYTE) (rel_off >> 8);
+ data[2] = (UBYTE) (rel_off >> 16);
+ data[3] = (UBYTE) (rel_off >> 24);
+ }
+ data += 4;
+ curpos += 5;
+ }
+ }
+ }
+ return DECR_OK;
+}
+
+#ifdef LZX_CHM_TESTDRIVER
+int main(int c, char **v)
+{
+ FILE *fin, *fout;
+ struct LZXstate state;
+ UBYTE ibuf[16384];
+ UBYTE obuf[32768];
+ int ilen, olen;
+ int status;
+ int i;
+ int count=0;
+ int w = atoi(v[1]);
+ LZXinit(&state, w);
+ fout = fopen(v[2], "wb");
+ for (i=3; i<c; i++)
+ {
+ fin = fopen(v[i], "rb");
+ ilen = fread(ibuf, 1, 16384, fin);
+ status = LZXdecompress(&state, ibuf, obuf, ilen, 32768);
+ switch (status)
+ {
+ case DECR_OK:
+ printf("ok\n");
+ fwrite(obuf, 1, 32768, fout);
+ break;
+ case DECR_DATAFORMAT:
+ printf("bad format\n");
+ break;
+ case DECR_ILLEGALDATA:
+ printf("illegal data\n");
+ break;
+ case DECR_NOMEMORY:
+ printf("no memory\n");
+ break;
+ default:
+ break;
+ }
+ fclose(fin);
+ if (++count == 2)
+ {
+ count = 0;
+ LZXreset(&state);
+ }
+ }
+ fclose(fout);
+}
+#endif
diff --git a/lib/chmlib/lzx.h b/lib/chmlib/lzx.h
new file mode 100644
index 0000000..26d71a8
--- /dev/null
+++ b/lib/chmlib/lzx.h
@@ -0,0 +1,62 @@
+/* $Id: lzx.h 148 2007-03-07 09:22:36Z gyunaev $ */
+/***************************************************************************
+ * lzx.h - LZX decompression routines *
+ * ------------------- *
+ * *
+ * maintainer: Jed Wing <jedwin@ugcs.caltech.edu> *
+ * source: modified lzx.c from cabextract v0.5 *
+ * notes: This file was taken from cabextract v0.5, which was, *
+ * itself, a modified version of the lzx decompression code *
+ * from unlzx. *
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 2 of the License, or *
+ * (at your option) any later version. Note that an exemption to this *
+ * license has been granted by Stuart Caie for the purposes of *
+ * distribution with chmlib. This does not, to the best of my *
+ * knowledge, constitute a change in the license of this (the LZX) code *
+ * in general. *
+ * *
+ ***************************************************************************/
+
+#ifndef INCLUDED_LZX_H
+#define INCLUDED_LZX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* return codes */
+#define DECR_OK (0)
+#define DECR_DATAFORMAT (1)
+#define DECR_ILLEGALDATA (2)
+#define DECR_NOMEMORY (3)
+
+/* opaque state structure */
+struct LZXstate;
+
+/* create an lzx state object */
+struct LZXstate *LZXinit(int window);
+
+/* destroy an lzx state object */
+void LZXteardown(struct LZXstate *pState);
+
+/* reset an lzx stream */
+int LZXreset(struct LZXstate *pState);
+
+/* decompress an LZX compressed block */
+int LZXdecompress(struct LZXstate *pState,
+ unsigned char *inpos,
+ unsigned char *outpos,
+ int inlen,
+ int outlen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDED_LZX_H */
diff --git a/lib/kio-msits/Makefile.am b/lib/kio-msits/Makefile.am
new file mode 100644
index 0000000..53f5205
--- /dev/null
+++ b/lib/kio-msits/Makefile.am
@@ -0,0 +1,14 @@
+METASOURCES = AUTO
+INCLUDES = $(QT_INCLUDES) $(CHM_INCLUDES) $(KDE_INCLUDES) $(LIBCHMFILE_INCLUDES)
+
+kde_module_LTLIBRARIES = kio_msits.la
+
+kio_msits_la_SOURCES = msits.cpp
+kio_msits_la_LIBADD = -lkio $(CHM_LIBS)
+kio_msits_la_LDFLAGS = -module -avoid-version $(QT_LIBS) $(KDE_LDFLAGS) $(KDE_LIBS) $(KDE_PLUGIN)
+
+protocol_DATA = msits.protocol
+protocoldir = $(kde_servicesdir)
+
+# Put it here to avoid creating another directory
+kde_apps_DATA = kchmviewer.desktop
diff --git a/lib/kio-msits/kchmviewer.desktop b/lib/kio-msits/kchmviewer.desktop
new file mode 100644
index 0000000..d97098a
--- /dev/null
+++ b/lib/kio-msits/kchmviewer.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Categories=Qt;KDE;Utility;
+Encoding=UTF-8
+Type=Application
+Exec=kchmviewer %U
+Icon=kchmviewer.png
+Comment=
+Terminal=0
+Name=KchmViewer
+Comment=A viewer of CHM (MS-Help) files
+MimeType=application/chm
diff --git a/lib/kio-msits/msits.cpp b/lib/kio-msits/msits.cpp
new file mode 100755
index 0000000..cf7cf27
--- /dev/null
+++ b/lib/kio-msits/msits.cpp
@@ -0,0 +1,320 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kinstance.h>
+#include <kurl.h>
+#include <kmimemagic.h>
+
+#include <qfile.h>
+#include <qbitarray.h>
+#include <qvaluevector.h>
+
+#include "msits.h"
+#include "libchmurlfactory.h"
+
+using namespace KIO;
+
+extern "C"
+{
+ int kdemain( int argc, char **argv )
+ {
+ kdDebug() << "*** kio_msits Init" << endl;
+
+ KInstance instance( "kio_msits" );
+
+ if ( argc != 4 )
+ {
+ kdDebug() << "Usage: kio_msits protocol domain-socket1 domain-socket2" << endl;
+ exit (-1);
+ }
+
+ ProtocolMSITS slave ( argv[2], argv[3] );
+ slave.dispatchLoop();
+
+ kdDebug() << "*** kio_msits Done" << endl;
+ return 0;
+ }
+}
+
+ProtocolMSITS::ProtocolMSITS (const QCString &pool_socket, const QCString &app_socket)
+ : SlaveBase ("kio_msits", pool_socket, app_socket)
+{
+ m_chmFile = 0;
+}
+
+ProtocolMSITS::~ProtocolMSITS()
+{
+ if ( !m_chmFile )
+ return;
+
+ chm_close (m_chmFile);
+ m_chmFile = 0;
+}
+
+// A simple stat() wrapper
+static bool isDirectory ( const QString & filename )
+{
+ return filename[filename.length() - 1] == '/';
+}
+
+
+void ProtocolMSITS::get( const KURL& url )
+{
+ QString htmdata, fileName;
+ chmUnitInfo ui;
+ QByteArray buf;
+
+ kdDebug() << "kio_msits::get() " << url.path() << endl;
+
+ if ( !parseLoadAndLookup ( url, fileName ) )
+ return; // error() has been called by parseLoadAndLookup
+
+ kdDebug() << "kio_msits::get: parseLoadAndLookup returned " << fileName << endl;
+
+ if ( LCHMUrlFactory::handleFileType( url.path(), htmdata ) )
+ {
+ buf = htmdata.utf8();
+ kdDebug() << "Using special handling for image pages: " << htmdata << endl;
+ }
+ else
+ {
+ if ( isDirectory (fileName) )
+ {
+ error( KIO::ERR_IS_DIRECTORY, url.prettyURL() );
+ return;
+ }
+
+ if ( !ResolveObject ( fileName, &ui) )
+ {
+ kdDebug() << "kio_msits::get: could not resolve filename " << fileName << endl;
+ error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
+ return;
+ }
+
+ buf.resize( ui.length );
+
+ if ( RetrieveObject (&ui, (unsigned char*) buf.data(), 0, ui.length) == 0 )
+ {
+ kdDebug() << "kio_msits::get: could not retrieve filename " << fileName << endl;
+ error( KIO::ERR_NO_CONTENT, url.prettyURL() );
+ return;
+ }
+ }
+
+ totalSize( buf.size() );
+ KMimeMagicResult * result = KMimeMagic::self()->findBufferFileType( buf, fileName );
+ kdDebug() << "Emitting mimetype " << result->mimeType() << endl;
+
+ mimeType( result->mimeType() );
+ data( buf );
+ processedSize( buf.size() );
+
+ finished();
+}
+
+
+bool ProtocolMSITS::parseLoadAndLookup ( const KURL& url, QString& abspath )
+{
+ kdDebug() << "ProtocolMSITS::parseLoadAndLookup (const KURL&) " << url.path() << endl;
+
+ int pos = url.path().find ("::");
+
+ if ( pos == -1 )
+ {
+ error( KIO::ERR_MALFORMED_URL, url.prettyURL() );
+ return false;
+ }
+
+ QString filename = url.path().left (pos);
+ abspath = url.path().mid (pos + 2); // skip ::
+
+ // Some buggy apps add ms-its:/ to the path as well
+ if ( abspath.startsWith( "ms-its:" ) )
+ abspath = abspath.mid( 7 );
+
+ kdDebug() << "ProtocolMSITS::parseLoadAndLookup: filename " << filename << ", path " << abspath << endl;
+
+ if ( filename.isEmpty() )
+ {
+ error( KIO::ERR_MALFORMED_URL, url.prettyURL() );
+ return false;
+ }
+
+ // If the file has been already loaded, nothing to do.
+ if ( m_chmFile && filename == m_openedFile )
+ return true;
+
+ kdDebug() << "Opening a new CHM file " << filename << endl;
+
+ // First try to open a temporary file
+ chmFile * tmpchm;
+
+ if ( (tmpchm = chm_open ( QFile::encodeName (filename))) == 0 )
+ {
+ error( KIO::ERR_COULD_NOT_READ, url.prettyURL() );
+ return false;
+ }
+
+ // Replace an existing file by a new one
+ if ( m_chmFile )
+ chm_close (m_chmFile);
+
+ m_chmFile = tmpchm;
+ m_openedFile = filename;
+
+ kdDebug() << "A CHM file " << filename << " has beed opened successfully" << endl;
+ return true;
+}
+
+/*
+ * Shamelessly stolen from a KDE KIO tutorial
+ */
+static void app_entry(UDSEntry& e, unsigned int uds, const QString& str)
+{
+ UDSAtom a;
+ a.m_uds = uds;
+ a.m_str = str;
+ e.append(a);
+}
+
+ // appends an int with the UDS-ID uds
+ static void app_entry(UDSEntry& e, unsigned int uds, long l)
+ {
+ UDSAtom a;
+ a.m_uds = uds;
+ a.m_long = l;
+ e.append(a);
+}
+
+// internal function
+// fills a directory item with its name and size
+static void app_dir(UDSEntry& e, const QString & name)
+{
+ e.clear();
+ app_entry(e, KIO::UDS_NAME, name);
+ app_entry(e, KIO::UDS_FILE_TYPE, S_IFDIR);
+ app_entry(e, KIO::UDS_SIZE, 1);
+}
+
+// internal function
+// fills a file item with its name and size
+static void app_file(UDSEntry& e, const QString & name, size_t size)
+{
+ e.clear();
+ app_entry(e, KIO::UDS_NAME, name);
+ app_entry(e, KIO::UDS_FILE_TYPE, S_IFREG);
+ app_entry(e, KIO::UDS_SIZE, size);
+}
+
+void ProtocolMSITS::stat (const KURL & url)
+{
+ QString fileName;
+ chmUnitInfo ui;
+
+ kdDebug() << "kio_msits::stat (const KURL& url) " << url.path() << endl;
+
+ if ( !parseLoadAndLookup ( url, fileName ) )
+ return; // error() has been called by parseLoadAndLookup
+
+ if ( !ResolveObject ( fileName, &ui ) )
+ {
+ error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
+ return;
+ }
+
+ kdDebug() << "kio_msits::stat: adding an entry for " << fileName << endl;
+ UDSEntry entry;
+
+ if ( isDirectory ( fileName ) )
+ app_dir(entry, fileName);
+ else
+ app_file(entry, fileName, ui.length);
+
+ statEntry (entry);
+
+ finished();
+}
+
+
+// A local CHMLIB enumerator
+static int chmlib_enumerator (struct chmFile *, struct chmUnitInfo *ui, void *context)
+{
+ ((QValueVector<QString> *) context)->push_back (QString::fromLocal8Bit (ui->path));
+ return CHM_ENUMERATOR_CONTINUE;
+}
+
+
+void ProtocolMSITS::listDir (const KURL & url)
+{
+ QString filepath;
+
+ kdDebug() << "kio_msits::listDir (const KURL& url) " << url.path() << endl;
+
+ if ( !parseLoadAndLookup ( url, filepath ) )
+ return; // error() has been called by parseLoadAndLookup
+
+ filepath += "/";
+
+ if ( !isDirectory (filepath) )
+ {
+ error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path());
+ return;
+ }
+
+ kdDebug() << "kio_msits::listDir: enumerating directory " << filepath << endl;
+
+ QValueVector<QString> listing;
+
+ if ( chm_enumerate_dir ( m_chmFile,
+ filepath.local8Bit(),
+ CHM_ENUMERATE_NORMAL | CHM_ENUMERATE_FILES | CHM_ENUMERATE_DIRS,
+ chmlib_enumerator,
+ &listing ) != 1 )
+ {
+ error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path());
+ return;
+ }
+
+ UDSEntry entry;
+ unsigned int striplength = filepath.length();
+
+ for ( unsigned int i = 0; i < listing.size(); i++ )
+ {
+ // Strip the direcroty name
+ QString ename = listing[i].mid (striplength);
+
+ if ( isDirectory ( ename ) )
+ app_dir(entry, ename);
+ else
+ app_file(entry, ename, 0);
+
+ listEntry(entry, false);
+ }
+
+ listEntry(entry, true);
+ finished();
+}
diff --git a/lib/kio-msits/msits.h b/lib/kio-msits/msits.h
new file mode 100755
index 0000000..3de7719
--- /dev/null
+++ b/lib/kio-msits/msits.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ * Copyright (C) 2004-2005 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef MSITS_H
+#define MSITS_H
+
+
+#include <kio/slavebase.h>
+#include <kurl.h>
+
+#include <qstring.h>
+#include <qcstring.h>
+
+#include "config.h"
+#include "chm_lib.h"
+
+
+class ProtocolMSITS : public KIO::SlaveBase
+{
+public:
+ ProtocolMSITS ( const QCString&, const QCString& );
+ virtual ~ProtocolMSITS();
+
+ virtual void get ( const KURL& );
+ virtual void listDir (const KURL & url);
+ virtual void stat (const KURL & url);
+
+private:
+ // This function does next thing:
+ // - parses the URL to get a file name and URL inside the file;
+ // - loads a new CHM file, if needed;
+ // - returns the parsed URL inside the file;
+ bool parseLoadAndLookup ( const KURL&, QString& abspath );
+
+ // Resolve an object inside a CHM file
+ inline bool ResolveObject (const QString& fileName, chmUnitInfo *ui)
+ {
+ return m_chmFile != NULL && ::chm_resolve_object(m_chmFile, fileName.utf8(), ui) == CHM_RESOLVE_SUCCESS;
+ }
+
+ // Retrieve an object from the CHM file
+ inline size_t RetrieveObject (const chmUnitInfo *ui, unsigned char *buffer, LONGUINT64 fileOffset, LONGINT64 bufferSize)
+ {
+#if USE_BUILTIN_CHMLIB
+ return ::chm_retrieve_object(m_chmFile, ui, buffer,
+ fileOffset, bufferSize);
+#else
+ return ::chm_retrieve_object(m_chmFile, const_cast<chmUnitInfo*>(ui),
+ buffer, fileOffset, bufferSize);
+#endif
+ }
+
+ // An opened file name, if presend
+ QString m_openedFile;
+
+ // a CHM structure file pointer (from chmlib)
+ chmFile * m_chmFile;
+};
+
+
+#endif /* MSITS_H */
diff --git a/lib/kio-msits/msits.protocol b/lib/kio-msits/msits.protocol
new file mode 100755
index 0000000..b087903
--- /dev/null
+++ b/lib/kio-msits/msits.protocol
@@ -0,0 +1,24 @@
+[Protocol]
+exec=kio_msits
+protocol=ms-its
+input=none
+output=filesystem
+reading=true
+listing=Name,Type,Size
+defaultMimetype=text/html
+Description=A kioslave for displaying WinHelp files
+Description[da]=En kioslave til visning af Windows hjælpefiler
+Description[de]=Ein Ein-/Ausgabemodul zur Anzeige von WinHelp-Dateien
+Description[es]=Un kioslave para mostrar archivos WinHelp
+Description[et]=WinHelp-failide kuvamise IO-moodul
+Description[fr]=Un module d'entrée / sortie pour l'affichage des fichiers WinHelp
+Description[hu]=KDE-protokoll WinHelp-fájlok megjelenítéséhez
+Description[it]=Un kioslave per mostrare i file WinHelp
+Description[nl]=Een kioslave voor het weergeven van WinHelp-bestanden
+Description[pl]=kioslave do pokazywania plików WinHelp
+Description[pt]=A 'kioslave' para mostrar ficheiros WinHelp
+Description[pt_BR]=Um kioslave para exibir arquivos WinHelp
+Description[ru]=Обработчик ввода-вывода для файлов WinHelp
+Description[sv]=En I/O-slav för att visa WinHelp-filer
+Description[xx]=xxA kioslave for displaying WinHelp filesxx
+Icon=help
diff --git a/lib/libchmfile/Makefile.am b/lib/libchmfile/Makefile.am
new file mode 100644
index 0000000..2e16016
--- /dev/null
+++ b/lib/libchmfile/Makefile.am
@@ -0,0 +1,10 @@
+lib_LIBRARIES=libchmfile.a
+libchmfile_a_SOURCES = libchmfile.cpp libchmfile_search.cpp libchmfileimpl.cpp \
+ libchmtextencoding.cpp libchmtocimage.cpp
+noinst_HEADERS = libchmfile.h bitfiddle.h libchmfileimpl.h libchmtextencoding.h \
+ libchmtocimage.h libchmurlfactory.h
+
+INCLUDES = $(QT_INCLUDES) $(CHM_INCLUDES) $(KDE_INCLUDES)
+
+METASOURCES = AUTO
+KDE_OPTIONS = qtonly
diff --git a/lib/libchmfile/bitfiddle.h b/lib/libchmfile/bitfiddle.h
new file mode 100644
index 0000000..cd97b8e
--- /dev/null
+++ b/lib/libchmfile/bitfiddle.h
@@ -0,0 +1,155 @@
+/*
+
+ Copyright (C) 2003 Razvan Cojocaru <razvanco@gmx.net>
+ Most of the code in this file is a modified version of code from
+ Pabs' GPL chmdeco project, credits and thanks go to him.
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+
+#define UINT16ARRAY(x) ((unsigned char)(x)[0] | ((u_int16_t)(x)[1] << 8))
+#define UINT32ARRAY(x) (UINT16ARRAY(x) | ((u_int32_t)(x)[2] << 16) \
+ | ((u_int32_t)(x)[3] << 24))
+
+inline unsigned int get_int32_le( void *addr)
+{
+ unsigned char *p = (unsigned char*) addr;
+ return (unsigned int) ( p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24) );
+}
+
+
+inline u_int64_t be_encint(unsigned char* buffer, size_t& length)
+{
+ u_int64_t result = 0;
+ int shift=0;
+ length = 0;
+
+ do {
+ result |= ((*buffer) & 0x7f) << shift;
+ shift += 7;
+ ++length;
+
+ } while (*(buffer++) & 0x80);
+
+ return result;
+}
+
+
+/*
+ Finds the first unset bit in memory. Returns the number of set bits found.
+ Returns -1 if the buffer runs out before we find an unset bit.
+*/
+inline int ffus(unsigned char* byte, int* bit, size_t& length)
+{
+ int bits = 0;
+ length = 0;
+
+ while(*byte & (1 << *bit)){
+ if(*bit)
+ --(*bit);
+ else {
+ ++byte;
+ ++length;
+ *bit = 7;
+ }
+ ++bits;
+ }
+
+ if(*bit)
+ --(*bit);
+ else {
+ ++length;
+ *bit = 7;
+ }
+
+ return bits;
+}
+
+
+inline u_int64_t sr_int(unsigned char* byte, int* bit,
+ unsigned char s, unsigned char r, size_t& length)
+{
+ u_int64_t ret;
+ unsigned char mask;
+ int n, n_bits, num_bits, base, count;
+ length = 0;
+ size_t fflen;
+
+ if(!bit || *bit > 7 || s != 2)
+ return ~(u_int64_t)0;
+ ret = 0;
+
+ count = ffus(byte, bit, fflen);
+ length += fflen;
+ byte += length;
+
+ n_bits = n = r + (count ? count-1 : 0) ;
+
+ while(n > 0) {
+ num_bits = n > *bit ? *bit : n-1;
+ base = n > *bit ? 0 : *bit - (n-1);
+
+ switch(num_bits){
+ case 0:
+ mask = 1;
+ break;
+ case 1:
+ mask = 3;
+ break;
+ case 2:
+ mask = 7;
+ break;
+ case 3:
+ mask = 0xf;
+ break;
+ case 4:
+ mask = 0x1f;
+ break;
+ case 5:
+ mask = 0x3f;
+ break;
+ case 6:
+ mask = 0x7f;
+ break;
+ case 7:
+ mask = 0xff;
+ break;
+ default:
+ mask = 0xff;
+ break;
+ }
+
+ mask <<= base;
+ ret = (ret << (num_bits+1)) |
+ (u_int64_t)((*byte & mask) >> base);
+
+ if( n > *bit ){
+ ++byte;
+ ++length;
+ n -= *bit+1;
+ *bit = 7;
+ } else {
+ *bit -= n;
+ n = 0;
+ }
+ }
+
+ if(count)
+ ret |= (u_int64_t)1 << n_bits;
+
+ return ret;
+}
diff --git a/lib/libchmfile/lchmurlhandler.cpp b/lib/libchmfile/lchmurlhandler.cpp
new file mode 100644
index 0000000..6e905f6
--- /dev/null
+++ b/lib/libchmfile/lchmurlhandler.cpp
@@ -0,0 +1,32 @@
+/***************************************************************************
+ * Copyright (C) 2004-2005 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "lchmurlhandler.h"
+
+LCHMUrlHandler::LCHMUrlHandler()
+{
+}
+
+
+LCHMUrlHandler::~LCHMUrlHandler()
+{
+}
+
+
diff --git a/lib/libchmfile/lchmurlhandler.h b/lib/libchmfile/lchmurlhandler.h
new file mode 100644
index 0000000..9eb29ec
--- /dev/null
+++ b/lib/libchmfile/lchmurlhandler.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef LCHMURLHANDLER_H
+#define LCHMURLHANDLER_H
+
+/**
+ @author tim <tim@krasnogorsk.ru>
+*/
+class LCHMUrlHandler{
+public:
+ LCHMUrlHandler();
+
+ ~LCHMUrlHandler();
+
+};
+
+#endif
diff --git a/lib/libchmfile/libchmfile.cpp b/lib/libchmfile/libchmfile.cpp
new file mode 100644
index 0000000..7d13aaa
--- /dev/null
+++ b/lib/libchmfile/libchmfile.cpp
@@ -0,0 +1,125 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "libchmfile.h"
+#include "libchmfileimpl.h"
+
+
+LCHMFile::LCHMFile( )
+{
+ m_impl = new LCHMFileImpl();
+}
+
+LCHMFile::~ LCHMFile( )
+{
+ delete m_impl;
+}
+
+bool LCHMFile::loadFile( const QString & archiveName )
+{
+ return m_impl->loadFile( archiveName );
+}
+
+void LCHMFile::closeAll( )
+{
+ m_impl->closeAll();
+}
+
+QString LCHMFile::title( ) const
+{
+ return m_impl->title();
+}
+
+QString LCHMFile::homeUrl( ) const
+{
+ QString url = m_impl->homeUrl();
+ return url.isNull() ? "/" : url;
+}
+
+bool LCHMFile::hasTableOfContents( ) const
+{
+ return !m_impl->m_topicsFile.isNull();
+}
+
+bool LCHMFile::hasIndexTable( ) const
+{
+ return !m_impl->m_indexFile.isNull();
+}
+
+bool LCHMFile::hasSearchTable( ) const
+{
+ return m_impl->m_searchAvailable;
+}
+
+bool LCHMFile::parseTableOfContents( QT34VECTOR< LCHMParsedEntry > * topics ) const
+{
+ return m_impl->parseFileAndFillArray( m_impl->m_topicsFile, topics, false );
+}
+
+bool LCHMFile::parseIndex( QT34VECTOR< LCHMParsedEntry > * indexes ) const
+{
+ return m_impl->parseFileAndFillArray( m_impl->m_indexFile, indexes, true );
+}
+
+bool LCHMFile::getFileContentAsString( QString * str, const QString & url )
+{
+ return m_impl->getFileContentAsString( str, url );
+}
+
+bool LCHMFile::getFileContentAsBinary( QByteArray * data, const QString & url )
+{
+ return m_impl->getFileContentAsBinary( data, url );
+}
+
+bool LCHMFile::enumerateFiles( QStringList * files )
+{
+ return m_impl->enumerateFiles( files );
+}
+
+QString LCHMFile::getTopicByUrl( const QString & url )
+{
+ return m_impl->getTopicByUrl( url );
+}
+
+const QPixmap * LCHMFile::getBookIconPixmap( unsigned int imagenum )
+{
+ return m_impl->getBookIconPixmap( imagenum );
+}
+
+const LCHMTextEncoding * LCHMFile::currentEncoding( ) const
+{
+ return m_impl->m_currentEncoding;
+}
+
+bool LCHMFile::setCurrentEncoding( const LCHMTextEncoding * encoding )
+{
+ return m_impl->setCurrentEncoding( encoding );
+}
+
+QString LCHMFile::normalizeUrl( const QString & url ) const
+{
+ return m_impl->normalizeUrl( url );
+}
+
+bool LCHMFile::getFileSize(unsigned int * size, const QString & url)
+{
+ return m_impl->getFileSize( size, url );
+}
diff --git a/lib/libchmfile/libchmfile.h b/lib/libchmfile/libchmfile.h
new file mode 100644
index 0000000..ab129b5
--- /dev/null
+++ b/lib/libchmfile/libchmfile.h
@@ -0,0 +1,290 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef INCLUDE_LIBCHMFILE_H
+#define INCLUDE_LIBCHMFILE_H
+
+#include <qstring.h>
+#include <qcstring.h>
+#include <qlistview.h>
+#include <qlistbox.h>
+#include <qmap.h>
+#include <qvaluevector.h>
+#include <qtextcodec.h>
+
+#include "libchmtextencoding.h"
+
+// Qt3/Qt4 compatibility: in Qt3 QVector stores pointers, not values - so QValueVector should be used.
+// In Qt4 QVector stores values, so we can use QVector
+#if defined (USE_QT_4)
+ #define QT34VECTOR QVector
+#else
+ #define QT34VECTOR QValueVector
+#endif
+
+
+//! Contains different (non-standard) image types
+namespace LCHMBookIcons
+{
+ const int IMAGE_NONE = -1;
+ const int IMAGE_AUTO = -2;
+ const int IMAGE_INDEX = -3;
+
+ const int MAX_BUILTIN_ICONS = 42;
+};
+
+
+//! Contains a single index or TOC entry. See LCHMFile::parseTOC() and LCHMFile::parseIndex()
+typedef struct
+{
+ //! Entry name
+ QString name;
+
+ //! Entry URLs. The TOC entry should have only one URL; the index entry could have several.
+ QStringList urls;
+
+ //! Associated image number. Used for TOC only; indexes does not have the image.
+ //! Use LCHMFile::getBookIconPixmap() to get associated pixmap icon
+ int imageid;
+
+ //! Indentation level for this entry.
+ int indent;
+
+} LCHMParsedEntry;
+
+
+// forward declaration
+class LCHMFileImpl;
+
+//! CHM files processor, heavily based on chmlib. Used search code from xchm.
+class LCHMFile
+{
+ public:
+ //! Default constructor and destructor.
+ LCHMFile();
+ ~LCHMFile();
+
+ /*!
+ * \brief Attempts to load a .chm file.
+ * \param archiveName The .chm filename.
+ * \return true on success, false on failure.
+ *
+ * Loads a CHM file. Could internally load more than one file, if files linked to
+ * this one are present locally (like MSDN).
+ * \ingroup init
+ */
+ bool loadFile( const QString& archiveName );
+
+ /*!
+ * \brief Closes all the files, and frees the appropriate data.
+ * \ingroup init
+ */
+ void closeAll();
+
+ /*!
+ * \brief Gets the title name of the opened .chm.
+ * \return The name of the opened document, or an empty string if no .chm has been loaded.
+ * \ingroup information
+ */
+ QString title() const;
+
+ /*!
+ * \brief Gets the URL of the default page in the chm archive.
+ * \return The home page name, with a '/' added in front and relative to
+ * the root of the archive filesystem. If no .chm has been opened,
+ * returns "/".
+ * \ingroup information
+ */
+ QString homeUrl() const;
+
+ /*!
+ * \brief Checks whether the Table of Contents is present in this file.
+ * \return true if it is available; false otherwise.
+ * \ingroup information
+ */
+ bool hasTableOfContents() const;
+
+ /*!
+ * \brief Checks whether the Index Table is present in this file.
+ * \return true if it is available; false otherwise.
+ * \ingroup information
+ */
+ bool hasIndexTable() const;
+
+ /*!
+ * \brief Checks whether the Search Table is available in this file.
+ * \return true if it is available; false otherwise.
+ * \ingroup information
+ *
+ * If the search table is not available, the search is not possible.
+ */
+ bool hasSearchTable() const;
+
+ /*!
+ * \brief Parses the Table of Contents (TOC)
+ * \param topics A pointer to the container which will store the parsed results.
+ * Will be cleaned before parsing.
+ * \return true if the tree is present and parsed successfully, false otherwise.
+ * The parser is built to be error-prone, however it still can abort with qFatal()
+ * by really buggy chm file; please report a bug if the file is opened ok under Windows.
+ * \ingroup fileparsing
+ */
+ bool parseTableOfContents( QT34VECTOR< LCHMParsedEntry > * topics ) const;
+
+ /*!
+ * \brief Parses the Index Table
+ * \param indexes A pointer to the container which will store the parsed results.
+ * Will be cleaned before parsing.
+ * \return true if the tree is present and parsed successfully, false otherwise.
+ * The parser is built to be error-prone, however it still can abort with qFatal()
+ * by really buggy chm file; so far it never happened on indexes.
+ * \ingroup fileparsing
+ */
+ bool parseIndex( QT34VECTOR< LCHMParsedEntry > * indexes ) const;
+
+ /*!
+ * \brief Retrieves the content from url in current chm file to QString.
+ * \param str A string where the retreived content should be stored.
+ * \param url An URL in chm file to retreive content from. Must be absolute.
+ * \return true if the content is successfully received; false otherwise.
+ *
+ * This function retreives the file content (mostly for HTML pages) from the chm archive
+ * opened by load() function. Because the content in chm file is not stored in Unicode, it
+ * will be recoded according to current encoding. Do not use for binary data.
+ *
+ * \sa setCurrentEncoding() currentEncoding() getFileContentAsBinary()
+ * \ingroup dataretrieve
+ */
+ bool getFileContentAsString( QString * str, const QString& url );
+
+ /*!
+ * \brief Retrieves the content from url in current chm file to QByteArray.
+ * \param data A data array where the retreived content should be stored.
+ * \param url An URL in chm file to retreive content from. Must be absolute.
+ * \return true if the content is successfully received; false otherwise.
+ *
+ * This function retreives the file content from the chm archive opened by load()
+ * function. The content is not encoded.
+ *
+ * \sa getFileContentAsString()
+ * \ingroup dataretrieve
+ */
+ bool getFileContentAsBinary( QByteArray * data, const QString& url );
+
+ /*!
+ * \brief Retrieves the content size.
+ * \param size A pointer where the size will be stored.
+ * \param url An URL in chm file to retreive content from. Must be absolute.
+ * \return true if the content size is successfully stored; false otherwise.
+ *
+ * \ingroup dataretrieve
+ */
+ bool getFileSize( unsigned int * size, const QString& url );
+
+ /*!
+ * \brief Obtains the list of all the files in current chm file archive.
+ * \param files An array to store list of URLs (file names) present in chm archive.
+ * \return true if the enumeration succeed; false otherwise (I could hardly imagine a reason).
+ *
+ * \ingroup dataretrieve
+ */
+ bool enumerateFiles( QStringList * files );
+
+ /*!
+ * \brief Gets the Title of the HTML page referenced by url.
+ * \param url An URL in chm file to get title from. Must be absolute.
+ * \return The title, or QString::null if the URL cannot be found or not a HTML page.
+ *
+ * \ingroup dataretrieve
+ */
+ QString getTopicByUrl ( const QString& url );
+
+ /*!
+ * \brief Gets the appropriate CHM pixmap icon.
+ * \param imagenum The image number from TOC.
+ * \return The pixmap to show in TOC tree.
+ *
+ * \ingroup dataretrieve
+ */
+ const QPixmap * getBookIconPixmap( unsigned int imagenum );
+
+ /*!
+ * \brief Normalizes the URL, converting relatives, adding "/" in front and removing ..
+ * \param url The URL to normalize.
+ * \return The normalized, cleaned up URL.
+ *
+ * \ingroup dataretrieve
+ */
+ QString normalizeUrl( const QString& url ) const;
+
+ /*!
+ * \brief Gets the current CHM archive encoding (set or autodetected)
+ * \return The current encoding.
+ *
+ * \ingroup encoding
+ */
+ const LCHMTextEncoding * currentEncoding() const;
+
+ /*!
+ * \brief Sets the CHM archive encoding to use
+ * \param encoding An encoding to use.
+ *
+ * \ingroup encoding
+ */
+ bool setCurrentEncoding ( const LCHMTextEncoding * encoding );
+
+ /*!
+ * \brief Execute a search query, return the results.
+ * \param query A search query.
+ * \param results An array to store URLs where the query was found.
+ * \return true if search was successful (this does not mean that it returned any results);
+ * false otherwise.
+ *
+ * This function executes a standard search query. The query should consist of one of more
+ * words separated by a space with a possible prefix. A prefix may be:
+ * + Plus indicates that the word is required; any page without this word is excluded from the result.
+ * - Minus indicates that the word is required to be absent; any page with this word is excluded from
+ * the result.
+ * "." Quotes indicates a phrase. Anything between quotes is a phrase, which is set of space-separated
+ * words. Will be in result only if the words in phrase are in page in the same sequence, and
+ * follow each other.
+ *
+ * If there is no prefix, the word considered as required.
+ * \ingroup search
+ */
+ bool searchQuery ( const QString& query, QStringList * results, unsigned int limit = 100 );
+
+ //! Access to implementation
+ LCHMFileImpl * impl() { return m_impl; }
+
+ private:
+ //! No copy construction allowed.
+ LCHMFile( const LCHMFile& );
+
+ //! No assignments allowed.
+ LCHMFile& operator=( const LCHMFile& );
+
+ //! Implementation
+ LCHMFileImpl * m_impl;
+};
+
+
+#endif // INCLUDE_LIBCHMFILE_H
diff --git a/lib/libchmfile/libchmfile_search.cpp b/lib/libchmfile/libchmfile_search.cpp
new file mode 100644
index 0000000..41acfb3
--- /dev/null
+++ b/lib/libchmfile/libchmfile_search.cpp
@@ -0,0 +1,289 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <qregexp.h>
+
+#include "libchmfile.h"
+#include "libchmfileimpl.h"
+
+//#define DEBUG_SEARCH(A) qDebug A
+#define DEBUG_SEARCH(A)
+
+
+static inline void validateWord ( QString & word, bool & query_valid )
+{
+ QRegExp rxvalid ("[^\\d\\w_\\.]+");
+
+ QString orig = word;
+ word.remove ( rxvalid );
+
+ if ( word != orig )
+ query_valid = false;
+}
+
+static inline void validateWords ( QStringList & wordlist, bool & query_valid )
+{
+ QRegExp rxvalid ("[^\\d\\w_\\.]+");
+
+ for ( unsigned int i = 0; i < wordlist.size(); i++ )
+ validateWord ( wordlist[i], query_valid );
+}
+
+
+inline static void mergeResults ( LCHMSearchProgressResults & results, const LCHMSearchProgressResults & src, bool add )
+{
+ if ( results.empty() && add )
+ {
+ results = src;
+ return;
+ }
+
+ for ( unsigned int s1 = 0; s1 < results.size(); s1++ )
+ {
+ bool found = false;
+
+ for ( unsigned int s2 = 0; s2 < src.size(); s2++ )
+ {
+ if ( results[s1].urloff == src[s2].urloff )
+ {
+ found = true;
+ break;
+ }
+ }
+
+ // If we're adding, we only add the items found (i.e. any item, which is not found, is removed.
+ // But if we're removing, we only remove the items found.
+ if ( (found && !add) || (!found && add) )
+ {
+ results.erase ( results.begin() + s1 );
+ s1--;
+ }
+ }
+}
+
+
+static inline void findNextWords ( QT34VECTOR<u_int64_t> & src, const QT34VECTOR<u_int64_t> & needle )
+{
+ for ( unsigned int s1 = 0; s1 < src.size(); s1++ )
+ {
+ bool found = false;
+ u_int64_t target_offset = src[s1] + 1;
+
+ DEBUG_SEARCH (("Offset loop: offset at %u is %u, target %u", (unsigned int) s1,
+ (unsigned int) src[s1], (unsigned int) target_offset));
+
+ // Search in the offsets list in attempt to find next word
+ for ( unsigned int s2 = 0; s2 < needle.size(); s2++ )
+ {
+ if ( needle[s2] == target_offset )
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if ( !found )
+ {
+ // Remove this offset, we don't need it anymore
+ DEBUG_SEARCH (("Offset loop failed: offset %u not found", (unsigned int) target_offset));
+ src.erase ( src.begin() + s1 );
+ s1--;
+ }
+ else
+ {
+ DEBUG_SEARCH (("Offset loop succeed: offset %u found", (unsigned int) target_offset));
+ src[s1]++;
+ }
+ }
+}
+
+
+inline bool searchPhrase( LCHMFileImpl * impl, const QStringList & phrase, LCHMSearchProgressResults & results )
+{
+ // Accumulate the phrase data here.
+ LCHMSearchProgressResults phrasekeeper;
+
+ // On the first word, just fill the phrasekeeper with every occupence of the first word
+ DEBUG_SEARCH (("Search word(0): '%s'", phrase[0].ascii()));
+ if ( !impl->searchWord ( phrase[0], true, false, phrasekeeper, true ) )
+ return false; // the word not found, so the whole phrase is not found either.
+
+ for ( unsigned int i = 1; i < phrase.size(); i++ )
+ {
+ LCHMSearchProgressResults srchtmp;
+
+ DEBUG_SEARCH (("Search word(%d): '%s'", i, phrase[i].ascii()));
+ if ( !impl->searchWord ( phrase[i], true, false, srchtmp, true ) )
+ return false; // the ith word not found, so the whole phrase is not found either.
+
+ // Iterate the both arrays, and remove every word in phrasekeeper, which is not found
+ // in the srchtmp, or is found on a different position.
+ for ( unsigned int p1 = 0; p1 < phrasekeeper.size(); p1++ )
+ {
+ bool found = false;
+
+ DEBUG_SEARCH (("Ext loop (it %d): urloff %d", p1, phrasekeeper[p1].urloff));
+
+ for ( unsigned int p2 = 0; p2 < srchtmp.size(); p2++ )
+ {
+ // look up for words on the the same page
+ if ( srchtmp[p2].urloff != phrasekeeper[p1].urloff )
+ continue;
+
+ // Now check every offset to find the one which is 1 bigger than the
+ findNextWords ( phrasekeeper[p1].offsets, srchtmp[p2].offsets );
+
+ // If at least one next word is found, we leave the block intact, otherwise remove it.
+ if ( !phrasekeeper[p1].offsets.empty() )
+ found = true;
+ }
+
+ if ( !found )
+ {
+ DEBUG_SEARCH (("Ext loop: this word not found on %d, remove it", phrasekeeper[p1].urloff));
+ phrasekeeper.erase ( phrasekeeper.begin() + p1 );
+ p1--;
+ }
+ }
+ }
+
+ for ( unsigned int o = 0; o < phrasekeeper.size(); o++ )
+ results.push_back ( LCHMSearchProgressResult (phrasekeeper[o].titleoff, phrasekeeper[o].urloff) );
+
+ return !results.empty();
+}
+
+
+
+bool LCHMFile::searchQuery( const QString& inquery, QStringList * searchresults, unsigned int limit )
+{
+ QStringList words_must_exist, words_must_not_exist, words_highlight;
+ QT34VECTOR<QStringList> phrases_must_exist;
+ QString query = inquery;
+ bool query_valid = true;
+ LCHMSearchProgressResults results;
+ int pos;
+ unsigned int i;
+
+ /*
+ * Parse the search query with a simple state machine.
+ * Query should consist of one of more words separated by a space with a possible prefix.
+ * A prefix may be:
+ * + indicates that the word is required; any page without this word is excluded from the result.
+ * - indicates that the word is required to be absent; any page with this word is excluded from
+ * the result.
+ * "." indicates a phrase. Anything between quotes indicates a phrase, which is set of space-separated
+ * words. Will be in result only if the words in phrase are in page in the same sequence, and
+ * follow each other.
+ * If there is no prefix, the word considered as required.
+ */
+
+ QRegExp rxphrase( "\"(.*)\"" );
+ QRegExp rxword( "([^\\s]+)" );
+ rxphrase.setMinimal( TRUE );
+
+ // First, get the phrase queries
+ while ( (pos = rxphrase.search (query, 0)) != -1 )
+ {
+ // A phrase query found. Locate its boundaries, and parse it.
+ QStringList plist = QStringList::split ( QRegExp ("\\s+"), rxphrase.cap ( 1 ));
+
+ validateWords ( plist, query_valid );
+
+ if ( plist.size() > 0 )
+ phrases_must_exist.push_back( plist );
+
+ query.remove (pos, rxphrase.matchedLength());
+ }
+
+ // Then, parse the rest query
+ while ( (pos = rxword.search (query, 0)) != -1 )
+ {
+ // A phrase query found. Locate its boundaries, and parse it.
+ QString word = rxword.cap ( 1 );
+ QChar type = '+';
+
+ if ( word[0] == '-' || word[0] == '+' )
+ {
+ type = word[0];
+ word.remove (0, 1);
+ }
+
+ validateWord ( word, query_valid );
+
+ if ( type == '-' )
+ words_must_not_exist.push_back ( word );
+ else
+ words_must_exist.push_back ( word );
+
+ query.remove (pos, rxword.matchedLength());
+ }
+
+#if defined (DUMP_SEARCH_QUERY)
+ // Dump the search query
+ QString qdump;
+ for ( i = 0; i < phrases_must_exist.size(); i++ )
+ qdump += QString(" \"") + phrases_must_exist[i].join (" ") + QString ("\"");
+
+ for ( i = 0; i < words_must_not_exist.size(); i++ )
+ qdump += QString (" -") + words_must_not_exist[i];
+
+ for ( i = 0; i < words_must_exist.size(); i++ )
+ qdump += QString (" +") + words_must_exist[i];
+
+ qDebug ("Search query dump: %s", qdump.ascii());
+#endif
+
+ // First search for phrases
+ if ( phrases_must_exist.size() > 0 )
+ {
+ LCHMSearchProgressResults tempres;
+
+ for ( i = 0; i < phrases_must_exist.size(); i++ )
+ {
+ if ( !searchPhrase ( impl(), phrases_must_exist[i], tempres ) )
+ return false;
+
+ mergeResults ( results, tempres, true );
+ }
+ }
+
+ for ( i = 0; i < words_must_exist.size(); i++ )
+ {
+ LCHMSearchProgressResults tempres;
+
+ if ( !m_impl->searchWord ( words_must_exist[i], true, false, tempres, false ) )
+ return false;
+
+ mergeResults ( results, tempres, true );
+ }
+
+ for ( i = 0; i < words_must_not_exist.size(); i++ )
+ {
+ LCHMSearchProgressResults tempres;
+
+ m_impl->searchWord ( words_must_not_exist[i], true, false, tempres, false );
+ mergeResults ( results, tempres, false );
+ }
+
+ m_impl->getSearchResults( results, searchresults, limit );
+ return true;
+}
diff --git a/lib/libchmfile/libchmfileimpl.cpp b/lib/libchmfile/libchmfileimpl.cpp
new file mode 100644
index 0000000..6f1e052
--- /dev/null
+++ b/lib/libchmfile/libchmfileimpl.cpp
@@ -0,0 +1,1271 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Portions Copyright (C) 2003 Razvan Cojocaru <razvanco@gmx.net> *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <sys/types.h>
+
+#include <qcursor.h>
+#include <qfile.h>
+#include <qapplication.h>
+
+#include "config.h"
+#include "chm_lib.h"
+#include "bitfiddle.h"
+#include "libchmfile.h"
+#include "libchmurlfactory.h"
+#include "libchmfileimpl.h"
+
+// Big-enough buffer size for use with various routines.
+#define BUF_SIZE 4096
+#define COMMON_BUF_LEN 1025
+
+#define TOPICS_ENTRY_LEN 16
+#define URLTBL_ENTRY_LEN 12
+
+//#define DEBUGPARSER(A) qDebug A
+#define DEBUGPARSER(A) ;
+
+class KCHMShowWaitCursor
+{
+ public:
+ KCHMShowWaitCursor () { QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); }
+ ~KCHMShowWaitCursor () { QApplication::restoreOverrideCursor(); }
+};
+
+
+LCHMFileImpl::LCHMFileImpl( )
+{
+ m_chmFile = NULL;
+ m_home = m_filename = m_home = m_topicsFile = m_indexFile = m_font = QString::null;
+ m_entityDecodeMap.clear();
+ m_textCodec = 0;
+ m_textCodecForSpecialFiles = 0;
+ m_detectedLCID = 0;
+ m_currentEncoding = 0;
+}
+
+
+LCHMFileImpl::~ LCHMFileImpl( )
+{
+ closeAll();
+}
+
+
+bool LCHMFileImpl::loadFile( const QString & archiveName )
+{
+ QString filename;
+
+ // If the file has a file:// prefix, remove it
+ if ( archiveName.startsWith( "file://" ) )
+ filename = archiveName.mid( 7 ); // strip it
+ else
+ filename = archiveName;
+
+ if( m_chmFile )
+ closeAll();
+
+ m_chmFile = chm_open( QFile::encodeName(filename) );
+
+ if ( m_chmFile == NULL )
+ return false;
+
+ m_filename = filename;
+
+ // Reset encoding
+ m_textCodec = 0;
+ m_textCodecForSpecialFiles = 0;
+ m_currentEncoding = 0;
+
+ // Get information from /#WINDOWS and /#SYSTEM files (encoding, title, context file and so)
+ // and guess the encoding
+ getInfoFromWindows();
+ getInfoFromSystem();
+ guessTextEncoding();
+
+ // Check whether the search tables are present
+ if ( ResolveObject("/#TOPICS", &m_chmTOPICS)
+ && ResolveObject("/#STRINGS", &m_chmSTRINGS)
+ && ResolveObject("/#URLTBL", &m_chmURLTBL)
+ && ResolveObject("/#URLSTR", &m_chmURLSTR) )
+ {
+ m_lookupTablesValid = true;
+ fillTopicsUrlMap();
+ }
+ else
+ m_lookupTablesValid = false;
+
+ if ( m_lookupTablesValid && ResolveObject ("/$FIftiMain", &m_chmFIftiMain) )
+ m_searchAvailable = true;
+ else
+ m_searchAvailable = false;
+
+ return true;
+}
+
+
+void LCHMFileImpl::closeAll( )
+{
+ if ( m_chmFile == NULL )
+ return;
+
+ chm_close( m_chmFile );
+
+ m_chmFile = NULL;
+ m_home = m_filename = m_home = m_topicsFile = m_indexFile = m_font = QString::null;
+ m_entityDecodeMap.clear();
+ m_textCodec = 0;
+ m_textCodecForSpecialFiles = 0;
+ m_detectedLCID = 0;
+ m_currentEncoding = 0;
+}
+
+
+QString LCHMFileImpl::decodeEntity( const QString & entity )
+{
+ // Set up m_entityDecodeMap characters according to current textCodec
+ if ( m_entityDecodeMap.isEmpty() )
+ {
+ m_entityDecodeMap["AElig"] = encodeWithCurrentCodec ("\306"); // capital AE diphthong (ligature)
+ m_entityDecodeMap["Aacute"] = encodeWithCurrentCodec ("\301"); // capital A, acute accent
+ m_entityDecodeMap["Acirc"] = encodeWithCurrentCodec ("\302"); // capital A, circumflex accent
+ m_entityDecodeMap["Agrave"] = encodeWithCurrentCodec ("\300"); // capital A, grave accent
+ m_entityDecodeMap["Aring"] = encodeWithCurrentCodec ("\305"); // capital A, ring
+ m_entityDecodeMap["Atilde"] = encodeWithCurrentCodec ("\303"); // capital A, tilde
+ m_entityDecodeMap["Auml"] = encodeWithCurrentCodec ("\304"); // capital A, dieresis or umlaut mark
+ m_entityDecodeMap["Ccedil"] = encodeWithCurrentCodec ("\307"); // capital C, cedilla
+ m_entityDecodeMap["Dstrok"] = encodeWithCurrentCodec ("\320"); // whatever
+ m_entityDecodeMap["ETH"] = encodeWithCurrentCodec ("\320"); // capital Eth, Icelandic
+ m_entityDecodeMap["Eacute"] = encodeWithCurrentCodec ("\311"); // capital E, acute accent
+ m_entityDecodeMap["Ecirc"] = encodeWithCurrentCodec ("\312"); // capital E, circumflex accent
+ m_entityDecodeMap["Egrave"] = encodeWithCurrentCodec ("\310"); // capital E, grave accent
+ m_entityDecodeMap["Euml"] = encodeWithCurrentCodec ("\313"); // capital E, dieresis or umlaut mark
+ m_entityDecodeMap["Iacute"] = encodeWithCurrentCodec ("\315"); // capital I, acute accent
+ m_entityDecodeMap["Icirc"] = encodeWithCurrentCodec ("\316"); // capital I, circumflex accent
+ m_entityDecodeMap["Igrave"] = encodeWithCurrentCodec ("\314"); // capital I, grave accent
+ m_entityDecodeMap["Iuml"] = encodeWithCurrentCodec ("\317"); // capital I, dieresis or umlaut mark
+ m_entityDecodeMap["Ntilde"] = encodeWithCurrentCodec ("\321"); // capital N, tilde
+ m_entityDecodeMap["Oacute"] = encodeWithCurrentCodec ("\323"); // capital O, acute accent
+ m_entityDecodeMap["Ocirc"] = encodeWithCurrentCodec ("\324"); // capital O, circumflex accent
+ m_entityDecodeMap["Ograve"] = encodeWithCurrentCodec ("\322"); // capital O, grave accent
+ m_entityDecodeMap["Oslash"] = encodeWithCurrentCodec ("\330"); // capital O, slash
+ m_entityDecodeMap["Otilde"] = encodeWithCurrentCodec ("\325"); // capital O, tilde
+ m_entityDecodeMap["Ouml"] = encodeWithCurrentCodec ("\326"); // capital O, dieresis or umlaut mark
+ m_entityDecodeMap["THORN"] = encodeWithCurrentCodec ("\336"); // capital THORN, Icelandic
+ m_entityDecodeMap["Uacute"] = encodeWithCurrentCodec ("\332"); // capital U, acute accent
+ m_entityDecodeMap["Ucirc"] = encodeWithCurrentCodec ("\333"); // capital U, circumflex accent
+ m_entityDecodeMap["Ugrave"] = encodeWithCurrentCodec ("\331"); // capital U, grave accent
+ m_entityDecodeMap["Uuml"] = encodeWithCurrentCodec ("\334"); // capital U, dieresis or umlaut mark
+ m_entityDecodeMap["Yacute"] = encodeWithCurrentCodec ("\335"); // capital Y, acute accent
+ m_entityDecodeMap["OElig"] = encodeWithCurrentCodec ("\338"); // capital Y, acute accent
+ m_entityDecodeMap["oelig"] = encodeWithCurrentCodec ("\339"); // capital Y, acute accent
+
+ m_entityDecodeMap["aacute"] = encodeWithCurrentCodec ("\341"); // small a, acute accent
+ m_entityDecodeMap["acirc"] = encodeWithCurrentCodec ("\342"); // small a, circumflex accent
+ m_entityDecodeMap["aelig"] = encodeWithCurrentCodec ("\346"); // small ae diphthong (ligature)
+ m_entityDecodeMap["agrave"] = encodeWithCurrentCodec ("\340"); // small a, grave accent
+ m_entityDecodeMap["aring"] = encodeWithCurrentCodec ("\345"); // small a, ring
+ m_entityDecodeMap["atilde"] = encodeWithCurrentCodec ("\343"); // small a, tilde
+ m_entityDecodeMap["auml"] = encodeWithCurrentCodec ("\344"); // small a, dieresis or umlaut mark
+ m_entityDecodeMap["ccedil"] = encodeWithCurrentCodec ("\347"); // small c, cedilla
+ m_entityDecodeMap["eacute"] = encodeWithCurrentCodec ("\351"); // small e, acute accent
+ m_entityDecodeMap["ecirc"] = encodeWithCurrentCodec ("\352"); // small e, circumflex accent
+ m_entityDecodeMap["Scaron"] = encodeWithCurrentCodec ("\352"); // small e, circumflex accent
+ m_entityDecodeMap["egrave"] = encodeWithCurrentCodec ("\350"); // small e, grave accent
+ m_entityDecodeMap["eth"] = encodeWithCurrentCodec ("\360"); // small eth, Icelandic
+ m_entityDecodeMap["euml"] = encodeWithCurrentCodec ("\353"); // small e, dieresis or umlaut mark
+ m_entityDecodeMap["iacute"] = encodeWithCurrentCodec ("\355"); // small i, acute accent
+ m_entityDecodeMap["icirc"] = encodeWithCurrentCodec ("\356"); // small i, circumflex accent
+ m_entityDecodeMap["igrave"] = encodeWithCurrentCodec ("\354"); // small i, grave accent
+ m_entityDecodeMap["iuml"] = encodeWithCurrentCodec ("\357"); // small i, dieresis or umlaut mark
+ m_entityDecodeMap["ntilde"] = encodeWithCurrentCodec ("\361"); // small n, tilde
+ m_entityDecodeMap["oacute"] = encodeWithCurrentCodec ("\363"); // small o, acute accent
+ m_entityDecodeMap["ocirc"] = encodeWithCurrentCodec ("\364"); // small o, circumflex accent
+ m_entityDecodeMap["ograve"] = encodeWithCurrentCodec ("\362"); // small o, grave accent
+ m_entityDecodeMap["oslash"] = encodeWithCurrentCodec ("\370"); // small o, slash
+ m_entityDecodeMap["otilde"] = encodeWithCurrentCodec ("\365"); // small o, tilde
+ m_entityDecodeMap["ouml"] = encodeWithCurrentCodec ("\366"); // small o, dieresis or umlaut mark
+ m_entityDecodeMap["szlig"] = encodeWithCurrentCodec ("\337"); // small sharp s, German (sz ligature)
+ m_entityDecodeMap["thorn"] = encodeWithCurrentCodec ("\376"); // small thorn, Icelandic
+ m_entityDecodeMap["uacute"] = encodeWithCurrentCodec ("\372"); // small u, acute accent
+ m_entityDecodeMap["ucirc"] = encodeWithCurrentCodec ("\373"); // small u, circumflex accent
+ m_entityDecodeMap["ugrave"] = encodeWithCurrentCodec ("\371"); // small u, grave accent
+ m_entityDecodeMap["uuml"] = encodeWithCurrentCodec ("\374"); // small u, dieresis or umlaut mark
+ m_entityDecodeMap["yacute"] = encodeWithCurrentCodec ("\375"); // small y, acute accent
+ m_entityDecodeMap["yuml"] = encodeWithCurrentCodec ("\377"); // small y, dieresis or umlaut mark
+
+ m_entityDecodeMap["iexcl"] = encodeWithCurrentCodec ("\241");
+ m_entityDecodeMap["cent"] = encodeWithCurrentCodec ("\242");
+ m_entityDecodeMap["pound"] = encodeWithCurrentCodec ("\243");
+ m_entityDecodeMap["curren"] = encodeWithCurrentCodec ("\244");
+ m_entityDecodeMap["yen"] = encodeWithCurrentCodec ("\245");
+ m_entityDecodeMap["brvbar"] = encodeWithCurrentCodec ("\246");
+ m_entityDecodeMap["sect"] = encodeWithCurrentCodec ("\247");
+ m_entityDecodeMap["uml"] = encodeWithCurrentCodec ("\250");
+ m_entityDecodeMap["ordf"] = encodeWithCurrentCodec ("\252");
+ m_entityDecodeMap["laquo"] = encodeWithCurrentCodec ("\253");
+ m_entityDecodeMap["not"] = encodeWithCurrentCodec ("\254");
+ m_entityDecodeMap["shy"] = encodeWithCurrentCodec ("\255");
+ m_entityDecodeMap["macr"] = encodeWithCurrentCodec ("\257");
+ m_entityDecodeMap["deg"] = encodeWithCurrentCodec ("\260");
+ m_entityDecodeMap["plusmn"] = encodeWithCurrentCodec ("\261");
+ m_entityDecodeMap["sup1"] = encodeWithCurrentCodec ("\271");
+ m_entityDecodeMap["sup2"] = encodeWithCurrentCodec ("\262");
+ m_entityDecodeMap["sup3"] = encodeWithCurrentCodec ("\263");
+ m_entityDecodeMap["acute"] = encodeWithCurrentCodec ("\264");
+ m_entityDecodeMap["micro"] = encodeWithCurrentCodec ("\265");
+ m_entityDecodeMap["para"] = encodeWithCurrentCodec ("\266");
+ m_entityDecodeMap["middot"] = encodeWithCurrentCodec ("\267");
+ m_entityDecodeMap["cedil"] = encodeWithCurrentCodec ("\270");
+ m_entityDecodeMap["ordm"] = encodeWithCurrentCodec ("\272");
+ m_entityDecodeMap["raquo"] = encodeWithCurrentCodec ("\273");
+ m_entityDecodeMap["frac14"] = encodeWithCurrentCodec ("\274");
+ m_entityDecodeMap["frac12"] = encodeWithCurrentCodec ("\275");
+ m_entityDecodeMap["frac34"] = encodeWithCurrentCodec ("\276");
+ m_entityDecodeMap["iquest"] = encodeWithCurrentCodec ("\277");
+ m_entityDecodeMap["times"] = encodeWithCurrentCodec ("\327");
+ m_entityDecodeMap["divide"] = encodeWithCurrentCodec ("\367");
+
+ m_entityDecodeMap["copy"] = encodeWithCurrentCodec ("\251"); // copyright sign
+ m_entityDecodeMap["reg"] = encodeWithCurrentCodec ("\256"); // registered sign
+ m_entityDecodeMap["nbsp"] = encodeWithCurrentCodec ("\240"); // non breaking space
+
+ m_entityDecodeMap["fnof"] = QChar((unsigned short) 402);
+
+ m_entityDecodeMap["Delta"] = QChar((unsigned short) 916);
+ m_entityDecodeMap["Pi"] = QChar((unsigned short) 928);
+ m_entityDecodeMap["Sigma"] = QChar((unsigned short) 931);
+
+ m_entityDecodeMap["beta"] = QChar((unsigned short) 946);
+ m_entityDecodeMap["gamma"] = QChar((unsigned short) 947);
+ m_entityDecodeMap["delta"] = QChar((unsigned short) 948);
+ m_entityDecodeMap["eta"] = QChar((unsigned short) 951);
+ m_entityDecodeMap["theta"] = QChar((unsigned short) 952);
+ m_entityDecodeMap["lambda"] = QChar((unsigned short) 955);
+ m_entityDecodeMap["mu"] = QChar((unsigned short) 956);
+ m_entityDecodeMap["nu"] = QChar((unsigned short) 957);
+ m_entityDecodeMap["pi"] = QChar((unsigned short) 960);
+ m_entityDecodeMap["rho"] = QChar((unsigned short) 961);
+
+ m_entityDecodeMap["lsquo"] = QChar((unsigned short) 8216);
+ m_entityDecodeMap["rsquo"] = QChar((unsigned short) 8217);
+ m_entityDecodeMap["rdquo"] = QChar((unsigned short) 8221);
+ m_entityDecodeMap["bdquo"] = QChar((unsigned short) 8222);
+ m_entityDecodeMap["trade"] = QChar((unsigned short) 8482);
+ m_entityDecodeMap["ldquo"] = QChar((unsigned short) 8220);
+ m_entityDecodeMap["ndash"] = QChar((unsigned short) 8211);
+ m_entityDecodeMap["mdash"] = QChar((unsigned short) 8212);
+ m_entityDecodeMap["bull"] = QChar((unsigned short) 8226);
+ m_entityDecodeMap["hellip"] = QChar((unsigned short) 8230);
+ m_entityDecodeMap["emsp"] = QChar((unsigned short) 8195);
+ m_entityDecodeMap["rarr"] = QChar((unsigned short) 8594);
+ m_entityDecodeMap["rArr"] = QChar((unsigned short) 8658);
+ m_entityDecodeMap["crarr"] = QChar((unsigned short) 8629);
+ m_entityDecodeMap["le"] = QChar((unsigned short) 8804);
+ m_entityDecodeMap["ge"] = QChar((unsigned short) 8805);
+ m_entityDecodeMap["lte"] = QChar((unsigned short) 8804); // wrong, but used somewhere
+ m_entityDecodeMap["gte"] = QChar((unsigned short) 8805); // wrong, but used somewhere
+ m_entityDecodeMap["dagger"] = QChar((unsigned short) 8224);
+ m_entityDecodeMap["Dagger"] = QChar((unsigned short) 8225);
+ m_entityDecodeMap["euro"] = QChar((unsigned short) 8364);
+ m_entityDecodeMap["asymp"] = QChar((unsigned short) 8776);
+ m_entityDecodeMap["isin"] = QChar((unsigned short) 8712);
+ m_entityDecodeMap["notin"] = QChar((unsigned short) 8713);
+ m_entityDecodeMap["prod"] = QChar((unsigned short) 8719);
+ m_entityDecodeMap["ne"] = QChar((unsigned short) 8800);
+
+ m_entityDecodeMap["amp"] = "&"; // ampersand
+ m_entityDecodeMap["gt"] = ">"; // greater than
+ m_entityDecodeMap["lt"] = "<"; // less than
+ m_entityDecodeMap["quot"] = "\""; // double quote
+ m_entityDecodeMap["apos"] = "'"; // single quote
+ m_entityDecodeMap["frasl"] = "/";
+ m_entityDecodeMap["minus"] = "-";
+ m_entityDecodeMap["oplus"] = "+";
+ m_entityDecodeMap["Prime"] = "\"";
+ }
+
+ // If entity is an ASCII code like &#12349; - just decode it
+ if ( entity[0] == '#' )
+ {
+ bool valid;
+ unsigned int ascode = entity.mid(1).toUInt( &valid );
+
+ if ( !valid )
+ {
+ qWarning ( "LCHMFileImpl::decodeEntity: could not decode HTML entity '%s'", entity.ascii() );
+ return QString::null;
+ }
+
+ return (QString) (QChar( ascode ));
+ }
+ else
+ {
+ QMap<QString, QString>::const_iterator it = m_entityDecodeMap.find( entity );
+
+ if ( it == m_entityDecodeMap.end() )
+ {
+ qWarning ("LCHMFileImpl::decodeEntity: could not decode HTML entity '%s'", entity.ascii());
+ return QString::null;
+ }
+
+ return *it;
+ }
+}
+
+
+inline int LCHMFileImpl::findStringInQuotes (const QString& tag, int offset, QString& value, bool firstquote, bool decodeentities)
+{
+ int qbegin = tag.find ('"', offset);
+
+ if ( qbegin == -1 )
+ qFatal ("LCHMFileImpl::findStringInQuotes: cannot find first quote in <param> tag: '%s'", tag.ascii());
+
+ int qend = firstquote ? tag.find ('"', qbegin + 1) : tag.findRev ('"');
+
+ if ( qend == -1 || qend <= qbegin )
+ qFatal ("LCHMFileImpl::findStringInQuotes: cannot find last quote in <param> tag: '%s'", tag.ascii());
+
+ // If we do not need to decode HTML entities, just return.
+ if ( decodeentities )
+ {
+ QString htmlentity = QString::null;
+ bool fill_entity = false;
+
+ value.reserve (qend - qbegin); // to avoid multiple memory allocations
+
+ for ( int i = qbegin + 1; i < qend; i++ )
+ {
+ if ( !fill_entity )
+ {
+ if ( tag[i] == '&' ) // HTML entity starts
+ fill_entity = true;
+ else
+ value.append (tag[i]);
+ }
+ else
+ {
+ if ( tag[i] == ';' ) // HTML entity ends
+ {
+ // If entity is an ASCII code, just decode it
+ QString decode = decodeEntity( htmlentity );
+
+ if ( decode.isNull() )
+ break;
+
+ value.append ( decode );
+ htmlentity = QString::null;
+ fill_entity = false;
+ }
+ else
+ htmlentity.append (tag[i]);
+ }
+ }
+ }
+ else
+ value = tag.mid (qbegin + 1, qend - qbegin - 1);
+
+ return qend + 1;
+}
+
+
+bool LCHMFileImpl::searchWord (const QString& text,
+ bool wholeWords,
+ bool titlesOnly,
+ LCHMSearchProgressResults& results,
+ bool phrase_search)
+{
+ bool partial = false;
+
+ if ( text.isEmpty() || !m_searchAvailable )
+ return false;
+
+ QString searchword = (QString) convertSearchWord (text);
+
+#define FTS_HEADER_LEN 0x32
+ unsigned char header[FTS_HEADER_LEN];
+
+ if ( RetrieveObject (&m_chmFIftiMain, header, 0, FTS_HEADER_LEN) == 0 )
+ return false;
+
+ unsigned char doc_index_s = header[0x1E], doc_index_r = header[0x1F];
+ unsigned char code_count_s = header[0x20], code_count_r = header[0x21];
+ unsigned char loc_codes_s = header[0x22], loc_codes_r = header[0x23];
+
+ if(doc_index_s != 2 || code_count_s != 2 || loc_codes_s != 2)
+ {
+ // Don't know how to use values other than 2 yet. Maybe next chmspec.
+ return false;
+ }
+
+ unsigned char* cursor32 = header + 0x14;
+ u_int32_t node_offset = UINT32ARRAY(cursor32);
+
+ cursor32 = header + 0x2e;
+ u_int32_t node_len = UINT32ARRAY(cursor32);
+
+ unsigned char* cursor16 = header + 0x18;
+ u_int16_t tree_depth = UINT16ARRAY(cursor16);
+
+ unsigned char word_len, pos;
+ QString word;
+ u_int32_t i = sizeof(u_int16_t);
+ u_int16_t free_space;
+
+ QMemArray<unsigned char> buffer(node_len);
+
+ node_offset = GetLeafNodeOffset (searchword, node_offset, node_len, tree_depth);
+
+ if ( !node_offset )
+ return false;
+
+ do
+ {
+ // got a leaf node here.
+ if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), node_offset, node_len) == 0 )
+ return false;
+
+ cursor16 = buffer.data() + 6;
+ free_space = UINT16ARRAY(cursor16);
+
+ i = sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int16_t);
+ u_int64_t wlc_count, wlc_size;
+ u_int32_t wlc_offset;
+
+ while (i < node_len - free_space)
+ {
+ word_len = *(buffer.data() + i);
+ pos = *(buffer.data() + i + 1);
+
+ char *wrd_buf = new char[word_len];
+ memcpy (wrd_buf, buffer.data() + i + 2, word_len - 1);
+ wrd_buf[word_len - 1] = 0;
+
+ if ( pos == 0 )
+ word = wrd_buf;
+ else
+ word = word.mid (0, pos) + wrd_buf;
+
+ delete[] wrd_buf;
+
+ i += 2 + word_len;
+ unsigned char title = *(buffer.data() + i - 1);
+
+ size_t encsz;
+ wlc_count = be_encint (buffer.data() + i, encsz);
+ i += encsz;
+
+ cursor32 = buffer.data() + i;
+ wlc_offset = UINT32ARRAY(cursor32);
+
+ i += sizeof(u_int32_t) + sizeof(u_int16_t);
+ wlc_size = be_encint (buffer.data() + i, encsz);
+ i += encsz;
+
+ cursor32 = buffer.data();
+ node_offset = UINT32ARRAY(cursor32);
+
+ if ( !title && titlesOnly )
+ continue;
+
+ if ( wholeWords && searchword == word )
+ return ProcessWLC(wlc_count, wlc_size,
+ wlc_offset, doc_index_s,
+ doc_index_r,code_count_s,
+ code_count_r, loc_codes_s,
+ loc_codes_r, results, phrase_search);
+
+ if ( !wholeWords )
+ {
+ if ( word.startsWith (searchword))
+ {
+ partial = true;
+
+ ProcessWLC(wlc_count, wlc_size,
+ wlc_offset, doc_index_s,
+ doc_index_r,code_count_s,
+ code_count_r, loc_codes_s,
+ loc_codes_r, results, phrase_search);
+
+ }
+ else if ( QString::compare (searchword, word.mid(0, searchword.length())) < -1 )
+ break;
+ }
+ }
+ }
+ while ( !wholeWords && word.startsWith (searchword) && node_offset );
+
+ return partial;
+}
+
+
+bool LCHMFileImpl::ResolveObject(const QString& fileName, chmUnitInfo *ui) const
+{
+ return m_chmFile != NULL
+ && ::chm_resolve_object(m_chmFile, fileName.ascii(), ui) ==
+ CHM_RESOLVE_SUCCESS;
+}
+
+
+size_t LCHMFileImpl::RetrieveObject(const chmUnitInfo *ui, unsigned char *buffer,
+ LONGUINT64 fileOffset, LONGINT64 bufferSize) const
+{
+#if USE_BUILTIN_CHMLIB
+ return ::chm_retrieve_object(m_chmFile, ui, buffer,
+ fileOffset, bufferSize);
+#else
+ return ::chm_retrieve_object(m_chmFile, const_cast<chmUnitInfo*>(ui),
+ buffer, fileOffset, bufferSize);
+#endif
+}
+
+
+inline u_int32_t LCHMFileImpl::GetLeafNodeOffset(const QString& text,
+ u_int32_t initialOffset,
+ u_int32_t buffSize,
+ u_int16_t treeDepth)
+{
+ u_int32_t test_offset = 0;
+ unsigned char* cursor16, *cursor32;
+ unsigned char word_len, pos;
+ u_int32_t i = sizeof(u_int16_t);
+ QMemArray<unsigned char> buffer(buffSize);
+ QString word;
+
+ while(--treeDepth)
+ {
+ if ( initialOffset == test_offset )
+ return 0;
+
+ test_offset = initialOffset;
+ if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), initialOffset, buffSize) == 0 )
+ return 0;
+
+ cursor16 = buffer.data();
+ u_int16_t free_space = UINT16ARRAY(cursor16);
+
+ while (i < buffSize - free_space )
+ {
+ word_len = *(buffer.data() + i);
+ pos = *(buffer.data() + i + 1);
+
+ char *wrd_buf = new char[word_len];
+ memcpy ( wrd_buf, buffer.data() + i + 2, word_len - 1 );
+ wrd_buf[word_len - 1] = 0;
+
+ if ( pos == 0 )
+ word = wrd_buf;
+ else
+ word = word.mid(0, pos) + wrd_buf;
+
+ delete[] wrd_buf;
+
+ if ( text <= word )
+ {
+ cursor32 = buffer.data() + i + word_len + 1;
+ initialOffset = UINT32ARRAY(cursor32);
+ break;
+ }
+
+ i += word_len + sizeof(unsigned char) +
+ sizeof(u_int32_t) + sizeof(u_int16_t);
+ }
+ }
+
+ if ( initialOffset == test_offset )
+ return 0;
+
+ return initialOffset;
+}
+
+
+inline bool LCHMFileImpl::ProcessWLC (u_int64_t wlc_count, u_int64_t wlc_size,
+ u_int32_t wlc_offset, unsigned char ds,
+ unsigned char dr, unsigned char cs,
+ unsigned char cr, unsigned char ls,
+ unsigned char lr,
+ LCHMSearchProgressResults& results,
+ bool phrase_search)
+{
+ int wlc_bit = 7;
+ u_int64_t index = 0, count;
+ size_t length, off = 0;
+ QMemArray<unsigned char> buffer (wlc_size);
+ unsigned char *cursor32;
+
+ unsigned char entry[TOPICS_ENTRY_LEN];
+ unsigned char combuf[13];
+
+ if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), wlc_offset, wlc_size) == 0 )
+ return false;
+
+ for ( u_int64_t i = 0; i < wlc_count; ++i )
+ {
+ if ( wlc_bit != 7 )
+ {
+ ++off;
+ wlc_bit = 7;
+ }
+
+ index += sr_int (buffer.data() + off, &wlc_bit, ds, dr, length);
+ off += length;
+
+ if ( RetrieveObject (&m_chmTOPICS, entry, index * 16, TOPICS_ENTRY_LEN) == 0 )
+ return false;
+
+ LCHMSearchProgressResult progres;
+
+ cursor32 = entry + 4;
+ progres.titleoff = UINT32ARRAY(cursor32);
+
+ cursor32 = entry + 8;
+ progres.urloff = UINT32ARRAY(cursor32);
+
+ if ( RetrieveObject (&m_chmURLTBL, combuf, progres.urloff, 12) == 0 )
+ return false;
+
+ cursor32 = combuf + 8;
+ progres.urloff = UINT32ARRAY (cursor32);
+
+ count = sr_int (buffer.data() + off, &wlc_bit, cs, cr, length);
+ off += length;
+
+ if ( phrase_search )
+ progres.offsets.reserve (count);
+
+ for (u_int64_t j = 0; j < count; ++j)
+ {
+ u_int64_t lcode = sr_int (buffer.data() + off, &wlc_bit, ls, lr, length);
+ off += length;
+
+ if ( phrase_search )
+ progres.offsets.push_back (lcode);
+ }
+
+ results.push_back (progres);
+ }
+
+ return true;
+}
+
+
+bool LCHMFileImpl::getInfoFromWindows()
+{
+#define WIN_HEADER_LEN 0x08
+ unsigned char buffer[BUF_SIZE];
+ unsigned int factor;
+ chmUnitInfo ui;
+ long size = 0;
+
+ if ( ResolveObject("/#WINDOWS", &ui) )
+ {
+ if ( !RetrieveObject(&ui, buffer, 0, WIN_HEADER_LEN) )
+ return false;
+
+ u_int32_t entries = get_int32_le( (u_int32_t *)(buffer) );
+ u_int32_t entry_size = get_int32_le( (u_int32_t *)(buffer + 0x04) );
+
+ QByteArray uptr(entries * entry_size);
+ unsigned char* raw = (unsigned char*) uptr.data();
+
+ if ( !RetrieveObject (&ui, raw, 8, entries * entry_size) )
+ return false;
+
+ if( !ResolveObject ("/#STRINGS", &ui) )
+ return false;
+
+ for ( u_int32_t i = 0; i < entries; ++i )
+ {
+ u_int32_t offset = i * entry_size;
+
+ u_int32_t off_title = get_int32_le( (u_int32_t *)(raw + offset + 0x14) );
+ u_int32_t off_home = get_int32_le( (u_int32_t *)(raw + offset + 0x68) );
+ u_int32_t off_hhc = get_int32_le( (u_int32_t *)(raw + offset + 0x60) );
+ u_int32_t off_hhk = get_int32_le( (u_int32_t *)(raw + offset + 0x64) );
+
+ factor = off_title / 4096;
+
+ if ( size == 0 )
+ size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE);
+
+ if ( size && off_title )
+ m_title = QString ((const char*) (buffer + off_title % 4096));
+
+ if ( factor != off_home / 4096)
+ {
+ factor = off_home / 4096;
+ size = RetrieveObject (&ui, buffer, factor * 4096, BUF_SIZE);
+ }
+
+ if ( size && off_home )
+ m_home = QString("/") + QString( (const char*) buffer + off_home % 4096);
+
+ if ( factor != off_hhc / 4096)
+ {
+ factor = off_hhc / 4096;
+ size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE);
+ }
+
+ if ( size && off_hhc )
+ m_topicsFile = QString("/") + QString ((const char*) buffer + off_hhc % 4096);
+
+ if ( factor != off_hhk / 4096)
+ {
+ factor = off_hhk / 4096;
+ size = RetrieveObject (&ui, buffer, factor * 4096, BUF_SIZE);
+ }
+
+ if ( size && off_hhk )
+ m_indexFile = QString("/") + QString((const char*) buffer + off_hhk % 4096);
+ }
+ }
+ return true;
+}
+
+
+
+bool LCHMFileImpl::getInfoFromSystem()
+{
+ unsigned char buffer[BUF_SIZE];
+ chmUnitInfo ui;
+
+ int index = 0;
+ unsigned char* cursor = NULL, *p;
+ u_int16_t value = 0;
+ long size = 0;
+
+ // Run the first loop to detect the encoding. We need this, because title could be
+ // already encoded in user encoding. Same for file names
+ if ( !ResolveObject ("/#SYSTEM", &ui) )
+ return false;
+
+ // Can we pull BUFF_SIZE bytes of the #SYSTEM file?
+ if ( (size = RetrieveObject (&ui, buffer, 4, BUF_SIZE)) == 0 )
+ return false;
+
+ buffer[size - 1] = 0;
+
+ // First loop to detect the encoding
+ for ( index = 0; index < (size - 1 - (long)sizeof(u_int16_t)) ;)
+ {
+ cursor = buffer + index;
+ value = UINT16ARRAY(cursor);
+
+ switch(value)
+ {
+ case 0:
+ index += 2;
+ cursor = buffer + index;
+
+ if(m_topicsFile.isEmpty())
+ m_topicsFile = QString("/") + QString((const char*) buffer + index + 2);
+
+ break;
+
+ case 1:
+ index += 2;
+ cursor = buffer + index;
+
+ if(m_indexFile.isEmpty())
+ m_indexFile = QString("/") + QString ((const char*)buffer + index + 2);
+ break;
+
+ case 2:
+ index += 2;
+ cursor = buffer + index;
+
+ if(m_home.isEmpty() || m_home == "/")
+ m_home = QString("/") + QString ((const char*) buffer + index + 2);
+ break;
+
+ case 3:
+ index += 2;
+ cursor = buffer + index;
+ m_title = QString((const char*) (buffer + index + 2));
+ break;
+
+ case 4:
+ index += 2;
+ cursor = buffer + index;
+
+ p = buffer + index + 2;
+ m_detectedLCID = (short) (p[0] | (p[1]<<8));
+
+ break;
+
+ case 6:
+ index += 2;
+ cursor = buffer + index;
+
+ if(m_topicsFile.isEmpty()) {
+ QString topicAttempt = "/", tmp;
+ topicAttempt += QString ((const char*) buffer +index +2);
+
+ tmp = topicAttempt + ".hhc";
+
+ if ( ResolveObject( tmp, &ui) )
+ m_topicsFile = tmp;
+
+ tmp = topicAttempt + ".hhk";
+
+ if ( ResolveObject( tmp, &ui) )
+ m_indexFile = tmp;
+ }
+ break;
+
+ case 16:
+ index += 2;
+ cursor = buffer + index;
+
+ m_font = QString ((const char*) buffer + index + 2);
+ break;
+
+ default:
+ index += 2;
+ cursor = buffer + index;
+ }
+
+ value = UINT16ARRAY(cursor);
+ index += value + 2;
+ }
+
+ return true;
+}
+
+
+QCString LCHMFileImpl::convertSearchWord( const QString & src )
+{
+ static const char * searchwordtable[128] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "s", 0, "oe", 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "s", 0, "oe", 0, 0, "y",
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ "a", "a", "a", "a", "a", "a", "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i",
+ "d", "n", "o", "o", "o", "o", "o", 0, "o", "u", "u", "u", "u", "y", "\xDE", "ss",
+ "a", "a", "a", "a", "a", "a", "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i",
+ "o", "n", "o", "o", "o", "o", "o", 0, "o", "u", "u", "u", "u", "y", "\xFE", "y"
+ };
+
+ if ( !m_textCodec )
+ return (QCString) src.lower();
+
+ QCString dest = m_textCodec->fromUnicode (src);
+
+ for ( unsigned int i = 0; i < dest.size(); i++ )
+ {
+ if ( dest[i] & 0x80 )
+ {
+ int index = dest[i] & 0x7F;
+ if ( searchwordtable[index] )
+ dest.replace (i, 1, searchwordtable[index]);
+ else
+ dest.remove (i, 1);
+ }
+ }
+
+ return dest.lower();
+}
+
+
+
+void LCHMFileImpl::getSearchResults( const LCHMSearchProgressResults& tempres,
+ QStringList * results,
+ unsigned int limit_results )
+{
+ unsigned char combuf [COMMON_BUF_LEN];
+ QMap<u_int32_t, u_int32_t> urlsmap; // used to prevent duplicated urls
+
+ for ( unsigned int i = 0; i < tempres.size(); i++ )
+ {
+ if ( urlsmap.find (tempres[i].urloff) != urlsmap.end() )
+ continue;
+
+ urlsmap[tempres[i].urloff] = 1;
+
+ if ( RetrieveObject (&m_chmURLSTR, combuf, tempres[i].urloff + 8, COMMON_BUF_LEN - 1) == 0 )
+ continue;
+
+ combuf[COMMON_BUF_LEN - 1] = 0;
+ results->push_back( LCHMUrlFactory::makeURLabsoluteIfNeeded( (const char*) combuf ) );
+
+ if ( --limit_results == 0 )
+ break;
+ }
+}
+
+
+QString LCHMFileImpl::normalizeUrl( const QString & path ) const
+{
+ int pos = path.find ('#');
+ QString fixedpath = pos == -1 ? path : path.left (pos);
+
+ return LCHMUrlFactory::makeURLabsoluteIfNeeded( fixedpath );
+}
+
+
+/*
+ * FIXME: <OBJECT type="text/sitemap"><param name="Merge" value="hhaxref.chm::/HHOCX_c.hhc"></OBJECT>
+ * (from htmlhelp.chm)
+*/
+bool LCHMFileImpl::parseFileAndFillArray( const QString & file, QT34VECTOR< LCHMParsedEntry > * data, bool asIndex )
+{
+ QString src;
+ const int MAX_NEST_DEPTH = 256;
+
+ if ( !getFileContentAsString( &src, file ) || src.isEmpty() )
+ return false;
+
+ KCHMShowWaitCursor wc;
+
+/*
+ // Save the index for debugging purposes
+ QFile outfile( "parsed.htm" );
+
+ if ( outfile.open( IO_WriteOnly ) )
+ {
+ QTextStream textstream( &outfile );
+ textstream << src;
+ outfile.close();
+ }
+*/
+
+ unsigned int defaultimagenum = asIndex ? LCHMBookIcons::IMAGE_INDEX : LCHMBookIcons::IMAGE_AUTO;
+ int pos = 0, indent = 0, root_indent_offset = 0;
+ bool in_object = false, root_indent_offset_set = false;
+
+ LCHMParsedEntry entry;
+ entry.imageid = defaultimagenum;
+
+ // Split the HHC file by HTML tags
+ int stringlen = src.length();
+
+ while ( pos < stringlen && (pos = src.find ('<', pos)) != -1 )
+ {
+ int i, word_end = 0;
+
+ for ( i = ++pos; i < stringlen; i++ )
+ {
+ // If a " or ' is found, skip to the next one.
+ if ( (src[i] == '"' || src[i] == '\'') )
+ {
+ // find where quote ends, either by another quote, or by '>' symbol (some people don't know HTML)
+ int nextpos = src.find (src[i], i+1);
+ if ( nextpos == -1 && (nextpos = src.find ('>', i+1)) == -1 )
+ {
+ qWarning ("LCHMFileImpl::ParseHhcAndFillTree: corrupted TOC: %s", src.mid(i).ascii());
+ return false;
+ }
+
+ i = nextpos;
+ }
+ else if ( src[i] == '>' )
+ break;
+ else if ( !src[i].isLetterOrNumber() && src[i] != '/' && !word_end )
+ word_end = i;
+ }
+
+ QString tagword, tag = src.mid (pos, i - pos);
+
+ if ( word_end )
+ tagword = src.mid (pos, word_end - pos).lower();
+ else
+ tagword = tag.lower();
+
+ //qDebug ("tag: '%s', tagword: '%s'\n", tag.ascii(), tagword.ascii());
+
+ // <OBJECT type="text/sitemap"> - a topic entry
+ if ( tagword == "object" && tag.find ("text/sitemap", 0, false) != -1 )
+ in_object = true;
+ else if ( tagword == "/object" && in_object )
+ {
+ // a topic entry closed. Add a tree item
+ if ( entry.name )
+ {
+ if ( !root_indent_offset_set )
+ {
+ root_indent_offset_set = true;
+ root_indent_offset = indent;
+
+ if ( root_indent_offset > 1 )
+ qWarning("CHM has improper index; root indent offset is %d", root_indent_offset);
+ }
+
+ int real_indent = indent - root_indent_offset;
+
+ entry.indent = real_indent;
+ data->push_back( entry );
+ }
+ else
+ {
+ if ( !entry.urls.isEmpty() )
+ qDebug ("LCHMFileImpl::ParseAndFillTopicsTree: <object> tag with url \"%s\" is parsed, but name is empty.", entry.urls[0].ascii());
+ else
+ qDebug ("LCHMFileImpl::ParseAndFillTopicsTree: <object> tag is parsed, but both name and url are empty.");
+ }
+
+ entry.name = QString::null;
+ entry.urls.clear();
+ entry.imageid = defaultimagenum;
+ in_object = false;
+ }
+ else if ( tagword == "param" && in_object )
+ {
+ // <param name="Name" value="First Page">
+ int offset; // strlen("param ")
+ QString name_pattern = "name=", value_pattern = "value=";
+ QString pname, pvalue;
+
+ if ( (offset = tag.find (name_pattern, 0, FALSE)) == -1 )
+ qFatal ("LCHMFileImpl::ParseAndFillTopicsTree: bad <param> tag '%s': no name=\n", tag.ascii());
+
+ // offset+5 skips 'name='
+ offset = findStringInQuotes (tag, offset + name_pattern.length(), pname, TRUE, FALSE);
+ pname = pname.lower();
+
+ if ( (offset = tag.find (value_pattern, offset, FALSE)) == -1 )
+ qFatal ("LCHMFileImpl::ParseAndFillTopicsTree: bad <param> tag '%s': no value=\n", tag.ascii());
+
+ // offset+6 skips 'value='
+ findStringInQuotes (tag, offset + value_pattern.length(), pvalue, FALSE, TRUE);
+
+ //qDebug ("<param>: name '%s', value '%s'", pname.ascii(), pvalue.ascii());
+
+ if ( pname == "name" )
+ {
+ // Some help files contain duplicate names, where the second name is empty. Work it around by keeping the first one
+ if ( !pvalue.isEmpty() )
+ entry.name = pvalue;
+ }
+ else if ( pname == "local" )
+ {
+ // Check for URL duplication
+ QString url = LCHMUrlFactory::makeURLabsoluteIfNeeded( pvalue );
+
+ if ( entry.urls.find( url ) == entry.urls.end() )
+ entry.urls.push_back( url );
+ }
+ else if ( pname == "see also" && asIndex && entry.name != pvalue )
+ entry.urls.push_back (":" + pvalue);
+ else if ( pname == "imagenumber" )
+ {
+ bool bok;
+ int imgnum = pvalue.toInt (&bok);
+
+ if ( bok && imgnum >= 0 && imgnum < LCHMBookIcons::MAX_BUILTIN_ICONS )
+ entry.imageid = imgnum;
+ }
+ }
+ else if ( tagword == "ul" ) // increase indent level
+ {
+ // Fix for buggy help files
+ if ( ++indent >= MAX_NEST_DEPTH )
+ qFatal("LCHMFileImpl::ParseAndFillTopicsTree: max nest depth (%d) is reached, error in help file", MAX_NEST_DEPTH);
+
+ // This intended to fix <ul><ul>, which was seen in some buggy chm files,
+ // and brokes rootentry[indent-1] check
+ }
+ else if ( tagword == "/ul" ) // decrease indent level
+ {
+ if ( --indent < root_indent_offset )
+ indent = root_indent_offset;
+
+ DEBUGPARSER(("</ul>: new intent is %d\n", indent - root_indent_offset));
+ }
+
+ pos = i;
+ }
+
+ return true;
+}
+
+
+bool LCHMFileImpl::getFileContentAsBinary( QByteArray * data, const QString & url ) const
+{
+ chmUnitInfo ui;
+
+ if( !ResolveObject( url, &ui ) )
+ return false;
+
+ data->resize( ui.length );
+
+ if ( RetrieveObject( &ui, (unsigned char*) data->data(), 0, ui.length ) )
+ return true;
+ else
+ return false;
+}
+
+
+bool LCHMFileImpl::getFileContentAsString( QString * str, const QString & url, bool internal_encoding )
+{
+ QByteArray buf;
+
+ if ( getFileContentAsBinary( &buf, url ) )
+ {
+ unsigned int length = buf.size();
+
+ if ( length > 0 )
+ {
+ buf.resize( length + 1 );
+ buf [length] = '\0';
+
+ *str = internal_encoding ? (QString)((const char*) buf) : encodeWithCurrentCodec((const char*) buf);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+QString LCHMFileImpl::getTopicByUrl( const QString & url ) const
+{
+ QMap< QString, QString >::const_iterator it = m_url2topics.find( url );
+
+ if ( it == m_url2topics.end() )
+ return QString::null;
+
+ return it.data();
+}
+
+
+static int chm_enumerator_callback( struct chmFile*, struct chmUnitInfo *ui, void *context )
+{
+ ((QStringList*) context)->push_back( ui->path );
+ return CHM_ENUMERATOR_CONTINUE;
+}
+
+bool LCHMFileImpl::enumerateFiles( QStringList * files )
+{
+ files->clear();
+ return chm_enumerate( m_chmFile, CHM_ENUMERATE_ALL, chm_enumerator_callback, files );
+}
+
+const QPixmap * LCHMFileImpl::getBookIconPixmap( unsigned int imagenum )
+{
+ return m_imagesKeeper.getImage( imagenum );
+}
+
+bool LCHMFileImpl::setCurrentEncoding( const LCHMTextEncoding * encoding )
+{
+ m_currentEncoding = encoding;
+ return changeFileEncoding( encoding->qtcodec );
+}
+
+
+bool LCHMFileImpl::guessTextEncoding( )
+{
+ const LCHMTextEncoding * enc = 0;
+
+ if ( !m_detectedLCID || (enc = lookupByLCID (m_detectedLCID)) == 0 )
+ qFatal ("Could not detect text encoding by LCID");
+
+ if ( changeFileEncoding (enc->qtcodec) )
+ {
+ m_currentEncoding = enc;
+ return true;
+ }
+
+ return false;
+}
+
+bool LCHMFileImpl::changeFileEncoding( const char *qtencoding )
+{
+ // Encoding could be either simple Qt codepage, or set like CP1251/KOI8, which allows to
+ // set up encodings separately for text (first) and internal files (second)
+ const char * p = strchr( qtencoding, '/' );
+ if ( p )
+ {
+ char buf[128]; // much bigger that any encoding possible. No DoS; all encodings are hardcoded.
+ strcpy( buf, qtencoding );
+ buf[p - qtencoding] = '\0';
+
+ m_textCodec = QTextCodec::codecForName( buf );
+
+ if ( !m_textCodec )
+ {
+ qWarning( "Could not set up Text Codec for encoding '%s'", buf );
+ return false;
+ }
+
+ m_textCodecForSpecialFiles = QTextCodec::codecForName( p + 1 );
+
+ if ( !m_textCodecForSpecialFiles )
+ {
+ qWarning( "Could not set up Text Codec for encoding '%s'", p + 1 );
+ return false;
+ }
+ }
+ else
+ {
+ m_textCodecForSpecialFiles = m_textCodec = QTextCodec::codecForName (qtencoding);
+
+ if ( !m_textCodec )
+ {
+ qWarning( "Could not set up Text Codec for encoding '%s'", qtencoding );
+ return false;
+ }
+ }
+
+ m_entityDecodeMap.clear();
+ return true;
+}
+
+
+void LCHMFileImpl::fillTopicsUrlMap()
+{
+ if ( !m_lookupTablesValid )
+ return;
+
+ // Read those tables
+ QByteArray topics( m_chmTOPICS.length ), urltbl( m_chmURLTBL.length ), urlstr( m_chmURLSTR.length ), strings( m_chmSTRINGS.length );
+
+ if ( !RetrieveObject( &m_chmTOPICS, (unsigned char*) topics.data(), 0, m_chmTOPICS.length )
+ || !RetrieveObject( &m_chmURLTBL, (unsigned char*) urltbl.data(), 0, m_chmURLTBL.length )
+ || !RetrieveObject( &m_chmURLSTR, (unsigned char*) urlstr.data(), 0, m_chmURLSTR.length )
+ || !RetrieveObject( &m_chmSTRINGS, (unsigned char*) strings.data(), 0, m_chmSTRINGS.length ) )
+ return;
+
+ for ( unsigned int i = 0; i < m_chmTOPICS.length; i += TOPICS_ENTRY_LEN )
+ {
+ u_int32_t off_title = get_int32_le( (u_int32_t *)(topics.data() + i + 4) );
+ u_int32_t off_url = get_int32_le( (u_int32_t *)(topics.data() + i + 8) );
+ off_url = get_int32_le( (u_int32_t *)( urltbl.data() + off_url + 8) ) + 8;
+
+ QString url = LCHMUrlFactory::makeURLabsoluteIfNeeded( (const char*) urlstr.data() + off_url );
+
+ if ( off_title < strings.size() )
+ m_url2topics[url] = encodeWithCurrentCodec ( (const char*) strings.data() + off_title );
+ else
+ m_url2topics[url] = "Untitled";
+ }
+}
+
+
+bool LCHMFileImpl::getFileSize(unsigned int * size, const QString & url)
+{
+ chmUnitInfo ui;
+
+ if( !ResolveObject( url, &ui ) )
+ return false;
+
+ *size = ui.length;
+ return true;
+}
diff --git a/lib/libchmfile/libchmfileimpl.h b/lib/libchmfile/libchmfileimpl.h
new file mode 100644
index 0000000..b609b16
--- /dev/null
+++ b/lib/libchmfile/libchmfileimpl.h
@@ -0,0 +1,286 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Portions Copyright (C) 2003 Razvan Cojocaru <razvanco@gmx.net> *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "chm_lib.h"
+
+#include "libchmfile.h"
+#include "libchmtocimage.h"
+
+#include <sys/types.h> /* for u_int{32,64}_t */
+
+//! Keeps the intermediate search result
+class LCHMSearchProgressResult
+{
+ public:
+ inline LCHMSearchProgressResult() {}
+ inline LCHMSearchProgressResult( u_int32_t t, u_int32_t u ) : titleoff(t),urloff(u) {}
+
+ QValueVector<u_int64_t> offsets;
+ u_int32_t titleoff;
+ u_int32_t urloff;
+};
+
+//! An array to keeps the intermediate search results
+typedef QT34VECTOR<LCHMSearchProgressResult> LCHMSearchProgressResults;
+
+
+//! CHM files processor; the implementation
+class LCHMFileImpl
+{
+ public:
+ LCHMFileImpl();
+ ~LCHMFileImpl();
+
+ // Implementations for LCHMFile members
+ bool loadFile( const QString& archiveName );
+ void closeAll();
+
+ QString title() const { return encodeWithCurrentCodec( m_title ); }
+ QString homeUrl() const { return encodeWithCurrentCodec( m_home ); }
+
+ bool getFileContentAsString( QString * str, const QString& url, bool internal_encoding = false );
+ bool getFileContentAsBinary( QByteArray * data, const QString& url ) const;
+ bool getFileSize( unsigned int * size, const QString& url );
+
+ bool enumerateFiles( QStringList * files );
+ QString getTopicByUrl ( const QString& url ) const;
+
+ const QPixmap * getBookIconPixmap( unsigned int imagenum );
+
+ bool setCurrentEncoding( const LCHMTextEncoding * encoding );
+
+ //! Parse the HHC or HHS file, and fill the context (asIndex is false) or index (asIndex is true) array.
+ bool parseFileAndFillArray (const QString& file, QT34VECTOR< LCHMParsedEntry > * data, bool asIndex );
+
+ /*!
+ * \brief Fast search using the $FIftiMain file in the .chm.
+ * \param text The text we're looking for.
+ * \param wholeWords Are we looking for whole words only?
+ * \param titlesOnly Are we looking for titles only?
+ * \param results A string-string hashmap that will hold
+ * the results in case of successful search. The keys are
+ * the URLs and the values are the page titles.
+ * \param phrase_search Indicates that word offset information should be kept.
+ * \return true if the search found something, false otherwise.
+ */
+ bool searchWord( const QString& word,
+ bool wholeWords,
+ bool titlesOnly,
+ LCHMSearchProgressResults& results,
+ bool phrase_search );
+
+ /*!
+ * \brief Finalize the search, resolve the matches, the and generate the results array.
+ * \param tempres Temporary search results from SearchWord.
+ * \param results A string-string hashmap that will hold the results in case of successful search.
+ * The keys are the URLs and the values are the page titles.
+ */
+ void getSearchResults( const LCHMSearchProgressResults& tempres,
+ QStringList * results,
+ unsigned int limit_results = 500 );
+
+ //! Looks up fileName in the archive.
+ bool ResolveObject( const QString& fileName, chmUnitInfo *ui ) const;
+
+ //! Retrieves an uncompressed chunk of a file in the .chm.
+ size_t RetrieveObject(const chmUnitInfo *ui, unsigned char *buffer, LONGUINT64 fileOffset, LONGINT64 bufferSize) const;
+
+ //! Encode the string with the currently selected text codec, if possible. Or return as-is, if not.
+ inline QString encodeWithCurrentCodec (const QString& str) const
+ {
+ return (m_textCodec ? m_textCodec->toUnicode (str) : str);
+ }
+
+ //! Encode the string with the currently selected text codec, if possible. Or return as-is, if not.
+ inline QString encodeWithCurrentCodec (const char * str) const
+ {
+ return (m_textCodec ? m_textCodec->toUnicode (str) : (QString) str);
+ }
+
+ //! Encode the string from internal files with the currently selected text codec, if possible.
+ //! Or return as-is, if not.
+ inline QString encodeInternalWithCurrentCodec (const QString& str) const
+ {
+ return (m_textCodecForSpecialFiles ? m_textCodecForSpecialFiles->toUnicode (str) : str);
+ }
+
+ //! Encode the string from internal files with the currently selected text codec, if possible.
+ //! Or return as-is, if not.
+ inline QString encodeInternalWithCurrentCodec (const char * str) const
+ {
+ return (m_textCodecForSpecialFiles ? m_textCodecForSpecialFiles->toUnicode (str) : (QString) str);
+ }
+
+ //! Helper. Translates from Win32 encodings to generic wxWidgets ones.
+ const char * GetFontEncFromCharSet (const QString& font) const;
+
+ //! Helper. Returns the $FIftiMain offset of leaf node or 0.
+ u_int32_t GetLeafNodeOffset(const QString& text,
+ u_int32_t initalOffset,
+ u_int32_t buffSize,
+ u_int16_t treeDepth );
+
+ //! Helper. Processes the word location code entries while searching.
+ bool ProcessWLC(u_int64_t wlc_count,
+ u_int64_t wlc_size,
+ u_int32_t wlc_offset,
+ unsigned char ds,
+ unsigned char dr,
+ unsigned char cs,
+ unsigned char cr,
+ unsigned char ls,
+ unsigned char lr,
+ LCHMSearchProgressResults& results,
+ bool phrase_search );
+
+ //! Looks up as much information as possible from #WINDOWS/#STRINGS.
+ bool getInfoFromWindows();
+
+ //! Looks up as much information as possible from #SYSTEM.
+ bool getInfoFromSystem();
+
+ //! Fill the topic-url map
+ void fillTopicsUrlMap();
+
+ //! Sets up textCodec
+ void setupTextCodec (const char * name);
+
+ //! Guess used text encoding, using m_detectedLCID and m_font. Set up m_textCodec
+ bool guessTextEncoding ();
+
+ //! Change the current CHM encoding for internal files and texts.
+ //! Encoding could be either simple Qt codepage, or set like CP1251/KOI8, which allows to
+ //! set up encodings separately for text (first) and internal files (second)
+ bool changeFileEncoding( const char *qtencoding );
+
+ //! Convert the word, so it has an appropriate encoding
+ QCString convertSearchWord ( const QString &src );
+
+ /*!
+ * Helper procedure in TOC parsing, decodes the string between the quotes (first or last) with decoding HTML
+ * entities like &iacute;
+ */
+ int findStringInQuotes (const QString& tag, int offset, QString& value, bool firstquote, bool decodeentities );
+
+ /*!
+ * Decodes Unicode HTML entities according to current encoding.
+ */
+ QString decodeEntity (const QString& entity );
+
+ /*!
+ * \brief Returns the list of all available text encodings.
+ * \return A pointer to the beginning of the text encoding table. The table could be
+ * enumerated until language == 0, which means end of table.
+ *
+ * \ingroup encoding
+ */
+ static const LCHMTextEncoding * getTextEncodingTable();
+
+ /*!
+ * \brief Looks up for encoding by LCID
+ * \param lcid LCID to look up
+ * \return A pointer to encoding structure.
+ *
+ * \ingroup encoding
+ */
+ static const LCHMTextEncoding * lookupByLCID( short lcid );
+
+ /*!
+ * \brief Get the encoding index
+ * \param enc Encoding
+ * \return An index in encoding table. getTextEncodingTable() + i gets the encoding.
+ *
+ * \ingroup encoding
+ */
+ static int getEncodingIndex( const LCHMTextEncoding * enc);
+
+ /*!
+ * Normalizes path to search in internal arrays
+ */
+ QString normalizeUrl (const QString& path ) const;
+
+
+ // Members
+
+ //! Pointer to the chmlib structure
+ chmFile * m_chmFile;
+
+ //! Opened file name
+ QString m_filename;
+
+ //! Home url, got from CHM file
+ QString m_home;
+
+ //! Context tree filename. Got from CHM file
+ QString m_topicsFile;
+
+ //! Index filename. Got from CHM file
+ QString m_indexFile;
+
+ //! Chm Title. Got from CHM file
+ QString m_title;
+
+ // Localization stuff
+ //! LCID from CHM file, used in encoding detection
+ short m_detectedLCID;
+
+ //! font charset from CHM file, used in encoding detection
+ QString m_font;
+
+ //! Chosen text codec
+ QTextCodec * m_textCodec;
+ QTextCodec * m_textCodecForSpecialFiles;
+
+ //! Current encoding
+ const LCHMTextEncoding * m_currentEncoding;
+
+ //! Map to decode HTML entitles like &acute; based on current encoding
+ QMap<QString, QString> m_entityDecodeMap;
+
+ //! TRUE if /#TOPICS, /#STRINGS, /#URLTBL and /#URLSTR are resolved, and the members below are valid
+ bool m_lookupTablesValid;
+
+ //! pointer to /#TOPICS
+ chmUnitInfo m_chmTOPICS;
+
+ //! pointer to /#STRINGS
+ chmUnitInfo m_chmSTRINGS;
+
+ //! pointer to /#URLTBL
+ chmUnitInfo m_chmURLTBL;
+
+ //! pointer to /#URLSTR
+ chmUnitInfo m_chmURLSTR;
+
+ //! Indicates whether the built-in search is available. This is true only when m_lookupTablesValid
+ //! is TRUE, and m_chmFIftiMain is resolved.
+ bool m_searchAvailable;
+
+ //! pointer to /$FIftiMain
+ chmUnitInfo m_chmFIftiMain;
+
+ //! Book TOC icon images storage
+ LCHMTocImageKeeper m_imagesKeeper;
+
+ //! Map url->topic
+ QMap< QString, QString > m_url2topics;
+};
diff --git a/lib/libchmfile/libchmtextencoding.cpp b/lib/libchmfile/libchmtextencoding.cpp
new file mode 100644
index 0000000..9ba35ee
--- /dev/null
+++ b/lib/libchmfile/libchmtextencoding.cpp
@@ -0,0 +1,197 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "libchmfileimpl.h"
+#include "libchmtextencoding.h"
+
+static const LCHMTextEncoding text_encoding_table [] =
+{
+ { "Afrikaans",0, 0x0436, 1252, 0, "CP1252" },
+ { "Albanian", 0, 0x041C, 1250, 238, "CP1250" },
+ { "Arabic", "Algeria", 0x1401, 1256, 0, "CP1256" },
+ { "Arabic", "Bahrain", 0x3C01, 1256, 0, "CP1256" },
+ { "Arabic", "Egypt", 0x0C01, 1256, 0, "CP1256" },
+ { "Arabic", "Iraq", 0x0801, 1256, 0, "CP1256" },
+ { "Arabic", "Jordan", 0x2C01, 1256, 0, "CP1256" },
+ { "Arabic", "Kuwait", 0x3401, 1256, 0, "CP1256" },
+ { "Arabic", "Lebanon", 0x3001, 1256, 0, "CP1256" },
+ { "Arabic", "Libya", 0x1001, 1256, 0, "CP1256" },
+ { "Arabic", "Morocco", 0x1801, 1256, 0, "CP1256" },
+ { "Arabic", "Oman", 0x2001, 1256, 0, "CP1256" },
+ { "Arabic", "Qatar", 0x4001, 1256, 0, "CP1256" },
+ { "Arabic", "Saudi Arabia", 0x0401, 1256, 0, "CP1256" },
+ { "Arabic", "Syria", 0x2801, 1256, 0, "CP1256" },
+ { "Arabic", "Tunisia", 0x1C01, 1256, 0, "CP1256" },
+ { "Arabic", "United Arab Emirates", 0x3801, 1256, 178, "CP1256" },
+ { "Arabic", "Yemen", 0x2401, 1256, 0, "CP1256" },
+ { "Armenian", 0, 0x042B, 0, 0, "Latin1" },
+ { "Azeri", "Cyrillic", 0x082C, 1251, 0, "CP1251" },
+ { "Azeri", "Latin", 0x042C, 1254, 162, "CP1254" },
+ { "Basque", 0, 0x042D, 1252, 0, "CP1252" },
+ { "Belarusian", 0, 0x0423, 1251, 0, "CP1251" },
+ { "Bulgarian", 0, 0x0402, 1251, 0, "CP1251" },
+ { "Catalan", 0, 0x0403, 1252, 0, "CP1252" },
+ { "Chinese", "China", 0x0804, 936, 134, "GBK" },
+ { "Chinese", "Hong Kong SAR", 0x0C04, 950, 136, "Big5" },
+ { "Chinese", "Macau SAR", 0x1404, 950, 136, "Big5" },
+ { "Chinese", "Singapore", 0x1004, 936, 134, "GB2313" },
+ { "Chinese", "Taiwan", 0x0404, 950, 136, "Big5" }, // traditional
+ { "Chinese", "Taiwan - Big5-HKSCS", 0x0404, 950, 136, "Big5-HKSCS" },
+ { "Chinese", "Taiwan - GB18030", 0x0404, 950, 136, "GB18030" },
+ { "Croatian", 0, 0x041A, 1250, 238, "CP1250" },
+ { "Czech", 0, 0x0405, 1250, 238, "CP1250" },
+ { "Danish", 0, 0x0406, 1252, 0, "CP1252" },
+ { "Dutch", "Belgium", 0x0813, 1252, 0, "CP1252" },
+ { "Dutch", "The Netherlands", 0x0413, 1252, 0, "CP1252" },
+ { "English", "Australia", 0x0C09, 1252, 0, "CP1252" },
+ { "English", "Belize", 0x2809, 1252, 0, "CP1252" },
+ { "English", "Canada", 0x1009, 1252, 0, "CP1252" },
+ { "English", "Caribbean", 0x2409, 1252, 0, "CP1252" },
+ { "English", "Ireland", 0x1809, 1252, 0, "CP1252" },
+ { "English", "Jamaica", 0x2009, 1252, 0, "CP1252" },
+ { "English", "New Zealand", 0x1409, 1252, 0, "CP1252" },
+ { "English", "Phillippines", 0x3409, 1252, 0, "CP1252" },
+ { "English", "South Africa", 0x1C09, 1252, 0, "CP1252" },
+ { "English", "Trinidad", 0x2C09, 1252, 0, "CP1252" },
+ { "English", "United Kingdom", 0x0809, 1252, 0, "CP1252" },
+ { "English", "United States", 0x0409, 1252, 0, "CP1252" },
+ { "Estonian", 0, 0x0425, 1257, 186, "CP1257" },
+ { "FYRO Macedonian", 0, 0x042F, 1251, 0, "CP1251" },
+ { "Faroese", 0, 0x0438, 1252, 0, "CP1252" },
+ { "Farsi", 0, 0x0429, 1256, 178, "CP1256" },
+ { "Finnish", 0, 0x040B, 1252, 0, "CP1252" },
+ { "French", "Belgium", 0x080C, 1252, 0, "CP1252" },
+ { "French", "Canada", 0x0C0C, 1252, 0, "CP1252" },
+ { "French", "France", 0x040C, 1252, 0, "CP1252" },
+ { "French", "Luxembourg", 0x140C, 1252, 0, "CP1252" },
+ { "French", "Switzerland", 0x100C, 1252, 0, "CP1252" },
+ { "German", "Austria", 0x0C07, 1252, 0, "CP1252" },
+ { "German", "Germany", 0x0407, 1252, 0, "CP1252" },
+ { "German", "Liechtenstein", 0x1407, 1252, 0, "CP1252" },
+ { "German", "Luxembourg", 0x1007, 1252, 0, "CP1252" },
+ { "German", "Switzerland", 0x0807, 1252, 0, "CP1252" },
+ { "Greek", 0, 0x0408, 1253, 161, "CP1253" },
+ { "Hebrew", 0, 0x040D, 1255, 177, "CP1255" },
+ { "Hindi", 0, 0x0439, 0, 0, "Latin1" },
+ { "Hungarian", 0, 0x040E, 1250, 238, "CP1250" },
+ { "Icelandic", 0, 0x040F, 1252, 0, "CP1252" },
+ { "Indonesian", 0, 0x0421, 1252, 0, "CP1252" },
+ { "Italian", "Italy", 0x0410, 1252, 0, "CP1252" },
+ { "Italian", "Switzerland", 0x0810, 1252, 0, "CP1252" },
+ { "Japanese", "Shift-JIS", 0x0411, 932, 128, "Shift-JIS" },
+ { "Japanese", "JIS7", 0x0411, 932, 128, "JIS7" },
+ { "Japanese", "eucJP", 0x0411, 932, 128, "eucJP" },
+ { "Korean", 0, 0x0412, 949, 129, "eucKR" },
+ { "Latvian", 0, 0x0426, 1257, 186, "CP1257" },
+ { "Lithuanian", 0, 0x0427, 1257, 186, "CP1257" },
+ { "Malay", "Brunei", 0x083E, 1252, 0, "CP1252" },
+ { "Malay", "Malaysia", 0x043E, 1252, 0, "CP1252" },
+ { "Maltese", 0, 0x043A, 0, 0, "Latin1" },
+ { "Marathi", 0, 0x044E, 0, 0, "Latin1" },
+ { "Norwegian", "Bokmal", 0x0414, 1252, 0, "CP1252" },
+ { "Norwegian", "Nynorsk", 0x0814, 1252, 0, "CP1252" },
+ { "Polish", 0, 0x0415, 1250, 238, "CP1250" },
+ { "Portuguese", "Brazil", 0x0416, 1252, 0, "CP1252" },
+ { "Portuguese", "Portugal", 0x0816, 1252, 0, "CP1252" },
+ { "Romanian", "Romania", 0x0418, 1250, 238, "CP1250" },
+ { "Russian", "Cyrillic", 0x0419, 1251, 204, "CP1251" },
+ { "Russian", "KOI-8", 0x7001, 2251, 204, "KOI8-R" },
+ { "Russian", "KOI-8 (TOC 1251)", 0x7002, 3251, 0, "CP1251/KOI8-R" },
+ { "Russian", "Cyrillic (TOC KOI8)", 0x7003, 3251, 0, "KOI8-R/CP1251" },
+ { "Sanskrit", 0, 0x044F, 0, 0, "Latin1" },
+ { "Serbian", "Cyrillic", 0x0C1A, 1251, 0, "CP1251" },
+ { "Serbian", "Latin", 0x081A, 1250, 238, "CP1250" },
+ { "Setsuana", 0, 0x0432, 1252, 0, "CP1252" },
+ { "Slovak", 0, 0x041B, 1250, 238, "CP1250" },
+ { "Slovenian", 0, 0x0424, 1250, 238, "CP1250" },
+ { "Spanish", "Argentina", 0x2C0A, 1252, 0, "CP1252" },
+ { "Spanish", "Bolivia", 0x400A, 1252, 0, "CP1252" },
+ { "Spanish", "Chile", 0x340A, 1252, 0, "CP1252" },
+ { "Spanish", "Colombia", 0x240A, 1252, 0, "CP1252" },
+ { "Spanish", "Costa Rica", 0x140A, 1252, 0, "CP1252" },
+ { "Spanish", "Dominican Republic", 0x1C0A, 1252, 0, "CP1252" },
+ { "Spanish", "Ecuador", 0x300A, 1252, 0, "CP1252" },
+ { "Spanish", "El Salvador", 0x440A, 1252, 0, "CP1252" },
+ { "Spanish", "Guatemala", 0x100A, 1252, 0, "CP1252" },
+ { "Spanish", "Honduras", 0x480A, 1252, 0, "CP1252" },
+ { "Spanish", "Mexico", 0x080A, 1252, 0, "CP1252" },
+ { "Spanish", "Nicaragua", 0x4C0A, 1252, 0, "CP1252" },
+ { "Spanish", "Panama", 0x180A, 1252, 0, "CP1252" },
+ { "Spanish", "Paraguay", 0x3C0A, 1252, 0, "CP1252" },
+ { "Spanish", "Peru", 0x280A, 1252, 0, "CP1252" },
+ { "Spanish", "Puerto Rico", 0x500A, 1252, 0, "CP1252" },
+ { "Spanish", "Spain", 0x0C0A, 1252, 0, "CP1252" },
+ { "Spanish", "Uruguay", 0x380A, 1252, 0, "CP1252" },
+ { "Spanish", "Venezuela", 0x200A, 1252, 0, "CP1252" },
+ { "Swahili", 0, 0x0441, 1252, 0, "CP1252" },
+ { "Swedish", "Finland", 0x081D, 1252, 0, "CP1252" },
+ { "Swedish", "Sweden", 0x041D, 1252, 0, "CP1252" },
+ { "Tamil", 0, 0x0449, 0, 0, "TSCII" },
+ { "Tatar", 0, 0x0444, 1251, 204, "CP1251" },
+ { "Thai", 0, 0x041E, 874, 222, "TIS-620" },
+ { "Turkish", 0, 0x041F, 1254, 162, "CP1254" },
+ { "Ukrainian", "Cyrillic", 0x0422, 1251, 0, "CP1251" },
+ { "Ukrainian", "KOI-8", 0x8422, 2251, 204, "KOI8-U" },
+ { "Unicode", "UTF-8", 0x7010, 0, 0, "UTF-8" },
+ { "Unicode", "UTF-16", 0x7011, 0, 0, "UTF-16" },
+ { "Urdu", 0, 0x0420, 1256, 178, "CP1256" },
+ { "Uzbek", "Cyrillic", 0x0843, 1251, 0, "CP1251" },
+ { "Uzbek", "Latin", 0x0443, 1254, 162, "CP1254" },
+ { "Vietnamese", 0, 0x042A, 1258, 163, "CP1258" },
+ { "Xhosa", 0, 0x0434, 1252, 0, "CP1252" },
+ { "Zulu", 0, 0x0435, 1252, 0, "CP1252" },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+
+const LCHMTextEncoding * LCHMFileImpl::getTextEncodingTable()
+{
+ return text_encoding_table;
+}
+
+const LCHMTextEncoding * LCHMFileImpl::lookupByLCID( short lcid )
+{
+ for ( const LCHMTextEncoding * t = text_encoding_table; t->language; t++ )
+ if ( t->winlcid == lcid )
+ return t;
+
+ return 0;
+}
+
+/*
+const LCHMTextEncoding * LCHMFileImpl::lookupByWinCharset( int charset )
+{
+ for ( const text_encoding_t * t = text_encoding_table; t->charset; t++ )
+ if ( t->wincharset == charset )
+ return t;
+
+ return 0;
+}
+*/
+
+int LCHMFileImpl::getEncodingIndex( const LCHMTextEncoding * enc)
+{
+ for ( int i = 0; text_encoding_table[i].language; i++ )
+ if ( (text_encoding_table + i) == enc )
+ return i;
+
+ return -1;
+}
diff --git a/lib/libchmfile/libchmtextencoding.h b/lib/libchmfile/libchmtextencoding.h
new file mode 100644
index 0000000..ff34736
--- /dev/null
+++ b/lib/libchmfile/libchmtextencoding.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef LIBCHMTEXTENCODING_H
+#define LIBCHMTEXTENCODING_H
+
+
+/*!
+ * Represents a text encoding of CHM file; also has some useful routines.
+ */
+typedef struct LCHMTextEncoding
+{
+ const char * language; //! French, English, etc. language == 0 represents the end of table.
+ const char * sublanguage; //! French:Canada, French:France etc. May be 0 - no sublanguage
+ int winlcid; //! Windows LCID for this language
+ int wincodepage; //! Windows codepage for this language.
+ int wincharset; //! Windows charset.
+ const char * qtcodec; //! Qt text codec to use
+};
+
+
+#endif /* LIBCHMTEXTENCODING_H */
diff --git a/lib/libchmfile/libchmtocimage.cpp b/lib/libchmfile/libchmtocimage.cpp
new file mode 100644
index 0000000..c272b10
--- /dev/null
+++ b/lib/libchmfile/libchmtocimage.cpp
@@ -0,0 +1,2112 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "libchmfile.h"
+#include "libchmtocimage.h"
+
+typedef struct
+{
+ unsigned int size;
+ const char * data;
+} png_memory_image_t;
+
+
+static const png_memory_image_t png_image_bookarray[42] =
+{
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x00"
+ "\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x80"
+ "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\xC0\xC0\xC0\x00\xC0\x40\xC0\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x40\xC0"
+ "\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\xFF\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x80\x00\x80\x00"
+ "\x80\x80\x80\x00\x00\x00\x00\x01\x02\x00\x00\x00\x01\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80"
+ "\x00\x80\x00\x80\x00\x80\x00\x80\x80\x80\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x40\xC0\x40\x00\x40\x40\x40\x00\x00\x00\x00\x00\x80\x80\x80\x00\x40\x40\x40\x00\x3F\x3F\x3F"
+ "\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\x80\x00\x80\xFF\x80\x00\x80\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF"
+ "\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80"
+ "\x00\x80\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x00\x00"
+ "\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\xFF\x00\x00\x00"
+ "\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x19\x71\xA3\xBE\x36\x4F\x5A\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80"
+ "\xFF\x40\x40\x40\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x80\x00\x00\x3F\xFF\x3F\x00\x00\x00\x00\x00\x80"
+ "\x80\x80\xFF\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x81\x81\x81\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x40\x40\x40\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x80\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x80\x80"
+ "\x80\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\xFF\xFF\xFF\x00\x80\x00\x80\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x40"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80"
+ "\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x81\x81\x81\x00\x81\x81\x81\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80\xFF\x80\x00\x80\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x80\x00\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xEC\xAF\x46\xD5\x91\xC8\xE3\xA4\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00"
+ "\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00"
+ "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x00"
+ "\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x81\x00\x80"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\x01"
+ "\x00\x00\x00\x81\x00\x80\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00"
+ "\x80\x00\x00\x00\x00\x00\x7F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x40\x40"
+ "\x00\x00\x00\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x80\x00\x81\x00\x80\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\xFF\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x80\x00\x40\xC0\x40\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\xC0\x40\xC0\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x80\x00\x80\x00"
+ "\x80\x80\x80\x00\x00\x00\x00\x01\x02\x00\x00\x00\x01\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80"
+ "\x00\x80\x00\x80\x00\x80\x00\x80\x80\x80\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x40\xC0\x40\x00\x40\x40\x40\x00\x00\x00\x00\x00\x80\x80\x80\x00\x40\x40\x40\x00\x3F\x3F\x3F"
+ "\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\x80\x00\x80\xFF\x80\x00\x80\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF"
+ "\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80"
+ "\x00\x80\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x00\x00"
+ "\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\xFF\x00\x00\x00"
+ "\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0B\x78\x8F\xD2\x1A\xFF\x32\x3B\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00"
+ "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x80\x80"
+ "\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x80\x80\x80\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF"
+ "\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x04\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x7F\xFF\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x80\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x02\x01"
+ "\x00\x00\x01\x01\x00\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\xFF\xFF\xFF\x00\x80\x00\x80\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x7F\x00\x80"
+ "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\x00\xFF\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x40"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80"
+ "\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x81\x81\x81\x00\x81\x81\x81\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80\xFF\x80\x00\x80\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x80\x00\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xB6\x69\xF8\x9A\x72\x7B\xFD\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x80\x80\x80\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00"
+ "\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x80\x80\x80\xFF\x7F\x7F\x80\x00\xC1\xC1\xC0\x00"
+ "\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x7F\x7F\x40\x00\x00\x00\x80\xFF\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00"
+ "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00"
+ "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0"
+ "\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80"
+ "\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00"
+ "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF"
+ "\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF"
+ "\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF"
+ "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0"
+ "\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF"
+ "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF"
+ "\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF"
+ "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF"
+ "\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x80\x80"
+ "\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\x7B\x78\xBB\x65\xD9\x1C\xEF\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x80\x80\x80\xFF\x7F\x7F\x7F\x00\x00\x00\x01\x00"
+ "\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\x7F\x7F\xFF\x00\x00\x00\x00\xFF\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00"
+ "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF"
+ "\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\xC1\xC1\xC1\x00"
+ "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x80\x00\x81\x81\x80\x00\x80\x80\x80\x00\x04\x00\x00\x00\x00\x7F\x7F"
+ "\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00"
+ "\x00\x00\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00"
+ "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00"
+ "\x00\x01\x00\x7F\x7F\x80\x00\x80\x80\x80\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0"
+ "\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF"
+ "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF"
+ "\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF"
+ "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF"
+ "\x00\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xCA\x77\x06\x21\xB0\x9C\x3D\x2E\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00"
+ "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00"
+ "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00"
+ "\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x81\x81\x80\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00"
+ "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01"
+ "\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\xFF\x00\x00\xC1\xC0\xC0\x00"
+ "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80"
+ "\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00"
+ "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF"
+ "\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF"
+ "\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF"
+ "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0"
+ "\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF"
+ "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF"
+ "\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF"
+ "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF"
+ "\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x80\x80"
+ "\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x67\x79\x5A\x0A\xDD\xD6\x45\x4D\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00"
+ "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00"
+ "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x04\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x7F\xFF\xFF\x00\x00\x00\x00\xFF\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\xFF"
+ "\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF"
+ "\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01"
+ "\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\xFF\x00\x00\xC1\xC0\xC0\x00"
+ "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x81\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\xC0\xC0\x00\x3F"
+ "\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0\x80\x00\x00\x00\xC0\x00\xC0\xC0\x80\x00\x00\x00\xC0\x00\xC0\xC0"
+ "\x80\x00\x00\x00\xC0\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\xC0\xC0\xC0\xFF"
+ "\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00"
+ "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00"
+ "\x00\x01\x00\x7F\x7F\x80\x00\x80\x80\x80\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0"
+ "\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF"
+ "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF"
+ "\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF"
+ "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF"
+ "\x00\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94\x33\x28\x09\x1C\xAE\x31\x32\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\xFF\x00\x00\x00\xFF\x00\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x00\x00\x01\x00\xFF\xFF\xFF\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00"
+ "\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE8\x04\x5D\xFD\xA0\x80\xC9\x63\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x81\x81\x80\x00\x00\x00\x00\x00\x80"
+ "\x80\x80\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\xFF\x00"
+ "\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x01\x01\x00\x01\x01\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x00\x00\x01\x00\xFF\xFF\xFF\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\x00\x00\x00\x00\x00\xFF\x00\x01\x00\xFF"
+ "\xFF\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\xFF\x00\x00\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00"
+ "\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x22\x4F\x1D\x9B\xFC\x6D\x6C\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01"
+ "\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x01\x01\x00\x00"
+ "\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\xFF\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE3\xD9\x62\x47\xFA\x28\x6C\x06\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
+ "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00"
+ "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x01"
+ "\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00"
+ "\x00\x00\xFF\xFF\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00"
+ "\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\xFF\xFF\x00\xFF\xFF\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2D\x7C\x8C\x20\x93\x9B\xCB\xA7\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0"
+ "\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x3F\x00\x00\x80\x81\x00\x00\x00\x00\x00\x00\x80"
+ "\x7F\x00\x00\x00\x00\x00\xC0\xC0\xC1\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF"
+ "\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x80\x00\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x00\x80\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF"
+ "\x7F\x7F\x7F\x00\xC1\xC1\xC1\x00\x40\xC0\xC0\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x01\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x01\x81"
+ "\x01\x00\x80\x00\x80\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC0"
+ "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0"
+ "\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\xC1\xC1\xC1\x00\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\xC0"
+ "\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\xC0\x00\x00\x00\x40"
+ "\x40\x3F\x00\xC0\xC0\xC1\x00\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\xC0\x40\x40\x00\x40\x40\x3F\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x01\x00\x3F\x3F\x3F\x00\xFF\xFF\xFF\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\x40\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x7F\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01"
+ "\x01\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x80\xFF\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40"
+ "\x01\x00\x00\x81\x00\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\x00\x00\x81\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\xC0\x00\x00\x00\x00\x00\x80\x80\x00"
+ "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x32\x9B\x2E\x2D\x01\x77\x57\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00"
+ "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00"
+ "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x80\x80\xFF\x00\x80\x80\xFF\x00\x00"
+ "\xFF\xFF\x00\x00\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF"
+ "\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x80\x00\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x00\x80\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x01\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x3F\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80"
+ "\x00\x00\xFF\x80\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC0"
+ "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x40\x40"
+ "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x80\xFF\x00\x81\x80\x80\x00\x00\xFF\xFF\x00"
+ "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\xC0"
+ "\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x80\x00\xC0\xC1\xC1\x00\x3F"
+ "\x00\x00\x00\xC0\xC0\xC1\x00\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\xC0\x40\x40\x00\x40\x40\x3F\x00\x01\x00\xFF\x00\x40\xC0\xC0\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x3F\x00\xFF\xFF\xFF\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\x40\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x7F\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01"
+ "\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x80\xFF\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40"
+ "\x01\x00\x00\x81\x00\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\x00\x00\x81\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\xC0\x00\x00\x00\x00\x00\x80\x80\x00"
+ "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x2B\xAD\x4B\x8B\x6D\x23\xB6\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0"
+ "\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x3F\x00\x00\x80\x81\x00\x00\x00\x00\x00\x00\x80"
+ "\x7F\x00\x00\x00\x00\x00\xC0\xC0\xC1\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF"
+ "\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x80\x00\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x00\x80\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF"
+ "\x7F\x7F\x7F\x00\xC1\xC1\xC1\x00\x40\xC0\xC0\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x01\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x01\x81"
+ "\x01\x00\x80\x00\x80\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC0"
+ "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0"
+ "\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\xC1\xC1\xC1\x00\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\xC0"
+ "\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\xC0\x00\x00\x00\x40"
+ "\x40\x3F\x00\xC0\xC0\xC1\x00\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x81\x81\x00\x00\x00"
+ "\x00\x00\xC0\x40\x40\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\xC0\x40\x40\x00\x40\x40\x3F\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x81\x80\x00\xFF\x7F\x7F\x00\x80\x00\x00\x00\x40\x40\xC0\x00\xC0\xC0\xC0\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\x40\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81"
+ "\x81\x81\x00\x80\x00\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x80\xFF\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x7F\x00\x00\x80\xFF\x00\x00\x00\x00"
+ "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x80\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\x00\xFF\x00\x00\x80\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\x40\x40\x81\x00\x00"
+ "\x00\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x7F\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\xC0\x00\x00\x00\x00\x00\x80\x80\x00"
+ "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF5\x35\xB3\xDB\x47\x22\xC5\x3E\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00"
+ "\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00"
+ "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x80\x80\xFF\x00\x80\x80\xFF\x00\x00"
+ "\xFF\xFF\x00\x00\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF"
+ "\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x80\x00\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x00\x80\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x01\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x3F\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80"
+ "\x00\x00\xFF\x80\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC0"
+ "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x40\x40"
+ "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x80\xFF\x00\x81\x80\x80\x00\x00\xFF\xFF\x00"
+ "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\xC0"
+ "\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x80\x00\xC0\xC1\xC1\x00\x3F"
+ "\x00\x00\x00\xC0\xC0\xC1\x00\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x81\x81\x00\x00\x00"
+ "\x00\x00\xC0\x40\x40\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\xC0\x40\x40\x00\x40\x40\x3F\x00\x01\x00\xFF\x00\x40\xC0\xC0\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x81\x80\x00\xFF\x7F\x7F\x00\x80\x00\x00\x00\x40\x40\xC0\x00\xC0\xC0\xC0\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\x40\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81"
+ "\x81\x81\x00\x80\x00\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x80\xFF\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x7F\x00\x00\x80\xFF\x00\x00\x00\x00"
+ "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x80\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\x00\xFF\x00\x00\x80\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\x40\x40\x81\x00\x00"
+ "\x00\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x7F\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\xC0\x00\x00\x00\x00\x00\x80\x80\x00"
+ "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD7\xDE\xC4\xFF\x42\xC7\x9B\xA9\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x80"
+ "\x80\x80\x00\xC1\xC1\xC1\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x80\x80\x80\x00\x3F\x3F\x3F\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x01\x00"
+ "\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x7F\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
+ "\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\xFF\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x75\x7A\xA1\xB2\x30\x65\x74\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80"
+ "\x80\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00"
+ "\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00"
+ "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00"
+ "\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\xFF\x00\x00\x00\x81\x80\x80\x00\x3F\x3F\x3F\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\xFF\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xA2\xDD\xCE\xCA\x46\xBC\x69\xD0\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x7F\xFF\x7F\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x81\x01\x81\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x7F\xFF"
+ "\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x01\x00\x00\x00\x00\x00\x7F\xFF\x80\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\x7F\xFF\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00"
+ "\x81\x01\x81\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7E\x13\x5A\xB8\x0F\x88\x51\xFF\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80"
+ "\x80\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00"
+ "\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00"
+ "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x80\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x02\x00"
+ "\x00\x00\x00\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x7F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x81\x00\x80\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x7F\xFF"
+ "\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x01\x00\x00\x00\x00\x00\x7F\xFF\x80\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\x7F\xFF\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00"
+ "\x81\x01\x81\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD9\x8B\x81\x99\x2A\x3C\x4C\x83\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\x00"
+ "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00"
+ "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x80\x00\x80"
+ "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x80\x80"
+ "\x80\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\xC0\xC0\xC0"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x80\x80\x80\x00\xFF\xFF\xFF\x00\xC1\xC1\xC1\x00\x40"
+ "\x40\x40\x00\x01\x80\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC9\x37\xA7\x79\xF8\x99\x78\xFD\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x81\x80\x80\x00"
+ "\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x81\x81\x80\x00\x81\x81\x81\x00\x01"
+ "\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00"
+ "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x80\x00\x80"
+ "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x80\x80"
+ "\x80\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\xC0\xC0\xC0"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x80\x80\x80\x00\xFF\xFF\xFF\x00\xC1\xC1\xC1\x00\x40"
+ "\x40\x40\x00\x01\x80\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7E\xFB\xBE\x76\x34\x86\xB8\x07\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x40\x40\x40\x00\xC0\xC0\xC0\x00\x40\x40"
+ "\x40\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x80\x80\x80"
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x01\x00\x00"
+ "\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x80\x80\x80\x00\x00\x00\x00\x00\x04\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0"
+ "\xFF\x40\x40\x40\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x01\x01\x01\x00\xFF"
+ "\xFF\xFF\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x01\x00\x00\x00\xFF\x00\x40\x40\x40\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\x01\x00\xFF\xFF\x00"
+ "\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\x00\x01\x01\x01\x00\x80\x80\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00"
+ "\x3F\x3F\x40\x00\xC0\xC0\xC0\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x3F\x3F\x3F\x00\x80\x80"
+ "\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x00\x00\x00\x01\x00\x81\x81\x01\x00\x40\x40\xC0\x00\x80\x80\x00\x00\x01\x01\x01\x00"
+ "\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0\x00\xC0\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x40"
+ "\x40\xC0\x00\x00\x00\x00\x00\x40\x40\xC0\x00\x80\x80\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00"
+ "\x00\x00\x40\x40\xC0\x00\xC0\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\x80\x80\x00\xC0\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD7\x04\xC0\x9D\x86\xE8\xEF\xDB\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\x00\x00\xFF\xFF\x00"
+ "\x00\xFF\x80\x80\x80\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xC0\xC0\xC0"
+ "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x02\x01"
+ "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0"
+ "\xC0\x00\x00\x00\x00\x00\x00\x01\x01\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x3F\x3F\x40\x00\x00\xFF\xFF\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF"
+ "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x80\x80\x00\xFF"
+ "\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00"
+ "\x3F\x3F\x40\x00\xC0\xC0\xC0\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x3F\x3F\x3F\x00\x80\x80"
+ "\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x00\x00\x00\x01\x00\x81\x81\x01\x00\x40\x40\xC0\x00\x80\x80\x00\x00\x01\x01\x01\x00"
+ "\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0\x00\xC0\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x40"
+ "\x40\xC0\x00\x00\x00\x00\x00\x40\x40\xC0\x00\x80\x80\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00"
+ "\x00\x00\x40\x40\xC0\x00\xC0\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\x80\x80\x00\xC0\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xAA\x18\xF9\xFF\xA4\xB4\xD4\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x80\x80\x80\xFF\x80\x80\x80\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\xFF\xFF\x00"
+ "\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0"
+ "\x00\x40\x40\x40\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x01\x01\x00\x80\x80\x80\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x80\x80\x80\x00\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01\x01"
+ "\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00"
+ "\x40\x40\x40\x00\x80\x80\x80\x00\x01\x01\x01\x00\x80\x80\x80\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\xC0\xC0"
+ "\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00"
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x80\x80\x80\x00\xFF"
+ "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD1\xD0\x9F\x60\xE3\xE0\x4D\xCB\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01"
+ "\x00\x00\x01\xC1\xC0\xC0\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0"
+ "\xC0\x00\x00\x00\x00\x00\x00\x01\x01\x00\xC1\xC1\xC1\x00\x01\x01\x00\x00\x01\x01\x01\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\x00\x00"
+ "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\x00\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\x01\x01\x01\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\xFF\x00\x3F\x3F\x3F\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01"
+ "\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00"
+ "\x40\x40\x40\x00\x80\x80\x80\x00\x01\x01\x01\x00\x80\x80\x80\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\xC0\xC0"
+ "\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00"
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x80\x80\x80\x00\xFF"
+ "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE9\xB2\xE9\x24\xBC\x59\xC0\x67\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x01\x81\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xC0\xC0\xC0"
+ "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x80\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
+ "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0"
+ "\xFF\x00\x00\x80\xFF\x80\x80\x00\x00\x00\x00\x00\x00\x01\x01\x81\x00\x01\x01\x81\x00\xC1\xC1\xC0\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\xFF\x00\xFF\xFF"
+ "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00"
+ "\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\x00\x00\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x80\x80\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x01\x01\x80\x00\xFF\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x80\xFF\x00\xFF\x00\xFF\x00\x00\x00\xFF\x00\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00"
+ "\x00\x01\x80\x00\x00\x00\x00\x00\x00\x01\x00\x00\x80\x80\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x89\x0B\xF3\xB4\x69\x4F\x85\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x80\xFF\xFF\xFF\x00"
+ "\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x80"
+ "\x80\xFF\x00\x00\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00"
+ "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
+ "\xFF\x00\x00\x00\x00\xC1\xC0\xC0\x00\x40\x40\xC0\x00\x00\x80\x00\x00\x00\x00\x00\x00\x01\x01\x81\x00"
+ "\x00\x00\x00\x00\xC0\xC0\x40\x00\x3F\x3F\x3F\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x80\xFF\xFF"
+ "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\xFF\x00"
+ "\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\xFF\x00"
+ "\x00\x00\x01\x01\x80\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80\x80\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x80\xFF\x00\xFF\x00\xFF\x00\x00\x00\xFF\x00\xFF\x00\xFF"
+ "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x00\x00\x80"
+ "\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97\x2A\x21\x92\x43\x90\x14\x7B\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x80\x00"
+ "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x01\x00\x7F\x7F"
+ "\xFF\x00\x80\x80\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x7F\x7F\xFF\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\x40\x00\x7F\x7F\xFF\x00\x00"
+ "\x00\x01\x00\x80\x80\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01"
+ "\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\x40\x00\x7F\x7F\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x80\x80\x00\x00\xC0\xC0\xC0"
+ "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\x00\x81\x81\x81\x00\x01\x01\x01\x00\x81\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\xFF\x80\x80\x00\xFF\xFF\xFF\x00\xFF\x00\x00"
+ "\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x00\xFF\x80\x80\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80"
+ "\x80\x00\xFF\x00\x00\x00\x00\x40\x40\xC1\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF"
+ "\xFF\x00\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\xC0\xC0\x40"
+ "\x00\x00\x00\xC0\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\xC1\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x34\xE6\xE2\x1F\x81\x45\x95\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x80\x00"
+ "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x00\x00\x00\x81\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01"
+ "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x00\x00\x7F\x7F"
+ "\xFF\x00\x80\x80\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
+ "\xFF\x00\xFF\xFF\x00\x81\x80\x00\x00\x7F\x7F\xFF\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\xC0\x81\x01\x00\x7F\x7F\xFF\x00\x00"
+ "\x00\x01\x00\x80\x80\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01"
+ "\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\x40\x00\x7F\x7F\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x80\x80\x00\x00\xC0\xC0\xC0"
+ "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\xFF\x00\x81\x81\x81\x00\x01\x01\x01\x00\x81\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\xFF\x80\x80\x00\xFF\xFF\xFF\x00\xFF\x00\x00"
+ "\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x00\xFF\x80\x80\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80"
+ "\x80\x00\xFF\x00\x00\x00\x00\x40\x40\xC1\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF"
+ "\xFF\x00\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\xC0\xC0\x40"
+ "\x00\x00\x00\xC0\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\xC1\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD0\x0C\x16\x8A\x64\xF0\xC0\x3D\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF"
+ "\x00\x00\x00\x00\x01\x01\x01\x00\x01\x01\x01\x00\x81\x81\x81\x00\x01\x01\x00\x00\xC1\xC1\xC1\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x04\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\x40\x00\x00\xFF\xFF\x00\x80\x00\x00\x00\x40\x40"
+ "\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\xC0\xC0\x80\x00\x7F\x7F\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00"
+ "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x02\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0"
+ "\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0"
+ "\xC0\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\xFF\x80\x80\x00\xFF\x00\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x80\x80\x80"
+ "\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x81\x00\x00"
+ "\x40\x00\xC0\x00\x00\x80\x80\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\xC0\xC0\xC0\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00"
+ "\x00\x00\x00\x00\x80\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC0\x80\x80\x00\x40\x40"
+ "\x40\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\xFF\x7F\x80\x00\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x80\x00\x00\x00\xC0\xC0\xC0"
+ "\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00"
+ "\xC1\xC1\xC0\x00\x80\x7F\x3F\x00\x00\x80\x01\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\x80\x80\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F"
+ "\x00\x00\x00\x00\x00\x00\x81\x81\x00\x00\x80\x80\x00\x00\xC0\xC0\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x40"
+ "\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xBE\x4D\x07\xF0\xED\x63\x0A\xFD\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\xC1\xC0\xC0\x00"
+ "\x81\x81\x81\x00\x01\x00\x00\x00\x01\x00\x00\x00\x81\x81\x81\x00\x01\x01\x00\x00\xC1\xC1\xC1\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x04\x01"
+ "\x00\x00\x01\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\x40\x00\x00\xFF\xFF\x00\x80\x00\x00\x00\x40\x40"
+ "\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\xC0\xC0\x80\x00\x7F\x7F\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00"
+ "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x02\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0"
+ "\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0"
+ "\xC0\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\xFF\x80\x80\x00\xFF\x00\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x80\x80\x80"
+ "\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x81\x00\x00"
+ "\x40\x00\xC0\x00\x00\x80\x80\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\xC0\xC0\xC0\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00"
+ "\x00\x00\x00\x00\x80\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC0\x80\x80\x00\x40\x40"
+ "\x40\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\xFF\x7F\x80\x00\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x80\x00\x00\x00\xC0\xC0\xC0"
+ "\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00"
+ "\xC1\xC1\xC0\x00\x80\x7F\x3F\x00\x00\x80\x01\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\x80\x80\xFF\xC0\xC0"
+ "\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F"
+ "\x00\x00\x00\x00\x00\x00\x81\x81\x00\x00\x80\x80\x00\x00\xC0\xC0\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x40"
+ "\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x76\x2F\x35\xC9\x77\x48\x56\x41\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x80"
+ "\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x80\x80\xFF\x00\x00\x00\x00\x40\x40\x40"
+ "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x7F\x7F\x80\x00\x00\x00\xFF\x00\x81\x81\x81\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40"
+ "\x40\x40\x00\x04\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x40\x40\x40\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x81\x81\x81\x00\x01\x01\x00\x00\x80\x80"
+ "\x81\x00\x00\x00\x00\x00\x80\x80\x80\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0"
+ "\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x01\x00\x00\x00\x00\x80\x80\x80\x00\x40\x40\x40\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x01\x01\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40"
+ "\x40\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x80\x80\x80"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80"
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xB6\x05\xC9\xAB\x7C\x77\xA6\xA1\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01"
+ "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x80\x80\x80\xFF\x00\x00\x00\x00\xFF\x00\x00"
+ "\xFF\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00"
+ "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x80\x80\x80\xFF\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00"
+ "\x00\x00\x81\x81\x81\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x00\x04\x00\x00\x00\x00\x80\x80"
+ "\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\xFF\xFF\xFF"
+ "\x00\x00\x00\x00\x00\x81\x81\x81\x00\x01\x01\x01\x00\x80\x80\x80\x00\x00\x00\x00\x00\x80\x80\x80\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00"
+ "\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00"
+ "\x00\x00\x01\x00\x00\x00\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x80"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x3F\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x40\x40\x40\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\x35\xD6\xA3\x81\xA7\xB0\x8B\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\x00\x00\xFF\x00"
+ "\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x3F"
+ "\x00\x81\x81\x80\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x00\x01\x01\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00"
+ "\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00"
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x67\x35\x86\x1E\xD6\xF6\xF1\x59\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x00\xFF"
+ "\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01"
+ "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00"
+ "\xFF\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00"
+ "\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x81\x81\x81\x00\x40\x40\x3F"
+ "\x00\x81\x81\x80\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x00\x01\x01\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00"
+ "\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00"
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\x34\xBA\xF9\x00\x88\x01\xD9\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x3F\x3F\x3F\x00\x01\x01"
+ "\x00\x00\xFF\xFF\x00\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\xFF\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xFF\xFF\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\xC0\xC0\x80\x00\x00\x00\x81"
+ "\x00\x7F\x7F\x80\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF"
+ "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF"
+ "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x7F\x7F\x80\x00\x00\x00\xFF\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xC0\xC0\xC0\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\x80\x80\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x3F\x3F\x3F\x00\xC1"
+ "\xC1\xC0\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x40\x40\x40\x00\x81\x81\x80\x00\x00\x00\x01\x00\xC0\xC0\xC0\x00\x7F\x7F\x80\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x40\x40\x40\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF"
+ "\x80\x80\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x7F"
+ "\x7F\x80\x00\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x81\x81\x80\x00\x80\x80\x80\x00\x80\x80\x80"
+ "\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\xD9\xC6\x01\x2A\xF1\x62\x54\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xC1\xC0\xC0\x00\x3F\x40\x40\x00\x00\x00"
+ "\x00\x00\x00\xFF\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\xFF"
+ "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x80\x80"
+ "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF"
+ "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF"
+ "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x01"
+ "\x00\x00\x01\x01\x00\x00\x01\x81\x80\x80\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xC0\xC0\xC0\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\x80\x80\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x3F\x3F\x3F\x00\xC1"
+ "\xC1\xC0\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x40\x40\x40\x00\x81\x81\x80\x00\x00\x00\x01\x00\xC0\xC0\xC0\x00\x7F\x7F\x80\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x40\x40\x40\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF"
+ "\x80\x80\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x7F"
+ "\x7F\x80\x00\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x81\x81\x80\x00\x80\x80\x80\x00\x80\x80\x80"
+ "\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x35\x50\x04\xC5\x7F\x63\x55\x6E\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x01\x01\x00\x00\xFF\xFF"
+ "\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00"
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF"
+ "\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x02\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x01\x01"
+ "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00"
+ "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
+ "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x40\x40\x40\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x01\x01\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\xFF"
+ "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x80\x80\x80\x00\xC1\xC1\xC1\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00"
+ "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40"
+ "\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00"
+ "\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\xD8\x09\x7C\xF1\x24\x22\x3A\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01"
+ "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x01\x01\x00\x00\xFF\xFF"
+ "\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\x00\x00"
+ "\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\xC1\xC0\xC0\x00\x00\xFF\xFF\x00"
+ "\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\xFF\x00\x00\x01\x01\x01\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\xFF\xFF\xFF\x00\x00"
+ "\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x01\x01"
+ "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00"
+ "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00"
+ "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x40\x40\x40\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x01\x01\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\xFF"
+ "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x80\x80\x80\x00\xC1\xC1\xC1\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00"
+ "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40"
+ "\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00"
+ "\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF"
+ "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00"
+ "\x00\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\xE9\x1F\xBE\x0F\x02\xCD\x5F\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xFF\x80\x80\x80\xFF\x00"
+ "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xFF\xFF\x00\x00\x01\x01\x00\xFF\xFF\xFF"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00"
+ "\x00\x00\x00\x01\x00\x01\x01\x00\x00\xFF\xFF\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\x80\x80\x80\x00\x00\x00"
+ "\x00\x00\x80\x80\x80\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\x80\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\xFF\x80\x80\x80\x00\x80"
+ "\x80\x80\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x40\x40\x40\xFF\xFF\xFF\xFF\x00\x01\x01\x01\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\xC1\xC1\xC1\x00\x3F\x3F\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x00\x01\x01\x00\x00\x7F\x7F\x00\x00\x80\x80\x00\x01"
+ "\x01\x01\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\xFF\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x80\x7F\x7F\x00\x00\xFF\xFF"
+ "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x80\x80\x80\x00"
+ "\x00\x7F\x7F\x00\x80\x81\x81\x00\x00\x01\x01\x00\x00\x01\x01\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\xFF\xFF\xFF\x00\x00\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\xC1\xC1\xC0\x00\xC1\xC1\xC1"
+ "\x00\xC0\xC0\xC0\x00\x00\x01\x01\x00\x00\xFF\xFF\x00\x01\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80"
+ "\x80\x80\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFC\x80\xFB\x9C\x8E\x95\x3D\x08\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+},
+
+{
+ 1108,
+ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08"
+ "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00"
+ "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00"
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF"
+ "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00"
+ "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01"
+ "\x00\x00\x01\xC1\xC0\xC0\x00\x81\x80\x80\x00\x01\x01\x01\x00\x01\x01\x01\x00\x80\x80\x80\x00\x01\xFF"
+ "\xFF\x00\x80\x80\x80\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\x80\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00"
+ "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\xFF\x80\x80\x80\x00\x80"
+ "\x80\x80\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00"
+ "\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x40\x40\x40\xFF\xFF\xFF\xFF\x00\x01\x01\x01\x00\x00\xFF\xFF"
+ "\x00\x00\x00\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\xC1\xC1\xC1\x00\x3F\x3F\xFF\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\xC0\xC0\xC0\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x00\x01\x01\x00\x00\x7F\x7F\x00\x00\x80\x80\x00\x01"
+ "\x01\x01\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x01\x00\xFF\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x80\x7F\x7F\x00\x00\xFF\xFF"
+ "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x80\x80\x80\x00"
+ "\x00\x7F\x7F\x00\x80\x81\x81\x00\x00\x01\x01\x00\x00\x01\x01\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\xFF\xFF\xFF\x00\x00\x00\xFF\xFF\xFF"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\xC1\xC1\xC0\x00\xC1\xC1\xC1"
+ "\x00\xC0\xC0\xC0\x00\x00\x01\x01\x00\x00\xFF\xFF\x00\x01\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80"
+ "\x80\x80\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x98\x02\xAF\x81\x39\xA0\x85\x00\x00\x00\x00"
+ "\x49\x45\x4E\x44\xAE\x42\x60\x82"
+}
+
+};
+
+
+LCHMTocImageKeeper::LCHMTocImageKeeper( )
+{
+ for ( int i = 0; i < LCHMBookIcons::MAX_BUILTIN_ICONS; i++ )
+ {
+ const png_memory_image_t * image = png_image_bookarray + i;
+
+ if ( !m_images[i].loadFromData ((const uchar*)image->data, image->size, "PNG") )
+ qFatal ( "Could not load image %d", i );
+ }
+}
+
+const QPixmap * LCHMTocImageKeeper::getImage( int id )
+{
+ if ( id < 0 || id > LCHMBookIcons::MAX_BUILTIN_ICONS )
+ qFatal("LCHMTocImageKeeper::getImage: requested image id (%d) is out of range (%d)", id, LCHMBookIcons::MAX_BUILTIN_ICONS );
+
+ return &m_images[id];
+}
diff --git a/lib/libchmfile/libchmtocimage.h b/lib/libchmfile/libchmtocimage.h
new file mode 100644
index 0000000..73f84da
--- /dev/null
+++ b/lib/libchmfile/libchmtocimage.h
@@ -0,0 +1,32 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+//! This class is used to retrieve the book TOC icons associated with images
+class LCHMTocImageKeeper
+{
+ public:
+ LCHMTocImageKeeper();
+ const QPixmap * getImage( int id );
+
+ private:
+ QPixmap m_images[LCHMBookIcons::MAX_BUILTIN_ICONS];
+};
diff --git a/lib/libchmfile/libchmurlfactory.h b/lib/libchmfile/libchmurlfactory.h
new file mode 100644
index 0000000..29ac433
--- /dev/null
+++ b/lib/libchmfile/libchmurlfactory.h
@@ -0,0 +1,122 @@
+/***************************************************************************
+ * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <qdir.h>
+#include <qstring.h>
+#include <qregexp.h>
+
+namespace LCHMUrlFactory
+{
+
+static inline bool isRemoteURL( const QString & url, QString & protocol )
+{
+ // Check whether the URL is external
+ QRegExp uriregex ( "^(\\w+):\\/\\/" );
+ QRegExp mailtoregex ( "^(mailto):" );
+
+ // mailto: can also have different format, so handle it
+ if ( url.startsWith( "mailto:" ) )
+ {
+ protocol = "mailto";
+ return true;
+ }
+ else if ( uriregex.search ( url ) != -1 )
+ {
+ QString proto = uriregex.cap ( 1 ).lower();
+
+ // Filter the URLs which need to be opened by a browser
+ if ( proto == "http"
+ || proto == "ftp"
+ || proto == "mailto"
+ || proto == "news" )
+ {
+ protocol = proto;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Some JS urls start with javascript://
+static inline bool isJavascriptURL( const QString & url )
+{
+ return url.startsWith ("javascript://");
+}
+
+// Parse urls like "ms-its:file name.chm::/topic.htm"
+static inline bool isNewChmURL( const QString & url, QString & chmfile, QString & page )
+{
+ QRegExp uriregex ( "^ms-its:(.*)::(.*)$" );
+
+ if ( uriregex.search ( url ) != -1 )
+ {
+ chmfile = uriregex.cap ( 1 );
+ page = uriregex.cap ( 2 );
+
+ return true;
+ }
+
+ return false;
+}
+
+static inline QString makeURLabsoluteIfNeeded( const QString & url )
+{
+ QString p1, p2, newurl = url;
+
+ if ( !isRemoteURL (url, p1)
+ && !isJavascriptURL (url)
+ && !isNewChmURL (url, p1, p2) )
+ {
+ newurl = QDir::cleanDirPath (url);
+
+ // Normalize url, so it becomes absolute
+ if ( newurl[0] != '/' )
+ newurl = "/" + newurl;
+ }
+
+ //qDebug ("makeURLabsolute (%s) -> (%s)", url.ascii(), newurl.ascii());
+ return newurl;
+}
+
+
+// Returns a special string, which allows the kio-slave, or viewwindow-browser iteraction
+// to regognize our own internal urls, which is necessary to show image-only pages.
+static inline QString getInternalUriExtension()
+{
+ return ".KCHMVIEWER_SPECIAL_HANDLER";
+}
+
+
+static inline bool handleFileType( const QString& link, QString& generated )
+{
+ QString intext = getInternalUriExtension();
+
+ if ( !link.endsWith( intext ) )
+ return false;
+
+ QString filelink = link.left( link.length() - strlen( intext ) );
+ generated = "<html><body><img src=\"" + filelink + "\"></body></html>";
+ return true;
+}
+
+
+};
diff --git a/lib/libchmfile/qt34.cpp b/lib/libchmfile/qt34.cpp
new file mode 100644
index 0000000..fd7028a
--- /dev/null
+++ b/lib/libchmfile/qt34.cpp
@@ -0,0 +1,259 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Albert Astals Cid, aacid@kde.org *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <qdir.h>
+
+#include "qt34.h"
+
+LIBCHMCString::LIBCHMCString()
+{
+}
+
+LIBCHMCString::LIBCHMCString(const char *string)
+{
+#if defined (USE_QT_4)
+ cs = QByteArray(string);
+#else
+ cs = QCString(string);
+#endif
+}
+
+
+const char *LIBCHMCString::toCString() const
+{
+ return cs.data();
+}
+
+
+void LIBCHMCString::clear()
+{
+#if defined (USE_QT_4)
+ cs = QByteArray();
+#else
+ cs = QCString();
+#endif
+}
+
+bool LIBCHMCString::operator==(const QString &string) const
+{
+ return QString(cs) == string;
+}
+
+uint LIBCHMCString::length() const
+{
+ return cs.length();
+}
+
+bool LIBCHMCString::isEmpty() const
+{
+ return cs.isEmpty();
+}
+
+void LIBCHMCString::prepend(char c)
+{
+ cs = c + cs;
+}
+
+char LIBCHMCString::at(uint i) const
+{
+ return cs.at(i);
+}
+
+void LIBCHMCString::replace(uint index, uint len, const char *str)
+{
+ cs.replace(index, len, str);
+}
+
+void LIBCHMCString::remove(uint index, uint len)
+{
+ cs.remove(index, len);
+}
+
+LIBCHMCString LIBCHMCString::lower()
+{
+#if defined (USE_QT_4)
+ return cs.toLower().data();
+#else
+ return cs.lower().data();
+#endif
+}
+
+
+
+LIBCHMRegExp::LIBCHMRegExp(const QString &regexp)
+{
+ re = QRegExp(regexp);
+}
+
+int LIBCHMRegExp::search(const QString &str, int offset)
+{
+#if defined (USE_QT_4)
+ return re.indexIn(str, offset);
+#else
+ return re.search(str, offset);
+#endif
+}
+
+QString LIBCHMRegExp::cap(int nth)
+{
+ return re.cap(nth);
+}
+
+void LIBCHMRegExp::setMinimal(bool minimal)
+{
+ return re.setMinimal(minimal);
+}
+
+int LIBCHMRegExp::matchedLength() const
+{
+ return re.matchedLength();
+}
+
+
+
+
+LIBCHMString::LIBCHMString()
+{
+}
+
+LIBCHMString::LIBCHMString(const QString &string)
+{
+ s = string;
+}
+
+LIBCHMString::LIBCHMString(const char *string)
+{
+ s = QString(string);
+}
+
+QString LIBCHMString::lower() const
+{
+#if defined (USE_QT_4)
+ return s.toLower();
+#else
+ return s.lower();
+#endif
+}
+
+const char *LIBCHMString::ascii() const
+{
+#if defined (USE_QT_4)
+ return s.toAscii();
+#else
+ return s.ascii();
+#endif
+}
+
+int LIBCHMString::find(char c, int index) const
+{
+#if defined (USE_QT_4)
+ return s.indexOf(c, index);
+#else
+ return s.find(c, index);
+#endif
+}
+
+int LIBCHMString::find(const QChar &c, int index) const
+{
+#if defined (USE_QT_4)
+ return s.indexOf(c, index);
+#else
+ return s.find(c, index);
+#endif
+}
+
+int LIBCHMString::find(const QString &string, int index, bool cs) const
+{
+#if defined (USE_QT_4)
+ Qt::CaseSensitivity cse;
+ if (cs) cse = Qt::CaseSensitive;
+ else cse = Qt::CaseInsensitive;
+ return s.indexOf(string, index, cse);
+#else
+ return s.find(string, index, cs);
+#endif
+}
+
+int LIBCHMString::findRev(char c) const
+{
+#if defined (USE_QT_4)
+ return s.lastIndexOf(c);
+#else
+ return s.findRev(c);
+#endif
+}
+
+QChar LIBCHMString::at(uint i) const
+{
+ return s.at(i);
+}
+
+QString LIBCHMString::left(uint len) const
+{
+ return s.left(len);
+}
+
+LIBCHMString LIBCHMString::mid(uint index, uint len) const
+{
+ return s.mid(index, len);
+}
+
+bool LIBCHMString::isEmpty() const
+{
+ return s.isEmpty();
+}
+
+QString LIBCHMString::toString() const
+{
+ return s;
+}
+
+bool LIBCHMString::operator==(const QString &string) const
+{
+ return s == string;
+}
+
+
+
+QString LIBCHMDir::cleanDirPath(const QString &dir)
+{
+#if defined (USE_QT_4)
+ return QDir::cleanPath(dir);
+#else
+ return QDir::cleanDirPath(dir);
+#endif
+}
+
+
+
+bool LIBCHMStringList::contains(const QStringList &list, const QString &string)
+{
+ return list.contains(string);
+}
+
+QStringList LIBCHMStringList::split(const QRegExp &regexp, const QString &string)
+{
+#if defined (USE_QT_4)
+ return string.split(regexp, QString::SkipEmptyParts);
+#else
+ return QStringList::split(regexp, string);
+#endif
+}
diff --git a/lib/libchmfile/qt34.h b/lib/libchmfile/qt34.h
new file mode 100644
index 0000000..0835b0a
--- /dev/null
+++ b/lib/libchmfile/qt34.h
@@ -0,0 +1,123 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Albert Astals Cid, aacid@kde.org *
+ * Please do not use email address above for bug reports; see *
+ * the README file *
+ * *
+ * 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 2 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef INCLUDE_QT34_H
+#define INCLUDE_QT34_H
+
+#include <qregexp.h>
+#include <qstring.h>
+
+// Qt3/Qt4 compatibility: in Qt3 QVector stores pointers, not values - so QValueVector should be used.
+// In Qt4 QVector stores values, so we can use QVector
+#if defined (USE_QT_4)
+ #define LIBCHMVector QVector
+#else
+#include <qvaluevector.h>
+ #define LIBCHMVector QValueVector
+#endif
+
+#if defined (USE_QT_4)
+ #define LIBCHMMemArray QVector
+#else
+ #define LIBCHMMemArray QMemArray
+#endif
+
+class LIBCHMCString
+{
+ public:
+ LIBCHMCString();
+ LIBCHMCString(const char *string);
+
+ const char *toCString() const;
+
+ void clear();
+
+ bool operator==(const QString &string) const;
+ uint length() const;
+ bool isEmpty() const;
+ void prepend(char c);
+ char at(uint i) const;
+ void replace(uint index, uint len, const char *str);
+ void remove(uint index, uint len);
+ LIBCHMCString lower();
+
+ private:
+#if defined (USE_QT_4)
+ QByteArray cs;
+#else
+ QCString cs;
+#endif
+};
+
+class LIBCHMRegExp
+{
+ public:
+ LIBCHMRegExp(const QString &regexp);
+
+ int search(const QString &str, int offset = 0);
+ QString cap(int nth);
+ void setMinimal(bool minimal);
+ int matchedLength() const;
+
+ private:
+ QRegExp re;
+};
+
+class LIBCHMString
+{
+ public:
+ LIBCHMString();
+ LIBCHMString(const QString &string);
+ LIBCHMString(const char *string);
+
+ QString lower() const;
+ const char *ascii() const;
+ int find(char c, int index = -1) const;
+ int find(const QChar &c, int index) const;
+ int find(const QString &string, int index, bool cs) const;
+ int findRev(char c) const;
+ QChar at(uint i) const;
+ QString left(uint len) const;
+ LIBCHMString mid(uint index, uint len = 0xffffffff) const;
+ bool isEmpty() const;
+
+ QString toString() const;
+
+ bool operator==(const QString &string) const;
+
+ private:
+ QString s;
+};
+
+class LIBCHMDir
+{
+ public:
+ static QString cleanDirPath(const QString &dir);
+};
+
+class LIBCHMStringList
+{
+ public:
+ static bool contains(const QStringList &list, const QString &string);
+ static QStringList split(const QRegExp &regexp, const QString &string);
+};
+
+#endif