diff --git a/cmake/modules/FindLibZip.cmake b/cmake/modules/FindLibZip.cmake new file mode 100644 index 000000000..a39f0e4c2 --- /dev/null +++ b/cmake/modules/FindLibZip.cmake @@ -0,0 +1,34 @@ +# - Try to find libzip +# Once done this will define +# +# LIBZIP_FOUND - system has the zip library +# LIBZIP_INCLUDE_DIR - the zip include directory +# LIBZIP_LIBRARY - Link this to use the zip library +# +# Copyright (c) 2006, Pino Toscano, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +if (LIBZIP_LIBRARY AND LIBZIP_INCLUDE_DIR) + # in cache already + set(LIBZIP_FOUND TRUE) +else (LIBZIP_LIBRARY AND LIBZIP_INCLUDE_DIR) + + find_path(LIBZIP_INCLUDE_DIR zip.h + ${GNUWIN32_DIR}/include + ) + + find_library(LIBZIP_LIBRARY NAMES zip + PATHS + ${GNUWIN32_DIR}/lib + ) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibZip DEFAULT_MSG LIBZIP_LIBRARY LIBZIP_INCLUDE_DIR) + + # ensure that they are cached + set(LIBZIP_INCLUDE_DIR ${LIBZIP_INCLUDE_DIR} CACHE INTERNAL "The libzip include path") + set(LIBZIP_LIBRARY ${LIBZIP_LIBRARY} CACHE INTERNAL "The libraries needed to use libzip") + +endif (LIBZIP_LIBRARY AND LIBZIP_INCLUDE_DIR) diff --git a/generators/CMakeLists.txt b/generators/CMakeLists.txt index 026cbce81..08e2124af 100644 --- a/generators/CMakeLists.txt +++ b/generators/CMakeLists.txt @@ -1,153 +1,160 @@ function(okular_add_generator _target) kcoreaddons_add_plugin(${_target} JSON "lib${_target}.json" INSTALL_NAMESPACE "okular/generators" SOURCES ${ARGN} ) endfunction() find_package(Poppler "0.12.1" COMPONENTS Qt5) set_package_properties("Poppler" PROPERTIES TYPE RECOMMENDED PURPOSE "Support for PDF files in okular.") set(LIBSPECTRE_MINIMUM_VERSION "0.2") find_package(LibSpectre "${LIBSPECTRE_MINIMUM_VERSION}") set_package_properties(LibSpectre PROPERTIES DESCRIPTION "A PostScript rendering library" URL "http://libspectre.freedesktop.org/wiki/" TYPE RECOMMENDED PURPOSE "Support for PS files in okular.") find_package(KF5KExiv2 CONFIG) set_package_properties("LibKExiv2" PROPERTIES DESCRIPTION "Wrapper around Exiv2 library" URL "http://www.digikam.org/sharedlibs" TYPE RECOMMENDED PURPOSE "Support for image files") find_package(CHM) set_package_properties("CHM" PROPERTIES DESCRIPTION "A library for dealing with Microsoft ITSS/CHM format files" URL "http://www.jedrea.com/chmlib" TYPE RECOMMENDED PURPOSE "Support CHM files in okular.") find_package(KF5KHtml CONFIG) set_package_properties("KF5KHtml" PROPERTIES DESCRIPTION "HTML rendering library" TYPE RECOMMENDED PURPOSE "Support CHM files in okular.") +find_package(LibZip) +set_package_properties("LibZip" PROPERTIES + DESCRIPTION "A library for dealing with Microsoft ITSS/CHM format files" + URL "http://www.jedrea.com/chmlib" + TYPE RECOMMENDED + PURPOSE "Support CHM files in okular.") + find_package(DjVuLibre "3.5.17") set_package_properties("DjVuLibre" PROPERTIES DESCRIPTION "A library for dealing with DjVu formatted files" URL "http://djvulibre.djvuzone.org" TYPE RECOMMENDED PURPOSE "Support for DjVu files in okular.") find_package(TIFF) set_package_properties("libTIFF" PROPERTIES DESCRIPTION "A library for reading and writing TIFF formatted files," URL "http://www.remotesensing.org/libtiff" TYPE RECOMMENDED PURPOSE "Support for TIFF files in okular.") find_package(Freetype) set_package_properties("FreeType" PROPERTIES DESCRIPTION "A font rendering engine" URL "http://www.freetype.org" TYPE RECOMMENDED PURPOSE "Provides freetype font support in the okular DVI generator.") find_package(JPEG) set_package_properties("JPEG" PROPERTIES DESCRIPTION "A library for reading and writing JPEG image files." URL "http://www.ijg.org" TYPE RECOMMENDED PURPOSE "Support for PalmDB documents in okular.") find_package(ZLIB) set_package_properties("ZLib" PROPERTIES DESCRIPTION "The Zlib compression library" URL "http://www.zlib.net" TYPE RECOMMENDED PURPOSE "Support for Plucker files in Okular.") find_package(EPub) set_package_properties("libepub" PROPERTIES DESCRIPTION "A library for reading EPub documents" URL "http://sourceforge.net/projects/ebook-tools" TYPE RECOMMENDED PURPOSE "Support for EPub documents in Okular.") find_package(QMobipocket "2" CONFIG) set_package_properties("libqmobipocket" PROPERTIES DESCRIPTION "A library for reading Mobipocket documents" URL "https://commits.kde.org/kdegraphics-mobipocket" TYPE RECOMMENDED PURPOSE "Support for Mobipocket documents in Okular.") find_package(Discount "2") set_package_properties("discount" PROPERTIES DESCRIPTION "A library that gives you formatting functions suitable for marking down entire documents or lines of text" URL "http://www.pell.portland.or.us/~orc/Code/discount/" TYPE RECOMMENDED PURPOSE "Support for Markdown documents in Okular.") # let's enable the generators properly configured if(Poppler_Qt5_FOUND) add_subdirectory(poppler) endif(Poppler_Qt5_FOUND) if(LIBSPECTRE_FOUND) add_subdirectory(spectre) endif(LIBSPECTRE_FOUND) if(KF5KExiv2_FOUND) add_subdirectory( kimgio ) endif() -if(CHM_FOUND AND KF5KHtml_FOUND) +if(CHM_FOUND AND KF5KHtml_FOUND AND LIBZIP_FOUND) add_subdirectory( chm ) endif() if(DJVULIBRE_FOUND) add_subdirectory(djvu) endif(DJVULIBRE_FOUND) add_subdirectory(dvi) if(TIFF_FOUND) add_subdirectory(tiff) endif(TIFF_FOUND) add_subdirectory(xps) add_subdirectory(ooo) add_subdirectory(fictionbook) add_subdirectory(comicbook) add_subdirectory(fax) if(JPEG_FOUND AND ZLIB_FOUND) add_subdirectory(plucker) endif(JPEG_FOUND AND ZLIB_FOUND) if(EPUB_FOUND) add_subdirectory(epub) endif(EPUB_FOUND) add_subdirectory(txt) if(QMobipocket_FOUND) add_subdirectory(mobipocket) endif() if(discount_FOUND) add_subdirectory(markdown) endif() diff --git a/generators/chm/CMakeLists.txt b/generators/chm/CMakeLists.txt index 8957fd938..9d82b9394 100644 --- a/generators/chm/CMakeLists.txt +++ b/generators/chm/CMakeLists.txt @@ -1,41 +1,46 @@ remove_definitions(-DTRANSLATION_DOMAIN="okular") add_definitions(-DTRANSLATION_DOMAIN="okular_chm") add_subdirectory( kio-msits ) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../.. ${CHM_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib + ${LIBZIP_INCLUDE_DIR} ) ########### next target ############### set(okularGenerator_chmlib_SRCS - lib/lchmurlhandler.cpp - lib/libchmfile.cpp - lib/libchmfileimpl.cpp - lib/libchmfile_search.cpp - lib/libchmtextencoding.cpp - lib/libchmtocimage.cpp + lib/ebook_chm.cpp + lib/ebook_epub.cpp + lib/ebook.cpp + lib/ebook_chm_encoding.cpp + lib/ebook_search.cpp + lib/helper_entitydecoder.cpp + lib/helper_search_index.cpp + lib/helperxmlhandler_epubcontainer.cpp + lib/helperxmlhandler_epubcontent.cpp + lib/helperxmlhandler_epubtoc.cpp generator_chm.cpp ) okular_add_generator(okularGenerator_chmlib ${okularGenerator_chmlib_SRCS}) -target_link_libraries(okularGenerator_chmlib okularcore ${CHM_LIBRARY} KF5::KHtml) +target_link_libraries(okularGenerator_chmlib okularcore ${CHM_LIBRARY} ${LIBZIP_LIBRARY} KF5::KHtml) ########### autotests ############### add_definitions( -DKDESRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/" ) ecm_add_test(autotests/chmgeneratortest.cpp TEST_NAME "chmgeneratortest" LINK_LIBRARIES Qt5::Test KF5::CoreAddons okularcore ) target_compile_definitions(chmgeneratortest PRIVATE -DGENERATOR_PATH="$") ########### install files ############### install( FILES okularChm.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) install( PROGRAMS okularApplication_chm.desktop org.kde.mobile.okular_chm.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) install( FILES org.kde.okular-chm.metainfo.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/generators/chm/generator_chm.cpp b/generators/chm/generator_chm.cpp index b6a770ece..4913f46f3 100644 --- a/generators/chm/generator_chm.cpp +++ b/generators/chm/generator_chm.cpp @@ -1,450 +1,448 @@ /*************************************************************************** * Copyright (C) 2005 by Piotr Szymański * * Copyright (C) 2008 by Albert Astals Cid * * * * 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. * ***************************************************************************/ #include "generator_chm.h" -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include #include #include #include #include #include #include #include #include OKULAR_EXPORT_PLUGIN(CHMGenerator, "libokularGenerator_chmlib.json") static QString absolutePath( const QString &baseUrl, const QString &path ) { QString absPath; if ( path.startsWith(QLatin1Char( '/' )) ) { // already absolute absPath = path; } else { QUrl url = QUrl::fromLocalFile( baseUrl ).adjusted(QUrl::RemoveFilename); url.setPath( url.path() + path ); absPath = url.toLocalFile(); } return absPath; } CHMGenerator::CHMGenerator( QObject *parent, const QVariantList &args ) : Okular::Generator( parent, args ) { setFeature( TextExtraction ); m_syncGen=0; m_file=0; m_request = 0; } CHMGenerator::~CHMGenerator() { delete m_syncGen; } bool CHMGenerator::loadDocument( const QString & fileName, QVector< Okular::Page * > & pagesVector ) { - m_file = new LCHMFile(); - if (!m_file->loadFile(fileName)) + m_file = new EBook_CHM(); + m_file = EBook::loadFile( fileName ); + if (!m_file) { - delete m_file; - m_file = 0; return false; } m_fileName=fileName; - QVector< LCHMParsedEntry > topics; - m_file->parseTableOfContents(&topics); + QList< EBookTocEntry > topics; + m_file->getTableOfContents(topics); // fill m_docSyn QMap lastIndentElement; QMap tmpPageList; int pageNum = 0; - foreach(const LCHMParsedEntry &e, topics) + foreach(const EBookTocEntry &e, topics) { QDomElement item = m_docSyn.createElement(e.name); - if (!e.urls.isEmpty()) + if (!e.url.isEmpty()) { - QString url = e.urls.first(); - if (url.contains(QChar::fromLatin1('%'))) - url = QString::fromUtf8(QByteArray::fromPercentEncoding(url.toUtf8())); + QString url = e.url.toString(); item.setAttribute(QStringLiteral("ViewportName"), url); if(!tmpPageList.contains(url)) {//add a page only once tmpPageList.insert(url, pageNum); pageNum++; } } - item.setAttribute(QStringLiteral("Icon"), e.imageid); + item.setAttribute(QStringLiteral("Icon"), e.iconid); if (e.indent == 0) m_docSyn.appendChild(item); else lastIndentElement[e.indent - 1].appendChild(item); lastIndentElement[e.indent] = item; } // fill m_urlPage and m_pageUrl - QStringList pageList; - m_file->enumerateFiles(&pageList); - const QString home = m_file->homeUrl(); + QList pageList; + m_file->enumerateFiles(pageList); + const QString home = m_file->homeUrl().toString(); if (home != QLatin1String("/")) pageList.prepend(home); m_pageUrl.resize(pageNum); - foreach (const QString &url, pageList) + foreach (const QUrl &qurl, pageList) { + QString url = qurl.toString(); const QString urlLower = url.toLower(); if (!urlLower.endsWith(QLatin1String(".html")) && !urlLower.endsWith(QLatin1String(".htm"))) continue; int pos = url.indexOf (QLatin1Char(('#'))); // insert the url into the maps, but insert always the variant without the #ref part QString tmpUrl = pos == -1 ? url : url.left(pos); // url already there, abort insertion if (m_urlPage.contains(tmpUrl)) continue; int foundPage = tmpPageList.value(tmpUrl, -1); if (foundPage != -1 ) { m_urlPage.insert(tmpUrl, foundPage); m_pageUrl[foundPage] = tmpUrl; } else { //add pages not present in toc m_urlPage.insert(tmpUrl, pageNum); m_pageUrl.append(tmpUrl); pageNum++; } } pagesVector.resize(m_pageUrl.count()); m_textpageAddedList.fill(false, pagesVector.count()); m_rectsGenerated.fill(false, pagesVector.count()); if (!m_syncGen) { m_syncGen = new KHTMLPart(); } disconnect( m_syncGen, 0, this, 0 ); for (int i = 0; i < m_pageUrl.count(); ++i) { preparePageForSyncOperation(m_pageUrl.at(i)); pagesVector[ i ] = new Okular::Page (i, m_syncGen->view()->contentsWidth(), m_syncGen->view()->contentsHeight(), Okular::Rotation0 ); } connect( m_syncGen, SIGNAL(completed()), this, SLOT(slotCompleted()) ); connect( m_syncGen, &KParts::ReadOnlyPart::canceled, this, &CHMGenerator::slotCompleted ); return true; } bool CHMGenerator::doCloseDocument() { // delete the document information of the old document delete m_file; m_file=0; m_textpageAddedList.clear(); m_rectsGenerated.clear(); m_urlPage.clear(); m_pageUrl.clear(); m_docSyn.clear(); if (m_syncGen) { m_syncGen->closeUrl(); } return true; } void CHMGenerator::preparePageForSyncOperation(const QString & url) { - QString pAddress= QStringLiteral("ms-its:") + m_fileName + QStringLiteral("::") + url; + QString pAddress = QStringLiteral("ms-its:") + m_fileName + QStringLiteral("::") + m_file->urlToPath(QUrl(url)); m_chmUrl = url; m_syncGen->openUrl(QUrl(pAddress)); m_syncGen->view()->layout(); QEventLoop loop; connect( m_syncGen, SIGNAL(completed()), &loop, SLOT(quit()) ); connect( m_syncGen, &KParts::ReadOnlyPart::canceled, &loop, &QEventLoop::quit ); // discard any user input, otherwise it breaks the "synchronicity" of this // function loop.exec( QEventLoop::ExcludeUserInputEvents ); } void CHMGenerator::slotCompleted() { if ( !m_request ) return; QImage image( m_request->width(), m_request->height(), QImage::Format_ARGB32 ); image.fill( Qt::white ); QPainter p( &image ); QRect r( 0, 0, m_request->width(), m_request->height() ); bool moreToPaint; m_syncGen->paint( &p, r, 0, &moreToPaint ); p.end(); if ( !m_textpageAddedList.at( m_request->pageNumber() ) ) { additionalRequestData(); m_textpageAddedList[ m_request->pageNumber() ] = true; } m_syncGen->closeUrl(); m_chmUrl = QString(); userMutex()->unlock(); Okular::PixmapRequest *req = m_request; m_request = 0; if ( !req->page()->isBoundingBoxKnown() ) updatePageBoundingBox( req->page()->number(), Okular::Utils::imageBoundingBox( &image ) ); req->page()->setPixmap( req->observer(), new QPixmap( QPixmap::fromImage( image ) ) ); signalPixmapRequestDone( req ); } Okular::DocumentInfo CHMGenerator::generateDocumentInfo( const QSet &keys ) const { Okular::DocumentInfo docInfo; if ( keys.contains( Okular::DocumentInfo::MimeType ) ) docInfo.set( Okular::DocumentInfo::MimeType, QStringLiteral("application/x-chm") ); if ( keys.contains( Okular::DocumentInfo::Title ) ) docInfo.set( Okular::DocumentInfo::Title, m_file->title() ); return docInfo; } const Okular::DocumentSynopsis * CHMGenerator::generateDocumentSynopsis() { return &m_docSyn; } bool CHMGenerator::canGeneratePixmap () const { bool isLocked = true; if ( userMutex()->tryLock() ) { userMutex()->unlock(); isLocked = false; } return !isLocked; } void CHMGenerator::generatePixmap( Okular::PixmapRequest * request ) { int requestWidth = request->width(); int requestHeight = request->height(); userMutex()->lock(); QString url= m_pageUrl[request->pageNumber()]; - QString pAddress= QStringLiteral("ms-its:") + m_fileName + QStringLiteral("::") + url; + QString pAddress= QStringLiteral("ms-its:") + m_fileName + QStringLiteral("::") + m_file->urlToPath(QUrl(url)); m_chmUrl = url; m_syncGen->view()->resizeContents(requestWidth,requestHeight); m_request=request; // will emit openURL without problems m_syncGen->openUrl ( QUrl(pAddress) ); } void CHMGenerator::recursiveExploreNodes(DOM::Node node,Okular::TextPage *tp) { if (node.nodeType() == DOM::Node::TEXT_NODE && !node.getRect().isNull()) { QString nodeText=node.nodeValue().string(); QRect r=node.getRect(); int vWidth=m_syncGen->view()->width(); int vHeight=m_syncGen->view()->height(); Okular::NormalizedRect *nodeNormRect; #define NOEXP #ifndef NOEXP int x,y,height; int x_next,y_next,height_next; int nodeTextLength = nodeText.length(); if (nodeTextLength==1) { nodeNormRect=new Okular::NormalizedRect (r,vWidth,vHeight); tp->append(nodeText,nodeNormRect,nodeNormRect->bottom,0,(nodeText=="\n")); } else { for (int i=0;iappend(nodeText,nodeNormRect/*,0*/); #endif } DOM::Node child = node.firstChild(); while ( !child.isNull() ) { recursiveExploreNodes(child,tp); child = child.nextSibling(); } } void CHMGenerator::additionalRequestData() { Okular::Page * page=m_request->page(); const bool genObjectRects = !m_rectsGenerated.at( m_request->page()->number() ); const bool genTextPage = !m_request->page()->hasTextPage() && genObjectRects; if (genObjectRects || genTextPage ) { DOM::HTMLDocument domDoc=m_syncGen->htmlDocument(); // only generate object info when generating a full page not a thumbnail if ( genObjectRects ) { QLinkedList< Okular::ObjectRect * > objRects; int xScale=m_syncGen->view()->width(); int yScale=m_syncGen->view()->height(); // getting links DOM::HTMLCollection coll=domDoc.links(); DOM::Node n; QRect r; if (! coll.isNull() ) { int size=coll.length(); for(int i=0;ipage()->setObjectRects( objRects ); m_rectsGenerated[ m_request->page()->number() ] = true; } if ( genTextPage ) { Okular::TextPage *tp=new Okular::TextPage(); recursiveExploreNodes(domDoc,tp); page->setTextPage (tp); } } } Okular::TextPage* CHMGenerator::textPage( Okular::Page * page ) { userMutex()->lock(); m_syncGen->view()->resize(page->width(), page->height()); preparePageForSyncOperation(m_pageUrl[page->number()]); Okular::TextPage *tp=new Okular::TextPage(); recursiveExploreNodes( m_syncGen->htmlDocument(), tp); userMutex()->unlock(); return tp; } QVariant CHMGenerator::metaData( const QString &key, const QVariant &option ) const { if ( key == QLatin1String("NamedViewport") && !option.toString().isEmpty() ) { const int pos = option.toString().indexOf(QLatin1Char('#')); QString tmpUrl = pos == -1 ? option.toString() : option.toString().left(pos); Okular::DocumentViewport viewport; QMap::const_iterator it = m_urlPage.find(tmpUrl); if (it != m_urlPage.end()) { viewport.pageNumber = it.value(); return viewport.toString(); } } else if ( key == QLatin1String("DocumentTitle") ) { return m_file->title(); } return QVariant(); } /* kate: replace-tabs on; tab-width 4; */ #include "generator_chm.moc" diff --git a/generators/chm/generator_chm.h b/generators/chm/generator_chm.h index 1485bc8aa..25295bf90 100644 --- a/generators/chm/generator_chm.h +++ b/generators/chm/generator_chm.h @@ -1,71 +1,71 @@ /*************************************************************************** * Copyright (C) 2005 by Piotr Szymański * * Copyright (C) 2008 by Albert Astals Cid * * * * 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. * ***************************************************************************/ #ifndef _OKULAR_CHMGENERATOR_H_ #define _OKULAR_CHMGENERATOR_H_ #include #include -#include "lib/libchmfile.h" +#include "lib/ebook_chm.h" #include class KHTMLPart; namespace Okular { class TextPage; } namespace DOM { class Node; } class CHMGenerator : public Okular::Generator { Q_OBJECT Q_INTERFACES( Okular::Generator ) public: CHMGenerator( QObject *parent, const QVariantList &args ); ~CHMGenerator(); bool loadDocument( const QString & fileName, QVector< Okular::Page * > & pagesVector ) override; Okular::DocumentInfo generateDocumentInfo( const QSet &keys ) const override; const Okular::DocumentSynopsis * generateDocumentSynopsis() override; bool canGeneratePixmap() const override; void generatePixmap( Okular::PixmapRequest * request ) override; QVariant metaData( const QString & key, const QVariant & option ) const override; public Q_SLOTS: void slotCompleted(); protected: bool doCloseDocument() override; Okular::TextPage* textPage( Okular::Page *page ) override; private: void additionalRequestData(); void recursiveExploreNodes( DOM::Node node, Okular::TextPage *tp ); void preparePageForSyncOperation( const QString &url ); QMap m_urlPage; QVector m_pageUrl; Okular::DocumentSynopsis m_docSyn; - LCHMFile* m_file; + EBook* m_file; KHTMLPart *m_syncGen; QString m_fileName; QString m_chmUrl; Okular::PixmapRequest* m_request; QBitArray m_textpageAddedList; QBitArray m_rectsGenerated; }; #endif diff --git a/generators/chm/lib/bitfiddle.h b/generators/chm/lib/bitfiddle.h index eb15b0fa9..d62088683 100644 --- a/generators/chm/lib/bitfiddle.h +++ b/generators/chm/lib/bitfiddle.h @@ -1,157 +1,170 @@ /* Copyright (C) 2003 Razvan Cojocaru 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include -#define UINT16ARRAY(x) ((unsigned char)(x)[0] | ((uint16_t)(x)[1] << 8)) -#define UINT32ARRAY(x) (UINT16ARRAY(x) | ((uint32_t)(x)[2] << 16) \ - | ((uint32_t)(x)[3] << 24)) +inline unsigned short UINT16ARRAY( const void * x ) +{ + unsigned char * p = (unsigned char *) x; + return p[0] | (p[1] << 8); +} + +inline unsigned int UINT32ARRAY( const void * x ) +{ + unsigned char * p = (unsigned char *) x; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +} + +inline int INT32ARRAY( const void * x ) +{ + char * p = (char *) x; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[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 uint64_t be_encint(unsigned char* buffer, size_t& length) +inline quint64 be_encint(unsigned char* buffer, size_t& length) { - uint64_t result = 0; + quint64 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 uint64_t sr_int(unsigned char* byte, int* bit, +inline quint64 sr_int(unsigned char* byte, int* bit, unsigned char s, unsigned char r, size_t& length) { - uint64_t ret; + quint64 ret; unsigned char mask; int n, n_bits, num_bits, base, count; length = 0; size_t fflen; if(!bit || *bit > 7 || s != 2) - return ~(uint64_t)0; + return ~(quint64)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)) | - (uint64_t)((*byte & mask) >> base); + (quint64)((*byte & mask) >> base); if( n > *bit ){ ++byte; ++length; n -= *bit+1; *bit = 7; } else { *bit -= n; n = 0; } } if(count) - ret |= (uint64_t)1 << n_bits; + ret |= (quint64)1 << n_bits; return ret; } diff --git a/generators/chm/lib/ebook.cpp b/generators/chm/lib/ebook.cpp new file mode 100644 index 000000000..f66e32d30 --- /dev/null +++ b/generators/chm/lib/ebook.cpp @@ -0,0 +1,52 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ebook.h" +#include "ebook_chm.h" +#include "ebook_epub.h" + +const char * const INTERNAL_URL_SCHEME = "kchm"; + +EBook::EBook() +{ +} + + +EBook::~EBook() +{ +} + +EBook * EBook::loadFile( const QString &archiveName ) +{ + EBook_CHM * cbook = new EBook_CHM(); + + if ( cbook->load( archiveName ) ) + return cbook; + + delete cbook; + + + EBook_EPUB * ebook = new EBook_EPUB(); + + if ( ebook->load( archiveName ) ) + return ebook; + + delete ebook; + return 0; +} + diff --git a/generators/chm/lib/ebook.h b/generators/chm/lib/ebook.h new file mode 100644 index 000000000..2f12b5c81 --- /dev/null +++ b/generators/chm/lib/ebook.h @@ -0,0 +1,233 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef INCLUDE_EBOOK_H +#define INCLUDE_EBOOK_H + +#include +#include +#include + +//! Stores a single table of content entry +class EBookTocEntry +{ + public: + //! Content TOC icon indexes for CHM books (epub books contain no icons) + enum Icon + { + IMAGE_NONE = -1, + IMAGE_AUTO = -2, + + MAX_BUILTIN_ICONS = 42 + }; + + //! Entry name + QString name; + + //! Entry URL. + QUrl url; + + //! Associated image number. Used for TOC only; indexes does not have the image. + //! If IMAGE_NONE, no icon is associated. Otherwise use getBookIconPixmap() to get associated pixmap icon. + Icon iconid; + + //! Indentation level for this entry. + int indent; +}; + + +//! Stores a single index entry +class EBookIndexEntry +{ + public: + //! Entry name + QString name; + + //! Entry URLs. The index entry could have several URLs + QList urls; + + //! Whether this is a 'see also' index type, and its value + QString seealso; + + //! Indentation level for this entry. + int indent; +}; + + +//! Universal ebook files processor supporting both CHM and EPUB. Abstract. +class EBook +{ + public: + enum Feature + { + FEATURE_TOC, // has table of contents + FEATURE_INDEX, // has index + FEATURE_ENCODING // Could be encoded with different encodings + }; + + //! Default constructor and destructor. + EBook(); + virtual ~EBook(); + + /*! + * \brief Attempts to load chm or epub file. + * \param archiveName filename. + * \return EBook object on success, NULL on failure. + * + * Loads a CHM or epub file. For CHM files it could internally load more than one file, + * if files linked to this one are present locally (like MSDN). + * \ingroup init + */ + static EBook * loadFile( const QString& archiveName ); + + /*! + * \brief Closes all the files, and frees the appropriate data. + * \ingroup init + */ + virtual void close() = 0; + + /*! + * \brief Gets the title name of the opened ebook. + * \return The name of the opened document, or an empty string if no ebook has been loaded. + * \ingroup information + */ + virtual QString title() const = 0; + + /*! + * \brief Gets the default URL of the e-book which should be opened when the book it first open + * + * \return The home page name, with a '/' added in front and relative to + * the root of the archive filesystem. If no book has been opened, returns "/". + * \ingroup information + */ + virtual QUrl homeUrl() const = 0; + + /*! + * \brief Checks whether the specific feature is present in this file. + * \return true if it is available; false otherwise. + * \ingroup information + */ + virtual bool hasFeature( Feature code ) const = 0; + + /*! + * \brief Parses and fills up 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 files; please report a bug if the file is opened ok under Windows. + * \ingroup fileparsing + */ + virtual bool getTableOfContents( QList< EBookTocEntry >& toc ) const = 0; + + /*! + * \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 + */ + virtual bool getIndex( QList< EBookIndexEntry >& index ) const = 0; + + /*! + * \brief Retrieves the content associated with the url from the current ebook as 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. Note content may be an empty string. + * + * This function retreives the file content (mostly for HTML pages) from the ebook. Because the content + * in chm file might not be stored in Unicode, it will be recoded according to current encoding. + * Do not use for binary data. + * + * \sa setCurrentEncoding() currentEncoding() getFileContentAsBinary() + * \ingroup dataretrieve + */ + virtual bool getFileContentAsString( QString& str, const QUrl& url ) const = 0; + + /*! + * \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 + */ + virtual bool getFileContentAsBinary( QByteArray& data, const QUrl& url ) const = 0; + + /*! + * \brief Obtains the list of all the files (URLs) in current ebook archive. This is used in search + * and to dump the e-book content. + * \param files An array to store list of URLs present in chm archive. + * \return true if the enumeration succeed; false otherwise (I could hardly imagine a reason). + * + * \ingroup dataretrieve + */ + virtual bool enumerateFiles( QList& files ) = 0; + + /*! + * \brief Gets the Title of the page referenced by url. + * \param url An URL in ebook 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 + */ + virtual QString getTopicByUrl ( const QUrl& url ) = 0; + + /*! + * \brief Gets the current ebook encoding (set or autodetected) as qtcodec name. Must be implemented, + * even if the book doesn't support change of encoding (then it should return a default encoding) + * \return The current encoding. + * + * \ingroup encoding + */ + virtual QString currentEncoding() const = 0; + + /*! + * \brief Sets the ebook encoding to use for TOC and content + * \param encoding An encoding to use. + * + * \ingroup encoding + */ + virtual bool setCurrentEncoding ( const char * encoding ) = 0; + + /*! + * \brief Checks if this kind of URL is supported by the ebook format (i.e. could be passed to ebook functions) + * \param url The url to check + */ + virtual bool isSupportedUrl( const QUrl& url ) = 0; + + // Converts the string to the ebook-specific URL format + virtual QUrl pathToUrl( const QString & link ) const = 0; + + // Extracts the path component from the URL + virtual QString urlToPath( const QUrl& link ) const = 0; + + + protected: + // Loads the file; returns true if loaded, false otherwise + virtual bool load( const QString& archiveName ) = 0; +}; + + +#endif // INCLUDE_LIBCHMFILE_H diff --git a/generators/chm/lib/ebook_chm.cpp b/generators/chm/lib/ebook_chm.cpp new file mode 100644 index 000000000..31921ce4f --- /dev/null +++ b/generators/chm/lib/ebook_chm.cpp @@ -0,0 +1,1112 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "ebook_chm.h" +#include "ebook_chm_encoding.h" +#include "helper_entitydecoder.h" + +#include "bitfiddle.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) + +static const char * URL_SCHEME_CHM = "ms-its"; + + +EBook_CHM::EBook_CHM() + : EBook() +{ + m_envOptions = getenv("KCHMVIEWEROPTS"); + m_chmFile = NULL; + m_filename = m_font = QString::null; + + m_textCodec = 0; + m_textCodecForSpecialFiles = 0; + m_detectedLCID = 0; + m_currentEncoding = "UTF-8"; + m_htmlEntityDecoder = 0; +} + +EBook_CHM::~EBook_CHM() +{ + close(); +} + +void EBook_CHM::close() +{ + if ( m_chmFile == NULL ) + return; + + chm_close( m_chmFile ); + + m_chmFile = NULL; + m_filename = m_font = QString::null; + + m_home.clear(); + m_topicsFile.clear(); + m_indexFile.clear(); + + m_textCodec = 0; + m_textCodecForSpecialFiles = 0; + m_detectedLCID = 0; + m_currentEncoding = "UTF-8"; +} + +QString EBook_CHM::title() const +{ + return encodeWithCurrentCodec( m_title ); +} + +QUrl EBook_CHM::homeUrl() const +{ + return pathToUrl( m_home ); +} + +bool EBook_CHM::hasFeature(EBook::Feature code) const +{ + switch ( code ) + { + case FEATURE_TOC: + return m_tocAvailable; + + case FEATURE_INDEX: + return m_indexAvailable; + + case FEATURE_ENCODING: + return true; + } + + return false; +} + +bool EBook_CHM::getTableOfContents( QList &toc ) const +{ + if ( parseBinaryTOC( toc ) ) + return true; + + // Parse the plain text TOC + QList< ParsedEntry > parsed; + + if ( !parseFileAndFillArray( m_topicsFile, parsed, false ) ) + return false; + + // Find out the root offset, and reduce the indent level to it + // so the toc starts from zero offset. + int root_offset = -1; + + // Fill up the real toc + toc.reserve( parsed.size() ); + Q_FOREACH( const ParsedEntry& e, parsed ) + { + if ( root_offset == -1 ) + root_offset = e.indent; + + EBookTocEntry entry; + entry.iconid = (EBookTocEntry::Icon) e.iconid; + entry.indent = e.indent - root_offset; + entry.name = e.name; + + if ( !e.urls.empty() ) + entry.url = e.urls[0]; + + toc.append( entry ); + } + + return true; +} + +bool EBook_CHM::getIndex(QList &index) const +{ + // Parse the plain text index + QList< ParsedEntry > parsed; + + if ( !parseFileAndFillArray( m_indexFile, parsed, true ) ) + return false; + + // Find out the root offset, and reduce the indent level to it + // so the index starts from zero offset. + int root_offset = 0; + + // Fill up the real index + index.reserve( parsed.size() ); + + // Find the index root offset + Q_FOREACH( const ParsedEntry& e, parsed ) + { + if ( e.urls.empty() ) + continue; + + root_offset = qMin( root_offset, e.indent ); + } + + // And apply the index + Q_FOREACH( const ParsedEntry& e, parsed ) + { + if ( e.urls.empty() ) + continue; + + EBookIndexEntry entry; + entry.name = e.name; + entry.urls = e.urls; + entry.seealso = e.seealso; + + // If the index array is empty, make sure the first entry is on root offset + if ( index.isEmpty() ) + entry.indent = root_offset; + else + entry.indent = e.indent - root_offset; + + index.append( entry ); + printf("%d: %s\n", entry.indent, qPrintable(entry.name)); + } + + return true; +} + +bool EBook_CHM::getFileContentAsString( QString &str, const QUrl &url ) const +{ + return getTextContent( str, urlToPath( url ) ); +} + +bool EBook_CHM::getFileContentAsBinary( QByteArray &data, const QUrl &url ) const +{ + return getBinaryContent( data, urlToPath(url) ); +} + +bool EBook_CHM::getBinaryContent( 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; + + return false; +} + +bool EBook_CHM::getTextContent( QString& str, const QString& url, bool internal_encoding ) const +{ + QByteArray buf; + + if ( getBinaryContent( buf, url ) ) + { + unsigned int length = buf.size(); + + if ( length > 0 ) + { + buf.resize( length + 1 ); + buf [length] = '\0'; + + str = internal_encoding ? (QString)( buf.constData() ) : encodeWithCurrentCodec( buf.constData() ); + return true; + } + } + + return false; +} + +int EBook_CHM::getContentSize(const QString &url) +{ + chmUnitInfo ui; + + if( !ResolveObject( url, &ui ) ) + return -1; + + return ui.length; +} + +bool EBook_CHM::load(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 ) + close(); + +#if defined (WIN32) + // chm_open on Windows OS uses the following prototype: + // struct chmFile* chm_open(BSTR filename); + // + // however internally it simply passes the filename + // directly to CreateFileW function without any conversion. + // Thus we need to pass it as WCHAR * and not BSTR. + m_chmFile = chm_open( (BSTR) filename.toStdWString().c_str() ); +#else + m_chmFile = chm_open( QFile::encodeName(filename) ); +#endif + + if ( m_chmFile == NULL ) + return false; + + m_filename = filename; + + // Reset encoding + m_textCodec = 0; + m_textCodecForSpecialFiles = 0; + m_currentEncoding = "UTF-8"; + + // 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; + + // Some CHM files have toc and index files, but do not set the name properly. + // Some heuristics here. + if ( m_topicsFile.isEmpty() && hasFile( "/toc.hhc" ) ) + m_topicsFile = "/toc.hhc"; + + if ( m_indexFile.isEmpty() && hasFile( "/index.hhk" ) ) + m_indexFile = "/index.hhk"; + + if ( !m_topicsFile.isEmpty() || ( m_lookupTablesValid && hasFile( "/#TOCIDX" ) ) ) + m_tocAvailable = true; + else + m_tocAvailable = false; + + if ( !m_indexFile.isEmpty() || ( m_lookupTablesValid && hasFile( "/$WWKeywordLinks/BTree" ) ) ) + m_indexAvailable = true; + else + m_indexAvailable = false; + + return true; +} + +int EBook_CHM::findStringInQuotes (const QString& tag, int offset, QString& value, bool firstquote, bool decodeentities) const +{ + int qbegin = tag.indexOf ('"', offset); + + if ( qbegin == -1 ) + qFatal ("EBook_CHMImpl::findStringInQuotes: cannot find first quote in tag: '%s'", qPrintable( tag )); + + int qend = firstquote ? tag.indexOf ('"', qbegin + 1) : tag.lastIndexOf ('"'); + + if ( qend == -1 || qend <= qbegin ) + qFatal ("EBook_CHMImpl::findStringInQuotes: cannot find last quote in tag: '%s'", qPrintable( tag )); + + // 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 = m_htmlEntityDecoder.decode( 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 EBook_CHM::parseFileAndFillArray( const QString& file, QList< ParsedEntry >& data, bool asIndex ) const +{ + QString src; + const int MAX_NEST_DEPTH = 256; + + if ( !getTextContent( src, file ) || src.isEmpty() ) + return false; + +/* + // Save the index for debugging purposes + QFile outfile( "parsed.htm" ); + + if ( outfile.open( QIODevice::WriteOnly ) ) + { + QTextStream textstream( &outfile ); + textstream << src; + outfile.close(); + } +*/ + + EBookTocEntry::Icon defaultimagenum = EBookTocEntry::IMAGE_AUTO; + int pos = 0, indent = 0, root_indent_offset = 0; + bool in_object = false, root_indent_offset_set = false; + + ParsedEntry entry; + entry.iconid = defaultimagenum; + + // Split the HHC file by HTML tags + int stringlen = src.length(); + + while ( pos < stringlen && (pos = src.indexOf ('<', 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.indexOf (src[i], i+1); + if ( nextpos == -1 && (nextpos = src.indexOf ('>', i+1)) == -1 ) + { + qWarning ("EBook_CHMImpl::ParseHhcAndFillTree: corrupted TOC: %s", qPrintable( src.mid(i) )); + 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).toLower(); + else + tagword = tag.toLower(); + + //DEBUGPARSER(("tag: '%s', tagword: '%s'\n", qPrintable( tag ), qPrintable( tagword ) )); + + // - a topic entry + if ( tagword == "object" && tag.indexOf ("text/sitemap", 0, Qt::CaseInsensitive ) != -1 ) + in_object = true; + else if ( tagword == "/object" && in_object ) + { + // a topic entry closed. Add a tree item + if ( entry.name.isEmpty() && entry.urls.isEmpty() ) + { + qWarning ("EBook_CHMImpl::ParseAndFillTopicsTree: tag is parsed, but both name and url are empty."); + } + else + { + // If the name is empty, use the URL as name + if ( entry.name.isEmpty() ) + entry.name = entry.urls[0].toString(); + + 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); + } + + // Trim the entry name + entry.name = entry.name.trimmed(); + + int real_indent = indent - root_indent_offset; + + entry.indent = real_indent; + data.push_back( entry ); + } + + entry.name = QString::null; + entry.urls.clear(); + entry.iconid = defaultimagenum; + entry.seealso.clear(); + in_object = false; + } + else if ( tagword == "param" && in_object ) + { + // + int offset; // strlen("param ") + QString name_pattern = "name=", value_pattern = "value="; + QString pname, pvalue; + + if ( (offset = tag.indexOf (name_pattern, 0, Qt::CaseInsensitive )) == -1 ) + qFatal ("EBook_CHMImpl::ParseAndFillTopicsTree: bad tag '%s': no name=\n", qPrintable( tag )); + + // offset+5 skips 'name=' + offset = findStringInQuotes (tag, offset + name_pattern.length(), pname, true, false); + pname = pname.toLower(); + + if ( (offset = tag.indexOf(value_pattern, offset, Qt::CaseInsensitive )) == -1 ) + qFatal ("EBook_CHMImpl::ParseAndFillTopicsTree: bad tag '%s': no value=\n", qPrintable( tag )); + + // offset+6 skips 'value=' + findStringInQuotes (tag, offset + value_pattern.length(), pvalue, false, true); + + //DEBUGPARSER((": name '%s', value '%s'", qPrintable( pname ), qPrintable( pvalue ))); + + if ( pname == "name" || pname == "keyword" ) + { + // 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 == "merge" ) + { + // MERGE implementation is experimental + QUrl mergeurl = pathToUrl( pvalue ); + QString mergecontent; + + if ( getFileContentAsString( mergecontent, mergeurl ) && !mergecontent.isEmpty() ) + { + qWarning( "MERGE is used in index; the implementation is experimental. Please let me know if it works" ); + + // Merge the read value into the current parsed file. + // To save memory it is done in a kinda hacky way: + src = mergecontent + src.mid( i ); + pos = 0; + stringlen = src.length(); + } + else + qWarning( "MERGE is used in index but file %s was not found in CHM archive", qPrintable(pvalue) ); + } + else if ( pname == "local" ) + { + // Check for URL duplication + QUrl url = pathToUrl( pvalue ); + + if ( !entry.urls.contains( url ) ) + entry.urls.push_back( url ); + } + else if ( pname == "see also" && asIndex && entry.name != pvalue ) + { + entry.urls.push_back( QUrl("seealso") ); + entry.seealso = pvalue; + } + else if ( pname == "imagenumber" ) + { + bool bok; + int imgnum = pvalue.toInt (&bok); + + if ( bok && imgnum >= 0 && imgnum < EBookTocEntry::MAX_BUILTIN_ICONS ) + entry.iconid = (EBookTocEntry::Icon) imgnum; + } + } + else if ( tagword == "ul" ) // increase indent level + { + // Fix for buggy help files + if ( ++indent >= MAX_NEST_DEPTH ) + qFatal("EBook_CHMImpl::ParseAndFillTopicsTree: max nest depth (%d) is reached, error in help file", MAX_NEST_DEPTH); + + DEBUGPARSER(("
    : new intent is %d\n", indent - root_indent_offset)); + } + else if ( tagword == "/ul" ) // decrease indent level + { + if ( --indent < root_indent_offset ) + indent = root_indent_offset; + + DEBUGPARSER(("
: new intent is %d\n", indent - root_indent_offset)); + } + + pos = i; + } + + // Dump our array +// for ( int i = 0; i < data.size(); i++ ) +// qDebug() << data[i].indent << data[i].name << data[i].urls; + + return true; +} + +bool EBook_CHM::ResolveObject(const QString& fileName, chmUnitInfo *ui) const +{ + return m_chmFile != NULL + && ::chm_resolve_object(m_chmFile, qPrintable( fileName ), ui) == + CHM_RESOLVE_SUCCESS; +} + + +bool EBook_CHM::hasFile(const QString & fileName) const +{ + chmUnitInfo ui; + + return m_chmFile != NULL + && ::chm_resolve_object(m_chmFile, qPrintable( fileName ), &ui) == + CHM_RESOLVE_SUCCESS; +} + + +size_t EBook_CHM::RetrieveObject(const chmUnitInfo *ui, unsigned char *buffer, + LONGUINT64 fileOffset, LONGINT64 bufferSize) const +{ + return ::chm_retrieve_object(m_chmFile, const_cast(ui), + buffer, fileOffset, bufferSize); +} + +bool EBook_CHM::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; + + unsigned int entries = get_int32_le( (unsigned int *)(buffer) ); + unsigned int entry_size = get_int32_le( (unsigned int *)(buffer + 0x04) ); + + QVector 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 ( unsigned int i = 0; i < entries; ++i ) + { + unsigned int offset = i * entry_size; + + unsigned int off_title = get_int32_le( (unsigned int *)(raw + offset + 0x14) ); + unsigned int off_home = get_int32_le( (unsigned int *)(raw + offset + 0x68) ); + unsigned int off_hhc = get_int32_le( (unsigned int *)(raw + offset + 0x60) ); + unsigned int off_hhk = get_int32_le( (unsigned int *)(raw + offset + 0x64) ); + + factor = off_title / 4096; + + if ( size == 0 ) + size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE); + + if ( size && off_title ) + m_title = QByteArray( (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 = QByteArray("/") + QByteArray( (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 = QByteArray("/") + QByteArray((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 = QByteArray("/") + QByteArray((const char*) buffer + off_hhk % 4096); + } + } + return true; +} + + + +bool EBook_CHM::getInfoFromSystem() +{ + unsigned char buffer[BUF_SIZE]; + chmUnitInfo ui; + + int index = 0; + unsigned char* cursor = NULL, *p; + unsigned short 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(unsigned short)) ;) + { + cursor = buffer + index; + value = UINT16ARRAY(cursor); + + switch(value) + { + case 0: + index += 2; + cursor = buffer + index; + + if(m_topicsFile.isEmpty()) + m_topicsFile = QByteArray("/") + QByteArray((const char*) buffer + index + 2); + + break; + + case 1: + index += 2; + cursor = buffer + index; + + if(m_indexFile.isEmpty()) + m_indexFile = QByteArray("/") + QByteArray((const char*)buffer + index + 2); + break; + + case 2: + index += 2; + cursor = buffer + index; + + if(m_home.isEmpty() || m_home == "/") + m_home = QByteArray("/") + QByteArray((const char*) buffer + index + 2); + break; + + case 3: + index += 2; + cursor = buffer + index; + m_title = QByteArray( (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 = qPrintable( tmp ); + + tmp = topicAttempt + ".hhk"; + + if ( ResolveObject( tmp, &ui) ) + m_indexFile = qPrintable( 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; +} + +QString EBook_CHM::getTopicByUrl( const QUrl& url ) +{ + QMap< QUrl, QString >::const_iterator it = m_url2topics.find( url ); + + if ( it == m_url2topics.end() ) + return QString::null; + + return it.value(); +} + + +static int chm_enumerator_callback( struct chmFile*, struct chmUnitInfo *ui, void *context ) +{ + EBook_CHM tmp; + ((QList *) context)->push_back( tmp.pathToUrl( ui->path ) ); + return CHM_ENUMERATOR_CONTINUE; +} + +bool EBook_CHM::enumerateFiles(QList &files ) +{ + files.clear(); + return chm_enumerate( m_chmFile, CHM_ENUMERATE_ALL, chm_enumerator_callback, &files ); +} + +QString EBook_CHM::currentEncoding() const +{ + return m_currentEncoding; +} + +bool EBook_CHM::setCurrentEncoding( const char * encoding ) +{ + m_currentEncoding = encoding; + return changeFileEncoding( encoding ); +} + +bool EBook_CHM::isSupportedUrl(const QUrl &url) +{ + return url.scheme() == URL_SCHEME_CHM; +} + +bool EBook_CHM::guessTextEncoding() +{ + if ( !m_detectedLCID ) + { + qWarning ("Could not detect LCID"); + return false; + } + + QString enc = Ebook_CHM_Encoding::guessByLCID( m_detectedLCID ); + + if ( changeFileEncoding ( enc ) ) + { + m_currentEncoding = enc; + return true; + } + + return false; +} + +bool EBook_CHM::changeFileEncoding( const QString& 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) + int p = qtencoding.indexOf( '/' ); + + if ( p != -1 ) + { + QString global = qtencoding.left( p ); + QString special = qtencoding.mid( p + 1 ); + + m_textCodec = QTextCodec::codecForName( global.toUtf8() ); + + if ( !m_textCodec ) + { + qWarning( "Could not set up Text Codec for encoding '%s'", qPrintable( global ) ); + return false; + } + + m_textCodecForSpecialFiles = QTextCodec::codecForName( special.toUtf8() ); + + if ( !m_textCodecForSpecialFiles ) + { + qWarning( "Could not set up Text Codec for encoding '%s'", qPrintable( special ) ); + return false; + } + } + else + { + m_textCodecForSpecialFiles = m_textCodec = QTextCodec::codecForName( qtencoding.toUtf8() ); + + if ( !m_textCodec ) + { + qWarning( "Could not set up Text Codec for encoding '%s'", qPrintable( qtencoding ) ); + return false; + } + } + + m_htmlEntityDecoder.changeEncoding( m_textCodec ); + return true; +} + + +void EBook_CHM::fillTopicsUrlMap() +{ + if ( !m_lookupTablesValid ) + return; + + // Read those tables + QVector 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 ) + { + unsigned int off_title = get_int32_le( (unsigned int *)(topics.data() + i + 4) ); + unsigned int off_url = get_int32_le( (unsigned int *)(topics.data() + i + 8) ); + off_url = get_int32_le( (unsigned int *)( urltbl.data() + off_url + 8) ) + 8; + + QUrl url = pathToUrl( (const char*) urlstr.data() + off_url ); + + if ( off_title < (unsigned int)strings.size() ) + m_url2topics[url] = encodeWithCurrentCodec ( (const char*) strings.data() + off_title ); + else + m_url2topics[url] = "Untitled"; + } +} + + +bool EBook_CHM::parseBinaryTOC( QList< EBookTocEntry >& toc ) const +{ + if ( !m_lookupTablesValid ) + return false; + + QByteArray tocidx, topics, urltbl, urlstr, strings; + + // Read the index tables + if ( !getBinaryContent( tocidx, "/#TOCIDX" ) + || !getBinaryContent( topics, "/#TOPICS" ) + || !getBinaryContent( urltbl, "/#URLTBL" ) + || !getBinaryContent( urlstr, "/#URLSTR" ) + || !getBinaryContent( strings, "/#STRINGS" ) ) + return false; + + // Shamelessly stolen from xchm + if ( !RecurseLoadBTOC( tocidx, topics, urltbl, urlstr, strings, UINT32ARRAY( tocidx.data() ), toc, 0 ) ) + { + qWarning("Failed to parse binary TOC, fallback to text-based TOC"); + toc.clear(); + return false; + } + + return true; +} + + +// +// This piece of code was based on the one in xchm written by Razvan Cojocaru +// +bool EBook_CHM::RecurseLoadBTOC( const QByteArray& tocidx, + const QByteArray& topics, + const QByteArray& urltbl, + const QByteArray& urlstr, + const QByteArray& strings, + int offset, + QList< EBookTocEntry >& entries, + int level ) const +{ + while ( offset ) + { + // If this is end of TOCIDX, return. + if ( tocidx.size() < offset + 20 ) + return true; + + unsigned int flags = UINT32ARRAY( tocidx.data() + offset + 4 ); + int index = UINT32ARRAY( tocidx.data() + offset + 8 ); + + if ( (flags & 0x04) || (flags & 0x08)) + { + QString name, value; + + if ( (flags & 0x08) == 0 ) + { + if ( strings.size() < index + 1 ) + { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid name index (%d) for book TOC entry!", index ); + return false; + } + + name = encodeWithCurrentCodec( strings.data() + index); + } + else + { + if ( topics.size() < (index * 16) + 12 ) + { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid name index (%d) for local TOC entry!", index ); + return false; + } + + int tocoffset = (int) UINT32ARRAY(topics.data()+ (index * 16) + 4); + + if ( strings.size() < tocoffset + 1 ) + { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid name tocoffset (%d) for TOC entry!", tocoffset ); + return false; + } + + if ( tocoffset < 0 ) + name.clear(); + else + name = encodeWithCurrentCodec( strings.data() + tocoffset ); + + // #URLTBL index + tocoffset = (int) UINT32ARRAY( topics.data() + (index * 16) + 8 ); + + if ( tocoffset < 0 || urltbl.size() < tocoffset + 12 ) + { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid url index (%d) for TOC entry!", tocoffset ); + return false; + } + + tocoffset = (int) UINT32ARRAY(urltbl.data() + tocoffset + 8); + + if ( tocoffset < 0 || urlstr.size() < tocoffset ) + { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid url offset (%d) for TOC entry!", tocoffset ); + return false; + } + + value = encodeWithCurrentCodec( urlstr.data() + tocoffset + 8 ); + } + + EBookTocEntry entry; + entry.name = name.trimmed(); + + if ( !entry.name.isEmpty() ) + { + if ( !value.isEmpty() ) + entry.url = pathToUrl( value ); + + entry.iconid = EBookTocEntry::IMAGE_AUTO; + entry.indent = level; + entries.push_back( entry ); + } + } + + if ( flags & 0x04 ) + { + // book + if ( tocidx.size() < offset + 24 ) + { + qWarning("EBook_CHM::RecurseLoadBTOC: invalid child entry offset (%d)", offset ); + return false; + } + + unsigned int childoffset = UINT32ARRAY( tocidx.data() + offset + 20 ); + + if ( childoffset ) + { + if ( !RecurseLoadBTOC( tocidx, topics, urltbl, urlstr, strings, childoffset, entries, level + 1 ) ) + return false; + } + } + + offset = UINT32ARRAY( tocidx.data() + offset + 0x10 ); + } + + return true; +} + +bool EBook_CHM::hasOption(const QString & name) const +{ + if ( !m_envOptions.isEmpty() && m_envOptions.contains( name ) ) + return true; + + return false; +} + +QUrl EBook_CHM::pathToUrl(const QString &link) const +{ + if ( link.startsWith( "http://" ) || link.startsWith( "https://" ) ) + return QUrl( link ); + + QUrl url; + url.setScheme( URL_SCHEME_CHM ); + url.setHost( URL_SCHEME_CHM ); + + // Does the link contain the fragment as well? + int off = link.indexOf( '#' ); + QString path; + + if ( off != -1 ) + { + path = link.left( off ); + url.setFragment( link.mid( off + 1 ) ); + } + else + path = link; + + if ( !path.startsWith( '/' ) ) + path.prepend( '/' ); + + url.setPath( QUrl::fromPercentEncoding( path.toUtf8() ) ); + return url; +} + +QString EBook_CHM::urlToPath(const QUrl &link) const +{ + if ( link.scheme() == URL_SCHEME_CHM ) + { + if ( link.path() == "/" || link.path().isEmpty() ) + return m_home; + + return link.path(); + } + + return ""; +} + + +EBook_CHM::ParsedEntry::ParsedEntry() +{ + iconid = 0; + indent = 0; +} diff --git a/generators/chm/lib/ebook_chm.h b/generators/chm/lib/ebook_chm.h new file mode 100644 index 000000000..cc093c32b --- /dev/null +++ b/generators/chm/lib/ebook_chm.h @@ -0,0 +1,343 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBOOK_CHM_H +#define EBOOK_CHM_H + +#include +#include + +// Enable Unicode use in libchm +#if defined (WIN32) + #define PPC_BSTR +#endif +#include + +#include "ebook.h" +#include "helper_entitydecoder.h" + + +class EBook_CHM : public EBook +{ + public: + EBook_CHM(); + ~EBook_CHM(); + + /*! + * \brief Attempts to load chm file. + * \param archiveName filename. + * \return EBook object on success, NULL on failure. + * + * Loads a CHM file. For CHM files it could internally load more than one file, + * if files linked to this one are present locally (like MSDN). + * \ingroup init + */ + bool load( const QString& archiveName ); + + /*! + * \brief Closes all the files, and frees the appropriate data. + * \ingroup init + */ + virtual void close(); + + /*! + * \brief Gets the title name of the opened ebook. + * \return The name of the opened document, or an empty string if no ebook has been loaded. + * \ingroup information + */ + virtual QString title() const; + + /*! + * \brief Gets the default URL of the e-book which should be opened when the book it first open + * + * \return The home page name, with a '/' added in front and relative to + * the root of the archive filesystem. If no book has been opened, returns "/". + * \ingroup information + */ + virtual QUrl homeUrl() const; + + /*! + * \brief Checks whether the specific feature is present in this file. + * \return true if it is available; false otherwise. + * \ingroup information + */ + virtual bool hasFeature( Feature code ) const; + + /*! + * \brief Parses and fills up 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 files; please report a bug if the file is opened ok under Windows. + * \ingroup fileparsing + */ + virtual bool getTableOfContents( QList< EBookTocEntry >& toc ) 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 + */ + virtual bool getIndex( QList< EBookIndexEntry >& index ) const; + + /*! + * \brief Retrieves the content associated with the url from the current ebook as 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. Note content may be an empty string. + * + * This function retreives the file content (mostly for HTML pages) from the ebook. Because the content + * in chm file might not be stored in Unicode, it will be recoded according to current encoding. + * Do not use for binary data. + * + * \sa setCurrentEncoding() currentEncoding() getFileContentAsBinary() + * \ingroup dataretrieve + */ + virtual bool getFileContentAsString( QString& str, const QUrl& url ) const; + + /*! + * \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 + */ + virtual bool getFileContentAsBinary( QByteArray& data, const QUrl& url ) const; + + /*! + * \brief Retrieves the content size. + * \param url An URL in ebook file to retreive content from. Must be absolute. + * \return the size; -1 in case of error. + * + * \ingroup dataretrieve + */ + virtual int getContentSize( const QString& url ); + + /*! + * \brief Obtains the list of all the files (URLs) in current ebook archive. This is used in search + * and to dump the e-book content. + * \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 + */ + virtual bool enumerateFiles( QList& files ); + + /*! + * \brief Gets the Title of the page referenced by url. + * \param url An URL in ebook 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 + */ + virtual QString getTopicByUrl ( const QUrl& url ); + + /*! + * \brief Gets the current ebook encoding (set or autodetected) as qtcodec + * \return The current encoding. + * + * \ingroup encoding + */ + virtual QString currentEncoding() const; + + /*! + * \brief Sets the ebook encoding to use for TOC and content + * \param encoding An encoding to use. + * + * \ingroup encoding + */ + virtual bool setCurrentEncoding ( const char * encoding ); + + /*! + * \brief Checks if this kind of URL is supported by the ebook format (i.e. could be passed to ebook functions) + * \param url The url to check + */ + virtual bool isSupportedUrl( const QUrl& url ); + + // Converts the string to the ebook-specific URL format + QUrl pathToUrl( const QString & link ) const; + + // Extracts the path component from the URL + QString urlToPath( const QUrl& link ) const; + + private: + // Used in local parser + class ParsedEntry + { + public: + ParsedEntry(); + + QString name; + QList urls; + int iconid; + int indent; + QString seealso; + }; + + //! Looks up fileName in the archive. + bool hasFile( const QString& fileName ) const; + + //! 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 QByteArray& str) const + { + return (m_textCodec ? m_textCodec->toUnicode( str.constData () ) : 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( qPrintable(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; + + //! Parse the HHC or HHS file, and fill the context (asIndex is false) or index (asIndex is true) array. + bool parseFileAndFillArray (const QString& file, QList< ParsedEntry >& data, bool asIndex ) const; + + bool getBinaryContent( QByteArray &data, const QString &url ) const; + bool getTextContent( QString& str, const QString& url, bool internal_encoding = false ) const; + + /*! + * Parse binary TOC + */ + bool parseBinaryTOC(QList &data ) const; + + //! btree string parser + QString getBtreeString( const QByteArray& btidx, unsigned long * offset, unsigned short * spaceLeft ) const; + + /*! + * Recursively parse and fill binary TOC + */ + bool RecurseLoadBTOC(const QByteArray& tocidx, + const QByteArray& topics, + const QByteArray& urltbl, + const QByteArray& urlstr, + const QByteArray& strings, + int offset, + QList &data, + int level ) const; + + /*! + * Helper procedure in TOC parsing, decodes the string between the quotes (first or last) with decoding HTML + * entities like í + */ + int findStringInQuotes (const QString& tag, int offset, QString& value, bool firstquote, bool decodeentities ) const; + bool getInfoFromWindows(); + bool getInfoFromSystem(); + bool changeFileEncoding(const QString &qtencoding); + bool guessTextEncoding(); + void fillTopicsUrlMap(); + bool hasOption(const QString &name) const; + + // Members + + //! Pointer to the chmlib structure + chmFile * m_chmFile; + + //! Opened file name + QString m_filename; + + //! Home url, got from CHM file + QByteArray m_home; + + //! Context tree filename. Got from CHM file + QByteArray m_topicsFile; + + //! Index filename. Got from CHM file + QByteArray m_indexFile; + + //! Chm Title. Got from CHM file + QByteArray 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 + QString m_currentEncoding; + + //! 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 TOC, either binary or text, is available. + bool m_tocAvailable; + + //! Indicates whether index, either binary or text, is available. + bool m_indexAvailable; + + //! Map url->topic + QMap< QUrl, QString > m_url2topics; + + //! KCHMViewer debug options from environment + QString m_envOptions; + + //! HTML entity decoder + HelperEntityDecoder m_htmlEntityDecoder; +}; + +#endif // EBOOK_CHM_H diff --git a/generators/chm/lib/ebook_chm_encoding.cpp b/generators/chm/lib/ebook_chm_encoding.cpp new file mode 100644 index 000000000..c2ffdf67b --- /dev/null +++ b/generators/chm/lib/ebook_chm_encoding.cpp @@ -0,0 +1,306 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ebook_chm_encoding.h" + +typedef struct +{ + const char * qtcodec; + const short * lcids; +} EbookChmTextEncodingEntry; + + +// Do not try to embed those in the text_encoding_table, it does not work - at least with gcc. +static short lcid_arabic[] = +{ + 0x1401, 0x3C01, 0x0C01, 0x0801, 0x2C01, 0x3401, 0x3001, 0x1001, + 0x1801, 0x2001, 0x4001, 0x0401, 0x2801, 0x1C01, 0x3801, 0x2401, + 0x0429, 0x0420, + 0, +}; + +static short lcid_baltic[] = +{ + 0x0425, 0x0426, 0x0427, 0 +}; + +static short lcid_centralEuropean[] = +{ + 0x041C, 0x041A, 0x0405, 0x040E, 0x0415, 0x0418, 0x081A, 0x041B, 0x0424, 0 +}; + +static short lcid_ChineseSimplifiedGB18030[] = +{ + 0x0804, 0 +}; + + +static short lcid_ChineseSimplifiedGBK[] = +{ + 0x0804, 0 +}; + + +static short lcid_ChineseSimplifiedGB2313[] = +{ + 0x1004, 0 +}; + +static short lcid_ChineseTraditionalBig5[] = +{ + 0x0404, 0x1404, 0 +}; + +static short lcid_ChineseTraditionalBigHKSCS[] = +{ + 0x0C04, 0 +}; + +static short lcid_CyrillicCP1251[] = +{ + 0x082C, 0x0423, 0x0402, 0x042F, 0x0419, 0x0C1A, 0x0444, 0x0422, 0x0843, 0 +}; + +static short lcid_CyrillicKOI8R[] = +{ + 0x7001, // artifical LCID + 0 +}; + + +static short lcid_Greek[] = +{ + 0x0408, 0 +}; + +static short lcid_Hebrew[] = +{ + 0x040D, 0 +}; + +static short lcid_Japanese_eucJP[] = +{ + 0x0411, 0 +}; + + +static short lcid_Japanese_JIS7[] = +{ + 0x0411, 0 +}; + +static short lcid_Japanese_ShiftJIS[] = +{ + 0x0411, 0 +}; + +static short lcid_Korean_eucKR[] = +{ + 0x0412, 0 +}; + +static short lcid_TamilTSCII[] = +{ + 0x0449, 0 +}; + +static short lcid_ThaiTIS[] = +{ + 0x041E, 0 +}; + +static short lcid_UkrainianKOI[] = +{ + 0x7006, 0 +}; + +static short lcid_Turkish[] = +{ + 0x042C, 0x041F, 0x0443, 0 +}; + +static short lcid_Vietnamese[] = +{ + 0x042A, 0 +}; + +static short lcid_UnicodeUTF8[] = +{ + 0x7004, // artifical LCID + 0 +}; + +static short lcid_UnicodeUTF16[] = +{ + 0x7005, // artifical LCID + 0 +}; + +static short lcid_Western[] = +{ + 0x0436, 0x042D, 0x0403, 0x0406, 0x0813, 0x0413, 0x0C09, 0x2809, + 0x1009, 0x2409, 0x1809, 0x2009, 0x1409, 0x3409, 0x1C09, 0x2C09, + 0x0809, 0x0409, 0x0438, 0x040B, 0x080C, 0x0C0C, 0x040C, 0x140C, + 0x100C, 0x0C07, 0x0407, 0x1407, 0x1007, 0x0807, 0x040F, 0x0421, + 0x0410, 0x0810, 0x083E, 0x043E, 0x0414, 0x0814, 0x0416, 0x0816, + 0x0432, 0x2C0A, 0x400A, 0x340A, 0x240A, 0x140A, 0x1C0A, 0x300A, + 0x440A, 0x100A, 0x480A, 0x080A, 0x4C0A, 0x180A, 0x3C0A, 0x280A, + 0x500A, 0x0C0A, 0x380A, 0x200A, 0x0441, 0x081D, 0x041D, 0x0434, + 0x0435, 0x042B, 0x042C, 0x0439, 0x043A, 0x044E, 0x044F, 0x081A, + 0x0443, + 0 +}; + + +static const EbookChmTextEncodingEntry text_encoding_table [] = +{ + { + "CP1256", + lcid_arabic + }, + + { + "CP1257", + lcid_baltic + }, + + { + "CP1250", + lcid_centralEuropean + }, + + { + "GB18030", + lcid_ChineseSimplifiedGB18030 + }, + + { + "GBK", + lcid_ChineseSimplifiedGBK + }, + + { + "GB2313", + lcid_ChineseSimplifiedGB2313 + }, + + { + "Big5", + lcid_ChineseTraditionalBig5 + }, + + { + "Big5-HKSCS", + lcid_ChineseTraditionalBigHKSCS + }, + + { + "CP1251", + lcid_CyrillicCP1251 + }, + + { + "KOI8-R", + lcid_CyrillicKOI8R + }, + + { + "CP1253", + lcid_Greek + }, + + { + "CP1255", + lcid_Hebrew + }, + + { + "Shift-JIS", + lcid_Japanese_ShiftJIS + }, + + { + "eucJP", + lcid_Japanese_eucJP + }, + + { + "JIS7", + lcid_Japanese_JIS7 + }, + + { + "eucKR", + lcid_Korean_eucKR + }, + + { + "TSCII", + lcid_TamilTSCII + }, + + { + "TIS-620", + lcid_ThaiTIS + }, + + { + "KOI8-U", + lcid_UkrainianKOI + }, + + { + "CP1254", + lcid_Turkish + }, + + { + "CP1258", + lcid_Vietnamese + }, + + { + "UTF-8", + lcid_UnicodeUTF8 + }, + + { + "UTF-16", + lcid_UnicodeUTF16 + }, + + { + "CP1252", + lcid_Western + }, + + { 0, 0 } +}; + + +QString Ebook_CHM_Encoding::guessByLCID(unsigned short lcid) +{ + for ( const EbookChmTextEncodingEntry * t = text_encoding_table; t->qtcodec; ++t ) + { + for ( const short * lcids = t->lcids; *lcids; lcids++ ) + if ( *lcids == lcid ) + return t->qtcodec; + } + + return "UTF-8"; +} diff --git a/generators/chm/lib/ebook_chm_encoding.h b/generators/chm/lib/ebook_chm_encoding.h new file mode 100644 index 000000000..a49e41f2c --- /dev/null +++ b/generators/chm/lib/ebook_chm_encoding.h @@ -0,0 +1,30 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBOOK_CHM_ENCODING_H +#define EBOOK_CHM_ENCODING_H + +#include + +class Ebook_CHM_Encoding +{ + public: + static QString guessByLCID( unsigned short lcid ); +}; + +#endif // EBOOK_CHM_ENCODING_H diff --git a/generators/chm/lib/ebook_epub.cpp b/generators/chm/lib/ebook_epub.cpp new file mode 100644 index 000000000..83a777339 --- /dev/null +++ b/generators/chm/lib/ebook_epub.cpp @@ -0,0 +1,380 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if defined (WIN32) + #include // dup +#else + #include +#endif + +#include +#include + +#include "ebook_epub.h" +#include "helperxmlhandler_epubcontainer.h" +#include "helperxmlhandler_epubcontent.h" +#include "helperxmlhandler_epubtoc.h" + +static const char * URL_SCHEME_EPUB = "epub"; + +EBook_EPUB::EBook_EPUB() + : EBook() +{ + m_zipFile = 0; +} + +EBook_EPUB::~EBook_EPUB() +{ + close(); +} + +bool EBook_EPUB::load(const QString &archiveName) +{ + close(); + + // We use QFile and zip_fdopen instead of zip_open because latter does not support Unicode file names + m_epubFile.setFileName( archiveName ); + + if ( !m_epubFile.open( QIODevice::ReadOnly ) ) + { + qWarning("Could not open file %s: %s", qPrintable(archiveName), qPrintable( m_epubFile.errorString())); + return false; + } + + // Open the ZIP archive: http://www.nih.at/libzip/zip_fdopen.html + // Note that zip_fdopen takes control over the passed descriptor, + // so we need to pass a duplicate of it for this to work correctly + int fdcopy = dup( m_epubFile.handle() ); + + if ( fdcopy < 0 ) + { + qWarning("Could not duplicate descriptor" ); + return false; + } + + int errcode; + m_zipFile = zip_fdopen( fdcopy, 0, &errcode ); + + if ( !m_zipFile ) + { + qWarning("Could not open file %s: error %d", qPrintable(archiveName), errcode); + return false; + } + + // Parse the book descriptor file + if ( !parseBookinfo() ) + return false; + + return true; +} + +void EBook_EPUB::close() +{ + if ( m_zipFile ) + { + zip_close( m_zipFile ); + m_zipFile = 0; + } + + //if ( m_epubFile.isOpen() ) + // m_epubFile.close(); + + +} + +bool EBook_EPUB::getFileContentAsString(QString &str, const QUrl &url) const +{ + return getFileAsString( str, urlToPath( url ) ); +} + +bool EBook_EPUB::getFileContentAsBinary(QByteArray &data, const QUrl &url) const +{ + return getFileAsBinary( data, urlToPath( url ) ); +} + +bool EBook_EPUB::enumerateFiles(QList &files) +{ + files = m_ebookManifest; + return true; +} + +QString EBook_EPUB::title() const +{ + return m_title; +} + +QUrl EBook_EPUB::homeUrl() const +{ + return m_tocEntries[0].url; +} + +bool EBook_EPUB::hasFeature(EBook::Feature code) const +{ + switch ( code ) + { + case FEATURE_TOC: + return true; + + case FEATURE_INDEX: + return false; + + case FEATURE_ENCODING: + return false; + } + + return false; +} + +bool EBook_EPUB::getTableOfContents( QList &toc ) const +{ + toc = m_tocEntries; + return true; +} + +bool EBook_EPUB::getIndex(QList &) const +{ + return false; +} + +QString EBook_EPUB::getTopicByUrl(const QUrl& url) +{ + if ( m_urlTitleMap.contains( url ) ) + return m_urlTitleMap[ url ]; + + return ""; +} + +QString EBook_EPUB::currentEncoding() const +{ + return "UTF-8"; +} + +bool EBook_EPUB::setCurrentEncoding(const char *) +{ + abort(); +} + +bool EBook_EPUB::isSupportedUrl(const QUrl &url) +{ + return url.scheme() == URL_SCHEME_EPUB; +} + +bool EBook_EPUB::parseXML(const QString &uri, QXmlDefaultHandler * parser) +{ + QByteArray container; + + if ( !getFileAsBinary( container, uri ) ) + { + qDebug("Failed to retrieve XML file %s", qPrintable( uri ) ); + return false; + } + + // Use it as XML source + QXmlInputSource source; + source.setData( container ); + + // Init the reader + QXmlSimpleReader reader; + reader.setContentHandler( parser ); + reader.setErrorHandler( parser ); + + return reader.parse( source ); +} + +bool EBook_EPUB::parseBookinfo() +{ + // Parse the container.xml to find the content descriptor + HelperXmlHandler_EpubContainer container_parser; + + if ( !parseXML( "META-INF/container.xml", &container_parser ) + || container_parser.contentPath.isEmpty() ) + return false; + + // Parse the content.opf + HelperXmlHandler_EpubContent content_parser; + + if ( !parseXML( container_parser.contentPath, &content_parser ) ) + return false; + + // At least title and the TOC must be present + if ( !content_parser.metadata.contains("title") || content_parser.tocname.isEmpty() ) + return false; + + // All the files, including TOC, are relative to the container_parser.contentPath + m_documentRoot.clear(); + int sep = container_parser.contentPath.lastIndexOf( '/' ); + + if ( sep != -1 ) + m_documentRoot = container_parser.contentPath.left( sep + 1 ); // Keep the trailing slash + + // Parse the TOC + HelperXmlHandler_EpubTOC toc_parser( this ); + + if ( !parseXML( content_parser.tocname, &toc_parser ) ) + return false; + + // Get the data + m_title = content_parser.metadata[ "title" ]; + + // Move the manifest entries into the list + Q_FOREACH( QString f, content_parser.manifest.values() ) + m_ebookManifest.push_back( pathToUrl( f ) ); + + // Copy the manifest information and fill up the other maps if we have it + if ( !toc_parser.entries.isEmpty() ) + { + Q_FOREACH( EBookTocEntry e, toc_parser.entries ) + { + // Add into url-title map + m_urlTitleMap[ e.url ] = e.name; + m_tocEntries.push_back( e ); + } + } + else + { + // Copy them from spline + Q_FOREACH( QString u, content_parser.spine ) + { + EBookTocEntry e; + QString url = u; + + if ( content_parser.manifest.contains( u ) ) + url = content_parser.manifest[ u ]; + + e.name = url; + e.url= pathToUrl( url ); + e.iconid = EBookTocEntry::IMAGE_NONE; + e.indent = 0; + + // Add into url-title map + m_urlTitleMap[ pathToUrl( url ) ] = url; + m_tocEntries.push_back( e ); + } + } + + // EPub with an empty TOC is not valid + if ( m_tocEntries.isEmpty() ) + return false; + + return true; +} + +QUrl EBook_EPUB::pathToUrl(const QString &link) const +{ + QUrl url; + url.setScheme( URL_SCHEME_EPUB ); + url.setHost( URL_SCHEME_EPUB ); + + // Does the link contain the fragment as well? + int off = link.indexOf( '#' ); + QString path; + + if ( off != -1 ) + { + path = link.left( off ); + url.setFragment( link.mid( off + 1 ) ); + } + else + path = link; + + if ( !path.startsWith( '/' ) ) + path.prepend( '/' ); + + url.setPath( QUrl::fromPercentEncoding( path.toUtf8() ) ); + + return url; +} + +QString EBook_EPUB::urlToPath(const QUrl &link) const +{ + if ( link.scheme() == URL_SCHEME_EPUB ) + return link.path(); + + return ""; +} + +bool EBook_EPUB::getFileAsString(QString &str, const QString &path) const +{ + QByteArray data; + + if ( !getFileAsBinary( data, path ) ) + return false; + + // I have never seen yet an UTF16 epub + if ( data.startsWith("" ); + int utf16 = data.indexOf("UTF-16"); + + if ( utf16 > 0 && utf16 < endxmltag ) + { + QMessageBox::critical( 0, + ("Unsupported encoding"), + ("The encoding of this ebook is not supported yet. Please send it to gyunaev@ulduzsoft.com for support to be added") ); + return false; + } + } + + str = QString::fromUtf8( data ); + return true; +} + +bool EBook_EPUB::getFileAsBinary(QByteArray &data, const QString &path) const +{ + // Retrieve the file size + struct zip_stat fileinfo; + QString completeUrl; + + if ( !path.isEmpty() && path[0] == '/' ) + completeUrl = m_documentRoot + path.mid( 1 ); + else + completeUrl = m_documentRoot + path; + + //qDebug("URL requested: %s (%s)", qPrintable(path), qPrintable(completeUrl)); + + // http://www.nih.at/libzip/zip_stat.html + if ( zip_stat( m_zipFile, completeUrl.toUtf8().constData(), 0, &fileinfo) != 0 ) + { + qDebug("File %s is not found in the archive", qPrintable(completeUrl)); + return false; + } + + // Make sure the size field is valid + if ( (fileinfo.valid & ZIP_STAT_SIZE) == 0 || (fileinfo.valid & ZIP_STAT_INDEX) == 0 ) + return false; + + // Open the file + struct zip_file * file = zip_fopen_index( m_zipFile, fileinfo.index, 0 ); + + if ( !file ) + return false; + + // Allocate the memory and read the file + data.resize( fileinfo.size ); + + // Could it return a positive number but not fileinfo.size??? + int ret = zip_fread( file, data.data(), fileinfo.size ); + if ( ret != (int) fileinfo.size ) + { + zip_fclose( file ); + return false; + } + + zip_fclose( file ); + return true; +} diff --git a/generators/chm/lib/ebook_epub.h b/generators/chm/lib/ebook_epub.h new file mode 100644 index 000000000..524e68cd0 --- /dev/null +++ b/generators/chm/lib/ebook_epub.h @@ -0,0 +1,205 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBOOK_EPUB_H +#define EBOOK_EPUB_H + +#include +#include +#include +#include + +#include "ebook.h" +#include "zip.h" + +class QXmlDefaultHandler; + + +class EBook_EPUB : public EBook +{ + public: + EBook_EPUB(); + virtual ~EBook_EPUB(); + + /*! + * \brief Attempts to load epub file. + * \param archiveName filename. + * \return EBook object on success, NULL on failure. + * + * Loads a epub file. + * \ingroup init + */ + bool load( const QString& archiveName ); + + /*! + * \brief Closes all the files, and frees the appropriate data. + * \ingroup init + */ + virtual void close(); + + /*! + * \brief Gets the title name of the opened ebook. + * \return The name of the opened document, or an empty string if no ebook has been loaded. + * \ingroup information + */ + virtual QString title() const; + + /*! + * \brief Gets the default URL of the e-book which should be opened when the book it first open + * + * \return The home page name, with a '/' added in front and relative to + * the root of the archive filesystem. If no book has been opened, returns "/". + * \ingroup information + */ + virtual QUrl homeUrl() const; + + /*! + * \brief Checks whether the specific feature is present in this file. + * \return true if it is available; false otherwise. + * \ingroup information + */ + virtual bool hasFeature( Feature code ) const; + + /*! + * \brief Parses and fills up 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 files; please report a bug if the file is opened ok under Windows. + * \ingroup fileparsing + */ + virtual bool getTableOfContents( QList< EBookTocEntry >& toc ) 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 + */ + virtual bool getIndex( QList< EBookIndexEntry >& index ) const; + + /*! + * \brief Retrieves the content associated with the url from the current ebook as 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. Note content may be an empty string. + * + * This function retreives the file content (mostly for HTML pages) from the ebook. Because the content + * in chm file might not be stored in Unicode, it will be recoded according to current encoding. + * Do not use for binary data. + * + * \sa setCurrentEncoding() currentEncoding() getFileContentAsBinary() + * \ingroup dataretrieve + */ + virtual bool getFileContentAsString( QString& str, const QUrl& url ) const; + + /*! + * \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 + */ + virtual bool getFileContentAsBinary( QByteArray& data, const QUrl& url ) const; + + /*! + * \brief Obtains the list of all the files (URLs) in current ebook archive. This is used in search + * and to dump the e-book content. + * \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 + */ + virtual bool enumerateFiles( QList& files ); + + /*! + * \brief Gets the Title of the page referenced by url. + * \param url An URL in ebook 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 + */ + virtual QString getTopicByUrl ( const QUrl& url ); + + /*! + * \brief Gets the current ebook encoding (set or autodetected) as qtcodec + * \return The current encoding. + * + * \ingroup encoding + */ + virtual QString currentEncoding() const; + + /*! + * \brief Sets the ebook encoding to use for TOC and content + * \param encoding An encoding to use. + * + * \ingroup encoding + */ + virtual bool setCurrentEncoding ( const char * encoding ); + + /*! + * \brief Checks if this kind of URL is supported by the ebook format (i.e. could be passed to ebook functions) + * \param url The url to check + */ + virtual bool isSupportedUrl( const QUrl& url ); + + // Converts the string to the ebook-specific URL format + QUrl pathToUrl( const QString & link ) const; + + // Extracts the path component from the URL + QString urlToPath( const QUrl& link ) const; + + private: + // Parses the XML file using a specified parser + bool parseXML( const QString& uri, QXmlDefaultHandler * reader ); + + // Parses the book description file. Fills up the ebook info + bool parseBookinfo(); + + // Get file content from path + bool getFileAsString( QString& str, const QString& path ) const; + bool getFileAsBinary( QByteArray& data, const QString& path ) const; + + // ZIP archive fd and structs + QFile m_epubFile; + struct zip * m_zipFile; + + // Ebook info + QString m_title; + QString m_documentRoot; + + // List of files in the ebook + QList m_ebookManifest; + + // Table of contents + QList< EBookTocEntry > m_tocEntries; + + // Map of URL-Title + QMap< QUrl, QString> m_urlTitleMap; +}; + +#endif // EBOOK_EPUB_H diff --git a/generators/chm/lib/ebook_search.cpp b/generators/chm/lib/ebook_search.cpp new file mode 100644 index 000000000..5f7dfce9d --- /dev/null +++ b/generators/chm/lib/ebook_search.cpp @@ -0,0 +1,225 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "ebook.h" +#include "ebook_search.h" + +// Helper class to simplity state management and data keeping +class SearchDataKeeper +{ + public: + SearchDataKeeper() { m_inPhrase = false; } + + void beginPhrase() + { + phrase_terms.clear(); + m_inPhrase = true; + } + + void endPhrase() + { + m_inPhrase = false; + phrasewords += phrase_terms; + phrases.push_back( phrase_terms.join(" ") ); + } + + bool isInPhrase() const { return m_inPhrase; } + + void addTerm( const QString& term ) + { + if ( !term.isEmpty() ) + { + terms.push_back( term ); + + if ( m_inPhrase ) + phrase_terms.push_back( term ); + } + } + + // Should contain all the search terms present in query, includind those from phrases. One element - one term . + QStringList terms; + + // Should contain phrases present in query without quotes. One element - one phrase. + QStringList phrases; + + // Should contain all the terms present in all the phrases (but not outside). + QStringList phrasewords; + + private: + bool m_inPhrase; + QStringList phrase_terms; +}; + + + +EBookSearch::EBookSearch() +{ + m_Index = 0; +} + + +EBookSearch::~ EBookSearch() +{ + delete m_Index; +} + + +bool EBookSearch::loadIndex( QDataStream & stream ) +{ + delete m_Index; + + m_Index = new QtAs::Index(); + return m_Index->readDict( stream ); +} + + +bool EBookSearch::generateIndex( EBook * ebookFile, QDataStream & stream ) +{ + QList< QUrl > documents; + QList< QUrl > alldocuments; + + emit progressStep( 0, "Generating the list of documents" ); + processEvents(); + + // Enumerate the documents + if ( !ebookFile->enumerateFiles( alldocuments ) ) + return false; + + if ( m_Index ) + delete m_Index; + + m_Index = new QtAs::Index(); + connect( m_Index, SIGNAL( indexingProgress( int, const QString& ) ), this, SLOT( updateProgress( int, const QString& ) ) ); + + // Process the list of files in CHM archive and keep only HTML document files from there + for ( int i = 0; i < alldocuments.size(); i++ ) + { + QString docpath = alldocuments[i].path(); + + if ( docpath.endsWith( ".html", Qt::CaseInsensitive ) + || docpath.endsWith( ".htm", Qt::CaseInsensitive ) + || docpath.endsWith( ".xhtml", Qt::CaseInsensitive ) ) + documents.push_back( alldocuments[i] ); + } + + if ( !m_Index->makeIndex( documents, ebookFile ) ) + { + delete m_Index; + m_Index = 0; + return false; + } + + m_Index->writeDict( stream ); + m_keywordDocuments.clear(); + + return true; +} + + +void EBookSearch::cancelIndexGeneration() +{ + m_Index->setLastWinClosed(); +} + + +void EBookSearch::updateProgress(int value, const QString & stepName) +{ + emit progressStep( value, stepName ); +} + +void EBookSearch::processEvents() +{ + // Do it up to ten times; some events generate other events + for ( int i = 0; i < 10; i++ ) + qApp->processEvents( QEventLoop::ExcludeUserInputEvents ); +} + +bool EBookSearch::searchQuery(const QString & query, QList< QUrl > * results, EBook *ebookFile, unsigned int limit) +{ + // We should have index + if ( !m_Index ) + return false; + + // Characters which split the words. We need to make them separate tokens + QString splitChars = m_Index->getCharsSplit(); + + // Characters which are part of the word. We should keep them apart. + QString partOfWordChars = m_Index->getCharsPartOfWord(); + + // Variables to store current state + SearchDataKeeper keeper; + QString term; + + for ( int i = 0; i < query.length(); i++ ) + { + QChar ch = query[i].toLower(); + + // a quote either begins or ends the phrase + if ( ch == '"' ) + { + keeper.addTerm( term ); + + if ( keeper.isInPhrase() ) + keeper.endPhrase(); + else + keeper.beginPhrase(); + + continue; + } + + // If new char does not stop the word, add ot and continue + if ( ch.isLetterOrNumber() || partOfWordChars.indexOf( ch ) != -1 ) + { + term.append( ch ); + continue; + } + + // If it is a split char, add this term and split char as separate term + if ( splitChars.indexOf( ch ) != -1 ) + { + // Add existing term if present + keeper.addTerm( term ); + + // Change the term variable, so it will be added when we exit this block + term = ch; + } + + // Just add the word; it is most likely a space or terminated by tokenizer. + keeper.addTerm( term ); + term = QString::null; + } + + keeper.addTerm( term ); + + if ( keeper.isInPhrase() ) + return false; + + QList< QUrl > foundDocs = m_Index->query( keeper.terms, keeper.phrases, keeper.phrasewords, ebookFile ); + + for ( QList< QUrl >::iterator it = foundDocs.begin(); it != foundDocs.end() && limit > 0; ++it, limit-- ) + results->push_back( *it ); + + return true; +} + +bool EBookSearch::hasIndex() const +{ + return m_Index != 0; +} diff --git a/generators/chm/lib/ebook_search.h b/generators/chm/lib/ebook_search.h new file mode 100644 index 000000000..463d9f018 --- /dev/null +++ b/generators/chm/lib/ebook_search.h @@ -0,0 +1,84 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBookSearch_H +#define EBookSearch_H + +#include +#include "helper_search_index.h" + +class EBook; + +class EBookSearch : public QObject +{ + Q_OBJECT + + public: + EBookSearch(); + ~EBookSearch(); + + //! Loads the search index from the data stream \param stream. + //! The index should be previously saved with generateIndex(). + bool loadIndex( QDataStream& stream ); + + //! Generates the search index from the opened CHM file \param chmFile, + //! and saves it to the data stream \param stream which should be writeable. + //! + //! To show the progress, this procedure emits a progressStep() signal periodically + //! with the value showing current progress in percentage (i.e. from 0 to 100) + //! After signal emission, the following event processing function will be called: + //! qApp->processEvents( QEventLoop::ExcludeUserInputEvents ) + //! to make sure the dialogs (if any) are properly updated. + //! + //! If \param progressDls is not null, it will be used to display progress. + //! Returns true if the index has been generated and saved, or false if internal + //! error occurs, or (most likely) the cancelIndexGeneration() slot has been called. + bool generateIndex( EBook * ebook, QDataStream& stream ); + + //! Executes the search query. The \param query is a string like "C++ language" class, + //! \param results is a pointer to QStringList, and \param limit limits the number of + //! results in case the query is too generic (like \a "a" ). + //! The \param chmFile is used to get the current encoding information. + //! The return value is false only if the index is not generated, or if a closing quote character + //! is missing. Call hasIndex() to clarify. If search returns no results, the return value is + //! true, but the \param results list will be empty. + //! + //! Note that the function does not clear \param results before adding search results, so if you are + //! not merging search results, make sure it's empty. + bool searchQuery ( const QString& query, QList< QUrl > * results, EBook * chmFile, unsigned int limit = 100 ); + + //! Returns true if a valid search index is present, and therefore search could be executed + bool hasIndex() const; + + signals: + void progressStep( int value, const QString& stepName ); + + public slots: + void cancelIndexGeneration(); + + private slots: + void updateProgress( int value, const QString& stepName ); + void processEvents(); + + private: + QStringList m_keywordDocuments; + QtAs::Index * m_Index; + +}; + +#endif diff --git a/generators/chm/lib/ebook_url.h b/generators/chm/lib/ebook_url.h new file mode 100644 index 000000000..1836e7af7 --- /dev/null +++ b/generators/chm/lib/ebook_url.h @@ -0,0 +1,13 @@ +#ifndef EBOOK_URL_H +#define EBOOK_URL_H + +#include + +class EbookURL : public QUrl +{ + public: + EbookURL(); + EbookURL( const QString & url ); +}; + +#endif // EBOOK_URL_H diff --git a/generators/chm/lib/helper_entitydecoder.cpp b/generators/chm/lib/helper_entitydecoder.cpp new file mode 100644 index 000000000..188a158fc --- /dev/null +++ b/generators/chm/lib/helper_entitydecoder.cpp @@ -0,0 +1,232 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "helper_entitydecoder.h" + + +HelperEntityDecoder::HelperEntityDecoder(QTextCodec *encoder) +{ + changeEncoding( encoder ); + +} + +static inline QString encodeWithCodec( QTextCodec *encoder, const QByteArray& str ) +{ + return (encoder ? encoder->toUnicode( str.constData () ) : str); +} + +void HelperEntityDecoder::changeEncoding(QTextCodec *encoder) +{ + // Set up m_entityDecodeMap characters according to current textCodec + m_entityDecodeMap.clear(); + + m_entityDecodeMap["AElig"] = encodeWithCodec( encoder, "\306"); // capital AE diphthong (ligature) + m_entityDecodeMap["Aacute"] = encodeWithCodec( encoder, "\301"); // capital A, acute accent + m_entityDecodeMap["Acirc"] = encodeWithCodec( encoder, "\302"); // capital A, circumflex accent + m_entityDecodeMap["Agrave"] = encodeWithCodec( encoder, "\300"); // capital A, grave accent + m_entityDecodeMap["Aring"] = encodeWithCodec( encoder, "\305"); // capital A, ring + m_entityDecodeMap["Atilde"] = encodeWithCodec( encoder, "\303"); // capital A, tilde + m_entityDecodeMap["Auml"] = encodeWithCodec( encoder, "\304"); // capital A, dieresis or umlaut mark + m_entityDecodeMap["Ccedil"] = encodeWithCodec( encoder, "\307"); // capital C, cedilla + m_entityDecodeMap["Dstrok"] = encodeWithCodec( encoder, "\320"); // whatever + m_entityDecodeMap["ETH"] = encodeWithCodec( encoder, "\320"); // capital Eth, Icelandic + m_entityDecodeMap["Eacute"] = encodeWithCodec( encoder, "\311"); // capital E, acute accent + m_entityDecodeMap["Ecirc"] = encodeWithCodec( encoder, "\312"); // capital E, circumflex accent + m_entityDecodeMap["Egrave"] = encodeWithCodec( encoder, "\310"); // capital E, grave accent + m_entityDecodeMap["Euml"] = encodeWithCodec( encoder, "\313"); // capital E, dieresis or umlaut mark + m_entityDecodeMap["Iacute"] = encodeWithCodec( encoder, "\315"); // capital I, acute accent + m_entityDecodeMap["Icirc"] = encodeWithCodec( encoder, "\316"); // capital I, circumflex accent + m_entityDecodeMap["Igrave"] = encodeWithCodec( encoder, "\314"); // capital I, grave accent + m_entityDecodeMap["Iuml"] = encodeWithCodec( encoder, "\317"); // capital I, dieresis or umlaut mark + m_entityDecodeMap["Ntilde"] = encodeWithCodec( encoder, "\321"); // capital N, tilde + m_entityDecodeMap["Oacute"] = encodeWithCodec( encoder, "\323"); // capital O, acute accent + m_entityDecodeMap["Ocirc"] = encodeWithCodec( encoder, "\324"); // capital O, circumflex accent + m_entityDecodeMap["Ograve"] = encodeWithCodec( encoder, "\322"); // capital O, grave accent + m_entityDecodeMap["Oslash"] = encodeWithCodec( encoder, "\330"); // capital O, slash + m_entityDecodeMap["Otilde"] = encodeWithCodec( encoder, "\325"); // capital O, tilde + m_entityDecodeMap["Ouml"] = encodeWithCodec( encoder, "\326"); // capital O, dieresis or umlaut mark + m_entityDecodeMap["THORN"] = encodeWithCodec( encoder, "\336"); // capital THORN, Icelandic + m_entityDecodeMap["Uacute"] = encodeWithCodec( encoder, "\332"); // capital U, acute accent + m_entityDecodeMap["Ucirc"] = encodeWithCodec( encoder, "\333"); // capital U, circumflex accent + m_entityDecodeMap["Ugrave"] = encodeWithCodec( encoder, "\331"); // capital U, grave accent + m_entityDecodeMap["Uuml"] = encodeWithCodec( encoder, "\334"); // capital U, dieresis or umlaut mark + m_entityDecodeMap["Yacute"] = encodeWithCodec( encoder, "\335"); // capital Y, acute accent + m_entityDecodeMap["OElig"] = encodeWithCodec( encoder, "\338"); // capital Y, acute accent + m_entityDecodeMap["oelig"] = encodeWithCodec( encoder, "\339"); // capital Y, acute accent + + m_entityDecodeMap["aacute"] = encodeWithCodec( encoder, "\341"); // small a, acute accent + m_entityDecodeMap["acirc"] = encodeWithCodec( encoder, "\342"); // small a, circumflex accent + m_entityDecodeMap["aelig"] = encodeWithCodec( encoder, "\346"); // small ae diphthong (ligature) + m_entityDecodeMap["agrave"] = encodeWithCodec( encoder, "\340"); // small a, grave accent + m_entityDecodeMap["aring"] = encodeWithCodec( encoder, "\345"); // small a, ring + m_entityDecodeMap["atilde"] = encodeWithCodec( encoder, "\343"); // small a, tilde + m_entityDecodeMap["auml"] = encodeWithCodec( encoder, "\344"); // small a, dieresis or umlaut mark + m_entityDecodeMap["ccedil"] = encodeWithCodec( encoder, "\347"); // small c, cedilla + m_entityDecodeMap["eacute"] = encodeWithCodec( encoder, "\351"); // small e, acute accent + m_entityDecodeMap["ecirc"] = encodeWithCodec( encoder, "\352"); // small e, circumflex accent + m_entityDecodeMap["Scaron"] = encodeWithCodec( encoder, "\352"); // small e, circumflex accent + m_entityDecodeMap["egrave"] = encodeWithCodec( encoder, "\350"); // small e, grave accent + m_entityDecodeMap["eth"] = encodeWithCodec( encoder, "\360"); // small eth, Icelandic + m_entityDecodeMap["euml"] = encodeWithCodec( encoder, "\353"); // small e, dieresis or umlaut mark + m_entityDecodeMap["iacute"] = encodeWithCodec( encoder, "\355"); // small i, acute accent + m_entityDecodeMap["icirc"] = encodeWithCodec( encoder, "\356"); // small i, circumflex accent + m_entityDecodeMap["igrave"] = encodeWithCodec( encoder, "\354"); // small i, grave accent + m_entityDecodeMap["iuml"] = encodeWithCodec( encoder, "\357"); // small i, dieresis or umlaut mark + m_entityDecodeMap["ntilde"] = encodeWithCodec( encoder, "\361"); // small n, tilde + m_entityDecodeMap["oacute"] = encodeWithCodec( encoder, "\363"); // small o, acute accent + m_entityDecodeMap["ocirc"] = encodeWithCodec( encoder, "\364"); // small o, circumflex accent + m_entityDecodeMap["ograve"] = encodeWithCodec( encoder, "\362"); // small o, grave accent + m_entityDecodeMap["oslash"] = encodeWithCodec( encoder, "\370"); // small o, slash + m_entityDecodeMap["otilde"] = encodeWithCodec( encoder, "\365"); // small o, tilde + m_entityDecodeMap["ouml"] = encodeWithCodec( encoder, "\366"); // small o, dieresis or umlaut mark + m_entityDecodeMap["szlig"] = encodeWithCodec( encoder, "\337"); // small sharp s, German (sz ligature) + m_entityDecodeMap["thorn"] = encodeWithCodec( encoder, "\376"); // small thorn, Icelandic + m_entityDecodeMap["uacute"] = encodeWithCodec( encoder, "\372"); // small u, acute accent + m_entityDecodeMap["ucirc"] = encodeWithCodec( encoder, "\373"); // small u, circumflex accent + m_entityDecodeMap["ugrave"] = encodeWithCodec( encoder, "\371"); // small u, grave accent + m_entityDecodeMap["uuml"] = encodeWithCodec( encoder, "\374"); // small u, dieresis or umlaut mark + m_entityDecodeMap["yacute"] = encodeWithCodec( encoder, "\375"); // small y, acute accent + m_entityDecodeMap["yuml"] = encodeWithCodec( encoder, "\377"); // small y, dieresis or umlaut mark + + m_entityDecodeMap["iexcl"] = encodeWithCodec( encoder, "\241"); + m_entityDecodeMap["cent"] = encodeWithCodec( encoder, "\242"); + m_entityDecodeMap["pound"] = encodeWithCodec( encoder, "\243"); + m_entityDecodeMap["curren"] = encodeWithCodec( encoder, "\244"); + m_entityDecodeMap["yen"] = encodeWithCodec( encoder, "\245"); + m_entityDecodeMap["brvbar"] = encodeWithCodec( encoder, "\246"); + m_entityDecodeMap["sect"] = encodeWithCodec( encoder, "\247"); + m_entityDecodeMap["uml"] = encodeWithCodec( encoder, "\250"); + m_entityDecodeMap["ordf"] = encodeWithCodec( encoder, "\252"); + m_entityDecodeMap["laquo"] = encodeWithCodec( encoder, "\253"); + m_entityDecodeMap["not"] = encodeWithCodec( encoder, "\254"); + m_entityDecodeMap["shy"] = encodeWithCodec( encoder, "\255"); + m_entityDecodeMap["macr"] = encodeWithCodec( encoder, "\257"); + m_entityDecodeMap["deg"] = encodeWithCodec( encoder, "\260"); + m_entityDecodeMap["plusmn"] = encodeWithCodec( encoder, "\261"); + m_entityDecodeMap["sup1"] = encodeWithCodec( encoder, "\271"); + m_entityDecodeMap["sup2"] = encodeWithCodec( encoder, "\262"); + m_entityDecodeMap["sup3"] = encodeWithCodec( encoder, "\263"); + m_entityDecodeMap["acute"] = encodeWithCodec( encoder, "\264"); + m_entityDecodeMap["micro"] = encodeWithCodec( encoder, "\265"); + m_entityDecodeMap["para"] = encodeWithCodec( encoder, "\266"); + m_entityDecodeMap["middot"] = encodeWithCodec( encoder, "\267"); + m_entityDecodeMap["cedil"] = encodeWithCodec( encoder, "\270"); + m_entityDecodeMap["ordm"] = encodeWithCodec( encoder, "\272"); + m_entityDecodeMap["raquo"] = encodeWithCodec( encoder, "\273"); + m_entityDecodeMap["frac14"] = encodeWithCodec( encoder, "\274"); + m_entityDecodeMap["frac12"] = encodeWithCodec( encoder, "\275"); + m_entityDecodeMap["frac34"] = encodeWithCodec( encoder, "\276"); + m_entityDecodeMap["iquest"] = encodeWithCodec( encoder, "\277"); + m_entityDecodeMap["times"] = encodeWithCodec( encoder, "\327"); + m_entityDecodeMap["divide"] = encodeWithCodec( encoder, "\367"); + + m_entityDecodeMap["copy"] = encodeWithCodec( encoder, "\251"); // copyright sign + m_entityDecodeMap["reg"] = encodeWithCodec( encoder, "\256"); // registered sign + m_entityDecodeMap["nbsp"] = encodeWithCodec( encoder, "\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"] = "\""; +} + + +QString HelperEntityDecoder::decode( const QString &entity ) const +{ + // If entity is an ASCII code like 〽 - just decode it + if ( entity.isEmpty() ) + { + return ""; + } + else if ( entity[0] == '#' ) + { + bool valid; + unsigned int ascode = entity.mid(1).toUInt( &valid ); + + if ( !valid ) + { + qWarning ( "HelperEntityDecoder::decode: could not decode HTML entity '%s'", qPrintable( entity ) ); + return QString::null; + } + + return (QString) (QChar( ascode )); + } + else + { + QMap::const_iterator it = m_entityDecodeMap.find( entity ); + + if ( it == m_entityDecodeMap.end() ) + { + qWarning ("HelperEntityDecoder::decode: could not decode HTML entity '%s'", qPrintable( entity )); + return ""; + } + + return *it; + } +} diff --git a/generators/chm/lib/helper_entitydecoder.h b/generators/chm/lib/helper_entitydecoder.h new file mode 100644 index 000000000..bb2a12be5 --- /dev/null +++ b/generators/chm/lib/helper_entitydecoder.h @@ -0,0 +1,45 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HELPER_ENTITYDECODER_H +#define HELPER_ENTITYDECODER_H + +#include +#include + +// +// This helper class decodes the Unicode HTML entities into the Unicode characters +// +class HelperEntityDecoder +{ + public: + // Initialization with the specific decoder + HelperEntityDecoder( QTextCodec * encoder = 0 ); + + // Used when the encoding changes + void changeEncoding( QTextCodec * encoder = 0 ); + + // The decoder function + QString decode( const QString& entity ) const; + + private: + // Map to decode HTML entitles like ´ based on current encoding, initialized upon the first use + QMap m_entityDecodeMap; +}; + +#endif // HELPER_ENTITYDECODER_H diff --git a/generators/chm/lib/helper_search_index.cpp b/generators/chm/lib/helper_search_index.cpp new file mode 100644 index 000000000..3d6c704f9 --- /dev/null +++ b/generators/chm/lib/helper_search_index.cpp @@ -0,0 +1,493 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "ebook.h" +#include "ebook_search.h" +#include "helper_search_index.h" + +static const int DICT_VERSION = 4; + +namespace QtAs { + +// Those characters are splitters (i.e. split the word), but added themselves into dictionary too. +// This makes the dictionary MUCH larger, but ensure that for the piece of "window->print" both +// search for "print" and "->print" will find it. +static const char SPLIT_CHARACTERS[] = "!()*&^%#@[]{}':;,.?/|/?<>\\-+=~`"; + +// Those characters are parts of word - for example, '_' is here, and search for _debug will find only _debug. +static const char WORD_CHARACTERS[] = "$_"; + + +struct Term +{ + Term() : frequency(-1) {} + Term( const QString &t, int f, QVector l ) : term( t ), frequency( f ), documents( l ) {} + QString term; + int frequency; + QVectordocuments; + bool operator<( const Term &i2 ) const { return frequency < i2.frequency; } +}; + + +QDataStream &operator>>( QDataStream &s, Document &l ) +{ + s >> l.docNumber; + s >> l.frequency; + return s; +} + +QDataStream &operator<<( QDataStream &s, const Document &l ) +{ + s << (short)l.docNumber; + s << (short)l.frequency; + return s; +} + +Index::Index() + : QObject( 0 ) +{ + lastWindowClosed = false; + connect( qApp, SIGNAL( lastWindowClosed() ), this, SLOT( setLastWinClosed() ) ); +} + +void Index::setLastWinClosed() +{ + lastWindowClosed = true; +} + + +bool Index::makeIndex(const QList< QUrl >& docs, EBook *chmFile ) +{ + if ( docs.isEmpty() ) + return false; + + docList = docs; + + if ( chmFile->hasFeature( EBook::FEATURE_ENCODING ) ) + entityDecoder.changeEncoding( QTextCodec::codecForName( chmFile->currentEncoding().toUtf8() ) ); + + QList< QUrl >::ConstIterator it = docList.begin(); + int steps = docList.count() / 100; + + if ( !steps ) + steps++; + + int prog = 0; + + for ( int i = 0; it != docList.end(); ++it, ++i ) + { + if ( lastWindowClosed ) + return false; + + QUrl filename = *it; + QStringList terms; + + if ( parseDocumentToStringlist( chmFile, filename, terms ) ) + { + for ( QStringList::ConstIterator tit = terms.begin(); tit != terms.end(); ++tit ) + insertInDict( *tit, i ); + } + + if ( i%steps == 0 ) + { + prog++; + prog = qMin( prog, 99 ); + emit indexingProgress( prog, tr("Processing document %1") .arg( (*it).path() ) ); + } + } + + emit indexingProgress( 100, tr("Processing completed") ); + return true; +} + + +void Index::insertInDict( const QString &str, int docNum ) +{ + Entry *e = 0; + if ( dict.count() ) + e = dict[ str ]; + + if ( e ) + { + if ( e->documents.last().docNumber != docNum ) + e->documents.append( Document(docNum, 1 ) ); + else + e->documents.last().frequency++; + } + else + { + dict.insert( str, new Entry( docNum ) ); + } +} + + +bool Index::parseDocumentToStringlist(EBook *chmFile, const QUrl& filename, QStringList& tokenlist ) +{ + QString parsedbuf, parseentity, text; + + if ( !chmFile->getFileContentAsString( text, filename ) + || text.isEmpty() ) + { + qWarning( "Search index generator: could not retrieve the document content for %s", qPrintable( filename.toString() ) ); + return false; + } + + m_charssplit = SPLIT_CHARACTERS; + m_charsword = WORD_CHARACTERS; + + tokenlist.clear(); + + // State machine states + enum state_t + { + STATE_OUTSIDE_TAGS, // outside HTML tags; parse text + STATE_IN_HTML_TAG, // inside HTML tags; wait for end tag + STATE_IN_QUOTES, // inside HTML tags and inside quotes; wait for end quote (in var QuoteChar) + STATE_IN_HTML_ENTITY // inside HTML entity; parse the entity + }; + + state_t state = STATE_OUTSIDE_TAGS; + QChar QuoteChar; // used in STATE_IN_QUOTES + + for ( int j = 0; j < text.length(); j++ ) + { + QChar ch = text[j]; + + if ( (j % 20000) == 0 ) + qApp->processEvents( QEventLoop::ExcludeUserInputEvents ); + + if ( state == STATE_IN_HTML_TAG ) + { + // We are inside HTML tag. + // Ignore everything until we see '>' (end of HTML tag) or quote char (quote start) + if ( ch == '"' || ch == '\'' ) + { + state = STATE_IN_QUOTES; + QuoteChar = ch; + } + else if ( ch == '>' ) + state = STATE_OUTSIDE_TAGS; + + continue; + } + else if ( state == STATE_IN_QUOTES ) + { + // We are inside quoted text inside HTML tag. + // Ignore everything until we see the quote character again + if ( ch == QuoteChar ) + state = STATE_IN_HTML_TAG; + + continue; + } + else if ( state == STATE_IN_HTML_ENTITY ) + { + // We are inside encoded HTML entity (like  ). + // Collect to parsedbuf everything until we see ; + if ( ch.isLetterOrNumber() ) + { + // get next character of this entity + parseentity.append( ch ); + continue; + } + + // The entity ended + state = STATE_OUTSIDE_TAGS; + + // Some shitty HTML does not terminate entities correctly. Screw it. + if ( ch != ';' && ch != '<' ) + { + if ( parseentity.isEmpty() ) + { + // straight '&' symbol. Add and continue. + parsedbuf += "&"; + } + else + qWarning( "Index::parseDocument: incorrectly terminated HTML entity '&%s%c', ignoring", qPrintable( parseentity ), ch.toLatin1() ); + + j--; // parse this character again, but in different state + continue; + } + + // Don't we have a space? + if ( parseentity.toLower() != "nbsp" ) + { + QString entity = entityDecoder.decode( parseentity ); + + if ( entity.isNull() ) + { + // decodeEntity() already printed error message + //qWarning( "Index::parseDocument: failed to decode entity &%s;", parsedbuf.ascii() ); + continue; + } + + parsedbuf += entity; + continue; + } + else + ch = ' '; // We got a space, so treat it like it, and not add it to parsebuf + } + + // + // Now process STATE_OUTSIDE_TAGS + // + + // Check for start of HTML tag, and switch to STATE_IN_HTML_TAG if it is + if ( ch == '<' ) + { + state = STATE_IN_HTML_TAG; + goto tokenize_buf; + } + + // Check for start of HTML entity + if ( ch == '&' ) + { + state = STATE_IN_HTML_ENTITY; + parseentity = QString::null; + continue; + } + + // Replace quote by ' - quotes are used in search window to set the phrase + if ( ch == '"' ) + ch = '\''; + + // Ok, we have a valid character outside HTML tags, and probably some in buffer already. + // If it is char or letter, add it and continue + if ( ch.isLetterOrNumber() || m_charsword.indexOf( ch ) != -1 ) + { + parsedbuf.append( ch ); + continue; + } + + // If it is a split char, add the word to the dictionary, and then add the char itself. + if ( m_charssplit.indexOf( ch ) != -1 ) + { + if ( !parsedbuf.isEmpty() ) + tokenlist.push_back( parsedbuf.toLower() ); + + tokenlist.push_back( ch.toLower() ); + parsedbuf = QString::null; + continue; + } + +tokenize_buf: + // Just add the word; it is most likely a space or terminated by tokenizer. + if ( !parsedbuf.isEmpty() ) + { + tokenlist.push_back( parsedbuf.toLower() ); + parsedbuf = QString::null; + } + } + + // Add the last word if still here - for broken htmls. + if ( !parsedbuf.isEmpty() ) + tokenlist.push_back( parsedbuf.toLower() ); + + return true; +} + + +void Index::writeDict( QDataStream& stream ) +{ + stream << DICT_VERSION; + stream << m_charssplit; + stream << m_charsword; + + // Document list + stream << docList; + + // Dictionary + for( QHash::ConstIterator it = dict.begin(); it != dict.end(); ++it ) + { + stream << it.key(); + stream << (int) it.value()->documents.count(); + stream << it.value()->documents; + } +} + + +bool Index::readDict( QDataStream& stream ) +{ + dict.clear(); + docList.clear(); + + QString key; + int version, numOfDocs; + + stream >> version; + + if ( version < 2 ) + return false; + + stream >> m_charssplit; + stream >> m_charsword; + + // Read the document list + stream >> docList; + + while ( !stream.atEnd() ) + { + stream >> key; + stream >> numOfDocs; + + QVector docs( numOfDocs ); + + stream >> docs; + dict.insert( key, new Entry( docs ) ); + } + + return dict.size() > 0; +} + + +QList< QUrl > Index::query(const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords, EBook *chmFile ) +{ + QList termList; + + QStringList::ConstIterator it = terms.begin(); + for ( it = terms.begin(); it != terms.end(); ++it ) + { + Entry *e = 0; + + if ( dict[ *it ] ) + { + e = dict[ *it ]; + termList.append( Term( *it, e->documents.count(), e->documents ) ); + } + else + { + return QList< QUrl >(); + } + } + + if ( !termList.count() ) + return QList< QUrl >(); + + qSort( termList ); + + QVector minDocs = termList.takeFirst().documents; + for(QList::Iterator it = termList.begin(); it != termList.end(); ++it) { + Term *t = &(*it); + QVector docs = t->documents; + for(QVector::Iterator minDoc_it = minDocs.begin(); minDoc_it != minDocs.end(); ) { + bool found = false; + for (QVector::ConstIterator doc_it = docs.constBegin(); doc_it != docs.constEnd(); ++doc_it ) { + if ( (*minDoc_it).docNumber == (*doc_it).docNumber ) { + (*minDoc_it).frequency += (*doc_it).frequency; + found = true; + break; + } + } + if ( !found ) + minDoc_it = minDocs.erase( minDoc_it ); + else + ++minDoc_it; + } + } + + QList< QUrl > results; + qSort( minDocs ); + if ( termSeq.isEmpty() ) { + for(QVector::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) + results << docList.at((int)(*it).docNumber); + return results; + } + + QUrl fileName; + for(QVector::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) { + fileName = docList[ (int)(*it).docNumber ]; + if ( searchForPhrases( termSeq, seqWords, fileName, chmFile ) ) + results << fileName; + } + + return results; +} + + +bool Index::searchForPhrases( const QStringList &phrases, const QStringList &words, const QUrl &filename, EBook * chmFile ) +{ + QStringList parsed_document; + + if ( !parseDocumentToStringlist( chmFile, filename, parsed_document ) ) + return false; + + miniDict.clear(); + + // Initialize the dictionary with the words in phrase(s) + for ( QStringList::ConstIterator cIt = words.begin(); cIt != words.end(); ++cIt ) + miniDict.insert( *cIt, new PosEntry( 0 ) ); + + // Fill the dictionary with the words from the document + unsigned int word_offset = 3; + for ( QStringList::ConstIterator it = parsed_document.begin(); it != parsed_document.end(); it++, word_offset++ ) + { + PosEntry * entry = miniDict[ *it ]; + + if ( entry ) + entry->positions.append( word_offset ); + } + + // Dump it +/* + QDictIterator it( miniDict ); + for( ; it.current(); ++it ) + { + QString text( it.currentKey() ); + QValueList pos = miniDict[text]->positions; + for ( unsigned int i = 1; i < pos.size(); i++ ) + text += " " + QString::number( pos[i] ); + + qDebug( "%s", text.ascii()); + } +*/ + + QList first_word_positions; + + for ( QStringList::ConstIterator phrase_it = phrases.begin(); phrase_it != phrases.end(); phrase_it++ ) + { + QStringList phrasewords = phrase_it->split( ' ' ); + first_word_positions = miniDict[ phrasewords[0] ]->positions; + + for ( int j = 1; j < phrasewords.count(); ++j ) + { + QList next_word_it = miniDict[ phrasewords[j] ]->positions; + QList::iterator dict_it = first_word_positions.begin(); + + while ( dict_it != first_word_positions.end() ) + { + if ( next_word_it.indexOf( *dict_it + 1 ) != -1 ) + { + (*dict_it)++; + ++dict_it; + } + else + dict_it = first_word_positions.erase( dict_it ); + } + } + } + + if ( first_word_positions.count() ) + return true; + + return false; +} + + +}; diff --git a/generators/chm/lib/helper_search_index.h b/generators/chm/lib/helper_search_index.h new file mode 100644 index 000000000..37af22ffc --- /dev/null +++ b/generators/chm/lib/helper_search_index.h @@ -0,0 +1,127 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef EBOOK_SEARCH_INDEX_H +#define EBOOK_SEARCH_INDEX_H + +#include +#include +#include +#include +#include + +#include "helper_entitydecoder.h" + + +class EBook; + +// This code is based on some pretty old version of Qt Assistant +namespace QtAs +{ + +struct Document +{ + Document( int d, int f ) : docNumber( d ), frequency( f ) {} + Document() : docNumber( -1 ), frequency( 0 ) {} + bool operator==( const Document &doc ) const + { + return docNumber == doc.docNumber; + } + + bool operator<( const Document &doc ) const + { + return frequency > doc.frequency; + } + + bool operator<=( const Document &doc ) const + { + return frequency >= doc.frequency; + } + + bool operator>( const Document &doc ) const + { + return frequency < doc.frequency; + } + + qint16 docNumber; + qint16 frequency; +}; + +QDataStream &operator>>( QDataStream &s, Document &l ); +QDataStream &operator<<( QDataStream &s, const Document &l ); + +class Index : public QObject +{ + Q_OBJECT + public: + + Index(); + + void writeDict( QDataStream& stream ); + bool readDict( QDataStream& stream ); + bool makeIndex(const QList &docs, EBook * chmFile ); + QList query( const QStringList&, const QStringList&, const QStringList&, EBook * chmFile ); + QString getCharsSplit() const { return m_charssplit; } + QString getCharsPartOfWord() const { return m_charsword; } + + signals: + void indexingProgress( int, const QString& ); + + public slots: + void setLastWinClosed(); + + private: + struct Entry + { + Entry( int d ) { documents.append( Document( d, 1 ) ); } + Entry( QVector l ) : documents( l ) {} + QVector documents; + }; + + struct PosEntry + { + PosEntry( int p ) { positions.append( p ); } + QList positions; + }; + + bool parseDocumentToStringlist( EBook * chmFile, const QUrl& filename, QStringList& tokenlist ); + void insertInDict( const QString&, int ); + + QStringList getWildcardTerms( const QString& ); + QStringList split( const QString& ); + QList setupDummyTerm( const QStringList& ); + bool searchForPhrases(const QStringList &phrases, const QStringList &words, const QUrl &filename, EBook * chmFile ); + + QList< QUrl > docList; + QHash dict; + QHashminiDict; + bool lastWindowClosed; + HelperEntityDecoder entityDecoder; + + // Those characters are splitters (i.e. split the word), but added themselves into dictionary too. + // This makes the dictionary MUCH larger, but ensure that for the piece of "window->print" both + // search for "print" and "->print" will find it. + QString m_charssplit; + + // Those characters are parts of word - for example, '_' is here, and search for _debug will find only _debug. + QString m_charsword; +}; + +}; + +#endif // EBOOK_SEARCH_INDEX_H diff --git a/generators/chm/lib/helperxmlhandler_epubcontainer.cpp b/generators/chm/lib/helperxmlhandler_epubcontainer.cpp new file mode 100644 index 000000000..2f2ca48eb --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubcontainer.cpp @@ -0,0 +1,34 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "helperxmlhandler_epubcontainer.h" + +bool HelperXmlHandler_EpubContainer::startElement(const QString &, const QString &, const QString &qName, const QXmlAttributes &atts) +{ + if ( qName == "rootfile" ) + { + int idx = atts.index( "full-path" ); + + if ( idx == -1 ) + return false; + + contentPath = atts.value( idx ); + } + + return true; +} diff --git a/generators/chm/lib/helperxmlhandler_epubcontainer.h b/generators/chm/lib/helperxmlhandler_epubcontainer.h new file mode 100644 index 000000000..3de9a604b --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubcontainer.h @@ -0,0 +1,34 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HELPERXMLHANDLER_EPUBCONTAINER_H +#define HELPERXMLHANDLER_EPUBCONTAINER_H + +#include + +class HelperXmlHandler_EpubContainer : public QXmlDefaultHandler +{ + public: + // Overridden members + bool startElement ( const QString & namespaceURI, const QString & localName, const QString & qName, const QXmlAttributes & atts ); + + // The content path + QString contentPath; +}; + +#endif // HELPERXMLHANDLER_EPUBCONTAINER_H diff --git a/generators/chm/lib/helperxmlhandler_epubcontent.cpp b/generators/chm/lib/helperxmlhandler_epubcontent.cpp new file mode 100644 index 000000000..57bbe7544 --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubcontent.cpp @@ -0,0 +1,93 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "helperxmlhandler_epubcontent.h" + +HelperXmlHandler_EpubContent::HelperXmlHandler_EpubContent() +{ + m_state = STATE_NONE; +} + +bool HelperXmlHandler_EpubContent::startElement(const QString &, const QString &localName, const QString &, const QXmlAttributes &atts) +{ + // tag contains the medatada which goes into m_metadata + if ( localName == "metadata" ) + m_state = STATE_IN_METADATA; + else if ( localName == "manifest" ) + m_state = STATE_IN_MANIFEST; + else if ( localName == "spine" ) + m_state = STATE_IN_SPINE; + // Now handle the states + else if ( m_state == STATE_IN_METADATA ) // we don't need to store the first 'metadata' here + m_tagname = localName; + else if ( m_state == STATE_IN_MANIFEST && localName == "item" ) + { + int idx_id = atts.index( "id" ); + int idx_href = atts.index( "href" ); + int idx_mtype = atts.index( "media-type" ); + + if ( idx_id == -1 || idx_href == -1 || idx_mtype == -1 ) + return false; + + manifest[ atts.value( idx_id ) ] = atts.value( idx_href ); + + if ( atts.value( idx_mtype ) == "application/x-dtbncx+xml" ) + tocname = atts.value( idx_href ); + + //qDebug() << "MANIFEST: " << atts.value( idx_id ) << "->" << atts.value( idx_href ); + } + else if ( m_state == STATE_IN_SPINE && localName == "itemref" ) + { + int idx = atts.index( "idref" ); + + if ( idx == -1 ) + return false; + + spine.push_back( atts.value( idx ) ); + //qDebug() << "SPINE: " << atts.value( idx ); + } + + return true; +} + +bool HelperXmlHandler_EpubContent::characters(const QString &ch) +{ + if ( m_state == STATE_IN_METADATA && !m_tagname.isEmpty() && !ch.trimmed().isEmpty() ) + { + // Some metadata may be duplicated; we concantenate them with | + if ( metadata.contains( m_tagname ) ) + { + metadata[ m_tagname ].append( "|" ); + metadata[ m_tagname ].append( ch.trimmed() ); + } + else + metadata[ m_tagname ] = ch.trimmed(); + + //qDebug() << "METATAG: " << m_tagname << " " << metadata[ m_tagname ]; + } + + return true; +} + +bool HelperXmlHandler_EpubContent::endElement(const QString &, const QString &, const QString &qName) +{ + if ( qName == "manifest" || qName == "metadata" || qName == "spine" ) + m_state = STATE_NONE; + + return true; +} diff --git a/generators/chm/lib/helperxmlhandler_epubcontent.h b/generators/chm/lib/helperxmlhandler_epubcontent.h new file mode 100644 index 000000000..874a49c4b --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubcontent.h @@ -0,0 +1,61 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HELPERXMLHANDLER_EPUBCONTENT_H +#define HELPERXMLHANDLER_EPUBCONTENT_H + +#include +#include +#include + +class HelperXmlHandler_EpubContent : public QXmlDefaultHandler +{ + public: + HelperXmlHandler_EpubContent(); + + // Keep the tag-associated metadata + QMap< QString, QString > metadata; + + // Manifest storage, id -> href + QMap< QString, QString > manifest; + + // Spline storage + QList< QString > spine; + + // TOC (NCX) filename + QString tocname; + + private: + enum State + { + STATE_NONE, + STATE_IN_METADATA, + STATE_IN_MANIFEST, + STATE_IN_SPINE + }; + + bool startElement ( const QString & namespaceURI, const QString & localName, const QString & qName, const QXmlAttributes & atts ); + bool characters(const QString &ch); + bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName); + + // Tracking + State m_state; + QString m_tagname; +}; + +#endif // HELPERXMLHANDLER_EPUBCONTENT_H diff --git a/generators/chm/lib/helperxmlhandler_epubtoc.cpp b/generators/chm/lib/helperxmlhandler_epubtoc.cpp new file mode 100644 index 000000000..af14518fb --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubtoc.cpp @@ -0,0 +1,112 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "helperxmlhandler_epubtoc.h" + +HelperXmlHandler_EpubTOC::HelperXmlHandler_EpubTOC(EBook_EPUB *epub) +{ + m_epub = epub; + m_inNavMap = false; + m_inText = false; + m_indent = 0; +} + +bool HelperXmlHandler_EpubTOC::startElement(const QString &, const QString &localName, const QString &, const QXmlAttributes &atts) +{ +// qDebug() << "startElement " << " " << localName; + +// for ( int i = 0; i < atts.count(); i++ ) +// qDebug() << " " << atts.localName(i) << " " << atts.value(i); + + if ( localName == "navMap" ) + { + m_inNavMap = true; + return true; + } + + if ( !m_inNavMap ) + return true; + + if ( localName == "navPoint" ) + m_indent++; + + if ( localName == "text" ) + m_inText = true; + + if ( localName == "content" ) + { + int idx = atts.index( "src" ); + + if ( idx == -1 ) + return false; + + m_lastId = atts.value( idx ); + checkNewTocEntry(); + } + + return true; +} + +bool HelperXmlHandler_EpubTOC::characters(const QString &ch) +{ + // qDebug() << "characters" << " " << ch; + if ( m_inText ) + m_lastTitle = ch; + + checkNewTocEntry(); + return true; +} + +bool HelperXmlHandler_EpubTOC::endElement(const QString& , const QString &localName, const QString &) +{ +// qDebug() << "endElement" << " " << qName; + + if ( localName == "navMap" ) + { + m_inNavMap = false; + return true; + } + + if ( localName == "navPoint" ) + m_indent--; + + if ( localName == "text" ) + m_inText = false; + + return true; +} + +void HelperXmlHandler_EpubTOC::checkNewTocEntry() +{ + if ( !m_lastId.isEmpty() && !m_lastTitle.isEmpty() ) + { + EBookTocEntry entry; + entry.name = m_lastTitle; + entry.url = m_epub->pathToUrl( m_lastId ); + entry.iconid = EBookTocEntry::IMAGE_AUTO; + entry.indent = m_indent - 1; + + entries.push_back( entry ); + + //qDebug() << "TOC entry: " << m_lastId << " :" << m_lastTitle << " :" << m_indent - 1; + + m_lastId.clear(); + m_lastTitle.clear(); + } +} diff --git a/generators/chm/lib/helperxmlhandler_epubtoc.h b/generators/chm/lib/helperxmlhandler_epubtoc.h new file mode 100644 index 000000000..cdb155b70 --- /dev/null +++ b/generators/chm/lib/helperxmlhandler_epubtoc.h @@ -0,0 +1,47 @@ +/* + * Kchmviewer - a CHM and EPUB file viewer with broad language support + * Copyright (C) 2004-2014 George Yunaev, gyunaev@ulduzsoft.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef HELPERXMLHANDLER_EPUBTOC_H +#define HELPERXMLHANDLER_EPUBTOC_H + +#include +#include "ebook_epub.h" + +class HelperXmlHandler_EpubTOC : public QXmlDefaultHandler +{ + public: + HelperXmlHandler_EpubTOC( EBook_EPUB * epub ); + + QList< EBookTocEntry > entries; + + private: + // Overridden members + bool startElement ( const QString & namespaceURI, const QString & localName, const QString & qName, const QXmlAttributes & atts ); + bool characters(const QString &ch); + bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName); + void checkNewTocEntry(); + + bool m_inNavMap; + bool m_inText; + unsigned int m_indent; + QString m_lastId; + QString m_lastTitle; + EBook_EPUB * m_epub; +}; + +#endif // HELPERXMLHANDLER_EPUBTOC_H diff --git a/generators/chm/lib/lchmurlhandler.cpp b/generators/chm/lib/lchmurlhandler.cpp deleted file mode 100644 index 9d98d87e1..000000000 --- a/generators/chm/lib/lchmurlhandler.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * 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/generators/chm/lib/lchmurlhandler.h b/generators/chm/lib/lchmurlhandler.h deleted file mode 100644 index 35133c41d..000000000 --- a/generators/chm/lib/lchmurlhandler.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************** - * 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 -*/ -class LCHMUrlHandler{ -public: - LCHMUrlHandler(); - - ~LCHMUrlHandler(); - -}; - -#endif diff --git a/generators/chm/lib/libchmfile.cpp b/generators/chm/lib/libchmfile.cpp deleted file mode 100644 index 60d03bc26..000000000 --- a/generators/chm/lib/libchmfile.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************************************** - * 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" - -#include - - -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() ? QStringLiteral("/") : 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( QVector< LCHMParsedEntry > * topics ) const -{ - return m_impl->parseFileAndFillArray( QString::fromLocal8Bit(m_impl->m_topicsFile), topics, false ); -} - -bool LCHMFile::parseIndex( QVector< LCHMParsedEntry > * indexes ) const -{ - return m_impl->parseFileAndFillArray( QString::fromLocal8Bit(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/generators/chm/lib/libchmfile.h b/generators/chm/lib/libchmfile.h deleted file mode 100644 index cb739ac79..000000000 --- a/generators/chm/lib/libchmfile.h +++ /dev/null @@ -1,280 +0,0 @@ -/*************************************************************************** - * 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 -#include -#include -#include -#include - -#include "libchmtextencoding.h" - - -//! 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( QVector< 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( QVector< LCHMParsedEntry > * indexes ) const; - - /*! - * \brief Retrieves the content from url in current chm file to QString. - * \param str A string where the retrieved content should be stored. - * \param url An URL in chm file to retrieve content from. Must be absolute. - * \return true if the content is successfully received; false otherwise. - * - * This function retrieves 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 retrieved content should be stored. - * \param url An URL in chm file to retrieve content from. Must be absolute. - * \return true if the content is successfully received; false otherwise. - * - * This function retrieves 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 retrieve 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/generators/chm/lib/libchmfile_search.cpp b/generators/chm/lib/libchmfile_search.cpp deleted file mode 100644 index 76532b182..000000000 --- a/generators/chm/lib/libchmfile_search.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/*************************************************************************** - * 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 - -#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 (QStringLiteral("[^\\d\\w_\\.]+")); - - QString orig = word; - word.remove ( rxvalid ); - - if ( word != orig ) - query_valid = false; -} - -static inline void validateWords ( QStringList & wordlist, bool & query_valid ) -{ - for ( 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 ( int s1 = 0; s1 < results.size(); s1++ ) - { - bool found = false; - - for ( 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 ( QVector & src, const QVector & needle ) -{ - for ( int s1 = 0; s1 < src.size(); s1++ ) - { - bool found = false; - uint64_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 ( 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 ( 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 ( int p1 = 0; p1 < phrasekeeper.size(); p1++ ) - { - bool found = false; - - DEBUG_SEARCH (("Ext loop (it %d): urloff %d", p1, phrasekeeper[p1].urloff)); - - for ( int p2 = 0; p2 < srchtmp.size(); p2++ ) - { - // look up for words on 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 ( 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; - QVector phrases_must_exist; - QString query = inquery; - bool query_valid = true; - LCHMSearchProgressResults results; - int pos; - 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( QStringLiteral("\"(.*)\"") ); - QRegExp rxword( QStringLiteral("([^\\s]+)") ); - rxphrase.setMinimal( true ); - - // First, get the phrase queries - while ( (pos = rxphrase.indexIn (query, 0)) != -1 ) - { - // A phrase query found. Locate its boundaries, and parse it. - QStringList plist = rxphrase.cap ( 1 ).split ( QRegExp (QStringLiteral("\\s+")) ); - - 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.indexIn( query, 0 )) != -1 ) - { - // A phrase query found. Locate its boundaries, and parse it. - QString word = rxword.cap ( 1 ); - QChar type = QLatin1Char('+'); - - if ( word[0] == QLatin1Char('-') || word[0] == QLatin1Char('+') ) - { - type = word[0]; - word.remove (0, 1); - } - - validateWord ( word, query_valid ); - - if ( type == QLatin1Char('-') ) - 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/generators/chm/lib/libchmfileimpl.cpp b/generators/chm/lib/libchmfileimpl.cpp deleted file mode 100644 index d10602028..000000000 --- a/generators/chm/lib/libchmfileimpl.cpp +++ /dev/null @@ -1,1292 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * - * Portions Copyright (C) 2003 Razvan Cojocaru * - * 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 - -#include -#include -#include -#include -#include -#include - -#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_filename = 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( QLatin1String("file://") ) ) - filename = archiveName.mid( 7 ); // strip it - else - filename = archiveName; - - if( m_chmFile ) - closeAll(); - - m_chmFile = chm_open( QFile::encodeName(filename).constData() ); - - 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(); - if ( !guessTextEncoding() ) - return false; - - // Check whether the search tables are present - if ( ResolveObject(QStringLiteral("/#TOPICS"), &m_chmTOPICS) - && ResolveObject(QStringLiteral("/#STRINGS"), &m_chmSTRINGS) - && ResolveObject(QStringLiteral("/#URLTBL"), &m_chmURLTBL) - && ResolveObject(QStringLiteral("/#URLSTR"), &m_chmURLSTR) ) - { - m_lookupTablesValid = true; - fillTopicsUrlMap(); - } - else - m_lookupTablesValid = false; - - if ( m_lookupTablesValid && ResolveObject (QStringLiteral("/$FIftiMain"), &m_chmFIftiMain) ) - m_searchAvailable = true; - else - m_searchAvailable = false; - - // Some CHM files have toc and index files, but do not set the name properly. - // Some heuristics here. - chmUnitInfo tui; - - if ( m_topicsFile.isEmpty() && ResolveObject(QStringLiteral("/toc.hhc"), &tui) ) - m_topicsFile = "/toc.hhc"; - - if ( m_indexFile.isEmpty() && ResolveObject(QStringLiteral("/index.hhk"), &tui) ) - m_indexFile = "/index.hhk"; - - return true; -} - - -void LCHMFileImpl::closeAll( ) -{ - if ( m_chmFile == NULL ) - return; - - chm_close( m_chmFile ); - - m_chmFile = NULL; - m_filename = m_font = QString::null; - - m_home.clear(); - m_topicsFile.clear(); - m_indexFile.clear(); - - 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[QStringLiteral("AElig")] = encodeWithCurrentCodec ("\306"); // capital AE diphthong (ligature) - m_entityDecodeMap[QStringLiteral("Aacute")] = encodeWithCurrentCodec ("\301"); // capital A, acute accent - m_entityDecodeMap[QStringLiteral("Acirc")] = encodeWithCurrentCodec ("\302"); // capital A, circumflex accent - m_entityDecodeMap[QStringLiteral("Agrave")] = encodeWithCurrentCodec ("\300"); // capital A, grave accent - m_entityDecodeMap[QStringLiteral("Aring")] = encodeWithCurrentCodec ("\305"); // capital A, ring - m_entityDecodeMap[QStringLiteral("Atilde")] = encodeWithCurrentCodec ("\303"); // capital A, tilde - m_entityDecodeMap[QStringLiteral("Auml")] = encodeWithCurrentCodec ("\304"); // capital A, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("Ccedil")] = encodeWithCurrentCodec ("\307"); // capital C, cedilla - m_entityDecodeMap[QStringLiteral("Dstrok")] = encodeWithCurrentCodec ("\320"); // whatever - m_entityDecodeMap[QStringLiteral("ETH")] = encodeWithCurrentCodec ("\320"); // capital Eth, Icelandic - m_entityDecodeMap[QStringLiteral("Eacute")] = encodeWithCurrentCodec ("\311"); // capital E, acute accent - m_entityDecodeMap[QStringLiteral("Ecirc")] = encodeWithCurrentCodec ("\312"); // capital E, circumflex accent - m_entityDecodeMap[QStringLiteral("Egrave")] = encodeWithCurrentCodec ("\310"); // capital E, grave accent - m_entityDecodeMap[QStringLiteral("Euml")] = encodeWithCurrentCodec ("\313"); // capital E, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("Iacute")] = encodeWithCurrentCodec ("\315"); // capital I, acute accent - m_entityDecodeMap[QStringLiteral("Icirc")] = encodeWithCurrentCodec ("\316"); // capital I, circumflex accent - m_entityDecodeMap[QStringLiteral("Igrave")] = encodeWithCurrentCodec ("\314"); // capital I, grave accent - m_entityDecodeMap[QStringLiteral("Iuml")] = encodeWithCurrentCodec ("\317"); // capital I, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("Ntilde")] = encodeWithCurrentCodec ("\321"); // capital N, tilde - m_entityDecodeMap[QStringLiteral("Oacute")] = encodeWithCurrentCodec ("\323"); // capital O, acute accent - m_entityDecodeMap[QStringLiteral("Ocirc")] = encodeWithCurrentCodec ("\324"); // capital O, circumflex accent - m_entityDecodeMap[QStringLiteral("Ograve")] = encodeWithCurrentCodec ("\322"); // capital O, grave accent - m_entityDecodeMap[QStringLiteral("Oslash")] = encodeWithCurrentCodec ("\330"); // capital O, slash - m_entityDecodeMap[QStringLiteral("Otilde")] = encodeWithCurrentCodec ("\325"); // capital O, tilde - m_entityDecodeMap[QStringLiteral("Ouml")] = encodeWithCurrentCodec ("\326"); // capital O, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("THORN")] = encodeWithCurrentCodec ("\336"); // capital THORN, Icelandic - m_entityDecodeMap[QStringLiteral("Uacute")] = encodeWithCurrentCodec ("\332"); // capital U, acute accent - m_entityDecodeMap[QStringLiteral("Ucirc")] = encodeWithCurrentCodec ("\333"); // capital U, circumflex accent - m_entityDecodeMap[QStringLiteral("Ugrave")] = encodeWithCurrentCodec ("\331"); // capital U, grave accent - m_entityDecodeMap[QStringLiteral("Uuml")] = encodeWithCurrentCodec ("\334"); // capital U, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("Yacute")] = encodeWithCurrentCodec ("\335"); // capital Y, acute accent - m_entityDecodeMap[QStringLiteral("OElig")] = encodeWithCurrentCodec ("\338"); // capital Y, acute accent - m_entityDecodeMap[QStringLiteral("oelig")] = encodeWithCurrentCodec ("\339"); // capital Y, acute accent - - m_entityDecodeMap[QStringLiteral("aacute")] = encodeWithCurrentCodec ("\341"); // small a, acute accent - m_entityDecodeMap[QStringLiteral("acirc")] = encodeWithCurrentCodec ("\342"); // small a, circumflex accent - m_entityDecodeMap[QStringLiteral("aelig")] = encodeWithCurrentCodec ("\346"); // small ae diphthong (ligature) - m_entityDecodeMap[QStringLiteral("agrave")] = encodeWithCurrentCodec ("\340"); // small a, grave accent - m_entityDecodeMap[QStringLiteral("aring")] = encodeWithCurrentCodec ("\345"); // small a, ring - m_entityDecodeMap[QStringLiteral("atilde")] = encodeWithCurrentCodec ("\343"); // small a, tilde - m_entityDecodeMap[QStringLiteral("auml")] = encodeWithCurrentCodec ("\344"); // small a, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("ccedil")] = encodeWithCurrentCodec ("\347"); // small c, cedilla - m_entityDecodeMap[QStringLiteral("eacute")] = encodeWithCurrentCodec ("\351"); // small e, acute accent - m_entityDecodeMap[QStringLiteral("ecirc")] = encodeWithCurrentCodec ("\352"); // small e, circumflex accent - m_entityDecodeMap[QStringLiteral("Scaron")] = encodeWithCurrentCodec ("\352"); // small e, circumflex accent - m_entityDecodeMap[QStringLiteral("egrave")] = encodeWithCurrentCodec ("\350"); // small e, grave accent - m_entityDecodeMap[QStringLiteral("eth")] = encodeWithCurrentCodec ("\360"); // small eth, Icelandic - m_entityDecodeMap[QStringLiteral("euml")] = encodeWithCurrentCodec ("\353"); // small e, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("iacute")] = encodeWithCurrentCodec ("\355"); // small i, acute accent - m_entityDecodeMap[QStringLiteral("icirc")] = encodeWithCurrentCodec ("\356"); // small i, circumflex accent - m_entityDecodeMap[QStringLiteral("igrave")] = encodeWithCurrentCodec ("\354"); // small i, grave accent - m_entityDecodeMap[QStringLiteral("iuml")] = encodeWithCurrentCodec ("\357"); // small i, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("ntilde")] = encodeWithCurrentCodec ("\361"); // small n, tilde - m_entityDecodeMap[QStringLiteral("oacute")] = encodeWithCurrentCodec ("\363"); // small o, acute accent - m_entityDecodeMap[QStringLiteral("ocirc")] = encodeWithCurrentCodec ("\364"); // small o, circumflex accent - m_entityDecodeMap[QStringLiteral("ograve")] = encodeWithCurrentCodec ("\362"); // small o, grave accent - m_entityDecodeMap[QStringLiteral("oslash")] = encodeWithCurrentCodec ("\370"); // small o, slash - m_entityDecodeMap[QStringLiteral("otilde")] = encodeWithCurrentCodec ("\365"); // small o, tilde - m_entityDecodeMap[QStringLiteral("ouml")] = encodeWithCurrentCodec ("\366"); // small o, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("szlig")] = encodeWithCurrentCodec ("\337"); // small sharp s, German (sz ligature) - m_entityDecodeMap[QStringLiteral("thorn")] = encodeWithCurrentCodec ("\376"); // small thorn, Icelandic - m_entityDecodeMap[QStringLiteral("uacute")] = encodeWithCurrentCodec ("\372"); // small u, acute accent - m_entityDecodeMap[QStringLiteral("ucirc")] = encodeWithCurrentCodec ("\373"); // small u, circumflex accent - m_entityDecodeMap[QStringLiteral("ugrave")] = encodeWithCurrentCodec ("\371"); // small u, grave accent - m_entityDecodeMap[QStringLiteral("uuml")] = encodeWithCurrentCodec ("\374"); // small u, dieresis or umlaut mark - m_entityDecodeMap[QStringLiteral("yacute")] = encodeWithCurrentCodec ("\375"); // small y, acute accent - m_entityDecodeMap[QStringLiteral("yuml")] = encodeWithCurrentCodec ("\377"); // small y, dieresis or umlaut mark - - m_entityDecodeMap[QStringLiteral("iexcl")] = encodeWithCurrentCodec ("\241"); - m_entityDecodeMap[QStringLiteral("cent")] = encodeWithCurrentCodec ("\242"); - m_entityDecodeMap[QStringLiteral("pound")] = encodeWithCurrentCodec ("\243"); - m_entityDecodeMap[QStringLiteral("curren")] = encodeWithCurrentCodec ("\244"); - m_entityDecodeMap[QStringLiteral("yen")] = encodeWithCurrentCodec ("\245"); - m_entityDecodeMap[QStringLiteral("brvbar")] = encodeWithCurrentCodec ("\246"); - m_entityDecodeMap[QStringLiteral("sect")] = encodeWithCurrentCodec ("\247"); - m_entityDecodeMap[QStringLiteral("uml")] = encodeWithCurrentCodec ("\250"); - m_entityDecodeMap[QStringLiteral("ordf")] = encodeWithCurrentCodec ("\252"); - m_entityDecodeMap[QStringLiteral("laquo")] = encodeWithCurrentCodec ("\253"); - m_entityDecodeMap[QStringLiteral("not")] = encodeWithCurrentCodec ("\254"); - m_entityDecodeMap[QStringLiteral("shy")] = encodeWithCurrentCodec ("\255"); - m_entityDecodeMap[QStringLiteral("macr")] = encodeWithCurrentCodec ("\257"); - m_entityDecodeMap[QStringLiteral("deg")] = encodeWithCurrentCodec ("\260"); - m_entityDecodeMap[QStringLiteral("plusmn")] = encodeWithCurrentCodec ("\261"); - m_entityDecodeMap[QStringLiteral("sup1")] = encodeWithCurrentCodec ("\271"); - m_entityDecodeMap[QStringLiteral("sup2")] = encodeWithCurrentCodec ("\262"); - m_entityDecodeMap[QStringLiteral("sup3")] = encodeWithCurrentCodec ("\263"); - m_entityDecodeMap[QStringLiteral("acute")] = encodeWithCurrentCodec ("\264"); - m_entityDecodeMap[QStringLiteral("micro")] = encodeWithCurrentCodec ("\265"); - m_entityDecodeMap[QStringLiteral("para")] = encodeWithCurrentCodec ("\266"); - m_entityDecodeMap[QStringLiteral("middot")] = encodeWithCurrentCodec ("\267"); - m_entityDecodeMap[QStringLiteral("cedil")] = encodeWithCurrentCodec ("\270"); - m_entityDecodeMap[QStringLiteral("ordm")] = encodeWithCurrentCodec ("\272"); - m_entityDecodeMap[QStringLiteral("raquo")] = encodeWithCurrentCodec ("\273"); - m_entityDecodeMap[QStringLiteral("frac14")] = encodeWithCurrentCodec ("\274"); - m_entityDecodeMap[QStringLiteral("frac12")] = encodeWithCurrentCodec ("\275"); - m_entityDecodeMap[QStringLiteral("frac34")] = encodeWithCurrentCodec ("\276"); - m_entityDecodeMap[QStringLiteral("iquest")] = encodeWithCurrentCodec ("\277"); - m_entityDecodeMap[QStringLiteral("times")] = encodeWithCurrentCodec ("\327"); - m_entityDecodeMap[QStringLiteral("divide")] = encodeWithCurrentCodec ("\367"); - - m_entityDecodeMap[QStringLiteral("copy")] = encodeWithCurrentCodec ("\251"); // copyright sign - m_entityDecodeMap[QStringLiteral("reg")] = encodeWithCurrentCodec ("\256"); // registered sign - m_entityDecodeMap[QStringLiteral("nbsp")] = encodeWithCurrentCodec ("\240"); // non breaking space - - m_entityDecodeMap[QStringLiteral("fnof")] = QChar((unsigned short) 402); - - m_entityDecodeMap[QStringLiteral("Delta")] = QChar((unsigned short) 916); - m_entityDecodeMap[QStringLiteral("Pi")] = QChar((unsigned short) 928); - m_entityDecodeMap[QStringLiteral("Sigma")] = QChar((unsigned short) 931); - - m_entityDecodeMap[QStringLiteral("beta")] = QChar((unsigned short) 946); - m_entityDecodeMap[QStringLiteral("gamma")] = QChar((unsigned short) 947); - m_entityDecodeMap[QStringLiteral("delta")] = QChar((unsigned short) 948); - m_entityDecodeMap[QStringLiteral("eta")] = QChar((unsigned short) 951); - m_entityDecodeMap[QStringLiteral("theta")] = QChar((unsigned short) 952); - m_entityDecodeMap[QStringLiteral("lambda")] = QChar((unsigned short) 955); - m_entityDecodeMap[QStringLiteral("mu")] = QChar((unsigned short) 956); - m_entityDecodeMap[QStringLiteral("nu")] = QChar((unsigned short) 957); - m_entityDecodeMap[QStringLiteral("pi")] = QChar((unsigned short) 960); - m_entityDecodeMap[QStringLiteral("rho")] = QChar((unsigned short) 961); - - m_entityDecodeMap[QStringLiteral("lsquo")] = QChar((unsigned short) 8216); - m_entityDecodeMap[QStringLiteral("rsquo")] = QChar((unsigned short) 8217); - m_entityDecodeMap[QStringLiteral("rdquo")] = QChar((unsigned short) 8221); - m_entityDecodeMap[QStringLiteral("bdquo")] = QChar((unsigned short) 8222); - m_entityDecodeMap[QStringLiteral("trade")] = QChar((unsigned short) 8482); - m_entityDecodeMap[QStringLiteral("ldquo")] = QChar((unsigned short) 8220); - m_entityDecodeMap[QStringLiteral("ndash")] = QChar((unsigned short) 8211); - m_entityDecodeMap[QStringLiteral("mdash")] = QChar((unsigned short) 8212); - m_entityDecodeMap[QStringLiteral("bull")] = QChar((unsigned short) 8226); - m_entityDecodeMap[QStringLiteral("hellip")] = QChar((unsigned short) 8230); - m_entityDecodeMap[QStringLiteral("emsp")] = QChar((unsigned short) 8195); - m_entityDecodeMap[QStringLiteral("rarr")] = QChar((unsigned short) 8594); - m_entityDecodeMap[QStringLiteral("rArr")] = QChar((unsigned short) 8658); - m_entityDecodeMap[QStringLiteral("crarr")] = QChar((unsigned short) 8629); - m_entityDecodeMap[QStringLiteral("le")] = QChar((unsigned short) 8804); - m_entityDecodeMap[QStringLiteral("ge")] = QChar((unsigned short) 8805); - m_entityDecodeMap[QStringLiteral("lte")] = QChar((unsigned short) 8804); // wrong, but used somewhere - m_entityDecodeMap[QStringLiteral("gte")] = QChar((unsigned short) 8805); // wrong, but used somewhere - m_entityDecodeMap[QStringLiteral("dagger")] = QChar((unsigned short) 8224); - m_entityDecodeMap[QStringLiteral("Dagger")] = QChar((unsigned short) 8225); - m_entityDecodeMap[QStringLiteral("euro")] = QChar((unsigned short) 8364); - m_entityDecodeMap[QStringLiteral("asymp")] = QChar((unsigned short) 8776); - m_entityDecodeMap[QStringLiteral("isin")] = QChar((unsigned short) 8712); - m_entityDecodeMap[QStringLiteral("notin")] = QChar((unsigned short) 8713); - m_entityDecodeMap[QStringLiteral("prod")] = QChar((unsigned short) 8719); - m_entityDecodeMap[QStringLiteral("ne")] = QChar((unsigned short) 8800); - - m_entityDecodeMap[QStringLiteral("amp")] = QStringLiteral("&"); // ampersand - m_entityDecodeMap[QStringLiteral("gt")] = QStringLiteral(">"); // greater than - m_entityDecodeMap[QStringLiteral("lt")] = QStringLiteral("<"); // less than - m_entityDecodeMap[QStringLiteral("quot")] = QStringLiteral("\""); // double quote - m_entityDecodeMap[QStringLiteral("apos")] = QStringLiteral("'"); // single quote - m_entityDecodeMap[QStringLiteral("frasl")] = QStringLiteral("/"); - m_entityDecodeMap[QStringLiteral("minus")] = QStringLiteral("-"); - m_entityDecodeMap[QStringLiteral("oplus")] = QStringLiteral("+"); - m_entityDecodeMap[QStringLiteral("Prime")] = QStringLiteral("\""); - } - - // If entity is an ASCII code like 〽 - just decode it - if ( entity[0] == QLatin1Char('#') ) - { - bool valid; - unsigned int ascode = entity.midRef(1).toUInt( &valid ); - - if ( !valid ) - { - qWarning ( "LCHMFileImpl::decodeEntity: could not decode HTML entity '%s'", qPrintable( entity ) ); - return QString::null; - } - - return (QString) (QChar( ascode )); - } - else - { - QMap::const_iterator it = m_entityDecodeMap.constFind( entity ); - - if ( it == m_entityDecodeMap.constEnd() ) - { - qWarning ("LCHMFileImpl::decodeEntity: could not decode HTML entity '%s'", qPrintable( entity )); - return QString::null; - } - - return *it; - } -} - - -inline int LCHMFileImpl::findStringInQuotes (const QString& tag, int offset, QString& value, bool firstquote, bool decodeentities) -{ - int qbegin = tag.indexOf (QLatin1Char('"'), offset); - - if ( qbegin == -1 ) - qFatal ("LCHMFileImpl::findStringInQuotes: cannot find first quote in tag: '%s'", qPrintable( tag )); - - int qend = firstquote ? tag.indexOf (QLatin1Char('"'), qbegin + 1) : tag.lastIndexOf (QLatin1Char('"')); - - if ( qend == -1 || qend <= qbegin ) - qFatal ("LCHMFileImpl::findStringInQuotes: cannot find last quote in tag: '%s'", qPrintable( tag )); - - // 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] == QLatin1Char('&') ) // HTML entity starts - fill_entity = true; - else - value.append (tag[i]); - } - else - { - if ( tag[i] == QLatin1Char(';') ) // 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::fromLocal8Bit( 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; - uint32_t node_offset = UINT32ARRAY(cursor32); - - cursor32 = header + 0x2e; - uint32_t node_len = UINT32ARRAY(cursor32); - - unsigned char* cursor16 = header + 0x18; - uint16_t tree_depth = UINT16ARRAY(cursor16); - - unsigned char word_len, pos; - QString word; - uint32_t i = sizeof(uint16_t); - uint16_t free_space; - - QVector 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(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t); - uint64_t wlc_count, wlc_size; - uint32_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 = QString::fromLocal8Bit(wrd_buf, word_len); - else - word = word.mid (0, pos) + QString::fromLocal8Bit((const char*) wrd_buf, word_len); - - 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(uint32_t) + sizeof(uint16_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, qPrintable( fileName ), ui) == - CHM_RESOLVE_SUCCESS; -} - - -size_t LCHMFileImpl::RetrieveObject(const chmUnitInfo *ui, unsigned char *buffer, - LONGUINT64 fileOffset, LONGINT64 bufferSize) const -{ - return ::chm_retrieve_object(m_chmFile, const_cast(ui), - buffer, fileOffset, bufferSize); -} - - -inline uint32_t LCHMFileImpl::GetLeafNodeOffset(const QString& text, - uint32_t initialOffset, - uint32_t buffSize, - uint16_t treeDepth) -{ - uint32_t test_offset = 0; - unsigned char* cursor16, *cursor32; - unsigned char word_len, pos; - uint32_t i = sizeof(uint16_t); - QVector 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(); - uint16_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 = QString::fromLocal8Bit(wrd_buf, word_len); - else - word = word.mid(0, pos) + QString::fromLocal8Bit((const char*) wrd_buf, word_len); - - delete[] wrd_buf; - - if ( text <= word ) - { - cursor32 = buffer.data() + i + word_len + 1; - initialOffset = UINT32ARRAY(cursor32); - break; - } - - i += word_len + sizeof(unsigned char) + - sizeof(uint32_t) + sizeof(uint16_t); - } - } - - if ( initialOffset == test_offset ) - return 0; - - return initialOffset; -} - - -inline bool LCHMFileImpl::ProcessWLC (uint64_t wlc_count, uint64_t wlc_size, - uint32_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; - uint64_t index = 0, count; - size_t length, off = 0; - QVector 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 ( uint64_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 (uint64_t j = 0; j < count; ++j) - { - uint64_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(QStringLiteral("/#WINDOWS"), &ui) ) - { - if ( !RetrieveObject(&ui, buffer, 0, WIN_HEADER_LEN) ) - return false; - - uint32_t entries = get_int32_le( (uint32_t *)(buffer) ); - uint32_t entry_size = get_int32_le( (uint32_t *)(buffer + 0x04) ); - - QVector uptr(entries * entry_size); - unsigned char* raw = (unsigned char*) uptr.data(); - - if ( !RetrieveObject (&ui, raw, 8, entries * entry_size) ) - return false; - - if( !ResolveObject (QStringLiteral("/#STRINGS"), &ui) ) - return false; - - for ( uint32_t i = 0; i < entries; ++i ) - { - uint32_t offset = i * entry_size; - - uint32_t off_title = get_int32_le( (uint32_t *)(raw + offset + 0x14) ); - uint32_t off_home = get_int32_le( (uint32_t *)(raw + offset + 0x68) ); - uint32_t off_hhc = get_int32_le( (uint32_t *)(raw + offset + 0x60) ); - uint32_t off_hhk = get_int32_le( (uint32_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 = QByteArray( (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 = QByteArray("/") + QByteArray( (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 = QByteArray("/") + QByteArray((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 = QByteArray("/") + QByteArray((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; - uint16_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 (QStringLiteral("/#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(uint16_t)) ;) - { - cursor = buffer + index; - value = UINT16ARRAY(cursor); - - switch(value) - { - case 0: - index += 2; - cursor = buffer + index; - - if(m_topicsFile.isEmpty()) - m_topicsFile = QByteArray("/") + QByteArray((const char*) buffer + index + 2); - - break; - - case 1: - index += 2; - cursor = buffer + index; - - if(m_indexFile.isEmpty()) - m_indexFile = QByteArray("/") + QByteArray((const char*)buffer + index + 2); - break; - - case 2: - index += 2; - cursor = buffer + index; - - if(m_home.isEmpty() || m_home == "/") - m_home = QByteArray("/") + QByteArray((const char*) buffer + index + 2); - break; - - case 3: - index += 2; - cursor = buffer + index; - m_title = QByteArray( (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 = QStringLiteral("/"), tmp; - topicAttempt += QString::fromLocal8Bit ((const char*) buffer +index +2); - - tmp = topicAttempt + QStringLiteral(".hhc"); - - if ( ResolveObject( tmp, &ui) ) - m_topicsFile = qPrintable( tmp ); - - tmp = topicAttempt + QStringLiteral(".hhk"); - - if ( ResolveObject( tmp, &ui) ) - m_indexFile = qPrintable( tmp ); - } - break; - - case 16: - index += 2; - cursor = buffer + index; - - m_font = QString::fromLocal8Bit ((const char*) buffer + index + 2); - break; - - default: - index += 2; - cursor = buffer + index; - } - - value = UINT16ARRAY(cursor); - index += value + 2; - } - - return true; -} - - -QByteArray 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 (QByteArray) qPrintable( src.toLower() ); - - QByteArray dest = m_textCodec->fromUnicode (src); - - for ( 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.toLower(); -} - - - -void LCHMFileImpl::getSearchResults( const LCHMSearchProgressResults& tempres, - QStringList * results, - unsigned int limit_results ) -{ - unsigned char combuf [COMMON_BUF_LEN]; - QMap urlsmap; // used to prevent duplicated urls - - for ( 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( QString::fromLocal8Bit((const char*) combuf) ) ); - - if ( --limit_results == 0 ) - break; - } -} - - -QString LCHMFileImpl::normalizeUrl( const QString & path ) const -{ - int pos = path.indexOf (QLatin1Char('#')); - QString fixedpath = pos == -1 ? path : path.left (pos); - - return LCHMUrlFactory::makeURLabsoluteIfNeeded( fixedpath ); -} - - -/* - * FIXME: - * (from htmlhelp.chm) -*/ -bool LCHMFileImpl::parseFileAndFillArray( const QString & file, QVector< 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.indexOf (QLatin1Char('<'), 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] == QLatin1Char('"') || src[i] == QLatin1Char('\'')) ) - { - // find where quote ends, either by another quote, or by '>' symbol (some people don't know HTML) - int nextpos = src.indexOf (src[i], i+1); - if ( nextpos == -1 && (nextpos = src.indexOf (QLatin1Char('>'), i+1)) == -1 ) - { - qWarning ("LCHMFileImpl::ParseHhcAndFillTree: corrupted TOC: %s", qPrintable( src.mid(i) )); - return false; - } - - i = nextpos; - } - else if ( src[i] == QLatin1Char('>') ) - break; - else if ( !src[i].isLetterOrNumber() && src[i] != QLatin1Char('/') && !word_end ) - word_end = i; - } - - QString tagword, tag = src.mid (pos, i - pos); - - if ( word_end ) - tagword = src.mid (pos, word_end - pos).toLower(); - else - tagword = tag.toLower(); - - //qDebug ("tag: '%s', tagword: '%s'\n", qPrintable( tag ), qPrintable( tagword ) ); - - // - a topic entry - if ( tagword == QLatin1String("object") && tag.indexOf (QStringLiteral("text/sitemap"), 0, Qt::CaseInsensitive ) != -1 ) - in_object = true; - else if ( tagword == QLatin1String("/object") && in_object ) - { - // a topic entry closed. Add a tree item - if ( !entry.name.isEmpty() ) - { - 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); - } - - // Trim the entry name - entry.name = entry.name.trimmed(); - - int real_indent = indent - root_indent_offset; - - entry.indent = real_indent; - data->push_back( entry ); - } - else - { - if ( !entry.urls.isEmpty() ) - qDebug ("LCHMFileImpl::ParseAndFillTopicsTree: tag with url \"%s\" is parsed, but name is empty.", qPrintable( entry.urls[0] )); - else - qDebug ("LCHMFileImpl::ParseAndFillTopicsTree: 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 == QLatin1String("param") && in_object ) - { - // - int offset; // strlen("param ") - QString name_pattern = QStringLiteral("name="), value_pattern = QStringLiteral("value="); - QString pname, pvalue; - - if ( (offset = tag.indexOf (name_pattern, 0, Qt::CaseInsensitive )) == -1 ) - qFatal ("LCHMFileImpl::ParseAndFillTopicsTree: bad tag '%s': no name=\n", qPrintable( tag )); - - // offset+5 skips 'name=' - offset = findStringInQuotes (tag, offset + name_pattern.length(), pname, true, false); - pname = pname.toLower(); - - if ( (offset = tag.indexOf(value_pattern, offset, Qt::CaseInsensitive )) == -1 ) - qFatal ("LCHMFileImpl::ParseAndFillTopicsTree: bad tag '%s': no value=\n", qPrintable( tag )); - - // offset+6 skips 'value=' - findStringInQuotes (tag, offset + value_pattern.length(), pvalue, false, true); - - //qDebug (": name '%s', value '%s'", qPrintable( pname ), qPrintable( pvalue )); - - if ( pname == QLatin1String("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 == QLatin1String("local") ) - { - // Check for URL duplication - QString url = LCHMUrlFactory::makeURLabsoluteIfNeeded( pvalue ); - - if ( !entry.urls.contains( url ) ) - entry.urls.push_back( url ); - } - else if ( pname == QLatin1String("see also") && asIndex && entry.name != pvalue ) - entry.urls.push_back (QLatin1Char(':') + pvalue); - else if ( pname == QLatin1String("imagenumber") ) - { - bool bok; - int imgnum = pvalue.toInt (&bok); - - if ( bok && imgnum >= 0 && imgnum < LCHMBookIcons::MAX_BUILTIN_ICONS ) - entry.imageid = imgnum; - } - } - else if ( tagword == QLatin1String("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
      , which was seen in some buggy chm files, - // and brokes rootentry[indent-1] check - } - else if ( tagword == QLatin1String("/ul") ) // decrease indent level - { - if ( --indent < root_indent_offset ) - indent = root_indent_offset; - - DEBUGPARSER(("
    : 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::fromLocal8Bit( buf.constData() ) : encodeWithCurrentCodec( buf.constData() ); - 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.value(); -} - - -extern "C" int chm_enumerator_callback( struct chmFile*, struct chmUnitInfo *ui, void *context ) -{ - ((QStringList*) context)->push_back(QString::fromLocal8Bit( 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 ) - { - qWarning ("Could not detect text encoding by LCID"); - return false; - } - - 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 - QVector 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 ) - { - uint32_t off_title = get_int32_le( (uint32_t *)(topics.data() + i + 4) ); - uint32_t off_url = get_int32_le( (uint32_t *)(topics.data() + i + 8) ); - off_url = get_int32_le( (uint32_t *)( urltbl.data() + off_url + 8) ) + 8; - - QString url = LCHMUrlFactory::makeURLabsoluteIfNeeded( QString::fromLocal8Bit ( (const char*) urlstr.data() + off_url ) ); - - if ( off_title < (uint32_t)strings.size() ) - m_url2topics[url] = encodeWithCurrentCodec ( (const char*) strings.data() + off_title ); - else - m_url2topics[url] = QStringLiteral("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/generators/chm/lib/libchmfileimpl.h b/generators/chm/lib/libchmfileimpl.h deleted file mode 100644 index f8d7cc112..000000000 --- a/generators/chm/lib/libchmfileimpl.h +++ /dev/null @@ -1,300 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * - * Portions Copyright (C) 2003 Razvan Cojocaru * - * 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 LCHMSEARCHPROGRESSRESULT_H -#define LCHMSEARCHPROGRESSRESULT_H -#include -#include - -#include "chm_lib.h" - -#include "libchmfile.h" -#include "libchmtocimage.h" - -#include - -//! Keeps the intermediate search result -class LCHMSearchProgressResult -{ - public: - inline LCHMSearchProgressResult() {} - inline LCHMSearchProgressResult( uint32_t t, uint32_t u ) : titleoff(t),urloff(u) {} - - QVector offsets; - uint32_t titleoff; - uint32_t urloff; -}; - -//! An array to keeps the intermediate search results -typedef QVector 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, QVector< 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 QByteArray& str) const - { - return (m_textCodec ? m_textCodec->toUnicode( str ) : QString::fromLocal8Bit(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::fromLocal8Bit(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( qPrintable(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::fromLocal8Bit(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. - uint32_t GetLeafNodeOffset(const QString& text, - uint32_t initalOffset, - uint32_t buffSize, - uint16_t treeDepth ); - - //! Helper. Processes the word location code entries while searching. - bool ProcessWLC(uint64_t wlc_count, - uint64_t wlc_size, - uint32_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 - QByteArray convertSearchWord ( const QString &src ); - - /*! - * Helper procedure in TOC parsing, decodes the string between the quotes (first or last) with decoding HTML - * entities like í - */ - 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 Looks up for encoding by QtCodec - * \param qtcodec Qt text codec name to look up - * \return A pointer to encoding structure. - * - * \ingroup encoding - */ - static const LCHMTextEncoding * lookupByQtCodec( const QString& codec ); - - /*! - * \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 - QByteArray m_home; - - //! Context tree filename. Got from CHM file - QByteArray m_topicsFile; - - //! Index filename. Got from CHM file - QByteArray m_indexFile; - - //! Chm Title. Got from CHM file - QByteArray 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 ´ based on current encoding - QMap 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; -}; -#endif diff --git a/generators/chm/lib/libchmtextencoding.cpp b/generators/chm/lib/libchmtextencoding.cpp deleted file mode 100644 index 0ed3f0710..000000000 --- a/generators/chm/lib/libchmtextencoding.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/*************************************************************************** - * 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" - -// Do not try to embed those in the text_encoding_table, it does not work - at least with gcc. -static short lcid_arabic[] = -{ - 0x1401, 0x3C01, 0x0C01, 0x0801, 0x2C01, 0x3401, 0x3001, 0x1001, - 0x1801, 0x2001, 0x4001, 0x0401, 0x2801, 0x1C01, 0x3801, 0x2401, - 0x0429, 0x0420, - 0, -}; - -static short lcid_baltic[] = -{ - 0x0425, 0x0426, 0x0427, 0 -}; - -static short lcid_centralEuropean[] = -{ - 0x041C, 0x041A, 0x0405, 0x040E, 0x0415, 0x0418, 0x081A, 0x041B, 0x0424, 0 -}; - -static short lcid_ChineseSimplifiedGB18030[] = -{ - 0x0404, 0 -}; - - -static short lcid_ChineseSimplifiedGBK[] = -{ - 0x0804, 0 -}; - - -static short lcid_ChineseSimplifiedGB2313[] = -{ - 0x1004, 0 -}; - -static short lcid_ChineseTraditionalBig5[] = -{ - 0x0C04, 0x1404, 0x0404, 0 -}; - -static short lcid_ChineseTraditionalBigHKSCS[] = -{ - 0x0404, 0 -}; - -static short lcid_CyrillicCP1251[] = -{ - 0x082C, 0x0423, 0x0402, 0x042F, 0x0419, 0x0C1A, 0x0444, 0x0422, 0x0843, 0 -}; - -static short lcid_CyrillicKOI8R[] = -{ - 0x7001, // artifical LCID - 0 -}; - -static short lcid_CyrillicBrokenCPKOI[] = -{ - 0x7002, // artifical LCID - 0 -}; - -static short lcid_CyrillicBrokenKOICP[] = -{ - 0x7003, // artifical LCID - 0 -}; - - -static short lcid_Greek[] = -{ - 0x0408, 0 -}; - -static short lcid_Hebrew[] = -{ - 0x040D, 0 -}; - -static short lcid_Japanese_eucJP[] = -{ - 0x0411, 0 -}; - - -static short lcid_Japanese_JIS7[] = -{ - 0x0411, 0 -}; - -static short lcid_Japanese_ShiftJIS[] = -{ - 0x0411, 0 -}; - -static short lcid_Korean_eucKR[] = -{ - 0x0412, 0 -}; - -static short lcid_TamilTSCII[] = -{ - 0x0449, 0 -}; - -static short lcid_ThaiTIS[] = -{ - 0x041E, 0 -}; - -static short lcid_UkrainianKOI[] = -{ - 0x7006, 0 -}; - -static short lcid_Turkish[] = -{ - 0x042C, 0x041F, 0x0443, 0 -}; - -static short lcid_Vietnamese[] = -{ - 0x042A, 0 -}; - -static short lcid_UnicodeUTF8[] = -{ - 0x7004, // artifical LCID - 0 -}; - -static short lcid_UnicodeUTF16[] = -{ - 0x7005, // artifical LCID - 0 -}; - -static short lcid_Western[] = -{ - 0x0436, 0x042D, 0x0403, 0x0406, 0x0813, 0x0413, 0x0C09, 0x2809, - 0x1009, 0x2409, 0x1809, 0x2009, 0x1409, 0x3409, 0x1C09, 0x2C09, - 0x0809, 0x0409, 0x0438, 0x040B, 0x080C, 0x0C0C, 0x040C, 0x140C, - 0x100C, 0x0C07, 0x0407, 0x1407, 0x1007, 0x0807, 0x040F, 0x0421, - 0x0410, 0x0810, 0x083E, 0x043E, 0x0414, 0x0814, 0x0416, 0x0816, - 0x0432, 0x2C0A, 0x400A, 0x340A, 0x240A, 0x140A, 0x1C0A, 0x300A, - 0x440A, 0x100A, 0x480A, 0x080A, 0x4C0A, 0x180A, 0x3C0A, 0x280A, - 0x500A, 0x0C0A, 0x380A, 0x200A, 0x0441, 0x081D, 0x041D, 0x0434, - 0x0435, 0x042B, 0x042C, 0x0439, 0x043A, 0x044E, 0x044F, 0x081A, - 0x0443, 0x0009, - 0 -}; - - -static const LCHMTextEncoding text_encoding_table [] = -{ - { - "Arabic", - "CP1256", - lcid_arabic - }, - - { - "Baltic", - "CP1257", - lcid_baltic - }, - - { - "Central European", - "CP1250", - lcid_centralEuropean - }, - - { - "Chinese Simplified", - "GB18030", - lcid_ChineseSimplifiedGB18030 - }, - - { - "Chinese Simplified", - "GBK", - lcid_ChineseSimplifiedGBK - }, - - { - "Chinese Simplified", - "GB2313", - lcid_ChineseSimplifiedGB2313 - }, - - { - "Chinese Traditional", - "Big5", - lcid_ChineseTraditionalBig5 - }, - - { - "Chinese Traditional", - "Big5-HKSCS", - lcid_ChineseTraditionalBigHKSCS - }, - - { - "Cyrillic", - "CP1251", - lcid_CyrillicCP1251 - }, - - { - "Cyrillic", - "KOI8-R", - lcid_CyrillicKOI8R - }, - - { - "Cyrillic Broken", - "CP1251/KOI8-R", - lcid_CyrillicBrokenCPKOI - }, - - { - "Cyrillic Broken", - "KOI8-R/CP1251", - lcid_CyrillicBrokenKOICP - }, - - { - "Greek", - "CP1253", - lcid_Greek - }, - - { - "Hebrew", - "CP1255", - lcid_Hebrew - }, - - { - "Japanese", - "eucJP", - lcid_Japanese_eucJP - }, - - { - "Japanese", - "JIS7", - lcid_Japanese_JIS7 - }, - - { - "Japanese", - "Shift-JIS", - lcid_Japanese_ShiftJIS - }, - - { - "Korean", - "eucKR", - lcid_Korean_eucKR - }, - - { - "Tamil", - "TSCII", - lcid_TamilTSCII - }, - - { - "Thai", - "TIS-620", - lcid_ThaiTIS - }, - - { - "Ukrainian", - "KOI8-U", - lcid_UkrainianKOI - }, - - { - "Turkish", - "CP1254", - lcid_Turkish - }, - - { - "Vietnamese", - "CP1258", - lcid_Vietnamese - }, - - { - "Unicode", - "UTF-8", - lcid_UnicodeUTF8 - }, - - { - "Unicode", - "UTF-16", - lcid_UnicodeUTF16 - }, - - { - "Western", - "CP1252", - lcid_Western - }, - - { 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->family; t++ ) - { - for ( const short * lcids = t->lcids; *lcids; lcids++ ) - if ( *lcids == lcid ) - return t; - } - - return 0; -} - - -int LCHMFileImpl::getEncodingIndex( const LCHMTextEncoding * enc) -{ - for ( int i = 0; text_encoding_table[i].family; i++ ) - if ( (text_encoding_table + i) == enc ) - return i; - - return -1; -} - -const LCHMTextEncoding * LCHMFileImpl::lookupByQtCodec(const QString & codec) -{ - for ( const LCHMTextEncoding * t = text_encoding_table; t->family; t++ ) - if ( codec == QString::fromLocal8Bit(t->qtcodec) ) - return t; - - return 0; -} diff --git a/generators/chm/lib/libchmtextencoding.h b/generators/chm/lib/libchmtextencoding.h deleted file mode 100644 index 5228b04c1..000000000 --- a/generators/chm/lib/libchmtextencoding.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************** - * 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 -{ - const char * family; //! Cyrillic, Western, Greek... NULL pointer represents the end of table. - const char * qtcodec; //! Qt text codec to use - const short * lcids; //! List of LCIDs to use for this codepage. Ends with LCID 0. -} LCHMTextEncoding; - - -#endif /* LIBCHMTEXTENCODING_H */ diff --git a/generators/chm/lib/libchmtocimage.cpp b/generators/chm/lib/libchmtocimage.cpp deleted file mode 100644 index 2952e8604..000000000 --- a/generators/chm/lib/libchmtocimage.cpp +++ /dev/null @@ -1,2112 +0,0 @@ -/*************************************************************************** - * 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/generators/chm/lib/libchmtocimage.h b/generators/chm/lib/libchmtocimage.h deleted file mode 100644 index c0d98b3ba..000000000 --- a/generators/chm/lib/libchmtocimage.h +++ /dev/null @@ -1,39 +0,0 @@ - -#ifndef LCHMTOCIMAGEKEEPER_H -#define LCHMTOCIMAGEKEEPER_H -//Added by qt3to4: -#include -/*************************************************************************** - * 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 - -//! 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]; -}; -#endif