From: Markus Koschany Date: Sun, 25 Nov 2018 15:04:12 +0000 (+0000) Subject: Import performous_1.1+git20181118.orig.tar.xz X-Git-Tag: archive/raspbian/1.1+git20181118-4+rpi1~4 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=2281b700a26613812e1d73740754dd6219a206d8;p=performous.git Import performous_1.1+git20181118.orig.tar.xz [dgit import orig performous_1.1+git20181118.orig.tar.xz] --- 2281b700a26613812e1d73740754dd6219a206d8 diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..880b7ad --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.semaphore-cache \ No newline at end of file diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..ffb0f4e --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at [our Discord server](https://discord.gg/NS3m3ad) by private messaging one of the admins around. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..18222e8 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,321 @@ +# Contributing + +## Preparations + +Be sure not to have multiple Performous versions installed at the same time. It may seem to work, but the graphics may display incorrectly due to wrong theme files being used. To prevent that, clean up old files: + +```bash +rm -rf /usr/local/bin/performous /usr/local/share/games/performous/ +``` + +## Dependencies + +If you happen to be running one of these, please start by installing the following packages. If not, just skip this section and follow the instructions. We try to keep these lists accurate and up-to-date with the development version. If you find that something is missing or that there are unnecessary package installs, please fix it. + +Gettext (localization), Help2Man (UNIX manual pages), OpenCV (webcam support) and PortMidi (MIDI drum support) are optional and can be left out if no support for these functions is required. + +### Debian and Ubuntu + +```bash +sudo apt-get install git-core cmake build-essential gettext help2man \ + libepoxy-dev libsdl2-dev libcairo2-dev libpango1.0-dev librsvg2-dev \ + libboost-all-dev libavcodec-dev libavformat-dev libswscale-dev libswresample-dev \ + libpng-dev libjpeg-dev libxml++2.6-dev portaudio19-dev \ + libopencv-dev libportmidi-dev libcppnetlib-dev libjsoncpp-dev +``` + +Notice: Dependency problems may prevent installation of portaudio19-dev. At least with Ubuntu 13.04 this can be solved by first installing libjack-jackd2-dev, even though that package is not actually needed for Performous. + +Alternatively, you can do: + +```bash +sudo apt-get build-dep performous +``` + +which installs all the build dependencies for the version in the repositories. It might not be completely accurate for the current git version, but should get you pretty far. + +Note: when building the webserver-branch you need CPP-netlib version `0.11.2` which can be downloaded from here: https://github.com/cpp-netlib/cpp-netlib/archive/cpp-netlib-0.11.2-final.zip and unpack the folder named "boost" into /usr/include. +if done correctly you should have the file: /usr/include/boost/network/protocol/http/server.hpp among some others. + +### Gentoo + +```bash +sudo emerge boost git cmake help2man glew libsdl2 ffmpeg portaudio libxmlpp \ + opencv portmidi +``` + +### Fedora + +(You need [http://rpmfusion.org/Configuration RPM Fusion Free] repository for ffmpeg): + +```bash +yum install git cmake gcc-c++ gettext cairo-devel librsvg2-devel libsigc++20-devel \ + glibmm24-devel libxml++-devel boost-devel SDL2-devel libepoxy-devel ffmpeg-devel \ + portaudio-devel help2man redhat-lsb opencv-devel portmidi-devel libjpeg-turbo-devel \ + pango-devel jsoncpp-devel +``` + +### MacOS + +These instructions will walk you through building Performous for macOS (10.9+) and bundling and packaging it inside a DMG ready to install. By default these instructions build the internal webserver, the extra tools (such as Singstar extractor; note, not all are currently working in macOS, even if they all do build succesfully), and support for webcam (via OpenCV) + +* These instruction have been tested with macOS 10.12.5 and XCode 8.3.3. + +1. Install macports first, clean installation is preferred to avoid conflicts. +2. Update macports and its port list via + +```bash +sudo port selfupdate +``` + +* Most dependencies required to use the provided build script must be installed using MacPorts. A couple of them (marked with asterisks, below) are not available in this manner and will have to be obtained and built separately. +You can use the default + sudo port install +to install the dependencies and it's reported to work. However, official macOS releases are built using the following configuration parameters: + +```bash + sudo /opt/local/bin/port -vsf install -universal configure.compiler="clang" \ + configure.cxx_stdlib="libc++" configure.macosx_deployment_target="10.9" \ + configure.sdkroot="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" \ + configure.cxxflags="-std=c++11 -mmacosx-version-min=10.9 -m64 -arch x86_64 -stdlib=libc++ \ + -Wl,-headerpad_max_install_names" configure.cflags="-m64 -arch x86_64 -mmacosx-version-min=10.9 \ + -Wl,-headerpad_max_install_names" configure.ldflags="-m64 -arch x86_64 -stdlib=libc++ \ + -headerpad_max_install_names -mmacosx-version-min=10.9" +``` + +and also these, in `~/.macports/macports.conf` (largely they're the same things as the commandline parameters, but Macports is sometimes... well, special, in deciding which things can be configured via command-line and which cannot. + +```bash + build_arch x86_64 + cxx_stdlib libc++ + configure.cxx_stdlib libc++ + macosx_deployment_target 10.9 + configure.cxxflags "-mmacosx-version-min=10.9 -m64 -arch x86_64 -stdlib=libc++ -Wl,-headerpad_max_install_names" + configure.cflags "-mmacosx-version-min=10.9 -m64 -arch x86_64 -Wl,-headerpad_max_install_names" + configure.ldflags "-m64 -arch x86_64 -stdlib=libc++ -headerpad_max_install_names -mmacosx-version-min=10.9" + cxxflags "-mmacosx-version-min=10.9 -m64 -arch x86_64 -stdlib=libc++ -Wl,-headerpad_max_install_names" + cflags "-mmacosx-version-min=10.9 -m64 -arch x86_64 -Wl,-headerpad_max_install_names" + ldflags "-m64 -arch x86_64 -stdlib=libc++ -headerpad_max_install_names -mmacosx-version-min=10.9" + configure.sdkroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk + sdkroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk + universal_archs x86_64 noarch + buildmakejobs 0 +``` + +3. Dependencies + +* npm +* boost +* libxmlxx2 +* libsdl2 +* ffmpeg +* cmake +* jsoncpp +* help2man +* libepoxy +* librsvg +* portaudio +* portmidi +* opencv +* dylibbundler (*) +* asio-c++ (*) +* cppnetlib (*) + + * Note: Libraries that are required by other dependencies are absent from this list (since they will be installed automatically) in order to simplify the instructions. + * Note: Dependencies marked with an asterisk are not available or are outdated in Macports and should be obtained elsewhere. + +4. Download dylibbundler, asioc++ and cpp-netlib version 0.11.2 + +* Download dylibbundler from https://github.com/auriamg/macdylibbundler/ and install it according to the README. +* Download asioc++ from http://think-async.com/Asio/Download, extract it, and open a terminal. Navigate to the folder where the asio folder is, and type the following: + +```bash + mkdir asio-build && cd asio-build + ASIO_STANDALONE=1 CXXFLAGS="-std=c++11 -stdlib=libc++" CC="/usr/bin/clang" CXX="/usr/bin/clang++" ../asio-1.10.6/configure --prefix=/opt/local --with-boost=no + make check && sudo make install +``` + +* Note: Make sure the path to configure is correct, here I am using the default folder to which asioc++ is extracted. + +* Download cpp-netlib 0.11.2 from https://github.com/cpp-netlib/cpp-netlib/releases/tag/cpp-netlib-0.11.2-final +* Extract it, and once again open a terminal. Navigate to where the cpp-netlib-0.11.2-final folder is, and type the following: + +```bash + mkdir cppnetlib-build && cd cppnetlib-build + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS="-std=c++11 \ + -stdlib=libc++ -arch x86_64 -Wl,-headerpad_max_install_names" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 \ + -DCMAKE_C_FLAGS="-Wl,-headerpad_max_install_names -arch x86_64" -DCMAKE_INSTALL_PREFIX=/opt/local/ \ + -DCMAKE_EXE_LINKER_FLAGS=-headerpad_max_install_names -DCPP-NETLIB_BUILD_SHARED_LIBS=ON -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_SHARED_LINKER_FLAGS=-headerpad_max_install_names -DCMAKE_MACOSX_RPATH=ON -DCMAKE_OSX_ARCHITECTURES=x86_64 \ + ../cpp-netlib-0.11.2-final + make -j0 test && sudo make install +``` + +* Note: In Sierra, it is possible the mime-roundtrip test fails with a SIGSEGV while using boost 1.59. If this happens you need to install boost 1.60+ (instructions on doing so will require creating a custom port; you can find instructions to do this and the required files in the macports website) + +* Note: Make sure the path to configure is correct, here I am using the default folder to which asioc++ is extracted. + +5. Clone Performous from git as per the other build instructions + +6. Run the provided build script +* Open a terminal and navigate to `performous/osx-tools/`, then type + +```bash + chmod +x ./performous-app-build.sh && ./performous-app-build.sh +``` + + * Note: There might be messages stating you need to install further dependencies for the build process. Follow on-screen instructions here + * Note: Make sure to edit the performous-app-build.sh script and change the MAKE_JOBS variable to a number suitable to your machine, as a rule-of-thumb, you should change it to the lesser of how many CPU cores or Gb of RAM your computer has. + +7. This should create a file '''Performous.dmg''' in that directory. Mount that and drag Performous to Applications to install. + +8. You'll most likely need to visit the audio configuration first in the configure menu. The integrated webserver can also be configured. Also check the wiki for supported paths for songs. + +9. Play and have fun! + + +### MacOS with Homebrew + +Building with Homebrew is easier than with MacPorts. However, creation of a software bundle from a Homebrew-build fails, so you will need to run Performous from console. + +```bash +brew install boost cmake ffmpeg help2man icu4c portaudio portmidi \ + opencv libepoxy librsvg libxml++3 sdl2 +``` + +Then follow the usual Performous build instructions. No special flags are required and you can do make install without sudo. + +### Windows + +Building in Windows is a bit trickier since you cannot get the dependencies as easily as in other systems. You should download the Git version (see [[Developing]]) and look at the scripts in win32 folder. They attempt to automatically set up the build environment (download and compile dependencies). Native builds should work with MSYS2, but have not been tested by anyone recently (that we know of, test reports welcome). The commonly used method is cross-compiling from Linux via MXE. + +### Cross compiling MXE + +The dependencies can be cross-compiled for Windows from Debian/Ubuntu Linux (possibly others, too), using the MinGW32/MinGW54 cross compiler. Best results are currently achieved using the "M cross environment" aka. [http://mxe.cc/ MXE]: + +Get MXE: + +```bash +git clone -b master https://github.com/mxe/mxe.git +``` + +Set up the settings.mk file (adjust JOBS to your number of CPU cores): + +```bash +JOBS := 4 +MXE_TARGETS := i686-w64-mingw32.shared +LOCAL_PKG_LIST := gettext sdl2 boost portaudio ffmpeg portmidi pango \ + gdk-pixbuf librsvg libsigc++ libxml++ libepoxy +.DEFAULT local-pkg-list: +local-pkg-list: $(LOCAL_PKG_LIST) +``` + +Run `make` to build the cross-compiler and packages (you can speed up the process by doing `make -j3`, where 3 is the number of CPU cores you wish to use). + +When building later, replace the plain cmake command with these commands: + +```bash +MXE_PREFIX=/where/mxe/is/installed +MXE_TARGET=i686-w64-mingw32.shared +cmake .. -DPKG_CONFIG_EXECUTABLE=$MXE_PREFIX/usr/bin/$MXE_TARGET-pkg-config \ + -DCMAKE_TOOLCHAIN_FILE=$MXE_PREFIX/usr/$MXE_TARGET/share/cmake/mxe-conf.cmake \ + -DBoost_THREAD_LIBRARY_RELEASE=$MXE_PREFIX/usr/$MXE_TARGET/bin/libboost_thread_win32-mt.dll \ + -DENABLE_WEBCAM=OFF +``` + +## Building + +### Obtain latest source code + +#### Recommended way: Git + +Use [[Git Help|Git]] to get the latest development version from our public repository: + +```bash +git clone git://github.com/performous/performous.git +``` + +You'll need a Git client. The command line program is fine, but if you prefer graphical interface, you can install e.g. git-gui on Linux and [TortoiseGit](https://tortoisegit.org) on Windows. + + +#### Alternative way: Tarballs + +If you don't want to bother with git, you can just [download the bleeding edge code directly](https://github.com/performous/performous/archive/master.tar.gz). + +Tarballs of stable releases are also available for distributors but they are not recommended if you are building it for yourself. You can download the released sources from [here](https://github.com/performous/performous/releases). + + +### Build and install + +```bash +cd performous # Where you downloaded the sources +mkdir build # Make the build in a separate folder that you can easily clean up +cd build +cmake .. # Prepare build and check that all dependencies are in place +make -j8 # Compile everything (replace 8 with number of CPU cores) +sudo make install # Install +performous # Start the game +``` + +If you get errors (especially if they are from the cmake command), you are probably missing some libraries required by the game. Install the needed libraries (development versions, e.g. libboost-dev) and retry the failing step until all dependencies are sorted out. + +Optionally, if you want to change installation path or do other compile-time configuration, you can use ccmake command line tool in build directory, after running cmake: + +```bash +ccmake . +``` + +There are also graphical interfaces for CMake, e.g. `cmake-qt-gui` on Ubuntu. Running cmake or ccmake is not required with GUI tools. + +Before installing do `make install`, modify `CMAKE_INSTALL_PREFIX` if you don't want it installed in `/usr/local/`. + + +## How to Write a Good Issue + +Please keep in mind that the GitHub issue tracker is not intended as a general support forum, but for reporting bugs and feature requests. +For end-user related support questions, please refer to one of the following: + +- Discord Channel General: https://discord.gg/NS3m3ad + +### Title + +The title must be short and descriptive. (~60 characters) + +### Description + +- Respect the issue template as much as possible. [template](.github/ISSUE_TEMPLATE.md) +- Explain the conditions which led you to write this issue: the context. +- The context should lead to something, an idea or a problem that you’re facing. +- Remain clear and concise. +- Format your messages to help the reader focus on what matters and understand the structure of your message, use [Markdown syntax](https://help.github.com/articles/github-flavored-markdown) + + +## How to Write a Good Pull Request + +### Title + +The title must be short and descriptive. (~60 characters) + +### Description + +- Respect the pull request template as much as possible. [template](.github/PULL_REQUEST_TEMPLATE.md) +- Explain the conditions which led you to write this PR: the context. +- The context should lead to something, an idea or a problem that you’re facing. +- Remain clear and concise. +- Format your messages to help the reader focus on what matters and understand the structure of your message, use [Markdown syntax](https://help.github.com/articles/github-flavored-markdown) + +### Content + +- Make it small. +- Do only one thing. +- Write useful descriptions and titles. +- Avoid re-formatting. +- Make sure the code builds. +- Make sure all tests pass. +- Add tests. +- Address review comments in terms of additional commits. +- Do not amend/squash existing ones unless the PR is trivial. +- If a PR involves changes to third-party dependencies, the commits pertaining to the vendor folder and the manifest/lock file(s) should be committed separated. + + +Read [10 tips for better pull requests](http://blog.ploeh.dk/2015/01/15/10-tips-for-better-pull-requests/). diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..62035d0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,60 @@ + + + +### Do you want to request a *feature* or report a *bug*? + + + +### What did you do? + + + +### What did you expect to see? + + + +### What did you see instead? + + + +### Output of `performous --version`: (_What version of Performous are you using?_) + + +``` +(paste your output here) +``` + +### What is your environment & configuration (arguments, platform, ...)? + + + + +### If applicable, please paste the log output at DEBUG level (`--logLevel=DEBUG` switch) + +``` +(paste your output here) +``` diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md new file mode 100644 index 0000000..0afd900 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -0,0 +1,62 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + + + + +### Do you want to request a *feature* or report a *bug*? + +Bug + +### What did you do? + + + +### What did you expect to see? + + + +### What did you see instead? + + + +### Output of `performous --version`: (_What version of Performous are you using?_) + +``` +(paste your output here) +``` + +### What is your environment & configuration (arguments, platform, ...)? + + + + +### If applicable, please paste the log output in DEBUG level (`--logLevel=DEBUG` switch) + +``` +(paste your output here) +``` diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md new file mode 100644 index 0000000..cadbd74 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -0,0 +1,35 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + + + + +### Do you want to request a *feature* or report a *bug*? + +Feature + +### What did you expect to see? + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..1e4b660 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,36 @@ + + +### What does this PR do? + + + +### Closes Issue(s) + + + +### Motivation + + + + +### More + +- [ ] Added/updated documentation + +### Additional Notes + + diff --git a/.github/PULL_REQUEST_TEMPLATE/mergeback.md b/.github/PULL_REQUEST_TEMPLATE/mergeback.md new file mode 100644 index 0000000..dfc8560 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/mergeback.md @@ -0,0 +1,7 @@ +### What does this PR do? + +Merge v{{.Version}} into master + +### Motivation + +Be sync. diff --git a/.github/PULL_REQUEST_TEMPLATE/release.md b/.github/PULL_REQUEST_TEMPLATE/release.md new file mode 100644 index 0000000..226a85a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/release.md @@ -0,0 +1,7 @@ +### What does this PR do? + +Prepare release v{{.Version}}. + +### Motivation + +Create a new release. diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b8a057c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,90 @@ +cmake_minimum_required(VERSION 2.8) +project(Performous CXX C) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") + +include(GetGitRevisionDescription) +git_describe(PROJECT_VERSION --tags) +if(NOT PROJECT_VERSION) + set(PROJECT_VERSION "1.1+") +endif() + +message("Building ${PROJECT_NAME} ${PROJECT_VERSION}") + +# Avoid source tree pollution +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + message(FATAL_ERROR "In-source builds are not permitted. Make a separate folder for building:\nmkdir build; cd build; cmake ..\nBefore that, remove the files already created:\nrm -rf CMakeCache.txt CMakeFiles") +endif(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + +# Add a sensible build type default and warning because empty means no optimization and no debug info. +if(NOT CMAKE_BUILD_TYPE) + message("WARNING: CMAKE_BUILD_TYPE is not defined!\n Defaulting to CMAKE_BUILD_TYPE=RelWithDebInfo. Use ccmake to set a proper value.") + SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) +endif(NOT CMAKE_BUILD_TYPE) + +if(CMAKE_BUILD_TYPE STREQUAL "Release") + add_definitions("-DNDEBUG") +endif() + +# Enable C++14 support and other compiler flags... +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + message("Detected GCC version ${GCC_VERSION}") + if (GCC_VERSION VERSION_GREATER 7 OR GCC_VERSION VERSION_EQUAL 7) + set(CMAKE_CXX_FLAGS "-std=c++14 -Wall -Wextra -fcx-limited-range ${CMAKE_CXX_FLAGS}") + elseif (GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8) + set(CMAKE_CXX_FLAGS "-std=c++1y -Wall -Wextra -Wno-attributes -Wno-deprecated-declarations -fcx-limited-range ${CMAKE_CXX_FLAGS}") + message(WARNING "Your GCC is rather old, disabling some useful compiler warnings (GCC 7+ or Clang 5+ recommended for proper C++17 support).") + else() + message(FATAL_ERROR "Your C++ compiler is too old, please upgrade.") + endif() +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # Note: AUTO_PTR is for Boost which won't compile with C++17 otherwise (fixed in Boost git but not in 1.66) + set(CMAKE_CXX_FLAGS "-std=c++1z -Wall -Wextra -D_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR ${CMAKE_CXX_FLAGS}") +endif() + +if(WIN32) + set(CMAKE_CXX_FLAGS "-DWIN32_LEAN_AND_MEAN ${CMAKE_CXX_FLAGS}") + set(SHARE_INSTALL_DEFAULT ".") + SET(LOCALE_DIR_DEFAULT "locale") +else() + set(SHARE_INSTALL_DEFAULT "share/games/performous") + SET(LOCALE_DIR_DEFAULT "share/locale") +endif() + +set(SHARE_INSTALL "${SHARE_INSTALL_DEFAULT}" CACHE STRING "Data file install path. Must be a relative path (from CMAKE_INSTALL_PREFIX), with no trailing slash.") +mark_as_advanced(SHARE_INSTALL) + +set(LOCALE_DIR "${LOCALE_DIR_DEFAULT}" CACHE STRING "Locale file install path. Must be a relative path (from CMAKE_INSTALL_PREFIX), with no trailing slash.") +mark_as_advanced(LOCALE_DIR) + +find_package(Gettext) +if(Gettext_FOUND) + message(STATUS "Localization enabled: Building and installing .mo files") + add_subdirectory(lang) +else() + message(STATUS "Localization disabled: Gettext tools (msgfmt) missing") +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ced) + +add_subdirectory(data) +add_subdirectory(game) +add_subdirectory(ced) +add_subdirectory(docs) + +if(WIN32) + install(FILES win32/ConfigureSongDirectory.bat DESTINATION .) +endif() + +#CPACK variables +include(CPack) +SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Niek Nooijens") +SET(CPACK_PACKAGE_CONTACT "nieknooijens@gmail.com") +SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libavcodec54, libavformat54, libswresample2, libsdl2-2.0-0, libportaudiocpp0, libboost-all-dev, libswscale2, libxml++2.6-2, libopencv-dev, librsvg2-2, libpango-1.0-0, libcairo2, libjpeg8, libpng12-0, libportmidi0 ") +SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION_SUMMARY "A free music rhythm game similar to SingStar, Guitar Hero and DDR") +SET(CPACK_DEBIAN_PACKAGE_VERSION ${PROJECT_VERSION}) +SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") +SET(CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${CMAKE_BINARY_DIR};${PROJECT_NAME};ALL;/") diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..979158a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +FROM ubuntu:16.04 + +# Install dependencies Bleh + +RUN mkdir /src/ +COPY . /src/ +WORKDIR /src/ + +RUN apt-get update && apt-get -y install software-properties-common && apt-add-repository -y ppa:litenstein/libicu60-xenial && apt-add-repository -y ppa:litenstein/libepoxy143-xenial && apt-add-repository -y ppa:litenstein/glm0-9-8-4-xenial && apt-get update && apt-get -y install cmake gettext help2man clang-3.8 libepoxy-dev libsdl2-dev libcairo2-dev libpango1.0-dev librsvg2-dev libboost-all-dev libavcodec-dev libavformat-dev libswscale-dev libswresample-dev libpng-dev libjpeg-dev libxml++2.6-dev portaudio19-dev libopencv-dev libportmidi-dev libqrencode-dev libicu-dev libglm-dev libssl-dev openssl wget && \ +\ +wget -O cpprestsdk.tar.gz https://github.com/Microsoft/cpprestsdk/archive/v2.10.2.tar.gz && \ +tar -xvzf cpprestsdk.tar.gz && cd cpprestsdk-2.10.2/Release && \ +mkdir build && cd build && \ +cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCPPREST_EXCLUDE_WEBSOCKETS=ON -DBUILD_TESTS=OFF -DBUILD_SAMPLES=OFF && make -j3 && \ +make install && \ +cd ../../../ && \ +\ +mkdir build.clang38 && \ +cd build.clang38 && \ +CC=clang-3.8 CXX=clang++-3.8 cmake .. && \ +make VERBOSE=1 && \ +\ +cd .. && \ +\ +mkdir build.gcc-5 && \ +cd build.gcc-5 && \ +\ +CC=gcc-5 CXX=g++-5 cmake .. && \ +make VERBOSE=1 + +CMD ["performous"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..8ebdde0 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +![alt text](http://performous.org/imgs/title.png "Performous") +Performous +========== + +Build status +[![Build Status](https://semaphoreci.com/api/v1/performous/performous/branches/master/badge.svg)](https://semaphoreci.com/performous/performous) + +An open-source karaoke, band and dancing game where one or more players perform a song and the game scores their performances. Supports songs in UltraStar, Frets on Fire and StepMania formats. Microphones and instruments from SingStar, Guitar Hero and Rock Band as well as some dance pads are autodetected. + +Website at http://performous.org/ << If you can't reach it try the mirror https://performous.asgardsings.nl +Wiki at https://github.com/performous/performous/wiki +Discord at https://discord.gg/NS3m3ad + +For compiling instructions, see docs/Compiling.txt or visit the wiki page: https://github.com/performous/performous/wiki/Building-and-installing-from-source diff --git a/boost_predef/detail/os_detected.h b/boost_predef/detail/os_detected.h new file mode 100644 index 0000000..08e10f9 --- /dev/null +++ b/boost_predef/detail/os_detected.h @@ -0,0 +1,10 @@ +/* +Copyright Rene Rivera 2013 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_DETAIL_OS_DETECTED +#define BOOST_PREDEF_DETAIL_OS_DETECTED 1 +#endif diff --git a/boost_predef/detail/test.h b/boost_predef/detail/test.h new file mode 100644 index 0000000..546a9e4 --- /dev/null +++ b/boost_predef/detail/test.h @@ -0,0 +1,17 @@ +/* +Copyright Rene Rivera 2011-2012 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_DETAIL_TEST_H +#define BOOST_PREDEF_DETAIL_TEST_H + +#if !defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) + +#define BOOST_PREDEF_DECLARE_TEST(x,s) + +#endif + +#endif diff --git a/boost_predef/make.h b/boost_predef/make.h new file mode 100644 index 0000000..3ce1a37 --- /dev/null +++ b/boost_predef/make.h @@ -0,0 +1,89 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ +#include "detail/test.h" + +#ifndef BOOST_PREDEF_MAKE_H +#define BOOST_PREDEF_MAKE_H + +/* +Shorthands for the common version number formats used by vendors... +*/ + +/*` +[heading `BOOST_PREDEF_MAKE_..` macros] + +These set of macros decompose common vendor version number +macros which are composed version, revision, and patch digits. +The naming convention indicates: + +* The base of the specified version number. "`BOOST_PREDEF_MAKE_0X`" for + hexadecimal digits, and "`BOOST_PREDEF_MAKE_10`" for decimal digits. +* The format of the vendor version number. Where "`V`" indicates the version digits, + "`R`" indicates the revision digits, "`P`" indicates the patch digits, and "`0`" + indicates an ignored digit. + +Macros are: +*/ +/*` `BOOST_PREDEF_MAKE_0X_VRP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRP(V) BOOST_VERSION_NUMBER((V&0xF00)>>8,(V&0xF0)>>4,(V&0xF)) +/*` `BOOST_PREDEF_MAKE_0X_VVRP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRP(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xF0)>>4,(V&0xF)) +/*` `BOOST_PREDEF_MAKE_0X_VRPP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRPP(V) BOOST_VERSION_NUMBER((V&0xF000)>>12,(V&0xF00)>>8,(V&0xFF)) +/*` `BOOST_PREDEF_MAKE_0X_VVRR(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRR(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xFF),0) +/*` `BOOST_PREDEF_MAKE_0X_VRRPPPP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRRPPPP(V) BOOST_VERSION_NUMBER((V&0xF000000)>>24,(V&0xFF0000)>>16,(V&0xFFFF)) +/*` `BOOST_PREDEF_MAKE_0X_VVRRP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRRP(V) BOOST_VERSION_NUMBER((V&0xFF000)>>12,(V&0xFF0)>>4,(V&0xF)) +/*` `BOOST_PREDEF_MAKE_0X_VRRPP000(V)` */ +#define BOOST_PREDEF_MAKE_0X_VRRPP000(V) BOOST_VERSION_NUMBER((V&0xF0000000)>>28,(V&0xFF00000)>>20,(V&0xFF000)>>12) +/*` `BOOST_PREDEF_MAKE_0X_VVRRPP(V)` */ +#define BOOST_PREDEF_MAKE_0X_VVRRPP(V) BOOST_VERSION_NUMBER((V&0xFF0000)>>16,(V&0xFF00)>>8,(V&0xFF)) +/*` `BOOST_PREDEF_MAKE_10_VPPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VPPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,0,(V)%1000) +/*` `BOOST_PREDEF_MAKE_10_VRP(V)` */ +#define BOOST_PREDEF_MAKE_10_VRP(V) BOOST_VERSION_NUMBER(((V)/100)%10,((V)/10)%10,(V)%10) +/*` `BOOST_PREDEF_MAKE_10_VRP000(V)` */ +#define BOOST_PREDEF_MAKE_10_VRP000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/10000)%10,((V)/1000)%10) +/*` `BOOST_PREDEF_MAKE_10_VRPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VRPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,((V)/100)%10,(V)%100) +/*` `BOOST_PREDEF_MAKE_10_VRR(V)` */ +#define BOOST_PREDEF_MAKE_10_VRR(V) BOOST_VERSION_NUMBER(((V)/100)%10,(V)%100,0) +/*` `BOOST_PREDEF_MAKE_10_VRRPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%10,((V)/100)%100,(V)%100) +/*` `BOOST_PREDEF_MAKE_10_VRR000(V)` */ +#define BOOST_PREDEF_MAKE_10_VRR000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/1000)%100,0) +/*` `BOOST_PREDEF_MAKE_10_VV00(V)` */ +#define BOOST_PREDEF_MAKE_10_VV00(V) BOOST_VERSION_NUMBER(((V)/100)%100,0,0) +/*` `BOOST_PREDEF_MAKE_10_VVRR(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR(V) BOOST_VERSION_NUMBER(((V)/100)%100,(V)%100,0) +/*` `BOOST_PREDEF_MAKE_10_VVRRPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%100,((V)/100)%100,(V)%100) +/*` `BOOST_PREDEF_MAKE_10_VVRR0PP00(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR0PP00(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,((V)/100)%100) +/*` `BOOST_PREDEF_MAKE_10_VVRR0PPPP(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR0PPPP(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,(V)%10000) +/*` `BOOST_PREDEF_MAKE_10_VVRR00PP00(V)` */ +#define BOOST_PREDEF_MAKE_10_VVRR00PP00(V) BOOST_VERSION_NUMBER(((V)/100000000)%100,((V)/1000000)%100,((V)/100)%100) +/*` +[heading `BOOST_PREDEF_MAKE_*..` date macros] + +Date decomposition macros return a date in the relative to the 1970 +Epoch date. If the month is not available, January 1st is used as the month and day. +If the day is not available, but the month is, the 1st of the month is used as the day. +*/ +/*` `BOOST_PREDEF_MAKE_DATE(Y,M,D)` */ +#define BOOST_PREDEF_MAKE_DATE(Y,M,D) BOOST_VERSION_NUMBER((Y)%10000-1970,(M)%100,(D)%100) +/*` `BOOST_PREDEF_MAKE_YYYYMMDD(V)` */ +#define BOOST_PREDEF_MAKE_YYYYMMDD(V) BOOST_PREDEF_MAKE_DATE(((V)/10000)%10000,((V)/100)%100,(V)%100) +/*` `BOOST_PREDEF_MAKE_YYYY(V)` */ +#define BOOST_PREDEF_MAKE_YYYY(V) BOOST_PREDEF_MAKE_DATE(V,1,1) +/*` `BOOST_PREDEF_MAKE_YYYYMM(V)` */ +#define BOOST_PREDEF_MAKE_YYYYMM(V) BOOST_PREDEF_MAKE_DATE((V)/100,(V)%100,1) + +#endif diff --git a/boost_predef/os.h b/boost_predef/os.h new file mode 100644 index 0000000..4e66caa --- /dev/null +++ b/boost_predef/os.h @@ -0,0 +1,33 @@ +/* +Copyright Rene Rivera 2008-2015 +Copyright Franz Detro 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#if !defined(BOOST_PREDEF_OS_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS) +#ifndef BOOST_PREDEF_OS_H +#define BOOST_PREDEF_OS_H +#endif + +#include "os/aix.h" +#include "os/amigaos.h" +#include "os/android.h" +#include "os/beos.h" +#include "os/bsd.h" +#include "os/cygwin.h" +#include "os/haiku.h" +#include "os/hpux.h" +#include "os/irix.h" +#include "os/ios.h" +#include "os/linux.h" +#include "os/macos.h" +#include "os/os400.h" +#include "os/qnxnto.h" +#include "os/solaris.h" +#include "os/unix.h" +#include "os/vms.h" +#include "os/windows.h" + +#endif diff --git a/boost_predef/os/aix.h b/boost_predef/os/aix.h new file mode 100644 index 0000000..f8540b9 --- /dev/null +++ b/boost_predef/os/aix.h @@ -0,0 +1,66 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_AIX_H +#define BOOST_PREDEF_OS_AIX_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_AIX`] + +[@http://en.wikipedia.org/wiki/AIX_operating_system IBM AIX] operating system. +Version number available as major, minor, and patch. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_AIX`] [__predef_detection__]] + [[`__TOS_AIX__`] [__predef_detection__]] + + [[`_AIX43`] [4.3.0]] + [[`_AIX41`] [4.1.0]] + [[`_AIX32`] [3.2.0]] + [[`_AIX3`] [3.0.0]] + ] + */ + +#define BOOST_OS_AIX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(_AIX) || defined(__TOS_AIX__) \ + ) +# undef BOOST_OS_AIX +# if !defined(BOOST_OS_AIX) && defined(_AIX43) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_AIX) && defined(_AIX41) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(4,1,0) +# endif +# if !defined(BOOST_OS_AIX) && defined(_AIX32) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_OS_AIX) && defined(_AIX3) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_OS_AIX) +# define BOOST_OS_AIX BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_AIX +# define BOOST_OS_AIX_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_AIX_NAME "IBM AIX" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AIX,BOOST_OS_AIX_NAME) diff --git a/boost_predef/os/amigaos.h b/boost_predef/os/amigaos.h new file mode 100644 index 0000000..05ee99d --- /dev/null +++ b/boost_predef/os/amigaos.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_AMIGAOS_H +#define BOOST_PREDEF_OS_AMIGAOS_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_AMIGAOS`] + +[@http://en.wikipedia.org/wiki/AmigaOS AmigaOS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`AMIGA`] [__predef_detection__]] + [[`__amigaos__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_AMIGAOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(AMIGA) || defined(__amigaos__) \ + ) +# undef BOOST_OS_AMIGAOS +# define BOOST_OS_AMIGAOS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_AMIGAOS +# define BOOST_OS_AMIGAOS_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_AMIGAOS_NAME "AmigaOS" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AMIGAOS,BOOST_OS_AMIGAOS_NAME) diff --git a/boost_predef/os/android.h b/boost_predef/os/android.h new file mode 100644 index 0000000..f97d47e --- /dev/null +++ b/boost_predef/os/android.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_ADROID_H +#define BOOST_PREDEF_OS_ADROID_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_ANDROID`] + +[@http://en.wikipedia.org/wiki/Android_%28operating_system%29 Android] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__ANDROID__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_ANDROID BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__ANDROID__) \ + ) +# undef BOOST_OS_ANDROID +# define BOOST_OS_ANDROID BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_ANDROID +# define BOOST_OS_ANDROID_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_ANDROID_NAME "Android" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_ANDROID,BOOST_OS_ANDROID_NAME) diff --git a/boost_predef/os/beos.h b/boost_predef/os/beos.h new file mode 100644 index 0000000..0f5f64d --- /dev/null +++ b/boost_predef/os/beos.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BEOS_H +#define BOOST_PREDEF_OS_BEOS_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_BEOS`] + +[@http://en.wikipedia.org/wiki/BeOS BeOS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__BEOS__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_BEOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__BEOS__) \ + ) +# undef BOOST_OS_BEOS +# define BOOST_OS_BEOS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_BEOS +# define BOOST_OS_BEOS_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_BEOS_NAME "BeOS" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BEOS,BOOST_OS_BEOS_NAME) diff --git a/boost_predef/os/bsd.h b/boost_predef/os/bsd.h new file mode 100644 index 0000000..36f589e --- /dev/null +++ b/boost_predef/os/bsd.h @@ -0,0 +1,103 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_H +#define BOOST_PREDEF_OS_BSD_H + +/* Special case: OSX will define BSD predefs if the sys/param.h + * header is included. We can guard against that, but only if we + * detect OSX first. Hence we will force include OSX detection + * before doing any BSD detection. + */ +#include "../os/macos.h" + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_BSD`] + +[@http://en.wikipedia.org/wiki/Berkeley_Software_Distribution BSD] operating system. + +BSD has various branch operating systems possible and each detected +individually. This detects the following variations and sets a specific +version number macro to match: + +* `BOOST_OS_BSD_DRAGONFLY` [@http://en.wikipedia.org/wiki/DragonFly_BSD DragonFly BSD] +* `BOOST_OS_BSD_FREE` [@http://en.wikipedia.org/wiki/Freebsd FreeBSD] +* `BOOST_OS_BSD_BSDI` [@http://en.wikipedia.org/wiki/BSD/OS BSDi BSD/OS] +* `BOOST_OS_BSD_NET` [@http://en.wikipedia.org/wiki/Netbsd NetBSD] +* `BOOST_OS_BSD_OPEN` [@http://en.wikipedia.org/wiki/Openbsd OpenBSD] + +[note The general `BOOST_OS_BSD` is set in all cases to indicate some form +of BSD. If the above variants is detected the corresponding macro is also set.] + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`BSD`] [__predef_detection__]] + [[`_SYSTYPE_BSD`] [__predef_detection__]] + + [[`BSD4_2`] [4.2.0]] + [[`BSD4_3`] [4.3.0]] + [[`BSD4_4`] [4.4.0]] + [[`BSD`] [V.R.0]] + ] + */ + +#include "../os/bsd/bsdi.h" +#include "../os/bsd/dragonfly.h" +#include "../os/bsd/free.h" +#include "../os/bsd/open.h" +#include "../os/bsd/net.h" + +#ifndef BOOST_OS_BSD +#define BOOST_OS_BSD BOOST_VERSION_NUMBER_NOT_AVAILABLE +#endif + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(BSD) || \ + defined(_SYSTYPE_BSD) \ + ) +# undef BOOST_OS_BSD +# include +# if !defined(BOOST_OS_BSD) && defined(BSD4_4) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,4,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD4_3) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD4_2) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,2,0) +# endif +# if !defined(BOOST_OS_BSD) && defined(BSD) +# define BOOST_OS_BSD BOOST_PREDEF_MAKE_10_VVRR(BSD) +# endif +# if !defined(BOOST_OS_BSD) +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD +# define BOOST_OS_BSD_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_BSD_NAME "BSD" + +#else + +#include "../os/bsd/bsdi.h" +#include "../os/bsd/dragonfly.h" +#include "../os/bsd/free.h" +#include "../os/bsd/open.h" +#include "../os/bsd/net.h" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD,BOOST_OS_BSD_NAME) diff --git a/boost_predef/os/bsd/bsdi.h b/boost_predef/os/bsd/bsdi.h new file mode 100644 index 0000000..70cf3a4 --- /dev/null +++ b/boost_predef/os/bsd/bsdi.h @@ -0,0 +1,48 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_BSDI_H +#define BOOST_PREDEF_OS_BSD_BSDI_H + +#include "../bsd.h" + +/*` +[heading `BOOST_OS_BSD_BSDI`] + +[@http://en.wikipedia.org/wiki/BSD/OS BSDi BSD/OS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__bsdi__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__bsdi__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_BSDI +# define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_BSD_BSDI +# define BOOST_OS_BSD_BSDI_AVAILABLE +# include "../../detail/os_detected.h" +#endif + +#define BOOST_OS_BSD_BSDI_NAME "BSDi BSD/OS" + +#endif + +#include "../../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_BSDI,BOOST_OS_BSD_BSDI_NAME) diff --git a/boost_predef/os/bsd/dragonfly.h b/boost_predef/os/bsd/dragonfly.h new file mode 100644 index 0000000..d7d8484 --- /dev/null +++ b/boost_predef/os/bsd/dragonfly.h @@ -0,0 +1,50 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_DRAGONFLY_H +#define BOOST_PREDEF_OS_BSD_DRAGONFLY_H + +#include "../bsd.h" + +/*` +[heading `BOOST_OS_BSD_DRAGONFLY`] + +[@http://en.wikipedia.org/wiki/DragonFly_BSD DragonFly BSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__DragonFly__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_BSD_DRAGONFLY BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__DragonFly__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_DRAGONFLY +# if defined(__DragonFly__) +# define BOOST_OS_DRAGONFLY_BSD BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_DRAGONFLY +# define BOOST_OS_BSD_DRAGONFLY_AVAILABLE +# include "../../detail/os_detected.h" +#endif + +#define BOOST_OS_BSD_DRAGONFLY_NAME "DragonFly BSD" + +#endif + +#include "../../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_DRAGONFLY,BOOST_OS_BSD_DRAGONFLY_NAME) diff --git a/boost_predef/os/bsd/free.h b/boost_predef/os/bsd/free.h new file mode 100644 index 0000000..98fda4d --- /dev/null +++ b/boost_predef/os/bsd/free.h @@ -0,0 +1,60 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_FREE_H +#define BOOST_PREDEF_OS_BSD_FREE_H + +#include "../bsd.h" + +/*` +[heading `BOOST_OS_BSD_FREE`] + +[@http://en.wikipedia.org/wiki/Freebsd FreeBSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__FreeBSD__`] [__predef_detection__]] + + [[`__FreeBSD_version`] [V.R.P]] + ] + */ + +#define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__FreeBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_FREE +# if defined(__FreeBSD_version) +# if __FreeBSD_version < 500000 +# define BOOST_OS_BSD_FREE \ + BOOST_PREDEF_MAKE_10_VRP000(__FreeBSD_version) +# else +# define BOOST_OS_BSD_FREE \ + BOOST_PREDEF_MAKE_10_VRR000(__FreeBSD_version) +# endif +# else +# define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_FREE +# define BOOST_OS_BSD_FREE_AVAILABLE +# include "../../detail/os_detected.h" +#endif + +#define BOOST_OS_BSD_FREE_NAME "Free BSD" + +#endif + +#include "../../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_FREE,BOOST_OS_BSD_FREE_NAME) diff --git a/boost_predef/os/bsd/net.h b/boost_predef/os/bsd/net.h new file mode 100644 index 0000000..f41a760 --- /dev/null +++ b/boost_predef/os/bsd/net.h @@ -0,0 +1,84 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_NET_H +#define BOOST_PREDEF_OS_BSD_NET_H + +#include "../bsd.h" + +/*` +[heading `BOOST_OS_BSD_NET`] + +[@http://en.wikipedia.org/wiki/Netbsd NetBSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__NETBSD__`] [__predef_detection__]] + [[`__NetBSD__`] [__predef_detection__]] + + [[`__NETBSD_version`] [V.R.P]] + [[`NetBSD0_8`] [0.8.0]] + [[`NetBSD0_9`] [0.9.0]] + [[`NetBSD1_0`] [1.0.0]] + [[`__NetBSD_Version`] [V.R.P]] + ] + */ + +#define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__NETBSD__) || defined(__NetBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_NET +# if defined(__NETBSD__) +# if defined(__NETBSD_version) +# if __NETBSD_version < 500000 +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VRP000(__NETBSD_version) +# else +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VRR000(__NETBSD_version) +# endif +# else +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE +# endif +# elif defined(__NetBSD__) +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_8) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,8,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_9) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,9,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(NetBSD1_0) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(1,0,0) +# endif +# if !defined(BOOST_OS_BSD_NET) && defined(__NetBSD_Version) +# define BOOST_OS_BSD_NET \ + BOOST_PREDEF_MAKE_10_VVRR00PP00(__NetBSD_Version) +# endif +# if !defined(BOOST_OS_BSD_NET) +# define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE +# endif +# endif +#endif + +#if BOOST_OS_BSD_NET +# define BOOST_OS_BSD_NET_AVAILABLE +# include "../../detail/os_detected.h" +#endif + +#define BOOST_OS_BSD_NET_NAME "DragonFly BSD" + +#endif + +#include "../../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_NET,BOOST_OS_BSD_NET_NAME) diff --git a/boost_predef/os/bsd/open.h b/boost_predef/os/bsd/open.h new file mode 100644 index 0000000..605bbe9 --- /dev/null +++ b/boost_predef/os/bsd/open.h @@ -0,0 +1,171 @@ +/* +Copyright Rene Rivera 2012-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_BSD_OPEN_H +#define BOOST_PREDEF_OS_BSD_OPEN_H + +#include "../bsd.h" + +/*` +[heading `BOOST_OS_BSD_OPEN`] + +[@http://en.wikipedia.org/wiki/Openbsd OpenBSD] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__OpenBSD__`] [__predef_detection__]] + + [[`OpenBSD2_0`] [2.0.0]] + [[`OpenBSD2_1`] [2.1.0]] + [[`OpenBSD2_2`] [2.2.0]] + [[`OpenBSD2_3`] [2.3.0]] + [[`OpenBSD2_4`] [2.4.0]] + [[`OpenBSD2_5`] [2.5.0]] + [[`OpenBSD2_6`] [2.6.0]] + [[`OpenBSD2_7`] [2.7.0]] + [[`OpenBSD2_8`] [2.8.0]] + [[`OpenBSD2_9`] [2.9.0]] + [[`OpenBSD3_0`] [3.0.0]] + [[`OpenBSD3_1`] [3.1.0]] + [[`OpenBSD3_2`] [3.2.0]] + [[`OpenBSD3_3`] [3.3.0]] + [[`OpenBSD3_4`] [3.4.0]] + [[`OpenBSD3_5`] [3.5.0]] + [[`OpenBSD3_6`] [3.6.0]] + [[`OpenBSD3_7`] [3.7.0]] + [[`OpenBSD3_8`] [3.8.0]] + [[`OpenBSD3_9`] [3.9.0]] + [[`OpenBSD4_0`] [4.0.0]] + [[`OpenBSD4_1`] [4.1.0]] + [[`OpenBSD4_2`] [4.2.0]] + [[`OpenBSD4_3`] [4.3.0]] + [[`OpenBSD4_4`] [4.4.0]] + [[`OpenBSD4_5`] [4.5.0]] + [[`OpenBSD4_6`] [4.6.0]] + [[`OpenBSD4_7`] [4.7.0]] + [[`OpenBSD4_8`] [4.8.0]] + [[`OpenBSD4_9`] [4.9.0]] + ] + */ + +#define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__OpenBSD__) \ + ) +# ifndef BOOST_OS_BSD_AVAILABLE +# define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE +# define BOOST_OS_BSD_AVAILABLE +# endif +# undef BOOST_OS_BSD_OPEN +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_0) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_1) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,1,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_2) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,2,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_3) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,3,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_4) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,4,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_5) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,5,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_6) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,6,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_7) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,7,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_8) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,8,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_9) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,9,0) +# endif +# if !defined(BOOST_OS_BSD_OPEN) +# define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_BSD_OPEN +# define BOOST_OS_BSD_OPEN_AVAILABLE +# include "../../detail/os_detected.h" +#endif + +#define BOOST_OS_BSD_OPEN_NAME "OpenBSD" + +#endif + +#include "../../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_OPEN,BOOST_OS_BSD_OPEN_NAME) diff --git a/boost_predef/os/cygwin.h b/boost_predef/os/cygwin.h new file mode 100644 index 0000000..55b48fe --- /dev/null +++ b/boost_predef/os/cygwin.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_CYGWIN_H +#define BOOST_PREDEF_OS_CYGWIN_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_CYGWIN`] + +[@http://en.wikipedia.org/wiki/Cygwin Cygwin] evironment. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__CYGWIN__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_CYGWIN BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__CYGWIN__) \ + ) +# undef BOOST_OS_CYGWIN +# define BOOST_OS_CYGWIN BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_CYGWIN +# define BOOST_OS_CYGWIN_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_CYGWIN_NAME "Cygwin" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_CYGWIN,BOOST_OS_CYGWIN_NAME) diff --git a/boost_predef/os/haiku.h b/boost_predef/os/haiku.h new file mode 100644 index 0000000..935861a --- /dev/null +++ b/boost_predef/os/haiku.h @@ -0,0 +1,46 @@ +/* +Copyright Jessica Hamilton 2014 +Copyright Rene Rivera 2014-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_HAIKU_H +#define BOOST_PREDEF_OS_HAIKU_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_HAIKU`] + +[@http://en.wikipedia.org/wiki/Haiku_(operating_system) Haiku] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__HAIKU__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_HAIKU BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__HAIKU__) \ + ) +# undef BOOST_OS_HAIKU +# define BOOST_OS_HAIKU BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_HAIKU +# define BOOST_OS_HAIKU_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_HAIKU_NAME "Haiku" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HAIKU,BOOST_OS_HAIKU_NAME) diff --git a/boost_predef/os/hpux.h b/boost_predef/os/hpux.h new file mode 100644 index 0000000..86b78cb --- /dev/null +++ b/boost_predef/os/hpux.h @@ -0,0 +1,47 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_HPUX_H +#define BOOST_PREDEF_OS_HPUX_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_HPUX`] + +[@http://en.wikipedia.org/wiki/HP-UX HP-UX] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`hpux`] [__predef_detection__]] + [[`_hpux`] [__predef_detection__]] + [[`__hpux`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_HPUX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(hpux) || defined(_hpux) || defined(__hpux) \ + ) +# undef BOOST_OS_HPUX +# define BOOST_OS_HPUX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_HPUX +# define BOOST_OS_HPUX_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_HPUX_NAME "HP-UX" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HPUX,BOOST_OS_HPUX_NAME) diff --git a/boost_predef/os/ios.h b/boost_predef/os/ios.h new file mode 100644 index 0000000..d66276e --- /dev/null +++ b/boost_predef/os/ios.h @@ -0,0 +1,51 @@ +/* +Copyright Franz Detro 2014 +Copyright Rene Rivera 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_IOS_H +#define BOOST_PREDEF_OS_IOS_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_IOS`] + +[@http://en.wikipedia.org/wiki/iOS iOS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__APPLE__`] [__predef_detection__]] + [[`__MACH__`] [__predef_detection__]] + [[`__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__`] [__predef_detection__]] + + [[`__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__`] [__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__*1000]] + ] + */ + +#define BOOST_OS_IOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__APPLE__) && defined(__MACH__) && \ + defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) \ + ) +# undef BOOST_OS_IOS +# define BOOST_OS_IOS (__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__*1000) +#endif + +#if BOOST_OS_IOS +# define BOOST_OS_IOS_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_IOS_NAME "iOS" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IOS,BOOST_OS_IOS_NAME) diff --git a/boost_predef/os/irix.h b/boost_predef/os/irix.h new file mode 100644 index 0000000..e12100f --- /dev/null +++ b/boost_predef/os/irix.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_IRIX_H +#define BOOST_PREDEF_OS_IRIX_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_IRIX`] + +[@http://en.wikipedia.org/wiki/Irix IRIX] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`sgi`] [__predef_detection__]] + [[`__sgi`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_IRIX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(sgi) || defined(__sgi) \ + ) +# undef BOOST_OS_IRIX +# define BOOST_OS_IRIX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_IRIX +# define BOOST_OS_IRIX_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_IRIX_NAME "IRIX" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IRIX,BOOST_OS_IRIX_NAME) diff --git a/boost_predef/os/linux.h b/boost_predef/os/linux.h new file mode 100644 index 0000000..13e5ad9 --- /dev/null +++ b/boost_predef/os/linux.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_LINUX_H +#define BOOST_PREDEF_OS_LINUX_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_LINUX`] + +[@http://en.wikipedia.org/wiki/Linux Linux] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`linux`] [__predef_detection__]] + [[`__linux`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_LINUX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(linux) || defined(__linux) \ + ) +# undef BOOST_OS_LINUX +# define BOOST_OS_LINUX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_LINUX +# define BOOST_OS_LINUX_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_LINUX_NAME "Linux" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_LINUX,BOOST_OS_LINUX_NAME) diff --git a/boost_predef/os/macos.h b/boost_predef/os/macos.h new file mode 100644 index 0000000..af1dccd --- /dev/null +++ b/boost_predef/os/macos.h @@ -0,0 +1,65 @@ +/* +Copyright Rene Rivera 2008-2015 +Copyright Franz Detro 2014 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_MACOS_H +#define BOOST_PREDEF_OS_MACOS_H + +/* Special case: iOS will define the same predefs as MacOS, and additionally + '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__'. We can guard against that, + but only if we detect iOS first. Hence we will force include iOS detection + * before doing any MacOS detection. + */ +#include "../os/ios.h" + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_MACOS`] + +[@http://en.wikipedia.org/wiki/Mac_OS Mac OS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`macintosh`] [__predef_detection__]] + [[`Macintosh`] [__predef_detection__]] + [[`__APPLE__`] [__predef_detection__]] + [[`__MACH__`] [__predef_detection__]] + + [[`__APPLE__`, `__MACH__`] [10.0.0]] + [[ /otherwise/ ] [9.0.0]] + ] + */ + +#define BOOST_OS_MACOS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(macintosh) || defined(Macintosh) || \ + (defined(__APPLE__) && defined(__MACH__)) \ + ) +# undef BOOST_OS_MACOS +# if !defined(BOOST_OS_MACOS) && defined(__APPLE__) && defined(__MACH__) +# define BOOST_OS_MACOS BOOST_VERSION_NUMBER(10,0,0) +# endif +# if !defined(BOOST_OS_MACOS) +# define BOOST_OS_MACOS BOOST_VERSION_NUMBER(9,0,0) +# endif +#endif + +#if BOOST_OS_MACOS +# define BOOST_OS_MACOS_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_MACOS_NAME "Mac OS" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_MACOS,BOOST_OS_MACOS_NAME) diff --git a/boost_predef/os/os400.h b/boost_predef/os/os400.h new file mode 100644 index 0000000..2389db7 --- /dev/null +++ b/boost_predef/os/os400.h @@ -0,0 +1,45 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_OS400_H +#define BOOST_PREDEF_OS_OS400_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_OS400`] + +[@http://en.wikipedia.org/wiki/IBM_i IBM OS/400] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__OS400__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_OS400 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__OS400__) \ + ) +# undef BOOST_OS_OS400 +# define BOOST_OS_OS400 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_OS400 +# define BOOST_OS_OS400_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_OS400_NAME "IBM OS/400" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_OS400,BOOST_OS_OS400_NAME) diff --git a/boost_predef/os/qnxnto.h b/boost_predef/os/qnxnto.h new file mode 100644 index 0000000..b3ae419 --- /dev/null +++ b/boost_predef/os/qnxnto.h @@ -0,0 +1,59 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_QNXNTO_H +#define BOOST_PREDEF_OS_QNXNTO_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_QNX`] + +[@http://en.wikipedia.org/wiki/QNX QNX] operating system. +Version number available as major, and minor if possible. And +version 4 is specifically detected. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__QNX__`] [__predef_detection__]] + [[`__QNXNTO__`] [__predef_detection__]] + + [[`_NTO_VERSION`] [V.R.0]] + [[`__QNX__`] [4.0.0]] + ] + */ + +#define BOOST_OS_QNX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(__QNX__) || defined(__QNXNTO__) \ + ) +# undef BOOST_OS_QNX +# if !defined(BOOST_OS_QNX) && defined(_NTO_VERSION) +# define BOOST_OS_QNX BOOST_PREDEF_MAKE_10_VVRR(_NTO_VERSION) +# endif +# if !defined(BOOST_OS_QNX) && defined(__QNX__) +# define BOOST_OS_QNX BOOST_VERSION_NUMBER(4,0,0) +# endif +# if !defined(BOOST_OS_QNX) +# define BOOST_OS_QNX BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_QNX +# define BOOST_OS_QNX_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_QNX_NAME "QNX" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_QNX,BOOST_OS_QNX_NAME) diff --git a/boost_predef/os/solaris.h b/boost_predef/os/solaris.h new file mode 100644 index 0000000..8c384cf --- /dev/null +++ b/boost_predef/os/solaris.h @@ -0,0 +1,46 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_SOLARIS_H +#define BOOST_PREDEF_OS_SOLARIS_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_SOLARIS`] + +[@http://en.wikipedia.org/wiki/Solaris_Operating_Environment Solaris] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`sun`] [__predef_detection__]] + [[`__sun`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_SOLARIS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(sun) || defined(__sun) \ + ) +# undef BOOST_OS_SOLARIS +# define BOOST_OS_SOLARIS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_SOLARIS +# define BOOST_OS_SOLARIS_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_SOLARIS_NAME "Solaris" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SOLARIS,BOOST_OS_SOLARIS_NAME) diff --git a/boost_predef/os/unix.h b/boost_predef/os/unix.h new file mode 100644 index 0000000..becc582 --- /dev/null +++ b/boost_predef/os/unix.h @@ -0,0 +1,76 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_UNIX_H +#define BOOST_PREDEF_OS_UNIX_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_UNIX`] + +[@http://en.wikipedia.org/wiki/Unix Unix Environment] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`unix`] [__predef_detection__]] + [[`__unix`] [__predef_detection__]] + [[`_XOPEN_SOURCE`] [__predef_detection__]] + [[`_POSIX_SOURCE`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_UNIX BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(unix) || defined(__unix) || \ + defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) +# undef BOOST_OS_UNIX +# define BOOST_OS_UNIX BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_UNIX +# define BOOST_OS_UNIX_AVAILABLE +#endif + +#define BOOST_OS_UNIX_NAME "Unix Environment" + +/*` +[heading `BOOST_OS_SVR4`] + +[@http://en.wikipedia.org/wiki/UNIX_System_V SVR4 Environment] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`__sysv__`] [__predef_detection__]] + [[`__SVR4`] [__predef_detection__]] + [[`__svr4__`] [__predef_detection__]] + [[`_SYSTYPE_SVR4`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_SVR4 BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if defined(__sysv__) || defined(__SVR4) || \ + defined(__svr4__) || defined(_SYSTYPE_SVR4) +# undef BOOST_OS_SVR4 +# define BOOST_OS_SVR4 BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_SVR4 +# define BOOST_OS_SVR4_AVAILABLE +#endif + +#define BOOST_OS_SVR4_NAME "SVR4 Environment" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_UNIX,BOOST_OS_UNIX_NAME) +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SVR4,BOOST_OS_SVR4_NAME) diff --git a/boost_predef/os/vms.h b/boost_predef/os/vms.h new file mode 100644 index 0000000..20789d5 --- /dev/null +++ b/boost_predef/os/vms.h @@ -0,0 +1,52 @@ +/* +Copyright Rene Rivera 2011-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_VMS_H +#define BOOST_PREDEF_OS_VMS_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_VMS`] + +[@http://en.wikipedia.org/wiki/Vms VMS] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`VMS`] [__predef_detection__]] + [[`__VMS`] [__predef_detection__]] + + [[`__VMS_VER`] [V.R.P]] + ] + */ + +#define BOOST_OS_VMS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(VMS) || defined(__VMS) \ + ) +# undef BOOST_OS_VMS +# if defined(__VMS_VER) +# define BOOST_OS_VMS BOOST_PREDEF_MAKE_10_VVRR00PP00(__VMS_VER) +# else +# define BOOST_OS_VMS BOOST_VERSION_NUMBER_AVAILABLE +# endif +#endif + +#if BOOST_OS_VMS +# define BOOST_OS_VMS_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_VMS_NAME "VMS" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_VMS,BOOST_OS_VMS_NAME) diff --git a/boost_predef/os/windows.h b/boost_predef/os/windows.h new file mode 100644 index 0000000..1c385c7 --- /dev/null +++ b/boost_predef/os/windows.h @@ -0,0 +1,51 @@ +/* +Copyright Rene Rivera 2008-2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_OS_WINDOWS_H +#define BOOST_PREDEF_OS_WINDOWS_H + +#include "../version_number.h" +#include "../make.h" + +/*` +[heading `BOOST_OS_WINDOWS`] + +[@http://en.wikipedia.org/wiki/Category:Microsoft_Windows Microsoft Windows] operating system. + +[table + [[__predef_symbol__] [__predef_version__]] + + [[`_WIN32`] [__predef_detection__]] + [[`_WIN64`] [__predef_detection__]] + [[`__WIN32__`] [__predef_detection__]] + [[`__TOS_WIN__`] [__predef_detection__]] + [[`__WINDOWS__`] [__predef_detection__]] + ] + */ + +#define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_NOT_AVAILABLE + +#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \ + defined(_WIN32) || defined(_WIN64) || \ + defined(__WIN32__) || defined(__TOS_WIN__) || \ + defined(__WINDOWS__) \ + ) +# undef BOOST_OS_WINDOWS +# define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_AVAILABLE +#endif + +#if BOOST_OS_WINDOWS +# define BOOST_OS_WINDOWS_AVAILABLE +# include "../detail/os_detected.h" +#endif + +#define BOOST_OS_WINDOWS_NAME "Microsoft Windows" + +#endif + +#include "../detail/test.h" +BOOST_PREDEF_DECLARE_TEST(BOOST_OS_WINDOWS,BOOST_OS_WINDOWS_NAME) diff --git a/boost_predef/version_number.h b/boost_predef/version_number.h new file mode 100644 index 0000000..3903a36 --- /dev/null +++ b/boost_predef/version_number.h @@ -0,0 +1,53 @@ +/* +Copyright Rene Rivera 2005, 2008-2013 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_PREDEF_VERSION_NUMBER_H +#define BOOST_PREDEF_VERSION_NUMBER_H + +/*` +[heading `BOOST_VERSION_NUMBER`] + +`` +BOOST_VERSION_NUMBER(major,minor,patch) +`` + +Defines standard version numbers, with these properties: + +* Decimal base whole numbers in the range \[0,1000000000). + The number range is designed to allow for a (2,2,5) triplet. + Which fits within a 32 bit value. +* The `major` number can be in the \[0,99\] range. +* The `minor` number can be in the \[0,99\] range. +* The `patch` number can be in the \[0,99999\] range. +* Values can be specified in any base. As the defined value + is an constant expression. +* Value can be directly used in both preprocessor and compiler + expressions for comparison to other similarly defined values. +* The implementation enforces the individual ranges for the + major, minor, and patch numbers. And values over the ranges + are truncated (modulo). + +*/ +#define BOOST_VERSION_NUMBER(major,minor,patch) \ + ( (((major)%100)*10000000) + (((minor)%100)*100000) + ((patch)%100000) ) + +#define BOOST_VERSION_NUMBER_MAX \ + BOOST_VERSION_NUMBER(99,99,99999) + +#define BOOST_VERSION_NUMBER_ZERO \ + BOOST_VERSION_NUMBER(0,0,0) + +#define BOOST_VERSION_NUMBER_MIN \ + BOOST_VERSION_NUMBER(0,0,1) + +#define BOOST_VERSION_NUMBER_AVAILABLE \ + BOOST_VERSION_NUMBER_MIN + +#define BOOST_VERSION_NUMBER_NOT_AVAILABLE \ + BOOST_VERSION_NUMBER_ZERO + +#endif diff --git a/ced/CMakeLists.txt b/ced/CMakeLists.txt new file mode 100644 index 0000000..93b565c --- /dev/null +++ b/ced/CMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# Old enough to support Ubuntu Precise. +cmake_minimum_required(VERSION 2.8.7) +set(PROJECT_VERSION 1.0) + +if (WIN32) + if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/compact_enc_det/compact_enc_det.h") + message(FATAL_ERROR "\nCould not find source code. Make sure you are running this script from the root of the distribution tree.") + endif() +endif() + +project(CED CXX) +set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS 1 CACHE INTERNAL "No dev warnings") + +option(BUILD_SHARED_LIBS "Build shared libraries" OFF) + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-narrowing") +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-c++11-narrowing") +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + if (NOT BUILD_SHARED_LIBS) + foreach(flag_var + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif(${flag_var} MATCHES "/MD") + endforeach(flag_var) + endif() +endif() + +set(EXTRA_TARGET_LINK_LIBRARIES) + +if(WIN32) + add_definitions(-DUNICODE -D_UNICODE -DSTRICT -DNOMINMAX) +endif() + +set(THREADING thread) +list(APPEND EXTRA_TARGET_LINK_LIBRARIES -pthread) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +set(CED_LIBRARY_SOURCES + compact_enc_det/compact_enc_det.cc + compact_enc_det/compact_enc_det_hint_code.cc + util/encodings/encodings.cc + util/languages/languages.cc + ) + +add_library(ced STATIC ${CED_LIBRARY_SOURCES}) + +# Uncomment to put CED into WHATWG-compliant mode. +#add_definitions(-DHTML5_MODE) \ No newline at end of file diff --git a/ced/LICENSE b/ced/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/ced/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ced/README.md b/ced/README.md new file mode 100644 index 0000000..c9c1f90 --- /dev/null +++ b/ced/README.md @@ -0,0 +1,46 @@ +### Introduction + +Compact Encoding Detection(CED for short) is a library written in C++ that +scans given raw bytes and detect the most likely text encoding. + +Basic usage: + +``` +#include "compact_enc_det/compact_enc_det.h" + +const char* text = "Input text"; +bool is_reliable; +int bytes_consumed; + +Encoding encoding = CompactEncDet::DetectEncoding( + text, strlen(text), + nullptr, nullptr, nullptr, + UNKNOWN_ENCODING, + UNKNOWN_LANGUAGE, + CompactEncDet::WEB_CORPUS, + false, + &bytes_consumed, + &is_reliable); + +``` + +### How to build + +You need [CMake](https://cmake.org/) to build the package. After unzipping +the source code , run `autogen.sh` to build everything automatically. +The script also downloads [Google Test](https://github.com/google/googletest) +framework needed to build the unittest. + +``` +$ cd compact_enc_det +$ ./autogen.sh +... +$ bin/ced_unittest +``` + +On Windows, run `cmake .` to download the test framework, and generate +project files for Visual Studio. + +``` +D:\packages\compact_enc_det> cmake . +``` diff --git a/ced/autogen.sh b/ced/autogen.sh new file mode 100755 index 0000000..76b4325 --- /dev/null +++ b/ced/autogen.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# +# Copyright 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +# Run this script to generate the configure script and other files that will +# be included in the distribution. These files are not checked in because they +# are automatically generated. + +set -e + +if [ ! -z "$@" ]; then + for argument in "$@"; do + case $argument in + # make curl silent + "-s") + curlopts="-s" + ;; + esac + done +fi + + +# Check that we're being run from the right directory. +if test ! -f compact_enc_det/compact_enc_det.h; then + cat >&2 << __EOF__ +Could not find source code. Make sure you are running this script from the +root of the distribution tree. +__EOF__ + exit 1 +fi + +# Check that gtest is present. It is used to build unit test suite. +if test ! -e gtest; then + if test -z $(which curl); then + echo "curl cannot be found. Please install it to build the package." + exit 1 + fi + + echo "Google Test not present. Fetching from the web..." + curl $curlopts -L -O https://github.com/google/googletest/archive/master.zip + unzip -q master.zip + rm master.zip + mv googletest-master gtest +fi + +if test -z $(which cmake); then + echo "CMake cannot be found. Please install it to build the package." + exit 1 +fi + +# Build gtest +(cd gtest && cmake . && make) + +# Build the main package +cmake . && make + +set -ex + +exit 0 diff --git a/ced/compact_enc_det/compact_enc_det.cc b/ced/compact_enc_det/compact_enc_det.cc new file mode 100644 index 0000000..61d5ee4 --- /dev/null +++ b/ced/compact_enc_det/compact_enc_det.cc @@ -0,0 +1,5739 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "compact_enc_det/compact_enc_det.h" + +#include // for sqrt +#include // for size_t +#include // for printf, fprintf, NULL, etc +#include // for qsort +#include // for memset, memcpy, memcmp, etc +#include +#include // for string, operator==, etc + +#include "compact_enc_det/compact_enc_det_hint_code.h" +#include "util/string_util.h" +#include "util/basictypes.h" +#include "util/commandlineflags.h" +#include "util/logging.h" + +using std::string; + +// TODO as of 2007.10.09: +// +// Consider font=TT-BHxxx as user-defined => binary +// Demote GB18030 if no 8x3x pair +// Map byte2 ascii punct to 0x60, digits to 0x7e, gets them into hires +// Consider removing/ignoring bytes 01-1F to avoid crap pollution +// Possibly boost declared encoding in robust scan +// googlebot tiny files +// look for ranges of encodings +// consider tags just as > < within aligned block of 32 +// flag too few characters in postproc (Latin 6 problem) +// Remove slow scan beyond 16KB +// Consider removing kMostLikelyEncoding or cut it in half + + +// A note on mixed encodings +// +// The most common encoding error on the web is a page containing a mixture of +// CP-1252 and UTF-8. A less common encoding error is a third-party feed that +// has been converted from CP-1252 to UTF-8 and then those bytes converted a +// second time to UTF-8. CED originally attempted to detect these error cases +// by using two synthetic encodings, UTF8CP1252 and UTF8UTF8. The intended +// implementation was to start these just below CP1252 and UTF8 respectively in +// overall liklihood, and allow 1252 and UTF8 to fall behind if mixtures are +// found. +// +// The UTF8UTF8 encoding is a possible outcome from CED, but unfortunately the +// UTF8CP1252 internal encoding was added late and not put into encodings.proto, +// so at the final step it is mapped to UTF8UTF8 also. This was a bad idea and +// is removed in this November 2011 CL. +// +// Mixed encoding detection never worked out as well as envisioned, so the +// ced_allow_utf8utf8 flag normally disables all this. +// +// The effect is that CP-1252 and UTF-8 mixtures will usually be detected as +// UTF8, and the inputconverter code for UTF8 normally will convert bare +// CP-1252 bytes to UTF-8, instead of the less-helpful FFFD substitution. UTF-8 +// and double-UTF-8 mixtures will be detected as UTF-8, and the double +// conversion will stand. +// +// However, it is occasionally useful to use CED to detect double-converted +// UTF-8 coming from third-party data feeds, so they can be fixed at the source. +// For this purpose, the UTF8UTF8 encoding remains available under the +// ced_allow_utf8utf8 flag. +// +// When UTF8UTF8 is detected, the inputconverter code will undo the double +// conversion, giving good text. + +// Norbert Runge has noted these words in CP1252 that are mistakenly identified +// as UTF-8 because of the last pair of characters: +// NESTLÉ® 0xC9 0xAE U+00C9 U+00AE C9AE = U+026E;SMALL LEZH +// drauß\u2019 0xDF 0x92 U+00DF U+2019 DF92 = U+07D2;NKO LETTER N +// Mutterschoß\u201c 0xDF 0x93 U+00DF U+201C DF93 = U+07D3;NKO LETTER BA +// Schoß\u201c 0xDF 0x93 U+00DF U+201C +// weiß\u201c 0xDF 0x93 U+00DF U+00AB +// Schnellfuß\u201c 0xDF 0x93 U+00DF U+201C +// süß« 0xDF 0xAB U+00DF U+00AB DFAB = U+07EB;NKO HIGH TONE +// These four byte combinations now explicitly boost Latin1/CP1252. + +// And for reference, here are a couple of Portuguese spellings +// that may be mistaken as double-byte encodings. +// informações 0xE7 0xF5 +// traição 0xE7 0xE3 + + +static const char* kVersion = "2.2"; + +DEFINE_bool(ced_allow_utf8utf8, false, "Allow the UTF8UTF8 encoding, " + "to handle mixtures of CP1252 " + "converted to UTF-8 zero, one, " + "or two times"); +DEFINE_int32(enc_detect_slow_max_kb, 16, + "Maximum number of Kbytes to examine for " + "7-bit-only (2022, Hz, UTF7) encoding detect. " + "You are unlikely to want to change this."); +DEFINE_int32(enc_detect_fast_max_kb, 256, + "Maximum number of Kbytes to examine for encoding detect. " + "You are unlikely to want to change this."); + +DEFINE_int32(ced_reliable_difference, 300, "30 * Bits of minimum probablility " + "difference 1st - 2nd to be considered reliable \n" + " 2 corresponds to min 4x difference\n" + " 4 corresponds to min 16x difference\n" + " 8 corresponds to min 256x difference\n" + " 10 corresponds to min 1024x difference\n" + " 20 corresponds to min 1Mx difference."); + +// Text debug output options +DEFINE_bool(enc_detect_summary, false, + "Print first 16 interesting pairs at exit."); +DEFINE_bool(counts, false, "Count major-section usage"); + +// PostScript debug output options +DEFINE_bool(enc_detect_detail, false, + "Print PostScript of every update, to stderr."); +DEFINE_bool(enc_detect_detail2, false, + "More PostScript detail of every update, to stderr."); +DEFINE_bool(enc_detect_source, false, "Include source text in detail"); +// Encoding name must exactly match FIRST column of kI18NInfoByEncoding in +// lang_enc.cc + +// Following flags are not in use. Replace them with constants to +// avoid static initialization. + +//DEFINE_string(enc_detect_watch1, "", "Do detail2 about this encoding name."); +//DEFINE_string(enc_detect_watch2, "", "Do detail2 about this encoding name."); + +static const char* const FLAGS_enc_detect_watch1 = ""; +static const char* const FLAGS_enc_detect_watch2 = ""; + +// Only for experiments. Delete soon. +DEFINE_bool(force127, false, "Force Latin1, Latin2, Latin7 based on trigrams"); + +// Demo-mode/debugging experiment +DEFINE_bool(demo_nodefault, false, + "Default to all equal; no boost for declared encoding."); +DEFINE_bool(dirtsimple, false, "Just scan and count for all encodings"); +DEFINE_bool(ced_echo_input, false, "Echo ced input to stderr"); + + +static const int XDECILOG2 = 3; // Multiplier for log base 2 ** n/10 +static const int XLOG2 = 30; // Multiplier for log base 2 ** n + +static const int kFinalPruneDifference = 10 * XLOG2; + // Final bits of minimum + // probability difference 1st-nth + // to be pruned + +static const int kInititalPruneDifference = kFinalPruneDifference * 4; + // Initial bits of minimum + // probability difference 1st-nth + // to be pruned + // +static const int kPruneDiffDecrement = kFinalPruneDifference; + // Decrements bits of minimum + // probability difference 1st-nth + // to be pruned + +static const int kSmallInitDiff = 2 * XLOG2; // bits of minimum + // probability difference, base to + // superset encodings + +static const int kBoostInitial = 20 * XLOG2; // bits of boost for + // initial byte patterns (BOM, 00) + +static const int kBadPairWhack = 20 * XLOG2; // bits of whack for + // one bad pair + +static const int kBoostOnePair = 20 * XLOG2; // bits of boost for + // one good pair in Hz, etc. + +static const int kGentleOnePair = 4 * XLOG2; // bits of boost for + // one good sequence + // +static const int kGentlePairWhack = 2 * XLOG2; // bits of whack + // for ill-formed sequence + +static const int kGentlePairBoost = 2 * XLOG2; // bits of boost + // for well-formed sequence + +static const int kBoostPerB64Byte = 2 * XLOG2; // bits of boost for + // one good pair in Hz, etc. + +static const int kDeclaredEncBoost = 5 * XDECILOG2; // bits/10 of boost for + // best declared encoding per bigram + +static const int kBestEncBoost = 5 * XDECILOG2; // bits/10 of boost for + // best encoding per bigram + +static const int kTrigramBoost = 2 * XLOG2; // bits of boost for Latin127 tri + +static const int kMaxPairs = 48; // Max interesting pairs to look at + // If you change this, + // adjust *PruneDiff* + +static const int kPruneMask = 0x07; // Prune every 8 interesting pairs + + +static const int kBestPairsCount = 16; // For first N pairs, do extra boost + // based on most likely encoding + // of pair over entire web + +static const int kDerateHintsBelow = 12; // If we have fewer than N bigrams, + // weaken the hints enough that + // unhinted encodings have a hope of + // rising to the top + +static const int kMinRescanLength = 800; // Don't bother rescanning for + // unreliable encoding if fewer + // than this many bytes unscanned. + // We will rescan at most last half + // of this. + +static const int kStrongBinary = 12; // Make F_BINARY the only encoding +static const int kWeakerBinary = 4; // Make F_BINARY likely encoding + +// These are byte counts from front of file +static const int kBinaryHardAsciiLimit = 6 * 1024; // Not binary if all ASCII +static const int kBinarySoftAsciiLimit = 8 * 1024; // " if mostly ASCII + +// We try here to avoid having title text dominate the encoding detection, +// for the not-infrequent error case of title in encoding1, body in encoding2: +// we want to bias toward encoding2 winning. +// +// kMaxBigramsTagTitleText should be a multiple of 2, 3, and 4, so that we +// rarely cut off mid-character in the original (not-yet-detected) encoding. +// This matters most for UTF-8 two- and three-byte codes and for +// Shift-JIS three-byte codes. +static const int kMaxBigramsTagTitleText = 12; // Keep only some tag text +static const int kWeightshiftForTagTitleText = 4; // Give text in tags, etc. + // 1/16 normal weight + +static const int kStrongPairs = 6; // Let reliable enc with this many + // pairs overcome missing hint + +enum CEDInternalFlags { + kCEDNone = 0, // The empty flag + kCEDRescanning = 1, // Do not further recurse + kCEDSlowscore = 2, // Do extra scoring + kCEDForceTags = 4, // Always examine text inside tags +}; + +// Forward declaration +Encoding InternalDetectEncoding( + CEDInternalFlags flags, const char* text, int text_length, + const char* url_hint, const char* http_charset_hint, + const char* meta_charset_hint, const int encoding_hint, + const Language language_hint, // User interface lang + const CompactEncDet::TextCorpusType corpus_type, + bool ignore_7bit_mail_encodings, int* bytes_consumed, bool* is_reliable, + Encoding* second_best_enc); + +typedef struct { + const uint8* hires[4]; // Pointers to possible high-resolution bigram deltas + uint8 x_bar; // Average byte2 value + uint8 y_bar; // Average byte1 value + uint8 x_stddev; // Standard deviation of byte2 value + uint8 y_stddev; // Standard deviation of byte1 value + int so; // Scaling offset -- add to probabilities below + uint8 b1[256]; // Unigram probability for first byte of aligned bigram + uint8 b2[256]; // Unigram probability for second byte of aligned bigram + uint8 b12[256]; // Unigram probability for cross bytes of aligned bigram +} UnigramEntry; + +//typedef struct { +// uint8 b12[256*256]; // Bigram probability for aligned bigram +//} FullBigramEntry; + + +// Include all the postproc-generated tables here: +// RankedEncoding +// kMapToEncoding +// unigram_table +// kMostLIkelyEncoding +// kTLDHintProbs +// kCharsetHintProbs +// HintEntry, kMaxTldKey kMaxTldVector, etc. +// ============================================================================= + +#include "compact_enc_det/compact_enc_det_generated_tables.h" + + +#define F_ASCII F_Latin1 // "ASCII" is a misnomer, so this code uses "Latin1" + +#define F_BINARY F_X_BINARYENC // We are mid-update for name change +#define F_UTF8UTF8 F_X_UTF8UTF8 // We are mid-update for name change +#define F_BIG5_CP950 F_BIG5 // We are mid-update for name change +#define F_Unicode F_UTF_16LE // We are mid-update for name change +// ============================================================================= + +// 7-bit encodings have at least one "interesting" byte value < 0x80 +// (00 0E 1B + ~) +// JIS 2022-cn 2022-kr hz utf7 +// Unicode UTF-16 UTF-32 +// 8-bit encodings have no interesting byte values < 0x80 +static const uint32 kSevenBitActive = 0x00000001; // needs <80 to detect +static const uint32 kUTF7Active = 0x00000002; // <80 and + +static const uint32 kHzActive = 0x00000004; // <80 and ~ +static const uint32 kIso2022Active = 0x00000008; // <80 and 1B 0E 0F +static const uint32 kUTF8Active = 0x00000010; +static const uint32 kUTF8UTF8Active = 0x00000020; +static const uint32 kUTF1632Active = 0x00000040; // <80 and 00 +static const uint32 kBinaryActive = 0x00000080; // <80 and 00 +static const uint32 kTwobyteCode = 0x00000100; // Needs 8xxx +static const uint32 kIsIndicCode = 0x00000200; // +static const uint32 kHighAlphaCode = 0x00000400; // full alphabet in 8x-Fx +static const uint32 kHighAccentCode = 0x00000800; // accents in 8x-Fx +static const uint32 kEUCJPActive = 0x00001000; // Have to mess with phase + + +// Debug only. not thread safe +static int encdet_used = 0; +static int rescore_used = 0; +static int rescan_used = 0; +static int robust_used = 0; +static int looking_used = 0; +static int doing_used = 0; + + +// For debugging only -- about 256B/entry times about 500 = 128KB +// TODO: only allocate this if being used +typedef struct { + int offset; + int best_enc; // Best ranked encoding for this bigram, or + // -1 for overhead entries + string label; + int detail_enc_prob[NUM_RANKEDENCODING]; +} DetailEntry; + +static int watch1_rankedenc = -1; // Debug. not threadsafe +static int watch2_rankedenc = -1; // Debug. not threadsafe +////static int next_detail_entry = 0; // Debug. not threadsafe +////static DetailEntry details[kMaxPairs * 10]; // Allow 10 details per bigram +// End For debugging only + +// Must match kTestPrintableAsciiTildePlus exit codes, minus one +enum PairSet {AsciiPair = 0, OtherPair = 1, NUM_PAIR_SETS = 2}; + +// The reasons for pruning +enum PruneReason {PRUNE_NORMAL, PRUNE_SLOWEND, PRUNE_FINAL}; + +static const char* kWhatSetName[] = {"Ascii", "Other"}; + + +// State for encodings that do shift-out/shift-in between one- and two-byte +// regions (ISO-2022-xx, HZ) +enum StateSoSi {SOSI_NONE, SOSI_ERROR, SOSI_ONEBYTE, SOSI_TWOBYTE}; + +typedef struct { + const uint8* initial_src; // For calculating byte offsets + const uint8* limit_src; // Range of input source + const uint8* prior_src; // Source consumed by prior call to BoostPrune + const uint8* last_pair; // Last pair inserted into interesting_pairs + + DetailEntry* debug_data; // Normally NULL. Ptr to debug data for + // FLAGS_enc_detect_detail PostScript data + int next_detail_entry; // Debug + + bool done; + bool reliable; + bool hints_derated; + int declared_enc_1; // From http/meta hint + int declared_enc_2; // from http/meta hint + int prune_count; // Number of times we have pruned + + int trigram_highwater_mark; // Byte offset of last trigram processing + bool looking_for_latin_trigrams; // True if we should test for doing + // Latin1/2/7 trigram processing + bool do_latin_trigrams; // True if we actually are scoring trigrams + + // Miscellaneous state variables for difficult encodings + int binary_quadrants_count; // Number of four bigram quadrants seen: + // 0xxxxxxx0xxxxxxx 0xxxxxxx1xxxxxx + // 1xxxxxxx0xxxxxxx 1xxxxxxx1xxxxxx + int binary_8x4_count; // Number of 8x4 buckets seen: + uint32 binary_quadrants_seen; // Bit[i] set if bigram i.......i....... seen + uint32 binary_8x4_seen; // Bit[i] set if bigram iii.....ii...... seen + int utf7_starts; // Count of possible UTF-7 beginnings seen + int prior_utf7_offset; // Source consumed by prior UTF-7 string + int next_utf8_ministate; // Mini state for UTF-8 sequences + int utf8_minicount[6]; // Number of correct 2- 3- 4-byte seq, errors + int next_utf8utf8_ministate; // Mini state for UTF8UTF8 sequences + int utf8utf8_odd_byte; // UTF8UTF8 seq has odd number of bytes + int utf8utf8_minicount[6]; // Number of correct 2- 3- 4-byte seq, errors + StateSoSi next_2022_state; // Mini state for 2022 sequences + StateSoSi next_hz_state; // Mini state for HZ sequences + bool next_eucjp_oddphase; // Mini state for EUC-JP sequences + int byte32_count[8]; // Count of top 3 bits of byte1 of bigram + // 0x1x 2x3x 4x5x 6x7x 8x9x AxBx CxDx ExFx + uint32 active_special; // Bits showing which special cases are active + + Encoding tld_hint; // Top TLD encoding or UNKNOWN + Encoding http_hint; // What the document says about itself or + Encoding meta_hint; // UNKNOWN_ENCODING. BOM is initial byte + Encoding bom_hint; // order mark for UTF-xx + + // small cache of previous interesting bigrams + int next_prior_bigram; + int prior_bigram[4]; + int prior_binary[1]; + + int top_rankedencoding; // Top two probabilities and families + int second_top_rankedencoding; + int top_prob; + int second_top_prob; + int prune_difference; // Prune things this much below the top prob + int rankedencoding_list_len; // Number of active encodings + int rankedencoding_list[NUM_RANKEDENCODING]; // List of active encodings + // + int enc_prob[NUM_RANKEDENCODING]; // Cumulative probability per enc + // This is where all the action is + int hint_prob[NUM_RANKEDENCODING]; // Initial hint probabilities + int hint_weight[NUM_RANKEDENCODING]; // Number of hints for this enc + + // Two sets -- one for printable ASCII, one for the rest + int prior_interesting_pair[NUM_PAIR_SETS]; // Pairs consumed by prior call + int next_interesting_pair[NUM_PAIR_SETS]; // Next pair to write + char interesting_pairs[NUM_PAIR_SETS][kMaxPairs * 2]; // Two bytes per pair + int interesting_offsets[NUM_PAIR_SETS][kMaxPairs]; // Src offset of pair + int interesting_weightshift[NUM_PAIR_SETS][kMaxPairs]; // weightshift of pair +} DetectEncodingState; + + +// Record a debug event that changes probabilities +void SetDetailsEncProb(DetectEncodingState* destatep, + int offset, int best_enc, const char* label) { + int next = destatep->next_detail_entry; + destatep->debug_data[next].offset = offset; + destatep->debug_data[next].best_enc = best_enc; + destatep->debug_data[next].label = label; + memcpy(&destatep->debug_data[next].detail_enc_prob, + &destatep->enc_prob, + sizeof(destatep->enc_prob)); + ++destatep->next_detail_entry; +} + +// Record a debug event that changes probabilities, copy offset +void SetDetailsEncProbCopyOffset(DetectEncodingState* destatep, + int best_enc, const char* label) { + int next = destatep->next_detail_entry; + destatep->debug_data[next].offset = destatep->debug_data[next - 1].offset; + destatep->debug_data[next].best_enc = best_enc; + destatep->debug_data[next].label = label; + memcpy(&destatep->debug_data[next].detail_enc_prob, + &destatep->enc_prob, + sizeof(destatep->enc_prob)); + ++destatep->next_detail_entry; +} + +// Record a debug event that changes probs and has simple text label +void SetDetailsEncLabel(DetectEncodingState* destatep, const char* label) { + int next = destatep->next_detail_entry; + destatep->debug_data[next].offset = destatep->debug_data[next - 1].offset; + destatep->debug_data[next].best_enc = -1; + destatep->debug_data[next].label = label; + memcpy(&destatep->debug_data[next].detail_enc_prob, + &destatep->enc_prob, + sizeof(destatep->enc_prob)); + ++destatep->next_detail_entry; +} + +// Record a debug event that is just a text label, no change in probs +void SetDetailsLabel(DetectEncodingState* destatep, const char* label) { + int next = destatep->next_detail_entry; + destatep->debug_data[next].offset = destatep->debug_data[next - 1].offset; + destatep->debug_data[next].best_enc = -1; + destatep->debug_data[next].label = label; + memcpy(&destatep->debug_data[next].detail_enc_prob, + &destatep->debug_data[next - 1].detail_enc_prob, + sizeof(destatep->enc_prob)); + ++destatep->next_detail_entry; +} + + +// Maps superset encodings to base, to see if 2 encodings are compatible +// (Non-identity mappings are marked "-->" below.) +static const Encoding kMapEncToBaseEncoding[] = { + ISO_8859_1, // 0: Teragram ASCII + ISO_8859_2, // 1: Teragram Latin2 + ISO_8859_3, // 2: in BasisTech but not in Teragram + ISO_8859_4, // 3: Teragram Latin4 + ISO_8859_5, // 4: Teragram ISO-8859-5 + ISO_8859_6, // 5: Teragram Arabic + ISO_8859_7, // 6: Teragram Greek + MSFT_CP1255, // 7: Teragram Hebrew --> 36 + ISO_8859_9, // 8: in BasisTech but not in Teragram + ISO_8859_10, // 9: in BasisTech but not in Teragram + JAPANESE_EUC_JP, // 10: Teragram EUC_JP + JAPANESE_SHIFT_JIS, // 11: Teragram SJS + JAPANESE_JIS, // 12: Teragram JIS + CHINESE_BIG5, // 13: Teragram BIG5 + CHINESE_GB, // 14: Teragram GB + CHINESE_EUC_CN, // 15: Teragram EUC-CN + KOREAN_EUC_KR, // 16: Teragram KSC + UNICODE, // 17: Teragram Unicode + CHINESE_EUC_CN, // 18: Teragram EUC --> 15 + CHINESE_EUC_CN, // 19: Teragram CNS --> 15 + CHINESE_BIG5, // 20: Teragram BIG5_CP950 --> 13 + JAPANESE_SHIFT_JIS, // 21: Teragram CP932 --> 11 + UTF8, // 22 + UNKNOWN_ENCODING, // 23 + ISO_8859_1, // 24: ISO_8859_1 with all characters <= 127 --> 0 + RUSSIAN_KOI8_R, // 25: Teragram KOI8R + RUSSIAN_CP1251, // 26: Teragram CP1251 + ISO_8859_1, // 27: CP1252 aka MSFT euro ascii --> 0 + RUSSIAN_KOI8_RU, // 28: CP21866 aka KOI8_RU, used for Ukrainian + MSFT_CP1250, // 29: CP1250 aka MSFT eastern european + ISO_8859_1, // 30: aka ISO_8859_0 aka ISO_8859_1 euroized --> 0 + ISO_8859_9, // 31: used for Turkish + ISO_8859_13, // 32: used in Baltic countries --> 43 + ISO_8859_11, // 33: aka TIS-620, used for Thai + ISO_8859_11, // 34: used for Thai --> 33 + MSFT_CP1256, // 35: used for Arabic + MSFT_CP1255, // 36: Logical Hebrew Microsoft + MSFT_CP1255, // 37: Iso Hebrew Logical --> 36 + MSFT_CP1255, // 38: Iso Hebrew Visual --> 36 + CZECH_CP852, // 39 + ISO_8859_2, // 40: aka ISO_IR_139 aka KOI8_CS --> 1 + MSFT_CP1253, // 41: used for Greek, but NOT a superset of 8859-7 + RUSSIAN_CP866, // 42 + ISO_8859_13, // 43 + ISO_2022_KR, // 44 + CHINESE_GB, // 45 GBK --> 14 + CHINESE_GB, // 46 GB18030 --> 14 + CHINESE_BIG5, // 47 BIG5_HKSCS --> 13 + ISO_2022_KR, // 48 ISO_2022_CN --> 44 + TSCII, // 49 Indic encoding + TAMIL_MONO, // 50 Indic encoding - Tamil + TAMIL_BI, // 51 Indic encoding - Tamil + JAGRAN, // 52 Indic encoding - Devanagari + MACINTOSH_ROMAN, // 53 + UTF7, // 54 + BHASKAR, // 55 Indic encoding - Devanagari + HTCHANAKYA, // 56 Indic encoding - Devanagari + UTF16BE, // 57 + UTF16LE, // 58 + UTF32BE, // 59 + UTF32LE, // 60 + BINARYENC, // 61 + HZ_GB_2312, // 62 + UTF8UTF8, // 63 + TAM_ELANGO, // 64 Elango - Tamil + TAM_LTTMBARANI, // 65 Barani - Tamil + TAM_SHREE, // 66 Shree - Tamil + TAM_TBOOMIS, // 67 TBoomis - Tamil + TAM_TMNEWS, // 68 TMNews - Tamil + TAM_WEBTAMIL, // 69 Webtamil - Tamil + KDDI_SHIFT_JIS, // 70 KDDI Shift_JIS + DOCOMO_SHIFT_JIS, // 71 DoCoMo Shift_JIS + SOFTBANK_SHIFT_JIS, // 72 SoftBank Shift_JIS + KDDI_ISO_2022_JP, // 73 KDDI ISO-2022-JP + SOFTBANK_ISO_2022_JP, // 74 SOFTBANK ISO-2022-JP +}; + +COMPILE_ASSERT(arraysize(kMapEncToBaseEncoding) == NUM_ENCODINGS, + kMapEncToBaseEncoding_has_incorrect_size); + +// Maps base encodings to 0, supersets to 1+, undesired to -1 +// (Non-identity mappings are marked "-->" below.) +static const int kMapEncToSuperLevel[] = { + 0, // 0: Teragram ASCII + 0, // 1: Teragram Latin2 + 0, // 2: in BasisTech but not in Teragram + 0, // 3: Teragram Latin4 + 0, // 4: Teragram ISO-8859-5 + 0, // 5: Teragram Arabic + 0, // 6: Teragram Greek + 0, // 7: Teragram Hebrew + 0, // 8: in BasisTech but not in Teragram + 0, // 9: in BasisTech but not in Teragram + 0, // 10: Teragram EUC_JP + 0, // 11: Teragram SJS + 0, // 12: Teragram JIS + 0, // 13: Teragram BIG5 + 0, // 14: Teragram GB + 0, // 15: Teragram EUC-CN + 0, // 16: Teragram KSC + 0, // 17: Teragram Unicode + -1, // 18: Teragram EUC --> 15 + -1, // 19: Teragram CNS --> 15 + 1, // 20: Teragram BIG5_CP950 --> 13 + 1, // 21: Teragram CP932 --> 11 + 0, // 22 + -1, // 23 + -1, // 24: ISO_8859_1 with all characters <= 127 --> 0 + 0, // 25: Teragram KOI8R + 0, // 26: Teragram CP1251 + 1, // 27: CP1252 aka MSFT euro ascii --> 0 + 0, // 28: CP21866 aka KOI8_RU, used for Ukrainian + 0, // 29: CP1250 aka MSFT eastern european + 1, // 30: aka ISO_8859_0 aka ISO_8859_1 euroized --> 0 + 0, // 31: used for Turkish + 1, // 32: used in Baltic countries --> 43 + 0, // 33: aka TIS-620, used for Thai + 1, // 34: used for Thai --> 33 + 0, // 35: used for Arabic + 0, // 36: Logical Hebrew Microsoft + -1, // 37: Iso Hebrew Logical --> 36 + -1, // 38: Iso Hebrew Visual --> 7 + 0, // 39 + 1, // 40: aka ISO_IR_139 aka KOI8_CS --> 1 + 0, // 41: used for Greek, NOT superset of 8859-7 + 0, // 42 + 0, // 43 + 0, // 44 + 1, // 45 GBK --> 14 + 1, // 46 GB18030 --> 14 + 1, // 47 BIG5_HKSCS --> 13 + 1, // 48 ISO_2022_CN --> 44 + 0, // 49 Indic encoding + 0, // 50 Indic encoding - Tamil + 0, // 51 Indic encoding - Tamil + 0, // 52 Indic encoding - Devanagari + 0, // 53 + 0, // 54 + 0, // 55 Indic encoding - Devanagari + 0, // 56 Indic encoding - Devanagari + 0, // 57 + 0, // 58 + 0, // 59 + 0, // 60 + 0, // 61 + 0, // 62 + 2, // 63 + 0, 0, 0, 0, 0, 0, // add six more Tamil + 0, 0, 0, 0, 0, // add five encodings with emoji +}; + +COMPILE_ASSERT(arraysize(kMapEncToSuperLevel) == NUM_ENCODINGS, + kMapEncToSuperLevel_has_incorrect_size); + + + +// Subscripted by Encoding enum value +static const uint32 kSpecialMask[] = { + kHighAccentCode, // 0 + kHighAccentCode, + kHighAccentCode, + kHighAccentCode, + kHighAlphaCode, // 4 + kHighAlphaCode, + kHighAlphaCode, + kHighAlphaCode, + kHighAccentCode, + kHighAccentCode, + + kTwobyteCode + kEUCJPActive, // 10 euc-jp + kTwobyteCode, + kSevenBitActive + kIso2022Active, // jis + kTwobyteCode, + kTwobyteCode, + kTwobyteCode, + kTwobyteCode, + kSevenBitActive + kUTF1632Active, // Unicode + kTwobyteCode, + kTwobyteCode, + + kTwobyteCode, // 20 + kTwobyteCode, + kUTF8Active, // UTF-8 + 0, + 0, + kHighAlphaCode, // 25 + kHighAlphaCode, + kHighAccentCode, + kHighAlphaCode, + kHighAccentCode, + + kHighAccentCode, // 30 + kHighAccentCode, + kHighAccentCode, + kHighAlphaCode, + kHighAlphaCode, + kHighAlphaCode, // 35 + kHighAlphaCode, + kHighAlphaCode, + kHighAlphaCode, + 0, + + 0, // 40 + kHighAlphaCode, + kHighAlphaCode, + kHighAccentCode, + kSevenBitActive + kIso2022Active, // 2022-kr + kTwobyteCode, + kTwobyteCode, + kTwobyteCode, + kSevenBitActive + kIso2022Active, // 2022-cn + kHighAlphaCode + kIsIndicCode, // 49 TSCII + + kHighAlphaCode + kIsIndicCode, // 50 TAMIL_MONO + kHighAlphaCode + kIsIndicCode, // 51 TAMIL_BI + kHighAlphaCode + kIsIndicCode, // 52 JAGRAN + kHighAccentCode, // 53 MACINTOSH_ROMAN + kSevenBitActive + kUTF7Active, // 54 UTF-7 + kHighAlphaCode + kIsIndicCode, // 55 BHASKAR Indic encoding - Devanagari + kHighAlphaCode + kIsIndicCode, // 56 HTCHANAKYA Indic encoding - Devanagari + kSevenBitActive + kUTF1632Active, // 57 UTF16BE + kSevenBitActive + kUTF1632Active, // 58 UTF16LE + kSevenBitActive + kUTF1632Active, // 59 UTF32BE + kSevenBitActive + kUTF1632Active, // 60 UTF32LE + + kSevenBitActive + kBinaryActive, // 61 BINARYENC + kSevenBitActive + kHzActive, // 62 HZ_GB_2312 + kHighAccentCode + kUTF8Active + kUTF8UTF8Active, // 63 UTF8UTF8 + kHighAlphaCode + kIsIndicCode, // 64 Elango - Tamil + kHighAlphaCode + kIsIndicCode, // 65 Barani - Tamil + kHighAlphaCode + kIsIndicCode, // 66 Shree - Tamil + kHighAlphaCode + kIsIndicCode, // 67 TBoomis - Tamil + kHighAlphaCode + kIsIndicCode, // 68 TMNews - Tamil + kHighAlphaCode + kIsIndicCode, // 69 Webtamil - Tamil + kTwobyteCode, // 70 KDDI Shift_JIS + kTwobyteCode, // 71 DoCoMo Shift_JIS + kTwobyteCode, // 72 SoftBank Shift_JIS + kSevenBitActive + kIso2022Active, // 73 KDDI-ISO-2022-JP + kSevenBitActive + kIso2022Active, // 74 SOFTBANK-ISO-2022-JP +}; + +COMPILE_ASSERT(arraysize(kSpecialMask) == NUM_ENCODINGS, + kSpecialMask_has_incorrect_size); + + +/*** + kHighAlphaCode -- full alphabet in 8x-Fx range, not just accents + + ISO_8859_5, // 4: Teragram ISO-8859-5 Cyrl UL bd + RUSSIAN_CP1251, // 26: Teragram CP1251 UL cdef + RUSSIAN_KOI8_R, // 25: Teragram KOI8R LU cdef + RUSSIAN_KOI8_RU, // 28: CP21866 aka KOI8_RU, LU cdef + RUSSIAN_CP866, // 42 89ae + + ISO_8859_6, // 5: Teragram Arabic nocase cde + MSFT_CP1256, // 35: used for Arabic nocase cde + + ISO_8859_7, // 6: Teragram Greek UL cdef + MSFT_CP1253, // 41: used for Greek UL cdef + + ISO_8859_8, // 7: Teragram Hebrew nocase ef + MSFT_CP1255, // 36: Logical Hebrew Microsoft nocase ef + ISO_8859_8_I, // 37: Iso Hebrew Logical nocase ef + HEBREW_VISUAL, // 38: Iso Hebrew Visual nocase ef + + ISO_8859_11, // 33: aka TIS-620, used for Thai nocase abcde + MSFT_CP874, // 34: used for Thai nocase abcde + + TSCII, // 49 8-f + TAMIL_MONO, // 50 + TAMIL_BI, // 51 + JAGRAN, // 52 + BHASKAR, // 55 Indic encoding - Devanagari + HTCHANAKYA, // 56 Indic encoding - Devanagari +***/ + +// We can scan bytes using this at about 500 MB/sec 2.8GHz P4 +// Slow scan uses this, stopping on NUL ESC SO SI bad C0 and + ~ +// We allow FF, 0x0C, here because it gives a better result for old +// Ascii text formatted for a TTY +// non-zero exits scan loop -- 1 for printable ASCII, 2 otherwise +static const char kTestPrintableAsciiTildePlus[256] = { + 2,2,2,2,2,2,2,2, 2,0,0,2,0,0,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,2, + + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, +}; + +// We can scan bytes using this at about 550 MB/sec 2.8GHz P4 +// Slow scan uses this, stopping on NUL ESC SO SI and bad C0 +// after Hz and UTF7 are pruned away +// We allow Form Feed, 0x0C, here +static const char kTestPrintableAscii[256] = { + 2,2,2,2,2,2,2,2, 2,0,0,2,0,0,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,2, + + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, +}; + +// Used in first-four-byte testing +static const char kIsPrintableAscii[256] = { + 0,0,0,0,0,0,0,0, 0,1,1,0,0,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,0, + + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +}; + + +static const signed char kBase64Value[256] = { + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,62,-1,-1,-1,63, + 52,53,54,55,56,57,58,59, 60,61,-1,-1,-1,-1,-1,-1, + + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, + 15,16,17,18,19,20,21,22, 23,24,25,-1,-1,-1,-1,-1, + -1,26,27,28,29,30,31,32, 33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48, 49,50,51,-1,-1,-1,-1,-1, + + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, +}; + + +// Subscripted by +// Accepts Cx->8x Dx->8x Ex->8x->8x Fx->8x->8x->8x +// +// Fixed Problem: GB has sequences like B2DB B8D6 BDE1 B9B9 +// which we can mis-parse as an error byte followed by good UTF-8: +// B2 DBB8 D6BD E1B9B9 +// To counteract this, we now require an ASCII7 byte to resync out +// of the error state +// Next problem: good UTF-8 with bad byte +// efbc a012 eea4 bee7 b280 c2b7 +// efbca0 12 eea4be e7b280 c2b7 +// ^^ bad byte +// fix: change state0 byte 1x to be don't-care +// +// Short UTF-8 ending in ASCII7 byte should resync immediately: +// E0 20 E0 A6 AA should give one error and resync at 2nd E0 +// +static const char kMiniUTF8State[8][16] = { + {0,0,0,0,0,0,0,0, 7,7,7,7,1,1,2,4,}, // [0] start char (allow cr/lf/ht) + {0,7,0,0,0,0,0,0, 0,0,0,0,7,7,7,7,}, // [1] continue 1 of 2 + {0,7,0,0,0,0,0,0, 3,3,3,3,7,7,7,7,}, // [2] continue 1 of 3 + {0,7,0,0,0,0,0,0, 0,0,0,0,7,7,7,7,}, // [3] continue 2 of 3 + {0,7,0,0,0,0,0,0, 5,5,5,5,7,7,7,7,}, // [4] continue 1 of 4 + {0,7,0,0,0,0,0,0, 6,6,6,6,7,7,7,7,}, // [5] continue 2 of 4 + {0,7,0,0,0,0,0,0, 0,0,0,0,7,7,7,7,}, // [6] continue 3 of 4 + {0,7,0,0,0,0,0,0, 7,7,7,7,7,7,7,7,}, // [7] error, soak up continues, + // ONLY resync after Ascii char + // then restart +}; +// Counter to increment: 0-don'tcare 1-error 2-good_2B 3-good_3B 4-good_4B +static const char kMiniUTF8Count[8][16] = { + {0,0,0,0,0,0,0,0, 1,1,1,1,0,0,0,0,}, // [0] start char (allow cr/lf/ht) + {1,1,1,1,1,1,1,1, 2,2,2,2,1,1,1,1,}, // [1] continue 1 of 2 + {1,1,1,1,1,1,1,1, 0,0,0,0,1,1,1,1,}, // [2] continue 1 of 3 + {1,1,1,1,1,1,1,1, 3,3,3,3,1,1,1,1,}, // [3] continue 2 of 3 + {1,1,1,1,1,1,1,1, 0,0,0,0,1,1,1,1,}, // [4] continue 1 of 4 + {1,1,1,1,1,1,1,1, 0,0,0,0,1,1,1,1,}, // [5] continue 2 of 4 + {1,1,1,1,1,1,1,1, 4,4,4,4,1,1,1,1,}, // [6] continue 3 of 4 + {0,1,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,}, // [7] error, soak up continues, + // then restart +}; + +// Subscripted by +// where f(x)= E2->4, Cx->8 and C3->12 and 0 otherwise +// and g(x) = (x >> 4) & 3 8x->0 9x->1 Ax->2 Bx->3 Cx->0, etc. +// (no checking for illegal bytes) +// Here are example patterns of CP1252 converted to UTF-8 0/1/2 times. We want +// to detect two, so we can back-convert to one. +// zero one two pattern +// ---- ------ ---------------- ----------------- +// 81 C281 C382C281 C3->8x->C2->xx +// 98 CB9C C38BC593 C3->8x->C5->xx +// C3 C383 C383C692 C3->8x->C6->xx +// C8 C388 C383CB86 C3->8x->CB->xx +// 83 C692 C386E28099 C3->8x->E2->xx->8x +// 80 E282AC C3A2E2809AC2AC C3->A2->E2->xx->xx->Cx->xx +// 92 E28099 C3A2E282ACE284A2 C3->A2->E2->xx->xx->E2->xx->xx +// +// We also want to detect bare-byte extra UTF-8 conversions: +// zero one two pattern +// ---- ------ ---------------- ----------------- +// C3 C3 C383 C3->8x->C2->xx +// D3 D3 C393 C3->9x->C2->xx->C2->xx +// E3 E3 C3A3 C3->Ax->C2->xx->C2->xx->C2->xx +// F3 F3 C3B2 C3->Bx->C2->xx->C2->xx->C2->xx->C2->xx +// + +/** +CP1252 => UTF8 => UTF8UTF8 +80 => E282AC => C3A2E2809AC2AC +81 => C281 => C382C281 +82 => E2809A => C3A2E282ACC5A1 +83 => C692 => C386E28099 +84 => E2809E => C3A2E282ACC5BE +85 => E280A6 => C3A2E282ACC2A6 +86 => E280A0 => C3A2E282ACC2A0 +87 => E280A1 => C3A2E282ACC2A1 +88 => CB86 => C38BE280A0 +89 => E280B0 => C3A2E282ACC2B0 +8A => C5A0 => C385C2A0 +8B => E280B9 => C3A2E282ACC2B9 +8C => C592 => C385E28099 +8D => C28D => C382C28D +8E => C5BD => C385C2BD +8F => C28F => C382C28F +90 => C290 => C382C290 +91 => E28098 => C3A2E282ACCB9C +92 => E28099 => C3A2E282ACE284A2 +93 => E2809C => C3A2E282ACC593 +94 => E2809D => C3A2E282ACC29D +95 => E280A2 => C3A2E282ACC2A2 +96 => E28093 => C3A2E282ACE2809C +97 => E28094 => C3A2E282ACE2809D +98 => CB9C => C38BC593 +99 => E284A2 => C3A2E2809EC2A2 +9A => C5A1 => C385C2A1 +9B => E280BA => C3A2E282ACC2BA +9C => C593 => C385E2809C +9D => C29D => C382C29D +9E => C5BE => C385C2BE +9F => C5B8 => C385C2B8 +A0 => C2A0 => C382C2A0 +A1 => C2A1 => C382C2A1 +A2 => C2A2 => C382C2A2 +A3 => C2A3 => C382C2A3 +A4 => C2A4 => C382C2A4 +A5 => C2A5 => C382C2A5 +A6 => C2A6 => C382C2A6 +A7 => C2A7 => C382C2A7 +A8 => C2A8 => C382C2A8 +A9 => C2A9 => C382C2A9 +AA => C2AA => C382C2AA +AB => C2AB => C382C2AB +AC => C2AC => C382C2AC +AD => C2AD => C382C2AD +AE => C2AE => C382C2AE +AF => C2AF => C382C2AF +B0 => C2B0 => C382C2B0 +B1 => C2B1 => C382C2B1 +B2 => C2B2 => C382C2B2 +B3 => C2B3 => C382C2B3 +B4 => C2B4 => C382C2B4 +B5 => C2B5 => C382C2B5 +B6 => C2B6 => C382C2B6 +B7 => C2B7 => C382C2B7 +B8 => C2B8 => C382C2B8 +B9 => C2B9 => C382C2B9 +BA => C2BA => C382C2BA +BB => C2BB => C382C2BB +BC => C2BC => C382C2BC +BD => C2BD => C382C2BD +BE => C2BE => C382C2BE +BF => C2BF => C382C2BF +C0 => C380 => C383E282AC +C1 => C381 => C383C281 +C2 => C382 => C383E2809A +C3 => C383 => C383C692 +C4 => C384 => C383E2809E +C5 => C385 => C383E280A6 +C6 => C386 => C383E280A0 +C7 => C387 => C383E280A1 +C8 => C388 => C383CB86 +C9 => C389 => C383E280B0 +CA => C38A => C383C5A0 +CB => C38B => C383E280B9 +CC => C38C => C383C592 +CD => C38D => C383C28D +CE => C38E => C383C5BD +CF => C38F => C383C28F +D0 => C390 => C383C290 +D1 => C391 => C383E28098 +D2 => C392 => C383E28099 +D3 => C393 => C383E2809C +D4 => C394 => C383E2809D +D5 => C395 => C383E280A2 +D6 => C396 => C383E28093 +D7 => C397 => C383E28094 +D8 => C398 => C383CB9C +D9 => C399 => C383E284A2 +DA => C39A => C383C5A1 +DB => C39B => C383E280BA +DC => C39C => C383C593 +DD => C39D => C383C29D +DE => C39E => C383C5BE +DF => C39F => C383C5B8 +E0 => C3A0 => C383C2A0 +E1 => C3A1 => C383C2A1 +E2 => C3A2 => C383C2A2 +E3 => C3A3 => C383C2A3 +E4 => C3A4 => C383C2A4 +E5 => C3A5 => C383C2A5 +E6 => C3A6 => C383C2A6 +E7 => C3A7 => C383C2A7 +E8 => C3A8 => C383C2A8 +E9 => C3A9 => C383C2A9 +EA => C3AA => C383C2AA +EB => C3AB => C383C2AB +EC => C3AC => C383C2AC +ED => C3AD => C383C2AD +EE => C3AE => C383C2AE +EF => C3AF => C383C2AF +F0 => C3B0 => C383C2B0 +F1 => C3B1 => C383C2B1 +F2 => C3B2 => C383C2B2 +F3 => C3B3 => C383C2B3 +F4 => C3B4 => C383C2B4 +F5 => C3B5 => C383C2B5 +F6 => C3B6 => C383C2B6 +F7 => C3B7 => C383C2B7 +F8 => C3B8 => C383C2B8 +F9 => C3B9 => C383C2B9 +FA => C3BA => C383C2BA +FB => C3BB => C383C2BB +FC => C3BC => C383C2BC +FD => C3BD => C383C2BD +FE => C3BE => C383C2BE +FF => C3BF => C383C2BF +**/ + +// Subscripted by +// where f(x)= E2->4, C2/5/6/B->8 and C3->12 and 0 otherwise +// and g(x) = (x >> 4) & 3 8x->0 9x->1 Ax->2 Bx->3 Cx->0, etc. + +// 81 C281 C382C281 C3->8x->C2->xx +// 98 CB9C C38BC593 C3->8x->C5->xx +// C3 C383 C383C692 C3->8x->C6->xx +// C8 C388 C383CB86 C3->8x->CB->xx +// [0] [2] [0] +// 83 C692 C386E28099 C3->8x->E2->xx->xx +// odd_byte=0 [0] [2] [0+] odd_byte flipped +// odd_byte=1 [0+] [2] [0] [0] odd_byte unflipped +// 80 E282AC C3A2E2809AC2AC C3->A2->E2->xx->xx->Cx->xx +// odd_byte=0 [0] [3] [4] [0+] +// odd_byte=1 [0+] [3] [4] [4] [0] +// 92 E28099 C3A2E282ACE284A2 C3->A2->E2->xx->xx->E2->xx->xx +// odd_byte=0 [0] [3] [4] [0] [0] +// odd_byte=1 [0+] [3] [4] [4] [0+] +// +// When an E2xxxx sequence is encountered, we absorb the two bytes E2xx and flip +// the odd_byte state. If that goes from 0 to 1, the next pair is offset up +// by one byte, picking up the two bytes just after E2xxxx. If odd_byte goes +// from 1 to 0, the next two bytes picked up are the two bytes xxxx of E2xxxx. +// These are absorbed with no error in state 0 or state 4 +// +// C3 C3 C383 C3->8x->C2->xx +// D3 D3 C393 C3->9x->C2->xx->C2->xx +// E3 E3 C3A3 C3->Ax->C2->xx->C2->xx->C2->xx +// F3 F3 C3B2 C3->Bx->C2->xx->C2->xx->C2->xx->C2->xx +// Counter3 for Fx Ex sequences is incremented at last C2 + +static const char kMiniUTF8UTF8State[8][16] = { + // xxxx E2xx CXxx C3xx + // 8 9 a b 8 9 a b 8 9 a b + {0,0,0,0,1,1,1,1, 1,1,1,1,2,2,3,5,}, // [0] looking for C38x/C3Ax/2020/8x8x, or err + {0,0,0,0,1,1,1,1, 1,1,1,1,2,2,3,5,}, // [1] error, back to looking + {1,1,1,1,0,0,0,0, 0,0,0,0,1,1,1,1,}, // [2] C38x looking for CXxx/E2xxxx + // + + + + // E2xxxx flips odd_byte + {1,1,1,1,4,4,4,4, 7,7,7,7,1,1,1,1,}, // [3] C3Ax looking for E2xx or C2xxC2xx + // + + + + // E2xxxx flips odd_byte + {4,4,4,4,0,0,0,0, 0,0,0,0,1,1,1,1,}, // [4] C3AxE2xx-- looking for C2xx/E2xxxx + // + + + + // E2xxxx flips odd_byte + {1,1,1,1,1,1,1,1, 6,6,6,6,1,1,1,1,}, // [5] C3Bx -- looking for C2xxC2xxC2xx + {1,1,1,1,1,1,1,1, 7,7,7,7,1,1,1,1,}, // [6] C3Bx -- looking for C2xxC2xx + {1,1,1,1,1,1,1,1, 0,0,0,0,1,1,1,1,}, // [7] C3Bx -- looking for C2xx +}; +// Counter to increment: 0-don'tcare 1-error 2-good_2B 3-good_3B 4-good_4B +static const char kMiniUTF8UTF8Count[8][16] = { + // xxxx E2xx C2Xx C3xx + // 8 9 a b 8 9 a b 8 9 a b + {0,0,0,0,1,1,1,1, 1,1,1,1,0,0,0,0,}, // [0] looking for C38x/C3Ax/2020/8x8x, or err + {0,0,0,0,1,1,1,1, 1,1,1,1,0,0,0,0,}, // [1] error, back to looking + {1,1,1,1,3,3,3,3, 2,2,2,2,1,1,1,1,}, // [2] C38x looking for CXxx/E2xxxx + // + + + + // E2xxxx flips odd_byte + {1,1,1,1,0,0,0,0, 0,0,0,0,1,1,1,1,}, // [3] C3Ax looking for E2xx + // + + + + // E2xxxx flips odd_byte + {1,1,1,1,4,4,4,4, 4,4,4,4,1,1,1,1,}, // [4] C3AxE2xx-- looking for C2xx/E2xxxx + // + + + + // E2xxxx flips odd_byte + {1,1,1,1,1,1,1,1, 0,0,0,0,1,1,1,1,}, // [5] C3Bx -- looking for C2xxC2xxC2xx + {1,1,1,1,1,1,1,1, 0,0,0,0,1,1,1,1,}, // [6] C3Bx -- looking for C2xxC2xx + {1,1,1,1,1,1,1,1, 3,3,3,3,1,1,1,1,}, // [7] C3Bx -- looking for C2xx +}; + +static const char kMiniUTF8UTF8Odd[8][16] = { + // xxxx E2xx C2Xx C3xx + // 8 9 a b 8 9 a b 8 9 a b + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,}, // [0] looking for C38x/C3Ax/2020/8x8x, or err + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,}, // [1] error, back to looking + {0,0,0,0,1,1,1,1, 0,0,0,0,0,0,0,0,}, // [2] C38x looking for CXxx/E2xxxx + // + + + + // E2xxxx flips odd_byte + {0,0,0,0,1,1,1,1, 0,0,0,0,0,0,0,0,}, // [3] C3Ax looking for E2xx + // + + + + // E2xxxx flips odd_byte + {0,0,0,0,1,1,1,1, 0,0,0,0,0,0,0,0,}, // [4] C3AxE2xx-- looking for C2xx/E2xxxx + // + + + + // E2xxxx flips odd_byte + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,}, // [5] C3Bx -- looking for C2xxC2xxC2xx + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,}, // [6] C3Bx -- looking for C2xxC2xx + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,}, // [7] C3Bx -- looking for C2xx +}; + +// Turn a pair of bytes into the subscript for UTF8UTF8 tables above +int UTF88Sub(char s0, char s1) { + int sub = (s1 >> 4) & 0x03; + uint8 u0 = static_cast(s0); + if (u0 == 0xc3) { + sub += 12; + } else if ((u0 & 0xf0) == 0xc0) { + if ((u0 == 0xc2) || (u0 == 0xc5) || (u0 == 0xc6) || (u0 == 0xcb)) { + sub += 8; + } + } else if (u0 == 0xe2) { + sub += 4; + } + return sub; +} + + + + + +// Default probability for an encoding rankedencoding +// Based on a scan of 55M web pages +// These values are 255 - log base 2**1/10 (occurrences / total) +// Large values are most likely. This the reverse of some Google code +// 255 = 1.0, 245 = 1/2, 235 = 1/4, 15 = 1/2**24, 0 = 0 (< 1/50M) +// +// TODO change this to be per encoding, not permuted +// + + +// Support function for unit test program +// Return ranked encoding corresponding to enc +// (also exported to compact_enc_det_text.cc) +int CompactEncDet::BackmapEncodingToRankedEncoding(Encoding enc) { + for (int i = 0; i < NUM_RANKEDENCODING; ++i) { + if (kMapToEncoding[i] == enc) { + return i; + } + } + return -1; +} + + +string DecodeActive(uint32 active) { + string temp(""); + if (active & kBinaryActive) { + temp.append("Binary "); + } + if (active & kUTF1632Active) { + temp.append("UTF1632 "); + } + if (active & kUTF8UTF8Active) { + temp.append("UTF8UTF8 "); + } + if (active & kUTF8Active) { + temp.append("UTF8 "); + } + if (active & kIso2022Active) { + temp.append("Iso2022 "); + } + if (active & kHzActive) { + temp.append("Hz "); + } + if (active & kUTF7Active) { + temp.append("UTF7A "); + } + if (active & kSevenBitActive) { + temp.append("SevenBit "); + } + if (active & kIsIndicCode) { + temp.append("Indic "); + } + if (active & kHighAlphaCode) { + temp.append("HighAlpha "); + } + if (active & kHighAccentCode) { + temp.append("HighAccent "); + } + if (active & kEUCJPActive) { + temp.append("EUCJP "); + } + return temp; +} + +static inline bool SevenBitEncoding(int enc) { + return ((kSpecialMask[enc] & kSevenBitActive) != 0); +} +static inline bool TwoByteEncoding(int enc) { + return ((kSpecialMask[enc] & kTwobyteCode) != 0); +} +static inline bool IndicEncoding(int enc) { + return ((kSpecialMask[enc] & kIsIndicCode) != 0); +} +static inline bool HighAlphaEncoding(int enc) { + return ((kSpecialMask[enc] & kHighAlphaCode) != 0); +} +static inline bool HighAccentEncoding(int enc) { + return ((kSpecialMask[enc] & kHighAccentCode) != 0); +} + + +static inline bool AnyActive(DetectEncodingState* destatep) { + return (destatep->active_special != 0); +} +static inline bool SevenBitActive(DetectEncodingState* destatep) { + return (destatep->active_special & kSevenBitActive) != 0; +} +static inline bool HzActive(DetectEncodingState* destatep) { + return (destatep->active_special & kHzActive) != 0; +} +static inline bool Iso2022Active(DetectEncodingState* destatep) { + return (destatep->active_special & kIso2022Active) != 0; +} +static inline bool UTF8Active(DetectEncodingState* destatep) { + return (destatep->active_special & kUTF8Active) != 0; +} +static inline bool UTF8UTF8Active(DetectEncodingState* destatep) { + return (destatep->active_special & kUTF8UTF8Active) != 0; +} +static inline bool UTF1632Active(DetectEncodingState* destatep) { + return (destatep->active_special & kUTF1632Active) != 0; +} +static inline bool BinaryActive(DetectEncodingState* destatep) { + return (destatep->active_special & kBinaryActive) != 0; +} +static inline bool UTF7OrHzActive(DetectEncodingState* destatep) { + return (destatep->active_special & (kHzActive + kUTF7Active)) != 0; +} +static inline bool EUCJPActive(DetectEncodingState* destatep) { + return ((destatep->active_special & kEUCJPActive) != 0); +} +static inline bool OtherActive(DetectEncodingState* destatep) { + return (destatep->active_special & (kIso2022Active + kBinaryActive + + kUTF8Active + kUTF8UTF8Active + + kUTF1632Active + kEUCJPActive)) != 0; +} + + +static inline bool CEDFlagRescanning(CEDInternalFlags flags) { + return (flags & kCEDRescanning) != 0; +} + +static inline bool CEDFlagForceTags(CEDInternalFlags flags) { + return (flags & kCEDForceTags) != 0; +} + + +static inline int maxint(int a, int b) {return (a > b) ? a : b;} +static inline int minint(int a, int b) {return (a < b) ? a : b;} + +static inline const char* MyRankedEncName(int r_enc) { + return MyEncodingName(kMapToEncoding[r_enc]); +} + + +// Only for debugging. not thread safe +static const int kPsSourceWidth = 32; +static int pssourcenext = 0; // debug only. not threadsafe. dump only >= this +static int pssourcewidth = 0; // debug only. +static char* pssource_mark_buffer = NULL; +int next_do_src_line; +int do_src_offset[16]; + + +void PsSourceInit(int len) { + pssourcenext = 0; + pssourcewidth = len; + delete[] pssource_mark_buffer; + // Allocate 2 Ascii characters per input byte + pssource_mark_buffer = new char[(pssourcewidth * 2) + 8]; // 8 = overscan + memset(pssource_mark_buffer, ' ', pssourcewidth * 2); + memset(pssource_mark_buffer + (pssourcewidth * 2), '\0', 8); + + next_do_src_line = 0; + memset(do_src_offset, 0, sizeof(do_src_offset)); +} + +void PsSourceFinish() { + // Print preceding mark buffer + int j = (pssourcewidth * 2) - 1; + while ((0 <= j) && (pssource_mark_buffer[j] == ' ')) {--j;} // trim + pssource_mark_buffer[j + 1] = '\0'; + fprintf(stderr, "( %s) do-src\n", pssource_mark_buffer); + memset(pssource_mark_buffer, ' ', pssourcewidth * 2); + memset(pssource_mark_buffer + (pssourcewidth * 2), '\0', 8); + + delete[] pssource_mark_buffer; + pssource_mark_buffer = NULL; +} + +// Dump aligned len bytes src... if not already dumped +void PsSource(const uint8* src, const uint8* isrc, const uint8* srclimit) { + int offset = src - isrc; + offset -= (offset % pssourcewidth); // round down to multiple of len bytes + if (offset < pssourcenext) { + return; + } + pssourcenext = offset + pssourcewidth; // Min offset for next dump + + // Print preceding mark buffer + int j = (pssourcewidth * 2) - 1; + while ((0 <= j) && (pssource_mark_buffer[j] == ' ')) {--j;} // trim + pssource_mark_buffer[j + 1] = '\0'; + fprintf(stderr, "( %s) do-src\n", pssource_mark_buffer); + memset(pssource_mark_buffer, ' ', pssourcewidth * 2); + memset(pssource_mark_buffer + (pssourcewidth * 2), '\0', 8); + + // Print source bytes + const uint8* src_aligned = isrc + offset; + int length = srclimit - src_aligned; + length = minint(pssourcewidth, length); + + fprintf(stderr, "(%05x ", offset); + for (int i = 0; i < length; ++i) { + char c = src_aligned[i]; + if (c == '\n') {c = ' ';} + if (c == '\r') {c = ' ';} + if (c == '\t') {c = ' ';} + if (c == '(') { + fprintf(stderr, "%s", "\\( "); + } else if (c == ')') { + fprintf(stderr, "%s", "\\) "); + } else if (c == '\\') { + fprintf(stderr, "%s", "\\\\ "); + } else if ((0x20 <= c) && (c <= 0x7e)) { + fprintf(stderr, "%c ", c); + } else { + fprintf(stderr, "%02x", c); + } + } + fprintf(stderr, ") do-src\n"); + // Remember which source offsets are where, mod 16 + do_src_offset[next_do_src_line & 0x0f] = offset; + ++next_do_src_line; +} + +// Mark bytes in just-previous source bytes +void PsMark(const uint8* src, int len, const uint8* isrc, int weightshift) { + int offset = src - isrc; + offset = (offset % pssourcewidth); // mod len bytes + char mark = (weightshift == 0) ? '-' : 'x'; + + pssource_mark_buffer[(offset * 2)] = '='; + pssource_mark_buffer[(offset * 2) + 1] = '='; + for (int i = 1; i < len; ++i) { + pssource_mark_buffer[(offset + i) * 2] = mark; + pssource_mark_buffer[((offset + i) * 2) + 1] = mark; + } +} + + +// Highlight trigram bytes in just-previous source bytes +// Unfortunately, we have to skip back N lines since source was printed for +// up to 8 bigrams before we get here. Match on src+1 to handle 0/31 better +void PsHighlight(const uint8* src, const uint8* isrc, int trigram_val, int n) { + int offset = (src + 1) - isrc; + int offset32 = (offset % pssourcewidth); // mod len bytes + offset -= offset32; // round down to multiple of len bytes + + for (int i = 1; i <= 16; ++i) { + if (do_src_offset[(next_do_src_line - i) & 0x0f] == offset) { + fprintf(stderr, "%d %d %d do-highlight%d\n", + i, offset32 - 1, trigram_val, n); + break; + } + } +} + + +void InitDetectEncodingState(DetectEncodingState* destatep) { + destatep->initial_src = NULL; // Filled in by caller + destatep->limit_src = NULL; + destatep->prior_src = NULL; + destatep->last_pair = NULL; + + destatep->debug_data = NULL; + destatep->next_detail_entry = 0; + + destatep->done = false; + destatep->reliable = false; + destatep->hints_derated = false; + //destatep->declared_enc_1 init in ApplyHints + //destatep->declared_enc_2 init in ApplyHints + destatep->prune_count = 0; + + destatep->trigram_highwater_mark = 0; + destatep->looking_for_latin_trigrams = false; + destatep->do_latin_trigrams = false; + + // Miscellaneous state variables for difficult encodings + destatep->binary_quadrants_count = 0; + destatep->binary_8x4_count = 0; + destatep->binary_quadrants_seen = 0; + destatep->binary_8x4_seen = 0; + destatep->utf7_starts = 0; + destatep->prior_utf7_offset = 0; + destatep->next_utf8_ministate = 0; + for (int i = 0; i < 6; i++) {destatep->utf8_minicount[i] = 0;} + destatep->next_utf8utf8_ministate = 0; + destatep->utf8utf8_odd_byte = 0; + for (int i = 0; i < 6; i++) {destatep->utf8utf8_minicount[i] = 0;} + destatep->next_2022_state = SOSI_NONE; + destatep->next_hz_state = SOSI_NONE; + destatep->next_eucjp_oddphase = false; + for (int i = 0; i < 8; i++) {destatep->byte32_count[i] = 0;} + destatep->active_special = 0xffffffff; + destatep->tld_hint = UNKNOWN_ENCODING; + destatep->http_hint = UNKNOWN_ENCODING; + destatep->meta_hint = UNKNOWN_ENCODING; + destatep->bom_hint = UNKNOWN_ENCODING; + destatep->top_rankedencoding = 0; // ASCII [seven-bit] is the default + destatep->second_top_rankedencoding = 0; // ASCII [seven-bit] is the default + destatep->top_prob = -1; + destatep->second_top_prob = -1; + // This is wide for first pruning, shrinks for 2nd and later + destatep->prune_difference = kInititalPruneDifference; + + destatep->next_prior_bigram = 0; + destatep->prior_bigram[0] = -1; + destatep->prior_bigram[1] = -1; + destatep->prior_bigram[2] = -1; + destatep->prior_bigram[3] = -1; + + destatep->prior_binary[0] = -1; + + // Initialize with all but Indic encodings, which we never detect + int k = 0; + for (int rankedencoding = 0; + rankedencoding < NUM_RANKEDENCODING; + rankedencoding++) { + Encoding enc = kMapToEncoding[rankedencoding]; + if (!IndicEncoding(enc)) { + destatep->rankedencoding_list[k++] = rankedencoding; + } + } + destatep->rankedencoding_list_len = k; + + // This is where all the action is + memset(destatep->enc_prob, 0, sizeof(destatep->enc_prob)); + + memset(destatep->hint_prob, 0, sizeof(destatep->hint_prob)); + memset(destatep->hint_weight, 0, sizeof(destatep->hint_weight)); + + destatep->prior_interesting_pair[AsciiPair] = 0; + destatep->prior_interesting_pair[OtherPair] = 0; + destatep->next_interesting_pair[AsciiPair] = 0; + destatep->next_interesting_pair[OtherPair] = 0; + // interesting_pairs/offsets/weightshifts not initialized; no need +} + +// Probability strings are uint8, with zeros removed via simple run-length: +// ( )* +// skip-take: +// 00 end +// x0 skip 16 x locations, take 0 data values +// xy skip x locations, take y data values +// Multiply all the incoming values by 3 to account for 3x unigram sums +// +// {{0x77,0x69,0x6e,0x64,0x31,0x32,0x35,0x35, +// 0x01,0xc2,0x10,0x41,0xfe,0x71,0xba,0x00,}}, // "wind1255" +// +// Weight is 0..100 percent +// +// Returns subscript of largest (most probable) value +// + + +// {{0x6e,0x6c,0x5f,0x5f, 0x05,0xb2,0xae,0xa0,0x32,0xa1,0x36,0x31,0x42,0x39,0x3b,0x33,0x45,0x11,0x6f,0x00,}}, // "nl__" +// // ASCII-7-bit=178 Latin1=174 UTF8=160 GB=50 CP1252=161 BIG5=49 Latin2=66 CP1251=57 CP1256=59 CP1250=51 Latin5=69 ISO-8859-15=111 [top ASCII-7-bit] +int ApplyCompressedProb(const char* iprob, int len, + int weight, DetectEncodingState* destatep) { + int* dst = &destatep->enc_prob[0]; + int* dst2 = &destatep->hint_weight[0]; + const uint8* prob = reinterpret_cast(iprob); + const uint8* problimit = prob + len; + + int largest = -1; + int subscript_of_largest = 0; + + // Continue with first byte and subsequent ones + while (prob < problimit) { + int skiptake = *prob++; + int skip = (skiptake & 0xf0) >> 4; + int take = skiptake & 0x0f; + if (skiptake == 00) { + break; + } else if (take == 0) { + dst += (skip << 4); + dst2 += (skip << 4); + } else { + dst += skip; // Normal case + dst2 += skip; // Normal case + for (int i = 0; i < take; i++) { + int enc = static_cast(dst - &destatep->enc_prob[0]) + i; + if (largest < prob[i]) { + largest = prob[i]; + subscript_of_largest = enc; + } + + int increment = prob[i] * 3; // The actual increment + + // Do maximum of previous hints plus this new one + if (weight > 0) { + increment = (increment * weight) / 100; + dst[i] = maxint(dst[i], increment); + dst2[i] = 1; // New total weight + } + } + prob += take; + dst += take; + dst2 += take; + } + } + return subscript_of_largest; +} + + +// Returns subscript of largest (most probable) value [for unit test] +int TopCompressedProb(const char* iprob, int len) { + const uint8* prob = reinterpret_cast(iprob); + const uint8* problimit = prob + len; + int next_prob_sub = 0; + int topprob = 0; + int toprankenc = 0; + + while (prob < problimit) { + int skiptake = *prob++; + int skip = (skiptake & 0xf0) >> 4; + int take = skiptake & 0x0f; + if (skiptake == 0) { + break; + } else if (take == 0) { + next_prob_sub += (skip << 4); + } else { + next_prob_sub += skip; // Normal case + for (int i = 0; i < take; i++) { + if (topprob < prob[i]) { + topprob = prob[i]; + toprankenc = next_prob_sub + i; + } + } + prob += take; + next_prob_sub += take; + } + } + return toprankenc; +} + + +// Find subscript of matching key in first 8 bytes of sorted hint array, or -1 +int HintBinaryLookup8(const HintEntry* hintprobs, int hintprobssize, + const char* norm_key) { + // Key is always in range [lo..hi) + int lo = 0; + int hi = hintprobssize; + while (lo < hi) { + int mid = (lo + hi) >> 1; + int comp = memcmp(&hintprobs[mid].key_prob[0], norm_key, 8); + if (comp < 0) { + lo = mid + 1; + } else if (comp > 0) { + hi = mid; + } else { + return mid; + } + } + return -1; +} + +// Find subscript of matching key in first 4 bytes of sorted hint array, or -1 +int HintBinaryLookup4(const HintEntry* hintprobs, int hintprobssize, + const char* norm_key) { + // Key is always in range [lo..hi) + int lo = 0; + int hi = hintprobssize; + while (lo < hi) { + int mid = (lo + hi) >> 1; + int comp = memcmp(&hintprobs[mid].key_prob[0], norm_key, 4); + if (comp < 0) { + lo = mid + 1; + } else if (comp > 0) { + hi = mid; + } else { + return mid; + } + } + return -1; +} + +static inline void Boost(DetectEncodingState* destatep, int r_enc, int boost) { + destatep->enc_prob[r_enc] += boost; +} + +static inline void Whack(DetectEncodingState* destatep, int r_enc, int whack) { + destatep->enc_prob[r_enc] -= whack; +} + +// Apply initial probability hint based on top level domain name +// Weight is 0..100 percent +// Return 1 if name match found +int ApplyTldHint(const char* url_tld_hint, int weight, + DetectEncodingState* destatep) { + if (url_tld_hint[0] == '~') { + return 0; + } + string normalized_tld = MakeChar4(string(url_tld_hint)); + int n = HintBinaryLookup4(kTLDHintProbs, kTLDHintProbsSize, + normalized_tld.c_str()); + if (n >= 0) { + // TLD is four bytes, probability table is ~12 bytes + int best_sub = ApplyCompressedProb(&kTLDHintProbs[n].key_prob[kMaxTldKey], + kMaxTldVector, weight, destatep); + // Never boost ASCII7; do CP1252 instead + if (best_sub == F_ASCII_7_bit) {best_sub = F_CP1252;} + destatep->declared_enc_1 = best_sub; + if (destatep->debug_data != NULL) { + // Show TLD hint + SetDetailsEncProb(destatep, 0, best_sub, url_tld_hint); + } + return 1; + } + return 0; +} + +// Apply initial probability hint based on charset= name +// Weight is 0..100 percent +// Return 1 if name match found +int ApplyCharsetHint(const char* charset_hint, int weight, + DetectEncodingState* destatep) { + if (charset_hint[0] == '~') { + return 0; + } + string normalized_charset = MakeChar44(string(charset_hint)); + int n = HintBinaryLookup8(kCharsetHintProbs, kCharsetHintProbsSize, + normalized_charset.c_str()); + if (n >= 0) { + // Charset is eight bytes, probability table is ~eight bytes + int best_sub = ApplyCompressedProb(&kCharsetHintProbs[n].key_prob[kMaxCharsetKey], + kMaxCharsetVector, weight, destatep); + // Never boost ASCII7; do CP1252 instead + if (best_sub == F_ASCII_7_bit) {best_sub = F_CP1252;} + destatep->declared_enc_1 = best_sub; + + // If first explicitly declared charset is confusable with Latin1/1252, put + // both declared forms in declared_enc_*, displacing Latin1/1252. + // This avoids a bit of Latin1 creep. + // Also boost the declared encoding and its pair + // TODO: This should all be folded into postproc-enc-detect.cc + if ((destatep->http_hint == UNKNOWN_ENCODING) && + (destatep->meta_hint == UNKNOWN_ENCODING)) { + // This is the first charset=hint + switch (best_sub) { + case F_Latin2: // 8859-2 Latin2, east euro + destatep->declared_enc_2 = F_CP1250; + Boost(destatep, F_Latin2, kGentleOnePair); + Boost(destatep, F_CP1250, kGentleOnePair); + break; + case F_CP1250: + destatep->declared_enc_2 = F_Latin2; + Boost(destatep, F_Latin2, kGentleOnePair); + Boost(destatep, F_CP1250, kGentleOnePair); + break; + + case F_Latin3: // 8859-3 Latin3, south euro, Esperanto + destatep->declared_enc_2 = F_ASCII_7_bit; + Boost(destatep, F_Latin3, kGentleOnePair); + break; + + case F_Latin4: // 8859-4 Latin4, north euro + destatep->declared_enc_2 = F_ASCII_7_bit; + Boost(destatep, F_Latin4, kGentleOnePair); + break; + + case F_ISO_8859_5: // 8859-5 Cyrillic + destatep->declared_enc_2 = F_ASCII_7_bit; // Don't boost 1251 + Boost(destatep, F_ISO_8859_5, kGentleOnePair); // (too different) + break; + case F_CP1251: + destatep->declared_enc_2 = F_ASCII_7_bit; // Don't boost -5 + Boost(destatep, F_CP1251, kGentleOnePair); // (too different) + break; + + case F_Arabic: // 8859-6 Arabic + destatep->declared_enc_2 = F_CP1256; + Boost(destatep, F_Arabic, kGentleOnePair); + Boost(destatep, F_CP1256, kGentleOnePair); + break; + case F_CP1256: + destatep->declared_enc_2 = F_Arabic; + Boost(destatep, F_Arabic, kGentleOnePair); + Boost(destatep, F_CP1256, kGentleOnePair); + break; + + case F_Greek: // 8859-7 Greek + destatep->declared_enc_2 = F_CP1253; + Boost(destatep, F_Greek, kGentleOnePair); + Boost(destatep, F_CP1253, kGentleOnePair); + break; + case F_CP1253: + destatep->declared_enc_2 = F_Greek; + Boost(destatep, F_Greek, kGentleOnePair); + Boost(destatep, F_CP1253, kGentleOnePair); + break; + + case F_Hebrew: // 8859-8 Hebrew + destatep->declared_enc_2 = F_CP1255; + Boost(destatep, F_Hebrew, kGentleOnePair); + Boost(destatep, F_CP1255, kGentleOnePair); + break; + case F_CP1255: + destatep->declared_enc_2 = F_Hebrew; + Boost(destatep, F_Hebrew, kGentleOnePair); + Boost(destatep, F_CP1255, kGentleOnePair); + break; + + case F_Latin5: // 8859-9 Latin5, Turkish + destatep->declared_enc_2 = F_ASCII_7_bit; // Don't boost 1254 + Boost(destatep, F_Latin5, kGentleOnePair); // (too different) + break; + case F_CP1254: + destatep->declared_enc_2 = F_ASCII_7_bit; // Don't boost Latin5 + Boost(destatep, F_CP1254, kGentleOnePair); // (too different) + break; + + case F_Latin6: // 8859-10 Latin6, Nordic + destatep->declared_enc_2 = F_ASCII_7_bit; + Boost(destatep, F_Latin6, kGentleOnePair); + break; + + case F_ISO_8859_11: // 8859-11 Thai, + destatep->declared_enc_2 = F_CP874; + Boost(destatep, F_ISO_8859_11, kGentleOnePair); + Boost(destatep, F_CP874, kGentleOnePair); + break; + case F_CP874: + destatep->declared_enc_2 = F_ISO_8859_11; + Boost(destatep, F_ISO_8859_11, kGentleOnePair); + Boost(destatep, F_CP874, kGentleOnePair); + break; + + case F_ISO_8859_13: // 8859-13 Latin7, Baltic + destatep->declared_enc_2 = F_CP1257; + Boost(destatep, F_ISO_8859_13, kGentleOnePair); + Boost(destatep, F_CP1257, kGentleOnePair); + break; + case F_CP1257: + destatep->declared_enc_2 = F_ISO_8859_13; + Boost(destatep, F_ISO_8859_13, kGentleOnePair); + Boost(destatep, F_CP1257, kGentleOnePair); + break; + + case F_ISO_8859_15: // 8859-15 Latin9, Latin0, Euro-ized Latin1 + destatep->declared_enc_2 = F_ASCII_7_bit; + Boost(destatep, F_ISO_8859_15, kGentleOnePair); + break; + + + // Greek all-caps is confusable with KOI8x all-lower and Hebrew. + // This turns some Greek documents into Cyrillic, etc. by mistake. + // Greek and Hebrew are boosted explicitly above; do KOI8x here. + // Boosting the declared encodingmakes it harder for the wrong one to + // creep up. + case F_KOI8R: + Boost(destatep, F_KOI8R, kGentleOnePair); + break; + case F_KOI8U: + Boost(destatep, F_KOI8U, kGentleOnePair); + break; + + default: + break; + } + } + + if (destatep->debug_data != NULL) { + // Show charset hint + SetDetailsEncProb(destatep, 0, best_sub, charset_hint); + } + + // + // Some fix-ups for the declared encodings + // + + // If non-UTF8, non-Latin1/1252 encoding declared, disable UTF8 combos + // TODO: This should all be folded into postproc-enc-detect.cc + if ((best_sub != F_UTF8) && + (best_sub != F_Latin1) && + (best_sub != F_CP1252)) { + Whack(destatep, F_UTF8UTF8, kBadPairWhack * 4); // demote + } + + // Latin2 and CP1250 differ in the overlap part, such as B1 or B9 + // The initial probabilites for charset=Latin2 explicitly put CP1250 + // down twice as far as normal, and vice versa. This is done in + // postproc-enc-detect.cc + + // If charset=user-defined, treat as Binary -- + // we can safely only do low ASCII, might be Indic + if (normalized_charset.substr(0,4) == "user") { + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } + + return 1; + } + return 0; +} + +// Apply initial probability hint based on caller-supplied encoding +// Negative hint whacks ~encoding, non-negative boosts encoding +// +// Negative hints are an experiment to see if they might be useful. +// Not operator used instead of unary minus to allow specifying not-zero +int ApplyEncodingHint(const int encoding_hint, int weight, + DetectEncodingState* destatep) { + Encoding enc_hint = static_cast((encoding_hint < 0) ? + ~encoding_hint : encoding_hint); + // Map to the right internal subscript + int rankedenc_hint = CompactEncDet::BackmapEncodingToRankedEncoding(enc_hint); + + // I'm not sure how strong this hint should be. Weight 100% = 1 bigram + int increment = (kBoostOnePair * weight) / 100; + + if (encoding_hint < 0) { + destatep->enc_prob[rankedenc_hint] -= increment; + } else { + destatep->enc_prob[rankedenc_hint] += increment; + } + + if (destatep->debug_data != NULL) { + // Show encoding hint + SetDetailsEncProb(destatep, 0, -1, MyEncodingName(enc_hint)); + } + return 1; +} + +// Apply initial probability hint based on user interface language +// Weight is 0..100 percent +// Return 1 if name match found +int ApplyUILanguageHint(const Language language_hint, + int weight, DetectEncodingState* destatep) { + if (language_hint == UNKNOWN_LANGUAGE) { + return 0; + } + string normalized_lang = MakeChar8(LanguageName(language_hint)); + int n = HintBinaryLookup8(kLangHintProbs, kLangHintProbsSize, + normalized_lang.c_str()); + if (n >= 0) { + // Language is eight bytes, probability table is ~eight bytes + int best_sub = ApplyCompressedProb(&kLangHintProbs[n].key_prob[kMaxLangKey], + kMaxLangVector, weight, destatep); + // Never boost ASCII7; do CP1252 instead + if (best_sub == F_ASCII_7_bit) {best_sub = F_CP1252;} + destatep->declared_enc_1 = best_sub; + if (destatep->debug_data != NULL) { + // Show language hint + SetDetailsEncProb(destatep, 0, best_sub, normalized_lang.c_str()); + } + return 1; + } + return 0; +} + +// Apply initial probability hint based on corpus type (web, email, etc) +// Weight is 0..100 percent IGNORED +// Return 1 if name match found +int ApplyDefaultHint(const CompactEncDet::TextCorpusType corpus_type, + int weight, DetectEncodingState* destatep) { + + for (int i = 0; i < NUM_RANKEDENCODING; i++) { + // Set the default probability + destatep->enc_prob[i] = kDefaultProb[i] * 3; + // Deliberately set 2022 seven-bit encodings to zero, + // so we can look for actual use + // TODO: This should all be folded into postproc-enc-detect.cc + if (SevenBitEncoding(kMapToEncoding[i])) { + destatep->enc_prob[i] = 0; + } + } + + // A little corpus distinction + switch (corpus_type) { + case CompactEncDet::WEB_CORPUS: + case CompactEncDet::XML_CORPUS: + // Allow double-converted UTF-8 to start nearly equal to normal UTF-8 + destatep->enc_prob[F_UTF8UTF8] = + destatep->enc_prob[F_UTF8] - kSmallInitDiff; + break; + case CompactEncDet::QUERY_CORPUS: + case CompactEncDet::EMAIL_CORPUS: + default: + break; + } + + if (FLAGS_demo_nodefault) { + // Demo, make initial probs all zero + for (int i = 0; i < NUM_RANKEDENCODING; i++) { + destatep->enc_prob[i] = 0; + } + } + + if (destatep->debug_data != NULL) { + // Show default hint + SetDetailsEncProb(destatep, 0, -1, "Default"); + } + return 1; +} + + + +// Do reverse search for c in [str..str+len) +// Note: initial pointer is to FRONT of string, not back +const char* MyMemrchr(const char* str, char c, size_t len) { + const char* ret = str + len; + while (str <= --ret) { + if (*ret == c) {return ret;} + } + return NULL; +} + + +// Minimum real URL is 11 bytes: "http://a.bc" -- shorter is assumed to be TLD +// Now that we are no longer trying to do Indic font-based encodigns, we +// don't need the full URL and can go back to simple TLD. This test remains for +// backwards compatility with any caller using full URL. +static const int kMinURLLength = 11; + +// Extract TLD from a full URL or just a TLD +// Return hostname and length if a full URL +void ExtractTLD(const char* url_hint, char* tld_hint, int tld_hint_len, + const char** ret_host_start, int* ret_host_len) { + // url_hint can either be a full URL (preferred) or just top-level domain name + // Extract the TLD from a full URL and use it for + // a normal TLD hint + + strncpy(tld_hint, "~", tld_hint_len); + tld_hint[tld_hint_len - 1] = '\0'; + *ret_host_start = NULL; + *ret_host_len = 0; + + int url_len = (url_hint != NULL) ? strlen(url_hint) : 0; + if (url_len == 0) { + // Empty TLD + return; + } + + // Minimum real URL is 11 bytes: "http://a.bc" -- shorter is assumed to be TLD + if (kMinURLLength <= url_len) { + // See if it really is a URL + const char* first_slash = strchr(url_hint, '/'); + if ((first_slash != NULL) && (first_slash != url_hint) && + (first_slash[-1] == ':') && (first_slash[1] == '/') && + (memrchr(url_hint, '.', first_slash - url_hint) == NULL)) { + // We found :// and no dot in front of it, so declare a real URL + + const char* hostname_start = first_slash + 2; + const char* hostname_end = strchr(hostname_start, '/'); + if (hostname_end == NULL) { + // No slash; end is first byte off end of the URL string + hostname_end = url_hint + url_len; + } + size_t hostname_len = hostname_end - hostname_start; + const char* port_start = + (const char*)memchr(hostname_start, ':', hostname_len); + if (port_start != NULL) { + // Port; shorten hostname + hostname_end = port_start; + hostname_len = hostname_end - hostname_start; + } + + const char* tld_start = MyMemrchr(hostname_start, '.', hostname_len); + if (tld_start != NULL) { + // Remember the TLD we just found + int tld_len = hostname_start + hostname_len - tld_start - 1; + if (tld_len > (tld_hint_len - 1)) { + tld_len = tld_hint_len - 1; + } + memcpy(tld_hint, tld_start + 1, tld_len); + tld_hint[tld_len] = '\0'; + } + *ret_host_start = hostname_start; + *ret_host_len = hostname_len; + return; + } + } else { + strncpy(tld_hint, url_hint, tld_hint_len); + tld_hint[tld_hint_len - 1] = '\0'; + } +} + +// Apply hints, if any, to probabilities +// NOTE: Encoding probabilites are all zero at this point +void ApplyHints(const char* url_hint, + const char* http_charset_hint, + const char* meta_charset_hint, + const int encoding_hint, + const Language language_hint, + const CompactEncDet::TextCorpusType corpus_type, + DetectEncodingState* destatep) { + int hint_count = 0; + // url_hint can either be a full URL (preferred) or just top-level domain name + // Extract the TLD from a full URL and use it for + // a normal TLD hint + + char tld_hint[16]; + const char* hostname_start = NULL; + int hostname_len = 0; + ExtractTLD(url_hint, tld_hint, sizeof(tld_hint), + &hostname_start, &hostname_len); + + + // Initial hints give slight boost to Ascii-7-bit and code page 1252 + // ApplyXxx routines copy enc_1 to enc_2 then update declared_enc_1 + // This gives a boost to 1252 if one of HTTP/META is specified, + // but this could be the wrong thing to do if Latin2/3/4/etc. is specified + destatep->declared_enc_1 = F_CP1252; + destatep->declared_enc_2 = F_ASCII_7_bit; + + // Applying various hints takes max of new hint and any old hint. + // This does better on multiple hints that a weighted average + + // Weight is 0..100 percent + if ((http_charset_hint != NULL) && (http_charset_hint[0] != '~')) { + destatep->declared_enc_2 = destatep->declared_enc_1; + hint_count += ApplyCharsetHint(http_charset_hint, 100, destatep); + destatep->http_hint = kMapToEncoding[destatep->declared_enc_1]; + if ((destatep->declared_enc_1 == F_CP1252) || + (destatep->declared_enc_1 == F_Latin1)) { + destatep->looking_for_latin_trigrams = true; + } + } + if ((meta_charset_hint != NULL) && (meta_charset_hint[0] != '~')) { + destatep->declared_enc_2 = destatep->declared_enc_1; + hint_count += ApplyCharsetHint(meta_charset_hint, 100, destatep); + destatep->meta_hint = kMapToEncoding[destatep->declared_enc_1]; + if ((destatep->declared_enc_1 == F_CP1252) || + (destatep->declared_enc_1 == F_Latin1)) { + destatep->looking_for_latin_trigrams = true; + } + } + if (encoding_hint != UNKNOWN_ENCODING) { + destatep->declared_enc_2 = destatep->declared_enc_1; + hint_count += ApplyEncodingHint(encoding_hint, 50, destatep); + } + if (language_hint != UNKNOWN_LANGUAGE) { + destatep->declared_enc_2 = destatep->declared_enc_1; + hint_count += ApplyUILanguageHint(language_hint, 50, destatep); + } + // Use top level domain if not .com and <=1 other hint was available + if (url_hint != NULL) { + destatep->tld_hint = CompactEncDet::TopEncodingOfTLDHint(tld_hint); + if (hint_count == 0) { + // Apply with weight 100% + destatep->declared_enc_2 = destatep->declared_enc_1; + hint_count += ApplyTldHint(tld_hint, 100, destatep); + if ((destatep->declared_enc_1 == F_CP1252) || + (destatep->declared_enc_1 == F_Latin1)) { + destatep->looking_for_latin_trigrams = true; + } + if (strcmp("hu", tld_hint) == 0) { + // Hungarian is particularly difficult to separate Latin2 from Latin1, + // so always look for trigram scanning if bare TLD=hu hint + destatep->looking_for_latin_trigrams = true; + } + // Treat .com as no TLD hint at all + } else if ((hint_count == 1) && (strcmp("com", tld_hint) != 0)) { + // Either shift weighting or consider doing no TLD here -- seems to + // distract from correct charset= hints. Or perhaps apply only if + // charset = Latin1/1252... + // Apply with weight 50% + destatep->declared_enc_2 = destatep->declared_enc_1; + hint_count += ApplyTldHint(tld_hint, 50, destatep); + if ((destatep->declared_enc_1 == F_CP1252) || + (destatep->declared_enc_1 == F_Latin1)) { + destatep->looking_for_latin_trigrams = true; // These need trigrams + } + } + // Else ignore TLD hint entirely + } + + // Use all-web default distribution if not even a TLD hint + if (hint_count == 0) { + destatep->looking_for_latin_trigrams = true; // Default needs trigrams + destatep->declared_enc_2 = destatep->declared_enc_1; + hint_count += ApplyDefaultHint(corpus_type, 100, destatep); + } + + +// ISO-Microsoft Pairs +// F_Latin1, F_CP1252, +// F_Latin2, F_CP1250, NOT really strict subset/superset pairs +// F_Latin3, +// F_Latin4, +// F_ISO_8859_5, F_CP1251, +// F_Arabic, F_CP1256, NOT +// F_Greek, F_CP1253, NOT really pairs +// (or upgrade incvt to make Greek use CP) +// F_Hebrew, F_CP1255, NOT really pairs +// F_Latin5, F_CP1254, +// F_Latin6, +// F_ISO_8859_11, +// F_ISO_8859_13, F_CP1257, +// F_ISO_8859_15, +// ISO-Microsoft Pairs + + // Get important families started together + // // This should fall out of the initializatoin vectors for charset, + // but we need to get rid of families alltogetrher + // + // TODO make this more graceful + + // Add small bias for subsets + + // Subtract small bias for supersets + destatep->enc_prob[F_CP932] = destatep->enc_prob[F_SJS] - kSmallInitDiff; + + destatep->enc_prob[F_GBK] = destatep->enc_prob[F_GB] - kSmallInitDiff; + destatep->enc_prob[F_GB18030] = destatep->enc_prob[F_GB] - kSmallInitDiff; + + destatep->enc_prob[F_BIG5_CP950] = destatep->enc_prob[F_BIG5] - + kSmallInitDiff; + destatep->enc_prob[F_BIG5_HKSCS] = destatep->enc_prob[F_BIG5] - + kSmallInitDiff; + + // Deliberate over-bias Ascii7 and underbias Binary [unneeded] + // destatep->enc_prob[F_ASCII_7_bit] = destatep->enc_prob[F_ASCII_7_bit] + kSmallInitDiff; + // destatep->enc_prob[F_BINARY] = destatep->enc_prob[F_BINARY] - (kBoostInitial / 2); + + if (destatep->debug_data != NULL) { + // Show state at end of hints + SetDetailsEncProb(destatep, 0, -1, "Endhints"); + if(FLAGS_enc_detect_detail2) { + // Add a line showing the watched encoding(s) + if (watch1_rankedenc >= 0) { + SetDetailsEncProb(destatep, 0, + watch1_rankedenc, FLAGS_enc_detect_watch1); + } + if (watch2_rankedenc >= 0) { + SetDetailsEncProb(destatep, 0, + watch2_rankedenc, FLAGS_enc_detect_watch2); + } + } // End detail2 + } + + // If duplicate hints, set second one to ASCII_7BIT to prevent double-boost + if (destatep->declared_enc_1 == destatep->declared_enc_2) { + destatep->declared_enc_2 = F_ASCII_7_bit; + } + + if (FLAGS_force127) { + destatep->do_latin_trigrams = true; + if (FLAGS_enc_detect_source) { + PsHighlight(0, destatep->initial_src, 0, 2); + } + } + + + if (FLAGS_counts && destatep->looking_for_latin_trigrams) {++looking_used;} + if (FLAGS_counts && destatep->do_latin_trigrams) {++doing_used;} + + // + // At this point, destatep->enc_prob[] is an initial probability vector based + // on the given hints/default. In general, it spreads out least-likely + // encodings to be about 2**-25 below the most-likely encoding. + // For input text with lots of bigrams, an unlikely encoding can rise to + // the top at a rate of about 2**6 per bigram, and more commonly 2**2 per + // bigram. So more than 4 bigrams and commonly more than 12 are + // needed to overcome the initial hints when the least-likely encoding + // is in fact the correct answer. So if the entire text has very few bigrams + // (as a two-word query might), it can be impossible for the correct + // encoding to win. + // + // To compensate for this, we take the initial hint vector and effectively + // apply it at the rate of 1/16 every bigram for the first 16 bigrams. The + // actual mechanism is done just before the last prune. + // + + // Remember Initial hint probabilities + memcpy(destatep->hint_prob, destatep->enc_prob, sizeof(destatep->enc_prob)); +} + +// Look for specific high-value patterns in the first 4 bytes +// Byte order marks (BOM) +// EFBBBF UTF-8 +// FEFF UTF-16 BE +// FFFE UTF-16 LE +// FFFE0000 UTF-32 BE +// 0000FEFF UTF-32 LE +// +// Likely UTF-x of seven-bit ASCII +// 00xx UTF-16 BE xx printable ASCII +// xx00 UTF-16 LE +// 000000xx UTF-32 BE +// xx000000 UTF-32 LE +// +void InitialBytesBoost(const uint8* src, + int text_length, + DetectEncodingState* destatep) { + if (text_length < 4) {return;} + + char32 pair01 = (src[0] << 8) | src[1]; + char32 pair23 = (src[2] << 8) | src[3]; + char32 quad0123 = (pair01 << 16) | pair23; + + bool utf_16_indication = false; + bool utf_32_indication = false; + int best_enc = -1; + + // Byte order marks + // UTF-8 + if ((quad0123 & 0xffffff00) == 0xEFBBBF00) { + destatep->bom_hint = UTF8; + Boost(destatep, F_UTF8, kBoostInitial * 2); + Boost(destatep, F_UTF8UTF8, kBoostInitial * 2); + best_enc = F_UTF8; + // UTF-32 (test before UTF-16) + } else if (quad0123 == 0x0000FEFF) { + destatep->bom_hint = UTF32BE; + Boost(destatep, F_UTF_32BE, kBoostInitial * 2); + best_enc = F_UTF_32BE; + } else if (quad0123 == 0xFFFE0000) { + destatep->bom_hint = UTF32LE; + Boost(destatep, F_UTF_32LE, kBoostInitial * 2); + best_enc = F_UTF_32LE; + // UTF-16 + } else if (pair01 == 0xFEFF) { + destatep->bom_hint = UTF16BE; + Boost(destatep, F_UTF_16BE, kBoostInitial * 3); + best_enc = F_UTF_16BE; + } else if (pair01 == 0xFFFE) { + destatep->bom_hint = UTF16LE; + Boost(destatep, F_UTF_16LE, kBoostInitial * 3); + best_enc = F_UTF_16LE; + + // Possible seven-bit ASCII encoded as UTF-16/32 + // UTF-32 (test before UTF-16) + } else if (((quad0123 & 0xffffff00) == 0) && + (kIsPrintableAscii[src[3]] != 0)) { + Boost(destatep, F_UTF_32BE, kBoostInitial); + Whack(destatep, F_UTF_32LE, kBadPairWhack); // Illegal char + best_enc = F_UTF_32BE; + } else if (((quad0123 & 0x00ffffff) == 0) && + (kIsPrintableAscii[src[0]] != 0)) { + Boost(destatep, F_UTF_32LE, kBoostInitial); + Whack(destatep, F_UTF_32BE, kBadPairWhack); // Illegal char + best_enc = F_UTF_32LE; + } else if ((src[0] == 0x00) && (kIsPrintableAscii[src[1]] != 0)) { + Boost(destatep, F_UTF_16BE, kBoostInitial); + best_enc = F_UTF_16BE; + } else if ((src[1] == 0x00) && (kIsPrintableAscii[src[0]] != 0)) { + Boost(destatep, F_UTF_16LE, kBoostInitial); + best_enc = F_UTF_16LE; + + // Whack if 0000 or FFFF + // UTF-32 (test before UTF-16) + } else if (quad0123 == 0x00000000) { + Whack(destatep, F_UTF_32BE, kBadPairWhack); // Illegal char + Whack(destatep, F_UTF_32LE, kBadPairWhack); + Whack(destatep, F_UTF_16BE, kBadPairWhack); + Whack(destatep, F_UTF_16LE, kBadPairWhack); + best_enc = -1; + } else if (quad0123 == 0xffffffff) { + Whack(destatep, F_UTF_32BE, kBadPairWhack); // Illegal char + Whack(destatep, F_UTF_32LE, kBadPairWhack); + Whack(destatep, F_UTF_16BE, kBadPairWhack); + Whack(destatep, F_UTF_16LE, kBadPairWhack); + best_enc = -1; + } else if (pair01 == 0x0000) { + Whack(destatep, F_UTF_16BE, kBadPairWhack); // Illegal char + Whack(destatep, F_UTF_16LE, kBadPairWhack); + best_enc = -1; + } else if (pair01 == 0xffff) { + Whack(destatep, F_UTF_16BE, kBadPairWhack); // Illegal char + Whack(destatep, F_UTF_16LE, kBadPairWhack); + best_enc = -1; + + + // These are the first four bytes of some known binary file formats + + // Boost BINARY bigtime if JPEG FFD8FFxx + // Boost BINARY bigtime if png 89504E47 (.PNG) + // Boost BINARY bigtime if gif 47494638 (GIF8) + // Boost BINARY bigtime if zip 504B0304 (PK..) + // Boost BINARY bigtime if gzip 1F8B08xx + // Boost BINARY bigtime if gzip 78DAxxxx + // Boost BINARY if PDF 25504446 (%PDF) + // Boost BINARY if SWF (FWSx or CWSx where x <= 0x1f) + } else if ((quad0123 & 0xffffff00) == 0xFFD8FF00) { // JPEG FFD8FFxx + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (quad0123 == 0x89504E47) { // Hex 89 P N G + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (quad0123 == 0x47494638) { // Hex GIF8 + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (quad0123 == 0x504B0304) { // Hex P K 03 04 + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if ((quad0123 & 0xffffff00) == 0x1F8B0800) { // gzip 1F8B08xx + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (pair01 == 0x78DA) { // gzip 78DAxxxx + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (quad0123 == 0x25504446) { // Hex %PDF + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if ((quad0123 & 0xffffff1f) == 0x66535700) { // Hex FWSx + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if ((quad0123 & 0xffffff1f) == 0x63535700) { // Hex CWSx + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + + // More binary detect prefixes + // 7F E L F Executable and linking format + // M M 00 * TIFF (little-endian) + // * 00 M M TIFF (big-endian) + // 01 f c p Final cut pro + } else if (quad0123 == 0x7F454C46) { // Hex 7F E L F + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (quad0123 == 0x4D4D002A) { // Hex M M 00 * + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (quad0123 == 0x2A004D4D) { // Hex * 00 M M + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (quad0123 == 0x01666370) { // Hex 01 f c p + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + + // More binary detect prefixes; all-ASCII names; heavy weight to avoid ASCII + // prefix overcoming binary + // C C S D USGS ISIS 3-D cube files + // S I M P FITS image header "SIMPLE " + } else if (quad0123 == 0x43435344) { // Hex C C S D + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (quad0123 == 0x53494D50) { // Hex S I M P + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + + // More binary detect prefixes; all-ASCII names; lighter weight + // H W P Hangul word processor + // 8 B P S Photoshop + // P D S _ xx "PDS_VERSION_ID " + } else if (quad0123 == 0x48575020) { // Hex H W P + if ((19 <= text_length) && + (memcmp(src, "HWP.Document.File.V", 19) == 0)) { + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if ((19 <= text_length) && + (memcmp(src, "HWP Document File V", 19) == 0)) { + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else { + Boost(destatep, F_BINARY, kBoostInitial * kWeakerBinary); + } + } else if (quad0123 == 0x38425053) { // Hex 8 B P S + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else if (quad0123 == 0x5044535F) { // Hex P D S _ + if ((14 <= text_length) && (memcmp(src, "PDS_VERSION_ID", 14) == 0)) { + Boost(destatep, F_BINARY, kBoostInitial * kStrongBinary); + } else { + Boost(destatep, F_BINARY, kBoostInitial * kWeakerBinary); + } + } + + // There are several main Windows EXE file formats. + // Not examined here (prefix too short; never see them in Google pipeline) + // M Z DOS .exe Mark Zbikowski + // N E DOS 4.0 16-bit + // L E OS/2 VxD drivers + // L X OS/2 + // P E Windows NT + + + // More user-defined + // http://www.freenet.am/armscii/ Armenian + + // If any hints or BOM, etc. keep UTF 16/32 around + if ((destatep->enc_prob[F_UTF_16BE] > 0) || + (destatep->enc_prob[F_UTF_16LE] > 0)) { + utf_16_indication = true; + } + if ((destatep->enc_prob[F_UTF_32BE] > 0) || + (destatep->enc_prob[F_UTF_32LE] > 0)) { + utf_32_indication = true; + } + + + // Kill UTF16/32 right now if no positive indication of them + // Otherwise, they tend to rise to the top in 7-bit files with an + // occasional 0x02 byte in some comment or javascript + if (!utf_16_indication) { + Whack(destatep, F_UTF_16BE, kBadPairWhack * 8); + Whack(destatep, F_UTF_16LE, kBadPairWhack * 8); + Whack(destatep, F_Unicode, kBadPairWhack * 8); + } + if (!utf_32_indication) { + Whack(destatep, F_UTF_32BE, kBadPairWhack * 8); + Whack(destatep, F_UTF_32LE, kBadPairWhack * 8); + } + + // Usually kill mixed encodings + if (!FLAGS_ced_allow_utf8utf8) { + Whack(destatep, F_UTF8UTF8, kBadPairWhack * 8); + } + // 2011.11.07 never use UTF8CP1252 -- answer will be UTF8 instead + Whack(destatep, F_UTF8CP1252, kBadPairWhack * 8); + + if (destatep->debug_data != NULL) { + // Show first four bytes of the input + char buff[16]; + snprintf(buff, sizeof(buff), "%04x%04x", pair01, pair23); + SetDetailsEncProb(destatep, 0, best_enc, buff); + } +} + + + +// Descending order +int IntCompare(const void* v1, const void* v2) { + const int* p1 = reinterpret_cast(v1); + const int* p2 = reinterpret_cast(v2); + if (*p1 < *p2) {return 1;} + if (*p1 > *p2) {return -1;} + return 0; +} + +bool Base64Char(uint8 c) { + if (('A' <= c) && (c <= 'Z')) {return true;} + if (('a' <= c) && (c <= 'z')) {return true;} + if (('0' <= c) && (c <= '9')) {return true;} + if ('+' == c) {return true;} + if ('/' == c) {return true;} + return false; +} + +int Base64ScanLen(const uint8* start, const uint8* limit) { + // We have a plausible beginning; scan entire base64 string + const uint8* ib64str = start; + const uint8* b64str = ib64str; + const uint8* b64strlimit = limit; + // if starts with + +++, assume it is drawing, so bogus + if (((limit - start) > 3) && (start[0] == '+') && + (start[1] == '+') && (start[2] == '+')) { + return 81; + } + // Scan over base64 + while ((b64str < b64strlimit) && (kBase64Value[*b64str++] >= 0)) { + } + b64str--; // We overshot by 1 + return b64str - ib64str; +} + +// Input is at least 8-character legal base64 string after +. +// But might be say + "Presse+Termine" +bool GoodUnicodeFromBase64(const uint8* start, const uint8* limit) { + // Reject base64 string len N if density of '+' is > 1 + N/16 (expect 1/64) + // Reject base64 string len N if density of A-Z is < 1 + N/16 (expect 26/64) + // Reject base64 string len N if density of a-z is < 1 + N/16 (expect 26/64) + // Reject base64 string len N if density of 0-9 is < 1 + N/32 (expect 10/64) + // NOTE: this requires at least one lower AND one upper AND one digit to pass + // + int plus_count = 0; + int lower_count = 0; + int upper_count = 0; + int digit_count = 0; + int len = limit - start; + for (const uint8* src = start; src < limit; ++src) { + uint8 c = *src; + if (('a' <= c) && (c <= 'z')) { + ++lower_count; + } else if (('A' <= c) && (c <= 'Z')) { + ++upper_count; + } else if (('0' <= c) && (c <= '0')) { + ++digit_count; + } else if (*src == '+') { + ++plus_count; + } + } + + if (plus_count > (1 + (len >> 4))) {return false;} + if (lower_count < (1 + (len >> 4))) {return false;} + if (upper_count < (1 + (len >> 4))) {return false;} + if (digit_count < (1 + (len >> 5))) {return false;} + + // checking the last character to reduce false positive + // since the last character may be padded to 0 bits at the end. + // refer to http://en.wikipedia.org/wiki/UTF-7 + int nmod8 = len & 7; + const uint8 last = *(start+len-1); + // When UTF-7 string length%8=3, the last two bits must be padded as 0 + if ((nmod8 == 3) && (kBase64Value[last] & 3)) {return false;} + // When UTF-7 string length%8=6, the last four bits must be padded as 0 + if ((nmod8 == 6) && (kBase64Value[last] & 15)) {return false;} + return true; +} + +// Prune here after N bytes +// Boost here for seven-bit sequences (at every prune) +// if (sevenbitrankedencoding) +// + UTF7 scan and boost/demote len mod 8 = 0 3 6 +// ~ Hz scan and boost/demote len mod 8 = 0 2 4 6 +// 1B 2022 scan and boost/demote len mod 8 = 0 2 4 6 +// 0E 2022 scan and boost/demote len mod 8 = 0 2 4 6 +// [0F 2022 boost/demote] +// 00 UTF16/32 scan and boost/demote offset = even/odd +// +// If still some seven-bit possibilities > pure ASCII, +// scan each possibility for clearer prob, s.t. about +// two good sequences is a clear win +// A-Z 00-19 00xx-64xx (B = 04xx) +// a-z 1A-33 68xx-CCxx (f = 7Cxx) +// 0-9 34-3D D0xx-F4xx (1 = D4xx) +// + 3E F8xx +// / 3F FCxx +// do another chunk with slow scan + + +// Boost, whack, or leave alone UTF-7 probablilty +void UTF7BoostWhack(DetectEncodingState* destatep, int next_pair, uint8 byte2) { + int off = destatep->interesting_offsets[AsciiPair][next_pair]; + if (off >= destatep->prior_utf7_offset) { + // Not part of a previous successful UTF-7 string + ++destatep->utf7_starts; + + if (byte2 == '-') { + // +- encoding for '+' neutral + } else if (!Base64Char(byte2)) { + // Not base64 -- not UTF-7, whack + Whack(destatep, F_UTF7, kBadPairWhack); // Illegal pair + } else { + // Starts with base64 byte, might be a good UTF7 sequence + const uint8* start = destatep->initial_src + off + 1; // over the + + int n = Base64ScanLen(start, destatep->limit_src); + int nmod8 = n & 7; + if ((n == 3) || (n == 6)) { + // short but legal -- treat as neutral + } else if ((nmod8 == 0) | (nmod8 == 3) | (nmod8 == 6)) { + // Good length. Check for good Unicode. + if (GoodUnicodeFromBase64(start, start + n)) { + // Good length and Unicode, boost + Boost(destatep, F_UTF7, kBoostOnePair); // Found good + destatep->prior_utf7_offset = off + n + 1; + } else { + // Bad Unicode. Whack + Whack(destatep, F_UTF7, kBadPairWhack); // Illegal length + } + } else { + // Bad length. Whack + Whack(destatep, F_UTF7, kBadPairWhack); // Illegal length + } + } + } +} + +// Boost, whack, or leave alone HZ probablilty +void HzBoostWhack(DetectEncodingState* destatep, uint8 byte1, uint8 byte2) { + if ((byte2 == '{') || (byte2 == '}')) { + Boost(destatep, F_HZ_GB_2312, kBoostOnePair); // Found ~{ or ~} + } else if ((byte2 == '~') || (byte2 == '\n')) { + destatep->enc_prob[F_HZ_GB_2312] += 0; // neutral + } else { + Whack(destatep, F_HZ_GB_2312, kBadPairWhack); // Illegal pair + } +} + +// Boost, whack, or leave alone BINARY probablilty +void BinaryBoostWhack(DetectEncodingState* destatep, uint8 byte1, uint8 byte2) { + int quadrant = ((byte1 & 0x80) >> 6) | ((byte2 & 0x80) >> 7); + int bucket8x4 = ((byte1 & 0xe0) >> 3) | ((byte2 & 0xc0) >> 6); + uint32 quad_mask = 1 << quadrant; + uint32 bucket8x4_mask = 1 << bucket8x4; + if ((destatep->binary_quadrants_seen & quad_mask) == 0) { + destatep->binary_quadrants_seen |= quad_mask; + destatep->binary_quadrants_count += 1; + if (destatep->binary_quadrants_count == 4) { + Boost(destatep, F_BINARY, kBoostOnePair * 2); // Found all 4 quadrants, + // boost 2 pairs + } + } + if ((destatep->binary_8x4_seen & bucket8x4_mask) == 0) { + destatep->binary_8x4_seen |= bucket8x4_mask; + destatep->binary_8x4_count += 1; + if (destatep->binary_8x4_count >= 11) { + Boost(destatep, F_BINARY, kBoostOnePair * 4); // Found 11+/20 buckets, + // boost 4 pairs each time + } + } +} + + +// Demote UTF-16/32 on 0000 or FFFF, favoring Binary +void UTF1632BoostWhack(DetectEncodingState* destatep, int offset, uint8 byte1) { + if (byte1 == 0) { // We have 0000 + Whack(destatep, F_UTF_16BE, kBadPairWhack); // Illegal pair + Whack(destatep, F_UTF_16LE, kBadPairWhack); // Illegal pair + switch (offset & 3) { + case 0: // We get called with 0 4 8, etc. for ASCII/BMP as UTF-32BE + Whack(destatep, F_UTF_32LE, kBadPairWhack); // Illegal pair + Boost(destatep, F_UTF_32BE, kSmallInitDiff); // Good pair + break; + case 1: // We get called with 1 5 9, etc. for ASCII as UTF-32LE + case 2: // We get called with 2 6 10, etc. for BMP as UTF-32LE + Whack(destatep, F_UTF_32BE, kBadPairWhack); // Illegal pair + Boost(destatep, F_UTF_32LE, kSmallInitDiff); // Good pair + break; + case 3: // ambiguous + break; + } + } else { // We have ffff + Whack(destatep, F_UTF_32BE, kBadPairWhack); // Illegal pair + Whack(destatep, F_UTF_32LE, kBadPairWhack); // Illegal pair + Whack(destatep, F_UTF_16BE, kBadPairWhack); // Illegal pair + Whack(destatep, F_UTF_16LE, kBadPairWhack); // Illegal pair + } +} + +// Make even offset +void UTF16MakeEven(DetectEncodingState* destatep, int next_pair) { + destatep->interesting_offsets[OtherPair][next_pair] &= ~1; +} + +bool ConsecutivePair(DetectEncodingState* destatep, int i) { + if (i <= 0) { + return false; + } + return destatep->interesting_offsets[OtherPair][i] == + (destatep->interesting_offsets[OtherPair][i - 1] + 2); +} + +// boost, whack, or leave alone UTF-8 probablilty +// Any whacks are also applied to UTF8UTF8; CheckUTF8UTF8Seq assumes good UTF8 +// Returns total boost +int CheckUTF8Seq(DetectEncodingState* destatep, int weightshift) { + int startcount = destatep->prior_interesting_pair[OtherPair]; + int endcount = destatep->next_interesting_pair[OtherPair]; + + int demotion_count = 0; + for (int i = startcount; i < endcount; ++i) { + int sub; + char* s = &destatep->interesting_pairs[OtherPair][i * 2]; + // Demote four byte patterns that are more likely Latin1 than UTF-8 + // C9AE, DF92, DF93, DFAB. See note at top. + // Demotion also boosts Latin1 and CP1252 + uint8 s0 = static_cast(s[0]); + uint8 s1 = static_cast(s[1]); + if ((s0 == 0xc9) && (s1 == 0xae)) {++demotion_count;} + if ((s0 == 0xdf) && (s1 == 0x92)) {++demotion_count;} + if ((s0 == 0xdf) && (s1 == 0x93)) {++demotion_count;} + if ((s0 == 0xdf) && (s1 == 0xab)) {++demotion_count;} + + if (!ConsecutivePair(destatep, i)) { + // Insert a blank into the sequence; avoid wrong splices + sub = (' ' >> 4) & 0x0f; + ++destatep->utf8_minicount[ + static_cast(kMiniUTF8Count[static_cast(destatep->next_utf8_ministate)][sub])]; + destatep->next_utf8_ministate = + kMiniUTF8State[destatep->next_utf8_ministate][sub]; + } + // Byte 0 + sub = (s0 >> 4) & 0x0f; + ++destatep->utf8_minicount[ + static_cast(kMiniUTF8Count[static_cast(destatep->next_utf8_ministate)][sub])]; + destatep->next_utf8_ministate = + kMiniUTF8State[destatep->next_utf8_ministate][sub]; + // Byte 1 + sub = (s1 >> 4) & 0x0f; + ++destatep->utf8_minicount[ + static_cast(kMiniUTF8Count[static_cast(destatep->next_utf8_ministate)][sub])]; + destatep->next_utf8_ministate = + kMiniUTF8State[destatep->next_utf8_ministate][sub]; + DCHECK((0 <= destatep->next_utf8_ministate) && + (destatep->next_utf8_ministate < 8)); + } + + + // For the four specific byte combinations above, Latin1/CP1252 is more likely + if (demotion_count > 0) { + Boost(destatep, F_Latin1, kGentleOnePair * demotion_count); + Boost(destatep, F_CP1252, kGentleOnePair * demotion_count); + } + + // Boost UTF8 for completed good sequences + int total_boost = 2 * destatep->utf8_minicount[2] + + 3 * destatep->utf8_minicount[3] + + 4 * destatep->utf8_minicount[4]; + // But not so much for demoted bytes + total_boost -= (3 * demotion_count); + + total_boost *= kGentleOnePair; + total_boost >>= weightshift; + // Design: boost both UTF8 and UTF8UTF8 for each good sequence + Boost(destatep, F_UTF8, total_boost); + Boost(destatep, F_UTF8UTF8, total_boost); + + destatep->utf8_minicount[5] += destatep->utf8_minicount[2]; // total chars + destatep->utf8_minicount[5] += destatep->utf8_minicount[3]; // total chars + destatep->utf8_minicount[5] += destatep->utf8_minicount[4]; // total chars + destatep->utf8_minicount[2] = 0; + destatep->utf8_minicount[3] = 0; + destatep->utf8_minicount[4] = 0; + + // Whack (2 bytes) for errors + int error_whack = 2 * destatep->utf8_minicount[1]; + error_whack *= kGentlePairWhack; + error_whack >>= weightshift; + Whack(destatep, F_UTF8, error_whack); + Whack(destatep, F_UTF8UTF8, error_whack); + destatep->utf8_minicount[1] = 0; + + return total_boost - error_whack; +} + + +// Boost, whack, or leave alone UTF8UTF8 probablilty +// +// We are looking for +// (1) chars ONLY in set UTF8(0080)..UTF8(00FF), including for 80..9F the +// MS CP1252 mappings, and +// (2) sequences of 2 or more such characters +// +// If so, we could be looking at some non-7-bit encoding extra-converted +// to UTF-8. The most common observed is CP1252->UTF8 twice, +// 1252=>UTF8 : 1252=>UTF8 +// where the colon means "take those bytes and pretend that they are 1252". +// We have a couple of examples of BIG5 bytes converted as though +// they were 1252, +// BIG5 : 1252=>UTF8 +// +// Of course, we don't want correctly converted 1252 to be flagged here +// 1252=>UTF8 +// So we want the input high bytes to be in pairs or longer, hence the +// output UTF8 in groups of four bytes or more +// +// Good chars: C2xx, C3xx, +// Good chars: C592, C593, C5A0, C5A1, C5B8, C5BD, C5BE, C692, CB86, CB9C +// Good chars: E280xx E282AC E284A2 +// C2xx 1100001x 10xxxxxx (128/128) +// C5xx 11000101 10xx00xx (16/4) +// C5xx 11000101 10111xxx (8/3) +// C692 11000110 10010010 (1/1) +// CBxx 11001011 100xx1x0 (8/2) +// E28x 11100010 10000xx0 (4/3) +// +// Returns total boost +int CheckUTF8UTF8Seq(DetectEncodingState* destatep, int weightshift) { + int this_pair = destatep->prior_interesting_pair[OtherPair]; + int startbyteoffset = this_pair * 2; + int endbyteoffset = destatep->next_interesting_pair[OtherPair] * 2; + char* startbyte = &destatep->interesting_pairs[OtherPair][startbyteoffset]; + char* endbyte = &destatep->interesting_pairs[OtherPair][endbyteoffset]; + + int pair_number = this_pair; + for (char* s = startbyte; s < endbyte; s += 2) { + int next = destatep->next_utf8utf8_ministate; + if (!ConsecutivePair(destatep, pair_number)) { + // Insert two blanks into the sequence to avoid wrong splices + // go back to no odd-byte offset + destatep->utf8utf8_odd_byte = 0; + int sub = UTF88Sub(' ', ' '); + ++destatep->utf8utf8_minicount[static_cast(kMiniUTF8UTF8Count[next][sub])]; + next = kMiniUTF8UTF8State[next][sub]; + } + + int odd = destatep->utf8utf8_odd_byte; + if (s + 1 + odd >= endbyte) continue; + int sub = UTF88Sub(s[0 + odd], s[1 + odd]); + destatep->utf8utf8_odd_byte ^= kMiniUTF8UTF8Odd[next][sub]; + ++destatep->utf8utf8_minicount[ + static_cast(kMiniUTF8UTF8Count[next][sub])]; + destatep->next_utf8utf8_ministate = kMiniUTF8UTF8State[next][sub]; + ++pair_number; + } + + // Boost for completed good sequences; each count covers two chars. + // Design: boost UTF8UTF8 above UTF8 for each good sequence + int total_boost = (2) * destatep->utf8utf8_minicount[2] + + (2) * destatep->utf8utf8_minicount[3] + + (2) * destatep->utf8utf8_minicount[4]; + total_boost *= kGentleOnePair; + total_boost >>= weightshift; + Boost(destatep, F_UTF8UTF8, total_boost); + + // Track total characters + destatep->utf8utf8_minicount[5] += destatep->utf8utf8_minicount[2]; + destatep->utf8utf8_minicount[5] += destatep->utf8utf8_minicount[3]; + destatep->utf8utf8_minicount[5] += destatep->utf8utf8_minicount[4]; + destatep->utf8utf8_minicount[2] = 0; + destatep->utf8utf8_minicount[3] = 0; + destatep->utf8utf8_minicount[4] = 0; + + // Design: Do not whack UTF8UTF8 below UTF8 for each bad sequence + + destatep->utf8utf8_minicount[1] = 0; + return total_boost; +} + + +// boost, whack, or leave alone UTF-32 probablilty +// Expecting 0000PPxx 0000QQxx where PP mostly = QQ (UTF-32BE) +// Expecting xxPP0000 xxQQ0000 where PP mostly = QQ (UTF-32LE) +void CheckUTF32ActiveSeq(DetectEncodingState* destatep) { + // Not needed + return; +} + +// We give a gentle boost for each paired SO ... SI, whack others +void CheckIso2022ActiveSeq(DetectEncodingState* destatep) { + int this_pair = destatep->prior_interesting_pair[OtherPair]; + int startbyteoffset = this_pair * 2; + int endbyteoffset = destatep->next_interesting_pair[OtherPair] * 2; + char* startbyte = &destatep->interesting_pairs[OtherPair][startbyteoffset]; + char* endbyte = &destatep->interesting_pairs[OtherPair][endbyteoffset]; + + // Initial char must precede SO/SI + // HZ_GB_2312 has no alternation constraint on 1- and 2-byte segments + // ISO-2022-JP (JIS) has no alternation constraint on 1- and 2-byte segments + // ISO-2022-CN has no alternation constraint on 1- and 2-byte segments + // ISO-2022-KR requires alternation between 1- and 2-byte segments + // JIS: + // ( B ISO-2022-JP [1b 28 42] SI to ASCII + // ( J ISO-2022-JP [1b 28 4a] SI to X0201 + // $ @ ISO-2022-JP [1b 24 40] SO to X0208-78 twobyte + // $ B ISO-2022-JP [1b 24 42] SO to X0208-83 twobyte + for (char* s = startbyte; s < endbyte; s += 2) { + if (s[0] == 0x1b) { + if (s[1] == 0x24) { + // $ is SO + destatep->next_2022_state = SOSI_TWOBYTE; // SO to two-byte + } else if (s[1] == 0x28) { + if (destatep->next_2022_state == SOSI_TWOBYTE) { + Boost(destatep, F_JIS, kGentlePairBoost); + } else if (destatep->next_2022_state == SOSI_ONEBYTE) { + Whack(destatep, F_JIS, kGentlePairWhack); + } + destatep->next_2022_state = SOSI_ONEBYTE; // JIS SI to one-byte + } else { + Whack(destatep, F_JIS, kBadPairWhack); + Whack(destatep, F_ISO_2022_CN, kBadPairWhack); + Whack(destatep, F_ISO_2022_KR, kBadPairWhack); + destatep->next_2022_state = SOSI_ERROR; // not 2022 + } + } else if (s[0] == 0x0e) { + // + Whack(destatep, F_JIS, kBadPairWhack); + if (destatep->next_2022_state != SOSI_NONE) { + destatep->next_2022_state = SOSI_TWOBYTE; // SO to two-byte + } else { + // ESC required before SO/SI + Whack(destatep, F_ISO_2022_CN, kBadPairWhack * 4); + Whack(destatep, F_ISO_2022_KR, kBadPairWhack * 4); + destatep->next_2022_state = SOSI_ERROR; // SO not after SI + } + } else if (s[0] == 0x0f) { + // + Whack(destatep, F_JIS, kBadPairWhack); + if (destatep->next_2022_state != SOSI_NONE) { + if (destatep->next_2022_state == SOSI_TWOBYTE) { + Boost(destatep, F_ISO_2022_CN, kGentlePairBoost); + Boost(destatep, F_ISO_2022_KR, kGentlePairBoost); + } else if (destatep->next_2022_state == SOSI_ONEBYTE) { + Whack(destatep, F_ISO_2022_CN, kGentlePairWhack); + Whack(destatep, F_ISO_2022_KR, kGentlePairWhack); + } + destatep->next_2022_state = SOSI_ONEBYTE; // SI to one-byte + } else { + // ESC required before SO/SI + Whack(destatep, F_ISO_2022_CN, kBadPairWhack * 4); + Whack(destatep, F_ISO_2022_KR, kBadPairWhack * 4); + destatep->next_2022_state = SOSI_ERROR; // SI not after SO + } + } else if (s[0] <= 0x1f) { + // Some other control code. Allow ht lf [ff] cr + if ((s[0] != 0x09) && (s[0] != 0x0a) && + (s[0] != 0x0c) && (s[0] != 0x0d)) { + // Otherwise these can float to the top on bad bytes + Whack(destatep, F_JIS, kBadPairWhack); + Whack(destatep, F_ISO_2022_CN, kBadPairWhack); + Whack(destatep, F_ISO_2022_KR, kBadPairWhack); + } + } + } + + // If no start, keep the probability pinned at zero (or below) + if (destatep->next_2022_state == SOSI_NONE) { + destatep->enc_prob[F_ISO_2022_CN] = + minint(0, destatep->enc_prob[F_ISO_2022_CN]); + destatep->enc_prob[F_ISO_2022_KR] = + minint(0, destatep->enc_prob[F_ISO_2022_KR]); + destatep->enc_prob[F_JIS] = + minint(0, destatep->enc_prob[F_JIS]); + } +} + +// We give a gentle boost for each paired ~{ ... ~}, whack others +void CheckHzActiveSeq(DetectEncodingState* destatep) { + int this_pair = destatep->prior_interesting_pair[AsciiPair]; + int startbyteoffset = this_pair * 2; + int endbyteoffset = destatep->next_interesting_pair[AsciiPair] * 2; + char* startbyte = &destatep->interesting_pairs[AsciiPair][startbyteoffset]; + char* endbyte = &destatep->interesting_pairs[AsciiPair][endbyteoffset]; + + for (char* s = startbyte; s < endbyte; s += 2) { + // Look for initial ~{ pair + if ((s[0] == '~') && (s[1] == '{')) { + destatep->next_hz_state = SOSI_TWOBYTE; // SO to two-byte + } + // Also look for closing ~} pair + if ((s[0] == '~') && (s[1] == '}')) { + if (destatep->next_hz_state == SOSI_TWOBYTE) { + Boost(destatep, F_HZ_GB_2312, kGentlePairBoost); + } else if (destatep->next_hz_state == SOSI_ONEBYTE) { + Whack(destatep, F_HZ_GB_2312, kGentlePairWhack); + } + destatep->next_hz_state = SOSI_ONEBYTE; // SI to one-byte + } + } + + // If no start, keep the probability pinned at zero (or below) + if (destatep->next_hz_state == SOSI_NONE) { + destatep->enc_prob[F_HZ_GB_2312] = + minint(0, destatep->enc_prob[F_HZ_GB_2312]); + } +} + +// We give a gentle boost after an odd number of 8Fxxxx triples, which +// put subsequent bigrams out of phase until a low byte or another 8Fxxxx +void CheckEucJpSeq(DetectEncodingState* destatep) { + int this_pair = destatep->prior_interesting_pair[OtherPair]; + int startbyteoffset = this_pair * 2; + int endbyteoffset = destatep->next_interesting_pair[OtherPair] * 2; + char* startbyte = &destatep->interesting_pairs[OtherPair][startbyteoffset]; + char* endbyte = &destatep->interesting_pairs[OtherPair][endbyteoffset]; + + for (char* s = startbyte; s < endbyte; s += 2) { + // Boost if out of phase (otherwise, EUC-JP will score badly after 8Fxxxx) + if (destatep->next_eucjp_oddphase) { + //printf(" EucJp boost[%02x%02x]\n", s[0], s[1]); // TEMP + Boost(destatep, F_EUC_JP, kGentlePairBoost * 2); + } + + uint8 s0 = static_cast(s[0]); + uint8 s1 = static_cast(s[1]); + // Look for phase flip at 8F + if ((s0 & 0x80) == 0x00) { + destatep->next_eucjp_oddphase = false; + } else if (s0 == 0x8f) { + destatep->next_eucjp_oddphase = !destatep->next_eucjp_oddphase; + } + if ((s1 & 0x80) == 0x00) { + destatep->next_eucjp_oddphase = false; + } else if (s1 == 0x8f) { + destatep->next_eucjp_oddphase = !destatep->next_eucjp_oddphase; + } + } +} + +// Boost, whack, or leave alone BINARY probablilty +// Also called if UTF 16/32 active +void CheckBinaryDensity(const uint8* src, DetectEncodingState* destatep, + int delta_otherpairs) { + // No change if not much gathered information + if (delta_otherpairs == 0) { + // Only ASCII pairs this call + return; + } + int next_pair = destatep->next_interesting_pair[OtherPair]; + + // Look at density of interesting pairs [0..src) + int delta_offset = static_cast(src - destatep->initial_src); // actual + + // Look at density of interesting pairs [0..next_interesting) + int low_byte = destatep->interesting_offsets[OtherPair][0]; + //int high_byte = destatep->interesting_offsets[OtherPair][next_pair - 1] + 2; + //int byte_span = high_byte - low_byte; + int byte_span = delta_offset - low_byte; + + // If all ASCII for the first 4KB, reject + // If mostly ASCII in the first 5KB, reject + if ((low_byte >= kBinaryHardAsciiLimit) || (delta_offset >= kBinarySoftAsciiLimit)) { + // Not binary early enough in text + Whack(destatep, F_BINARY, kBadPairWhack * 4); + Whack(destatep, F_UTF_32BE, kBadPairWhack * 4); + Whack(destatep, F_UTF_32LE, kBadPairWhack * 4); + Whack(destatep, F_UTF_16BE, kBadPairWhack * 4); + Whack(destatep, F_UTF_16LE, kBadPairWhack * 4); + return; + } + + // Density 1.0 for N pairs takes 2*N bytes + // Whack if < 1/16 after first non_ASCII pair + if ((next_pair * 2 * 16) < byte_span) { + // Not dense enough + Whack(destatep, F_BINARY, kBadPairWhack * 4); + Whack(destatep, F_UTF_32BE, kBadPairWhack * 4); + Whack(destatep, F_UTF_32LE, kBadPairWhack * 4); + Whack(destatep, F_UTF_16BE, kBadPairWhack * 4); + Whack(destatep, F_UTF_16LE, kBadPairWhack * 4); + } + + if (next_pair < 8) { + // Fewer than 8 non-ASCII total; too soon to boost + return; + } + + // Density 1.0 for N pairs takes 2*N bytes + // Boost if density >= 1/4, whack if < 1/16 + if ((next_pair * 2 * 4) >= byte_span) { + // Very dense + // Only boost if at least 2 quadrants seen + if (destatep->binary_quadrants_count >= 2) { + Boost(destatep, F_BINARY, kSmallInitDiff); + Boost(destatep, F_UTF_32BE, kSmallInitDiff); + Boost(destatep, F_UTF_32LE, kSmallInitDiff); + Boost(destatep, F_UTF_16BE, kSmallInitDiff); + Boost(destatep, F_UTF_16LE, kSmallInitDiff); + } + } +} + + +// Look at a number of special-case encodings whose reliable detection depends +// on sequencing or other properties +// AsciiPair probibilities (UTF7 and HZ) are all done here +void ActiveSpecialBoostWhack(const uint8* src, DetectEncodingState* destatep) { + int delta_asciipairs = destatep->next_interesting_pair[AsciiPair] - + destatep->prior_interesting_pair[AsciiPair]; + int delta_otherpairs = destatep->next_interesting_pair[OtherPair] - + destatep->prior_interesting_pair[OtherPair]; + + // The two pure ASCII encodings + if (UTF7OrHzActive(destatep) && (delta_asciipairs > 0)) { + // Adjust per pair + for (int i = 0; i < delta_asciipairs; ++i) { + int next_pair = destatep->prior_interesting_pair[AsciiPair] + i; + uint8 byte1 = destatep->interesting_pairs[AsciiPair][next_pair * 2 + 0]; + uint8 byte2 = destatep->interesting_pairs[AsciiPair][next_pair * 2 + 1]; + if (byte1 == '+') { + // Boost, whack, or leave alone UTF-7 probablilty + UTF7BoostWhack(destatep, next_pair, byte2); + if (destatep->debug_data != NULL) { + // Show UTF7 entry + char buff[16]; + snprintf(buff, sizeof(buff), "%02x%02x+", byte1, byte2); + SetDetailsEncProb(destatep, + destatep->interesting_offsets[AsciiPair][next_pair], + kMostLikelyEncoding[(byte1 << 8) + byte2], + buff); + } + } else if (byte1 == '~') { + // Boost, whack, or leave alone HZ probablilty + HzBoostWhack(destatep, byte1, byte2); + if (destatep->debug_data != NULL) { + // Show Hz entry + char buff[16]; + snprintf(buff, sizeof(buff), "%02x%02x~", byte1, byte2); + SetDetailsEncProb(destatep, + destatep->interesting_offsets[AsciiPair][next_pair], + kMostLikelyEncoding[(byte1 << 8) + byte2], + buff); + } + } + } + + // Kill UTF-7 now if at least 8 + pairs and not confirmed valid UTF-7 + if ((destatep->utf7_starts >= 8) && (destatep->prior_utf7_offset == 0)) { + Whack(destatep, F_UTF7, kBadPairWhack * 8); // flush + } + } + + + + // All the other encodings + if (OtherActive(destatep) && (delta_otherpairs > 0)) { + // Adjust per pair + int biggest_weightshift = 0; + for (int i = 0; i < delta_otherpairs; ++i) { + int next_pair = destatep->prior_interesting_pair[OtherPair] + i; + uint8 byte1 = destatep->interesting_pairs[OtherPair][next_pair * 2 + 0]; + uint8 byte2 = destatep->interesting_pairs[OtherPair][next_pair * 2 + 1]; + int off = destatep->interesting_offsets[OtherPair][next_pair]; + int weightshift = destatep->interesting_weightshift[OtherPair][next_pair]; + biggest_weightshift = maxint(biggest_weightshift, weightshift); + + if (byte1 == 0x00) { + if (byte2 == 0x00) { + UTF1632BoostWhack(destatep, off, byte1); + } else if ((kIsPrintableAscii[byte2] != 0) && ((off & 1) != 0)) { + // We have 00xx at an odd offset. Turn into preceding even offset + // for possible Ascii text in UTF-16LE or UTF-32LE (vs BE) + // This will cascade into caller's probability update + // 00 is illegal for all other encodings, so it doesn't matter to them + UTF16MakeEven(destatep, next_pair); + } + if (destatep->debug_data != NULL) { + // Show 0000 detail entry for this bigram + char buff[16]; + snprintf(buff, sizeof(buff), "%02x%02xZ", byte1, byte2); + SetDetailsEncProb(destatep, + destatep->interesting_offsets[OtherPair][next_pair], + kMostLikelyEncoding[(byte1 << 8) + byte2], + buff); + } + } + if (byte1 == 0xff) { + if (byte2 == 0xff) { + UTF1632BoostWhack(destatep, off, byte1); + } + if (destatep->debug_data != NULL) { + // Show FFFF detail entry for this bigram + char buff[16]; + snprintf(buff, sizeof(buff), "%02x%02xF", byte1, byte2); + SetDetailsEncProb(destatep, + destatep->interesting_offsets[OtherPair][next_pair], + kMostLikelyEncoding[(byte1 << 8) + byte2], + buff); + } + } + if (BinaryActive(destatep)) { + BinaryBoostWhack(destatep, byte1, byte2); + } + } // End for i + + // Adjust per entire-pair-span + int utf8_boost = 0; + int utf8utf8_boost = 0; + if (UTF8Active(destatep)) { + utf8_boost = CheckUTF8Seq(destatep, biggest_weightshift); + } + + if (UTF8UTF8Active(destatep)) { + utf8utf8_boost = CheckUTF8UTF8Seq(destatep, biggest_weightshift); + } + + if (UTF1632Active(destatep)) { + CheckUTF32ActiveSeq(destatep); + } + + if (Iso2022Active(destatep)) { + CheckIso2022ActiveSeq(destatep); + } + + if (HzActive(destatep)) { + CheckHzActiveSeq(destatep); + } + + if (EUCJPActive(destatep)) { + CheckEucJpSeq(destatep); + } + + if (BinaryActive(destatep) || UTF1632Active(destatep)) { + CheckBinaryDensity(src, destatep, delta_otherpairs); + } + } + // ISO-2022 do OK on their own, using stright probabilities? Not on bad bytes + + if (destatep->debug_data != NULL) { + // Show sequencing result + SetDetailsEncLabel(destatep, "seq"); + } +} + + +void PrintTopEnc(DetectEncodingState* destatep, int n) { + // Print top n or fewer + int temp_sort[NUM_RANKEDENCODING]; + for (int j = 0; j < destatep->rankedencoding_list_len; ++j) { + int rankedencoding = destatep->rankedencoding_list[j]; + temp_sort[j] = destatep->enc_prob[rankedencoding]; + } + + qsort(temp_sort, destatep->rankedencoding_list_len, + sizeof(temp_sort[0]), IntCompare); + + int top_n = minint(n, destatep->rankedencoding_list_len); + int showme = temp_sort[top_n - 1]; // Print this value and above + + printf("rankedencodingList top %d: ", top_n); + for (int j = 0; j < destatep->rankedencoding_list_len; ++j) { + int rankedencoding = destatep->rankedencoding_list[j]; + if (showme <= destatep->enc_prob[rankedencoding]) { + printf("%s=%d ", + MyEncodingName(kMapToEncoding[rankedencoding]), + destatep->enc_prob[rankedencoding]); + } + } + printf("\n\n"); +} + +// If the same bigram repeats, don't boost its best encoding too much +bool RepeatedBigram(DetectEncodingState* destatep, uint8 byte1, uint8 byte2) { + int this_bigram = (byte1 << 8) | byte2; + // If 00xx 01xx 02xx ... 1fxx, take out bottom 4 bits of xx. + // This ignores parts of Yahoo 0255 0254 0243 0247 0245 0243 0250 0255 ... + // It may screw up UTF-16BE + // It may screw up ISO-2022 (1b24 suppresses 1b28) + if (byte1 < 0x20) { + this_bigram &= 0xfff0; + } + if (this_bigram == destatep->prior_bigram[0]) {return true;} + if (this_bigram == destatep->prior_bigram[1]) {return true;} + if (this_bigram == destatep->prior_bigram[2]) {return true;} + if (this_bigram == destatep->prior_bigram[3]) {return true;} + // Round-robin replacement + destatep->prior_bigram[destatep->next_prior_bigram] = this_bigram; + destatep->next_prior_bigram = (destatep->next_prior_bigram + 1) & 3; + return false; +} + +// Sometimes illegal bytes are used as markers between text that Javascript +// is going to decode. Don't overboost the Binary encoding for markers 01-FF. +// Just count first pair per 8x4 bucket +bool RepeatedBinary(DetectEncodingState* destatep, uint8 byte1, uint8 byte2) { + int bucket8x4 = ((byte1 & 0xe0) >> 3) | ((byte2 & 0xc0) >> 6); + uint32 bucket8x4_mask = 1 << bucket8x4; + if ((destatep->binary_8x4_seen & bucket8x4_mask) == 0) { + destatep->binary_8x4_seen |= bucket8x4_mask; + destatep->binary_8x4_count += 1; + return false; + } + return true; +} + + + + +// Find current top two rankedencoding probabilities +void ReRank(DetectEncodingState* destatep) { + destatep->top_prob = -1; + destatep->second_top_prob = -1; + // Leave unchanged + //destatep->top_rankedencoding = + // destatep->rankedencoding_list[0]; // Just to make well-defined + //destatep->second_top_rankedencoding = + // destatep->rankedencoding_list[1]; // Just to make well-defined + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + int rankedencoding = destatep->rankedencoding_list[j]; + if (destatep->top_prob < destatep->enc_prob[rankedencoding]) { + // Make sure top 2 are in different superset groups + if (kMapEncToBaseEncoding[kMapToEncoding[destatep->top_rankedencoding]] != + kMapEncToBaseEncoding[kMapToEncoding[rankedencoding]]) { + destatep->second_top_prob = + destatep->top_prob; // old top to second + destatep->second_top_rankedencoding = + destatep->top_rankedencoding; // old top to second + } + destatep->top_prob = destatep->enc_prob[rankedencoding]; + destatep->top_rankedencoding = rankedencoding; + } else if (destatep->second_top_prob < destatep->enc_prob[rankedencoding]) { + if (kMapEncToBaseEncoding[kMapToEncoding[destatep->top_rankedencoding]] != + kMapEncToBaseEncoding[kMapToEncoding[rankedencoding]]) { + destatep->second_top_prob = destatep->enc_prob[rankedencoding]; + destatep->second_top_rankedencoding = rankedencoding; + } + } + } +} + +void SimplePrune(DetectEncodingState* destatep, int prune_diff) { + // Prune the list of active encoding families + int keep_prob = destatep->top_prob - prune_diff; + + destatep->active_special = 0; + int k = 0; + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + bool keep = true; + int rankedencoding = destatep->rankedencoding_list[j]; + + // If count is too low, ditch it + if (destatep->enc_prob[rankedencoding] < keep_prob) {keep = false;} + + // Keep it. This will always keep at least top_prob rankedencoding + if (keep) { + destatep->active_special |= kSpecialMask[kMapToEncoding[rankedencoding]]; + destatep->rankedencoding_list[k++] = rankedencoding; + } + } + + destatep->rankedencoding_list_len = k; +} + +// Recalculate reliable +void CalcReliable(DetectEncodingState* destatep) { + // Encoding result is reliable if big difference in top two, or if + // only Ascii7 ever encountered + // Also reliable if exactly one OtherPair and it's best encoding matches top + destatep->reliable = false; + if (destatep->next_interesting_pair[OtherPair] == 0) { + // Only 7-bit ASCII + destatep->reliable = true; + return; + } + if ((destatep->top_prob - destatep->second_top_prob) >= + FLAGS_ced_reliable_difference) { + destatep->reliable = true; + return; + } + if (destatep->next_interesting_pair[OtherPair] == 1) { + uint8 byte1 = destatep->interesting_pairs[OtherPair][0]; + uint8 byte2 = destatep->interesting_pairs[OtherPair][1]; + int best_enc = kMostLikelyEncoding[(byte1 << 8) + byte2]; + if (best_enc == destatep->top_rankedencoding) { + destatep->reliable = true; + return; + } + } + + // If we pruned to one encoding, we are done + if (destatep->rankedencoding_list_len == 1) { + destatep->reliable = true; + destatep->done = true; + return; + } + + // If we pruned to two or three encodings in the same *superset/subset + // rankedencoding* and enough pairs, we are done. Else keep going + if (destatep->rankedencoding_list_len == 2) { + Encoding enc0 = kMapToEncoding[destatep->rankedencoding_list[0]]; + Encoding enc1 = kMapToEncoding[destatep->rankedencoding_list[1]]; + if (kMapEncToBaseEncoding[enc0] == kMapEncToBaseEncoding[enc1]) { + if (destatep->prune_count >= 3) { + destatep->reliable = true; + destatep->done = true; + return; + } + } + } else if (destatep->rankedencoding_list_len == 3) { + Encoding enc0 = kMapToEncoding[destatep->rankedencoding_list[0]]; + Encoding enc1 = kMapToEncoding[destatep->rankedencoding_list[1]]; + Encoding enc2 = kMapToEncoding[destatep->rankedencoding_list[2]]; + Encoding base0 = kMapEncToBaseEncoding[enc0]; + Encoding base1 = kMapEncToBaseEncoding[enc1]; + Encoding base2 = kMapEncToBaseEncoding[enc2]; + + if ((base0 == base1) && (base0 == base2)) { + if (destatep->prune_count >= 3) { + destatep->reliable = true; + destatep->done = true; + return; + } + } + } + +} + + +// Find current top two rankedencoding probabilities +void FindTop2(DetectEncodingState* destatep, + int* first_renc, int* second_renc, + int* first_prob, int* second_prob) { + *first_prob = -1; + *second_prob = -1; + *first_renc = 0; + *second_renc = 0; + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + int rankedencoding = destatep->rankedencoding_list[j]; + if (*first_prob < destatep->enc_prob[rankedencoding]) { + *second_prob = *first_prob; // old top to second + *second_renc = *first_renc; // old top to second + *first_prob = destatep->enc_prob[rankedencoding]; + *first_renc = rankedencoding; + } else if (*second_prob < destatep->enc_prob[rankedencoding]) { + *second_prob = destatep->enc_prob[rankedencoding]; + *second_renc = rankedencoding; + } + } +} + + +void PrintRankedEncodingList(DetectEncodingState* destatep, const char* str) { + printf("Current ranked encoding list %s\n", str); + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + int rankedencoding = destatep->rankedencoding_list[j]; + if ((rankedencoding < 0) || (rankedencoding > NUM_RANKEDENCODING)) { + printf(" [%d] BOGUS rankedencoding = %d\n", j, rankedencoding); + } else { + printf(" [%d] rankedencoding = %d %-12.12s enc_prob = %d\n", + j, rankedencoding, MyRankedEncName(rankedencoding), + destatep->enc_prob[rankedencoding]); + } + } + printf("End current ranked encoding list\n\n"); +} + + + + +// Map unencoded bytes down to five bits, largely preserving letters +// This design struggles to put 33 values into 5 bits. +#define XX 0 // Punctuation (00-7F range) +#define HA 27 // High vowel a in Latin1/2/sometimes7 +#define HE 28 // High vowel e +#define HI 29 // High vowel i +#define HO 30 // High vowel o +#define HU 30 // High vowel u on top of HO +#define Hc 31 // High consonant (80-FF range) +static const char kMapToFiveBits[256] = { + XX,XX,XX,XX,XX,XX,XX,XX, XX,XX,XX,XX,XX,XX,XX,XX, + XX,XX,XX,XX,XX,XX,XX,XX, XX,XX,XX,XX,XX,XX,XX,XX, + XX,XX,XX,XX,XX,XX,XX,XX, XX,XX,XX,XX,XX,XX,XX,XX, + XX,XX,XX,XX,XX,XX,XX,XX, XX,XX,XX,XX,XX,XX,XX,XX, + + XX, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23, 24,25,26,XX,XX,XX,XX,XX, + XX, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23, 24,25,26,XX,XX,XX,XX,XX, + + Hc,HA,Hc,Hc,Hc,Hc,Hc,Hc, HO,Hc,Hc,Hc,Hc,Hc,Hc,Hc, + Hc,HA,Hc,Hc,Hc,Hc,Hc,Hc, HO,Hc,Hc,Hc,Hc,Hc,Hc,Hc, + Hc,HA,Hc,Hc,Hc,Hc,Hc,Hc, HO,Hc,Hc,Hc,Hc,Hc,Hc,Hc, + Hc,HA,Hc,Hc,Hc,Hc,Hc,Hc, HO,Hc,Hc,Hc,Hc,Hc,Hc,Hc, + + Hc,HA,HA,HA,HA,Hc,Hc,Hc, Hc,HE,HE,HE,HI,HI,HI,Hc, + Hc,Hc,Hc,HO,HO,HO,HO,Hc, Hc,HU,HU,HU,HU,Hc,Hc,Hc, + Hc,HA,HA,HA,HA,Hc,Hc,Hc, Hc,HE,HE,HE,HI,HI,HI,Hc, + Hc,Hc,Hc,HO,HO,HO,HO,Hc, Hc,HU,HU,HU,HU,Hc,Hc,Hc, + +}; +#undef XX +#undef HA +#undef HE +#undef HI +#undef HO +#undef HU +#undef Hc + +static const int kTriNoneLikely = 0; +static const int kTriLatin1Likely = 1; +static const int kTriLatin2Likely = 2; +static const int kTriLatin7Likely = 3; + +// Each table entry has 32 times two bits, selected by byte[2] +// Entry subscript is selected by byte[0] and byte[1] +// Latin1/2/7 boost vector, generated 2007.09.26 by postproc-enc-detect-short.cc +static const uint64 kLatin127Trigrams[1024] = { +0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x304080c0402c3330ULL, 0x0008400004000000ULL, 0x082800000c200000ULL, +0x23a0000420800030ULL, 0x00000000000ccc00ULL, 0x0500100100100000ULL, 0x0388400000200010ULL, +0x0000000000000c00ULL, 0xd0f0300740f0cf00ULL, 0x2aa0a2a22882a2acULL, 0x081d800000000080ULL, +0x0c82000020000000ULL, 0x200a03c000a00000ULL, 0x0008400400290000ULL, 0x0400870000000000ULL, +0x00f040c00000c080ULL, 0x0008004000000410ULL, 0x0020300000000030ULL, 0x00a030002c300000ULL, +0x0c8030c020a00000ULL, 0x15410030f0f4c000ULL, 0x3000000300a00000ULL, 0xa2880980a0880a88ULL, +0x0900300000000000ULL, 0x0000040100300000ULL, 0x0888820020a00000ULL, 0xc044002242010000ULL, +0x000000121d300040ULL, 0x40100040440c0d54ULL, 0x00008423102f8144ULL, 0x0b40808400000280ULL, +0x0000000000000000ULL, 0x0680a000000c0000ULL, 0x0880008020aa0000ULL, 0x2aaa0141010a4940ULL, +0xcb80000000010000ULL, 0x2280000000000000ULL, 0x5248000001800000ULL, 0x8000401004040010ULL, +0x1540010201001010ULL, 0x0080080400000000ULL, 0x5a00044040000108ULL, 0x0288000282080008ULL, +0x4800008002200000ULL, 0x4a00000000010100ULL, 0x8a88040080000800ULL, 0x0140800000000400ULL, +0x40010050000c0000ULL, 0x0000008000000000ULL, 0x0028000020140040ULL, 0x8620401401005308ULL, +0xc082000000000400ULL, 0x05c0b004c0240600ULL, 0x0288000080000000ULL, 0x0000014000000000ULL, +0x00000000040000c0ULL, 0x8001861008004280ULL, 0x0200000000000300ULL, 0x0000240242288620ULL, +0x801000c05434c200ULL, 0x9020162040a2d2b4ULL, 0x0021840000240704ULL, 0x2a80280080084908ULL, +0x0000000000000000ULL, 0x0500004000000040ULL, 0x0080000000040000ULL, 0x0108058104440000ULL, +0x0900000000040000ULL, 0x00c0000000208008ULL, 0x2000005000000000ULL, 0x0080000000050000ULL, +0x0808000000001080ULL, 0x9880810100308000ULL, 0x2285480080081a08ULL, 0x8a80000080080000ULL, +0x1450000000600010ULL, 0x2210000100000000ULL, 0x8a88000100011000ULL, 0x1541804000000010ULL, +0xc084011140040100ULL, 0x0000000000000800ULL, 0x0400000000000030ULL, 0x2a800000a0890128ULL, +0x1140a00054000104ULL, 0x1440000101200404ULL, 0x028800400400d800ULL, 0x0000000000000000ULL, +0x0000000000002330ULL, 0x0020820228a02280ULL, 0xa2888a02aa8008a8ULL, 0xd0040a0044202500ULL, +0x8000044104a29424ULL, 0xc000100178b2c5b4ULL, 0x0000810100241504ULL, 0xd040030000380008ULL, +0x0000000000000000ULL, 0x26c08c0000200130ULL, 0x4a08000110080000ULL, 0x2aa0004001080800ULL, +0x0aac000000004000ULL, 0x2000000000200000ULL, 0x4240000100020000ULL, 0x4100000080000000ULL, +0x4900040000000000ULL, 0x0800000400300040ULL, 0x6a80000000040800ULL, 0x2a08182000588008ULL, +0x0a00000c81000008ULL, 0x0a000c0010000000ULL, 0x8a88001080280808ULL, 0x0020000200300600ULL, +0xaac00000900a0000ULL, 0x0000100004000000ULL, 0x0020081020000000ULL, 0x8220105010084110ULL, +0x4a80800000004000ULL, 0x050000c0c0200000ULL, 0x288c000084000000ULL, 0xa048082280000000ULL, +0x0000000000000000ULL, 0x8000900000032080ULL, 0xee889e81b8880820ULL, 0xc2200a8142800424ULL, +0xc020141543361010ULL, 0x10a000204a801634ULL, 0x3a808800802a00a0ULL, 0x28808b00803d0800ULL, +0x0000000000000000ULL, 0x0020000000000030ULL, 0x0808400121010040ULL, 0x0c28240100200040ULL, +0x2008200028800000ULL, 0xc10004c80f30c030ULL, 0x0400440114100000ULL, 0x2208200280a22220ULL, +0x0600000030c01000ULL, 0x1201001040c00000ULL, 0x0aa02ea22aa22aa0ULL, 0x30008000000200a0ULL, +0x20c8400400800000ULL, 0x08280b0420800000ULL, 0x0800100000210000ULL, 0x10000300c0100400ULL, +0xc8c0000420000000ULL, 0x1000000010000000ULL, 0x0420000400000000ULL, 0x0220000500204000ULL, +0x2200000420000000ULL, 0x0000540400000000ULL, 0x0000000020000000ULL, 0x00080c00a0810080ULL, +0x1540000000043000ULL, 0x0000000000100000ULL, 0x2e88a22220200a20ULL, 0xc06030e34ea503a0ULL, +0x0001100204048500ULL, 0x000000e0000c0d54ULL, 0x3000820310a31400ULL, 0x13088c0320e00280ULL, +0x0000000000000000ULL, 0x0480000000200000ULL, 0x4000200100000000ULL, 0x0000300040040000ULL, +0x4400000000000000ULL, 0x0401000002240000ULL, 0x0540000000040000ULL, 0x4004010000000000ULL, +0x4001111001100000ULL, 0x2880000000300040ULL, 0x4040004040002404ULL, 0x0200000000000000ULL, +0x0140040000100000ULL, 0x4040010040040080ULL, 0x0a00140000041004ULL, 0x0000a00400808000ULL, +0x1010200000430040ULL, 0x0010000000000000ULL, 0x0540000000104000ULL, 0x1400114005000000ULL, +0x0000204000440010ULL, 0x0500000000004400ULL, 0x4500000018000400ULL, 0x0000400000000000ULL, +0x000000300000cc00ULL, 0x0100001011300000ULL, 0x0040000000000000ULL, 0xc0e0000248a00444ULL, +0x0000040020340144ULL, 0x0000046445105454ULL, 0x32a0a80280880128ULL, 0x0880040000100100ULL, +0x0000000000000000ULL, 0x14003000030c0004ULL, 0x4a04001100000000ULL, 0x0a00108010000000ULL, +0x28a8004000200248ULL, 0x0100040000b00000ULL, 0x42000000000008c0ULL, 0x6008044010550010ULL, +0x0800401000010400ULL, 0x080080040cf80000ULL, 0x5080000001001010ULL, 0x2a80100000000000ULL, +0xcc8010010d401100ULL, 0x0200000001001000ULL, 0x0480001004001000ULL, 0x8d00800040b40210ULL, +0x6200800000300000ULL, 0x0000010000000000ULL, 0x0428004100010000ULL, 0x4320105141501100ULL, +0xe28c0000000c1000ULL, 0xd5c000c3c0e00300ULL, 0x0001000000100200ULL, 0x1004010202400008ULL, +0x0000000000003000ULL, 0x2aa038a0800aab08ULL, 0x2a88038000000000ULL, 0xc220040242f09720ULL, +0x8020200200ba0420ULL, 0x0020106105101004ULL, 0x0480800000220400ULL, 0x2280100080000008ULL, +0x0000000000000000ULL, 0x9000000000200000ULL, 0x0001000000100000ULL, 0x2aa40c0000080800ULL, +0x0040000040010000ULL, 0x0040000000c01000ULL, 0x4000000040000400ULL, 0x0000001000200000ULL, +0x0000010000000000ULL, 0x05808004000c0000ULL, 0x50400c0000000400ULL, 0x020040008f000040ULL, +0x0800000000100000ULL, 0x0000000000000000ULL, 0x0a08440000004000ULL, 0x0064000400008200ULL, +0x0010010010034170ULL, 0x0000000010000000ULL, 0x0100204021000000ULL, 0x022000d000010100ULL, +0x0840300000c00000ULL, 0x1400000040204400ULL, 0x09800c0040000000ULL, 0x0209708000000000ULL, +0x000000000000c040ULL, 0x90000c50204040a0ULL, 0x0000000000000000ULL, 0x00e1500040200004ULL, +0x8020260540204494ULL, 0x0020026150201054ULL, 0x0281800380105634ULL, 0x0884900481105000ULL, +0x0000000000000000ULL, 0x84203c00002c0200ULL, 0xc089040000000000ULL, 0xc2a8100040200004ULL, +0xe00c1c0000000000ULL, 0x0ce1330080200080ULL, 0x0000000000200000ULL, 0xc400110000404010ULL, +0x0088400000000000ULL, 0x00083cc00c00c00cULL, 0xcac01c00c000580cULL, 0xe300b0f000100000ULL, +0x0300000000000000ULL, 0xc0000f0000000000ULL, 0xc3c01c0400000000ULL, 0x81008004c0f40000ULL, +0xc3d8003000000440ULL, 0x0000000000000000ULL, 0xc430000000000000ULL, 0x0060000000001000ULL, +0x0800000000000000ULL, 0x00c03300f0fc0008ULL, 0x3000000400200010ULL, 0xa2a80892a0880a28ULL, +0x0500000040000004ULL, 0x0000000000000000ULL, 0xc80032070c200020ULL, 0x0220820060a296a0ULL, +0x802084021db486a0ULL, 0x00000d60080c0080ULL, 0xb281803313a32428ULL, 0x1808300320300000ULL, +0x0000000000000000ULL, 0x85208cc0ccac1f20ULL, 0x2081000186100808ULL, 0x22a80880000a0808ULL, +0xaaa8086880000000ULL, 0x802084800a2e9200ULL, 0xa280000000002008ULL, 0xa000000080080400ULL, +0x2080010000000008ULL, 0x802020c00c028c80ULL, 0x2080000000140810ULL, 0x2a80086080080008ULL, +0x2a800000a8000800ULL, 0xaa881800a2080800ULL, 0xaa98004080280808ULL, 0x004483d0c0300000ULL, +0xa280002080080000ULL, 0x0000000000300000ULL, 0x22a1030000000008ULL, 0xa8a0301088880880ULL, +0xaa80002080222808ULL, 0x85400c03fc030400ULL, 0x8a88000000000008ULL, 0xa008008010080008ULL, +0x0000000000010000ULL, 0x0040100000301040ULL, 0x28800000a0002008ULL, 0x122482306cbc0eacULL, +0x8020224222b8c6a0ULL, 0x802002004a82c284ULL, 0x0aa08fc440a41c80ULL, 0x888080d181385098ULL, +0x0000000000000000ULL, 0x00c0b000000c0080ULL, 0x2208001000000800ULL, 0x0a28000000200000ULL, +0x0000000300000000ULL, 0x00c1040000200000ULL, 0x0203020000000000ULL, 0x0248000000020000ULL, +0x0000840000100000ULL, 0x0a808c00c000008cULL, 0x5200040040000004ULL, 0x02000c00000080a0ULL, +0x0b0c000020000000ULL, 0x0b04000001000000ULL, 0x088c0010002000c0ULL, 0x80e08b00c0030c20ULL, +0x0280000200014040ULL, 0x0000000000000000ULL, 0x0e20a0a008000020ULL, 0x0e280fd03f00111cULL, +0x200080c020001000ULL, 0x8cc00c02c02f0400ULL, 0x480c0001000c404cULL, 0x0208014281080808ULL, +0x000000000000fcfcULL, 0x004403300cf00030ULL, 0x2200000000004400ULL, 0x02202000c08c0c20ULL, +0x02202022683a80a0ULL, 0x4020228028008c00ULL, 0x32208cc0002c0200ULL, 0x3ec00c0080304008ULL, +0x0000000000000000ULL, 0x34000c00002c0000ULL, 0x0b00000100100030ULL, 0x0823018000000000ULL, +0x0e8c001c01e00000ULL, 0x1200800600330000ULL, 0x4000110000000000ULL, 0x0080000300000000ULL, +0x0800000000000000ULL, 0x08c08c04000c0000ULL, 0x0080400000880000ULL, 0x0a08000080c00008ULL, +0x0800000304400000ULL, 0x0208000000c00000ULL, 0x2888300080400800ULL, 0x8dc0204400000000ULL, +0xc0000000c0800000ULL, 0x0000c10000000000ULL, 0x24000c4010c00000ULL, 0x272000541d811000ULL, +0x0200400000001000ULL, 0x0400000400001004ULL, 0xc08c007004001000ULL, 0x2048004000000000ULL, +0x000000000003fcfcULL, 0x2aa030000cf8c800ULL, 0xe280000000000000ULL, 0x0a21008142000340ULL, +0x0021002000b61040ULL, 0x800004064006d444ULL, 0x3aa0800300230008ULL, 0x0b00030000300000ULL, +0x0000000000000000ULL, 0x01c080000000040cULL, 0x0100000000004000ULL, 0x0aa8018010001000ULL, +0x0800000000100000ULL, 0x3000000000008c00ULL, 0x5400000013000000ULL, 0x02c0c00004004010ULL, +0x5241100010000c00ULL, 0x0e00080000000808ULL, 0x5281000000000800ULL, 0x0a08108020000800ULL, +0x0a80000000005210ULL, 0x0100000041000000ULL, 0x2a88000002080110ULL, 0x8520800000c00080ULL, +0x01000010108c0100ULL, 0x0000000000000000ULL, 0x42a0420080000000ULL, 0x0020001004010010ULL, +0xc4000000000c0000ULL, 0x01000c00c0200400ULL, 0x4600000100000000ULL, 0x0000000000000000ULL, +0x0010001000000010ULL, 0x910400900820d030ULL, 0x2280000000000000ULL, 0xc2212004400040e4ULL, +0x8001000000b61420ULL, 0xa00002a248e810b4ULL, 0x32008000002c0008ULL, 0x0c010034803c5010ULL, +0x0000000000000000ULL, 0x85008002002c0000ULL, 0x0204001000004010ULL, 0x0120008000200000ULL, +0x000010000c2000c0ULL, 0xccc0000000200000ULL, 0x0400000c00100040ULL, 0x0003300100004100ULL, +0x4000551040000004ULL, 0x0e0080000c820808ULL, 0xc000000000080800ULL, 0xc803000000000000ULL, +0x0a4000c000200000ULL, 0x0040000000c00000ULL, 0x0918145000405000ULL, 0x81400000c0300400ULL, +0x0050000000000000ULL, 0xd000045000000000ULL, 0x0400004000400000ULL, 0x0420104010000110ULL, +0x0700000000203000ULL, 0x34800300c0e00704ULL, 0x4440100044000400ULL, 0x0040000040000000ULL, +0x0030000044000000ULL, 0xeaaca0008808c880ULL, 0x0a01000000200000ULL, 0x1220a300403ccf20ULL, +0x002024c200b61044ULL, 0x802014346aa2d434ULL, 0x30008c00c0820c44ULL, 0x0a000000000c4800ULL, +0x0000000000000000ULL, 0x0000404000340c90ULL, 0x08a8a10820800280ULL, 0x8128009022201000ULL, +0x0020808228a000a0ULL, 0x0020400100410000ULL, 0x0400000110000000ULL, 0xa609000000200000ULL, +0x8008330000d00000ULL, 0x8060100040404010ULL, 0xeaa00ea0ea00808cULL, 0x200c8020a0000020ULL, +0x0408800020200000ULL, 0x0189001403200000ULL, 0xc00800000000c000ULL, 0x200430c00c300000ULL, +0x0100300100004000ULL, 0x0000040000000000ULL, 0x2420000400001000ULL, 0x89a1200400000000ULL, +0x20c8a000208c0000ULL, 0x8080000000000000ULL, 0x28a0108020210080ULL, 0xa2a84800a0880988ULL, +0x258008000400c000ULL, 0x0140000000100000ULL, 0xa028a222a0aa0228ULL, 0xc060012054044040ULL, +0x0010010400000000ULL, 0x00000050150c0114ULL, 0x0000008010c20010ULL, 0xaa088000a0200880ULL, +0x0000000000000000ULL, 0x0700b0c0000c0000ULL, 0x2200040000080030ULL, 0x2aa8808040240800ULL, +0x08b0500000000100ULL, 0x1000830400200000ULL, 0x4204000010000000ULL, 0x40c2200050040050ULL, +0x0104404001010000ULL, 0x1a808c8103c00030ULL, 0x30900010c0000b00ULL, 0x200812b283000008ULL, +0x000c000020e00000ULL, 0x2140000000400000ULL, 0x0288000080200000ULL, 0x8060a200c8a20280ULL, +0x0400114010215000ULL, 0x0000000000000000ULL, 0x082b200002000010ULL, 0x22a0030000031000ULL, +0x008100001000000cULL, 0x05400c00c0230400ULL, 0xca3000003c080100ULL, 0x0000000020000004ULL, +0x0000000100000000ULL, 0x8004320813f5c000ULL, 0xa280080200000800ULL, 0xc22000044e334c20ULL, +0x000004146e361024ULL, 0x800126806aa0d584ULL, 0xb000a0040023c41cULL, 0x0a083000803053d8ULL, +0x0000000000000000ULL, 0x0000100000020000ULL, 0x0000000010000010ULL, 0x0000000045040004ULL, +0x0000000000100000ULL, 0x0000020400000010ULL, 0x0003015000000000ULL, 0x0400000000000000ULL, +0x0000000400000000ULL, 0x0100000000000800ULL, 0x0000001000000000ULL, 0x0000000000000000ULL, +0x0000000040000000ULL, 0x0000000000000000ULL, 0x0004001000000000ULL, 0x0008001000000000ULL, +0x0010000000000004ULL, 0x0000010100001000ULL, 0x0004000000000004ULL, 0x0000014040050014ULL, +0x0014000000000040ULL, 0x5540000000041000ULL, 0x0000000000000000ULL, 0x0000040000000d00ULL, +0x0000000000000000ULL, 0x0000000000100000ULL, 0x0001000000000000ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x0000000000000000ULL, 0x4500000000040400ULL, 0x0000800000000400ULL, +0x0000000000000000ULL, 0x13e080000020000cULL, 0xcf00001005100000ULL, 0x04a8008000200300ULL, +0x00280100100000c0ULL, 0x1c8c000040200000ULL, 0x0600005000100000ULL, 0x050800000c104000ULL, +0x4c10101000110000ULL, 0x0c00000000300000ULL, 0x22040c00100000c0ULL, 0x0800700010100000ULL, +0x0000000000001000ULL, 0x0a08000010000040ULL, 0x0800034004210010ULL, 0x04e0000400000000ULL, +0x0800030020000000ULL, 0x0000005000000000ULL, 0x0400110101304110ULL, 0x0428000010a01000ULL, +0x060b000000800010ULL, 0x35810c00c020c000ULL, 0x00800c4321800000ULL, 0x4208088020000080ULL, +0x040000111003ff00ULL, 0x0020900020202080ULL, 0x22888180a8000888ULL, 0x0225200542005420ULL, +0x2020040400340020ULL, 0x10300424500cc444ULL, 0x3081a00400e00200ULL, 0x33001300c0300000ULL, +0x0000000000000000ULL, 0x04003c0000000000ULL, 0x0a04001000100100ULL, 0x1408000001000000ULL, +0x1800000044100000ULL, 0x3400040400000300ULL, 0x5000040801000040ULL, 0x4088401040000040ULL, +0x1010110130100000ULL, 0xca800c3000300000ULL, 0x5a01000000080100ULL, 0x020280000cd01300ULL, +0x0302000410200010ULL, 0x0000102000300000ULL, 0x0b09000000000000ULL, 0x20008004c4800004ULL, +0x28c0410010000000ULL, 0x0004015041000050ULL, 0x0a01006000200200ULL, 0x0020d00000100040ULL, +0x0010a00100900000ULL, 0x3500bf00c0030300ULL, 0x080c010000200d00ULL, 0x2248000004020010ULL, +0x0000c00000000000ULL, 0x8044b00200e08000ULL, 0xaaa82aa2aa8a2aa8ULL, 0x0220002241c08604ULL, +0x4200260440328444ULL, 0x68001226103008b4ULL, 0x3a0080c0b0000400ULL, 0x2a804804803c4008ULL, +0x0000000000000000ULL, 0x04008c0300000400ULL, 0x008000c0000c0000ULL, 0x088001000000001cULL, +0x0840000001000010ULL, 0x0400000000200c00ULL, 0x4244000101040000ULL, 0x4238007011100000ULL, +0x1000d00100000010ULL, 0x1d00800400300000ULL, 0x4204080c00000000ULL, 0x2a88080080000008ULL, +0x08001c0200001000ULL, 0x0a00000400000000ULL, 0x8a88003080080000ULL, 0x0521800400300000ULL, +0x3200051000201000ULL, 0x0000000000000000ULL, 0x0020801404000000ULL, 0x322010401c0c101cULL, +0x0c01100013000000ULL, 0x04003000c0204000ULL, 0x088c0020a0cc0000ULL, 0x2200000080000018ULL, +0x0404000044000000ULL, 0x82a0b000008820b0ULL, 0x0000040020440000ULL, 0xc2650004403f1420ULL, +0x0021340241b64464ULL, 0x8020040242c2d474ULL, 0x32018c0480288000ULL, 0x00800b0080300000ULL, +0x0000000000000000ULL, 0x05008c0000040130ULL, 0xc0d8000000800000ULL, 0x0020000020200200ULL, +0x23a2000120204000ULL, 0x5052100550104150ULL, 0x1000101100040000ULL, 0xc40001c301000000ULL, +0x8288000000c00000ULL, 0x5150040144d01404ULL, 0xea8c0ea028ae088cULL, 0xc31010c000000c80ULL, +0x0002000060000000ULL, 0xc80800f030000000ULL, 0x0000000400300000ULL, 0xc00080c00ff0c344ULL, +0x00080001200c0000ULL, 0x0000050080000000ULL, 0x0328000300300000ULL, 0x082030000cc01040ULL, +0xeb08800100004000ULL, 0x8030003300c80f00ULL, 0xfb0d0000e4ac0000ULL, 0x0020006080000008ULL, +0x0500100100040000ULL, 0x1140000000000000ULL, 0xcb883330a0e00000ULL, 0xc000010050000080ULL, +0x0010104005b54150ULL, 0x40111d5155001554ULL, 0x80000070140f0004ULL, 0x0b0830c3a0003380ULL, +0x0000000000000000ULL, 0x04c13000000f830cULL, 0x2808000000000000ULL, 0x2810000000000800ULL, +0x08c0080004400000ULL, 0x04c0240300801c20ULL, 0x4040000080000004ULL, 0x0000400100100010ULL, +0x020001008000c0c0ULL, 0x1d008c000c3c0000ULL, 0x0080003000000800ULL, 0x2288080080000008ULL, +0x0a84004020220000ULL, 0x0800080000100000ULL, 0xaa80004080400008ULL, 0x8024000400c01660ULL, +0x80841c2001000104ULL, 0x0001000000000000ULL, 0x0020028020020280ULL, 0x0860404011900100ULL, +0xec80080200000000ULL, 0x010103c100200400ULL, 0x0200004000000000ULL, 0x0000000000400400ULL, +0x000010000003fcfcULL, 0x8040083238c20000ULL, 0x08800220a0920a00ULL, 0x08210004483c0c24ULL, +0xc020240740b0a200ULL, 0x802006014a201494ULL, 0x3201233070ac0e00ULL, 0x08002806033a48a0ULL, +0x0000000000000000ULL, 0x8020820028a00680ULL, 0x2000002000000104ULL, 0x22a80801100a0808ULL, +0xa2a8002080000000ULL, 0xa000800008a08000ULL, 0x0000100000400000ULL, 0x8000002100000000ULL, +0x0000010000004404ULL, 0xa2a0088080000888ULL, 0x0000000010400800ULL, 0xa280082080080008ULL, +0x2280000080010008ULL, 0x2000000000000000ULL, 0x228800008c080808ULL, 0x8021828002a98200ULL, +0xa200002000080000ULL, 0x0000040000000000ULL, 0x22a0000080000000ULL, 0x202882c200800080ULL, +0xa000000001004000ULL, 0x000000c808a00600ULL, 0x0000000010000000ULL, 0x000001000000040cULL, +0x0000000000000000ULL, 0x802002a2a8aa82a0ULL, 0x20000024a8088228ULL, 0x8020820001000000ULL, +0x8020000000808280ULL, 0x8000000000000000ULL, 0x0020800000200280ULL, 0x2080082280a00888ULL, +0x0000000000000000ULL, 0x0000015000000040ULL, 0x0000040000040000ULL, 0x0100010010001000ULL, +0x0000003210008000ULL, 0x0000000404000000ULL, 0x0000000000000400ULL, 0x0200000000000000ULL, +0x0000000000000100ULL, 0x5180014400004050ULL, 0x1000000014000000ULL, 0x4200000000000000ULL, +0x0040200000000000ULL, 0x0201004000000000ULL, 0x0a00000000000010ULL, 0x0040200000800000ULL, +0x0040051000000500ULL, 0x0000000100800400ULL, 0x6000000000000000ULL, 0x0000000000000000ULL, +0x280000c1400040ccULL, 0x4180001000000000ULL, 0x00000000c1000104ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x0000000000000000ULL, 0x0080000000c00000ULL, 0x0004006066004000ULL, +0x0000005000040440ULL, 0x0000106005804044ULL, 0x0000a10511004440ULL, 0x0000000000000110ULL, +0x0000000000000000ULL, 0x0000000000080000ULL, 0xeb0808a020800080ULL, 0x29a80081002a1800ULL, +0x0b2c000202100100ULL, 0x0001000000888000ULL, 0x2280102010000000ULL, 0x020000602a004110ULL, +0x8a800160a6108100ULL, 0x0280000000000020ULL, 0x8a8000a0a8808208ULL, 0x0280882080500308ULL, +0x0b18010020804100ULL, 0xeb080000c0080080ULL, 0x2b08000000810130ULL, 0x0000000008040020ULL, +0xaa0a08e082894140ULL, 0x0000000000000000ULL, 0x202081409010001cULL, 0x8aa8805082806000ULL, +0xeb082900289c0000ULL, 0x0000000000008000ULL, 0xf80c2e20002e0000ULL, 0xa288080420880888ULL, +0x0000010000000000ULL, 0x0000000000102000ULL, 0x22880000a8a80808ULL, 0x022022a22aa880a0ULL, +0x0000222222aa0620ULL, 0x0000022002800000ULL, 0x208080004028a000ULL, 0x2b888800801c0828ULL, +0x0000000000000000ULL, 0x22e0828280a08028ULL, 0xaa88002082080308ULL, 0x0ea80080410a0040ULL, +0x2a28222000a00000ULL, 0x8aa2808028a0a2a0ULL, 0x0200001000000000ULL, 0x82080000a0000000ULL, +0x8800000082000808ULL, 0x2a008a0000300888ULL, 0x0a80080080080808ULL, 0xaa882800840b0808ULL, +0x0a80000080000040ULL, 0xea080820a0000000ULL, 0xaa88080080080808ULL, 0x8040a2800a8024a0ULL, +0xaa800020a0080808ULL, 0x0000040000000000ULL, 0x2a280a0080080880ULL, 0x2a20081080008a00ULL, +0x2a88882088aa0008ULL, 0x81800202c0a01480ULL, 0xea88082082200000ULL, 0xaa88002080080008ULL, +0x0000100000000000ULL, 0x802082a22aa0a2a0ULL, 0x2e80000000000000ULL, 0x0220a2a26aa0a2a8ULL, +0x800022a2228a22a0ULL, 0x880002212e82c0b0ULL, 0x02a0aa0002a82228ULL, 0x2d808b0080380008ULL, +0x0000000000000000ULL, 0x000407551c154244ULL, 0x2a00208088a02228ULL, 0x12a82182a2402a88ULL, +0xe32821e020826d00ULL, 0x801130100ccc1330ULL, 0x028010c000841008ULL, 0x88a08002a0a664a0ULL, +0x0048270080000100ULL, 0x00001f010cd10f30ULL, 0xe2242ce22aaea2a0ULL, 0xc2c00cc20ae22460ULL, +0xe208003128021c10ULL, 0x2a2021c010821080ULL, 0x2a88202082202020ULL, 0x4010111104941410ULL, +0xc80c02c182b00080ULL, 0x0000040000000000ULL, 0xe28030068002c300ULL, 0x2aa02024a2a22228ULL, +0xe20889328aa22080ULL, 0x0000000000210100ULL, 0xaa0028e0a9b221a0ULL, 0x2000008080400000ULL, +0x0000010041150404ULL, 0x0000105114410100ULL, 0xeaa82aa6aaaaaaa8ULL, 0x000000f44300c434ULL, +0x0000222222b00020ULL, 0x0000002000000000ULL, 0x0000004014000000ULL, 0x0039b3f73fbcd3fcULL, +0x0000000000000000ULL, 0x0000104015045040ULL, 0x20a80490a08800a0ULL, 0x40a8258410a909a0ULL, +0xe0a8a2022aa2e2a0ULL, 0xc111010014000500ULL, 0x2080044041840004ULL, 0x28a8200220a2aba0ULL, +0x008400a0a2840800ULL, 0x0101015451009464ULL, 0x20000ea0e02c2c2cULL, 0xe2a828a2aca2aaa8ULL, +0x682020a228a222a0ULL, 0xe8882ae22aa2a2a0ULL, 0xe9a80e6022a24140ULL, 0x0011055005001040ULL, +0x2aa8208229a0aaa4ULL, 0x0000040000000000ULL, 0x28a0228026a62260ULL, 0xe2a020a422a2a020ULL, +0xe808a0022aa1a220ULL, 0x0000010014000100ULL, 0x28ac22802aa2a020ULL, 0x0020000000000000ULL, +0x0100010100040000ULL, 0x0000000000000000ULL, 0x22a822a22a8aaaa0ULL, 0x0000000000000000ULL, +0x0000102410800100ULL, 0x0000000000000000ULL, 0x0000000002000000ULL, 0x00000fb2a08c0aa8ULL, +0x0000000000000000ULL, 0x4010005015440140ULL, 0x18c81c00b180001cULL, 0x2800048021820800ULL, +0x8ab820c06a802580ULL, 0x00100170f4040000ULL, 0x4000144041041404ULL, 0x0ac800d0002e440cULL, +0x20880820a2000808ULL, 0x400000f03f300c00ULL, 0xaa000ea22aa22aa0ULL, 0xa2880ac0a8942a20ULL, +0xaa880a81a1804188ULL, 0xeea022a0aaa02080ULL, 0xaaa820a2aaa66120ULL, 0x0000005115800150ULL, +0x2a880920a0840040ULL, 0x0000040000000000ULL, 0xaea82222aaa22a28ULL, 0x8a28041260055150ULL, +0xa28824008aa28880ULL, 0x0000025014019000ULL, 0xea882ae02aa200a0ULL, 0x0000000000000000ULL, +0x0000000040000400ULL, 0x0000000000000000ULL, 0xaaa82aa22aaaaaa0ULL, 0x0000000000000000ULL, +0x0000000000000000ULL, 0x002003003c80c000ULL, 0x0000020014000000ULL, 0x00200010a0980a20ULL, +0x0000000000000000ULL, 0x0020001200801240ULL, 0x0a88000089800020ULL, 0xcaa00080a1000000ULL, +0x0a200c0020a04080ULL, 0x4002034003840880ULL, 0x4690500190000050ULL, 0x2228004000601000ULL, +0x0a803f00803f400cULL, 0x400033e24dd0cf34ULL, 0xaa80a2a229a220a0ULL, 0x0a224000002c0000ULL, +0x028000202000008cULL, 0x0a08000070000030ULL, 0x00800c040020000cULL, 0x0000000002850000ULL, +0x02881cc310200000ULL, 0x0000040004000000ULL, 0xcba8000400000080ULL, 0xcaa02c0680000000ULL, +0xcc880002008c4080ULL, 0x300000f007f0cf0cULL, 0x0a80001080a00000ULL, 0x820880802a880a80ULL, +0x0000050001040004ULL, 0x0000011000000000ULL, 0x0a8020a2a0202000ULL, 0x0000022202008000ULL, +0x0000222212808000ULL, 0x0020226010000000ULL, 0x000033f33ff3c33cULL, 0x00288002a08c02a8ULL, +0x0000000000000000ULL, 0x04408e0000008200ULL, 0x0808004000900000ULL, 0x0aa8200010ca00c0ULL, +0x0ba80101005d4010ULL, 0x00018604802c8288ULL, 0x00049400101c0000ULL, 0x000c101110505010ULL, +0x0000000000100000ULL, 0x30000c00c022000cULL, 0xd0c00dd0d51d431cULL, 0x0008000010100000ULL, +0x000c1001a0280000ULL, 0x0bc80000c0000000ULL, 0x0a00000080280000ULL, 0x8000a00220308420ULL, +0x0808000010301000ULL, 0x0000040000000000ULL, 0x0d00031480100000ULL, 0x07200000108c0300ULL, +0x0bc0a0c000004000ULL, 0x8000b002c0208480ULL, 0x340c0100118c111cULL, 0x8008008020890000ULL, +0x0000000000040010ULL, 0x0020b00320c1d0b0ULL, 0x00002000000c0000ULL, 0x0020be226e2008a0ULL, +0x002010c03fb0a6a0ULL, 0x00202e222aaec284ULL, 0x00008f0000208400ULL, 0x0000000000300000ULL, +}; +// Latin1 6%, Latin2 11%, Latin7 3% + + + +// Just for debugging. not thread-safe +static char tri_string[4]; +char* Latin127Str(int trisub) { + tri_string[0] = "_abcdefghijklmnopqrstuvwxyzAEIOC"[(trisub >> 10) & 0x1f]; + tri_string[1] = "_abcdefghijklmnopqrstuvwxyzAEIOC"[(trisub >> 5) & 0x1f]; + tri_string[2] = "_abcdefghijklmnopqrstuvwxyzAEIOC"[(trisub >> 0) & 0x1f]; + tri_string[3] = '\0'; + return tri_string; +} + +// Returns two bits per three-byte trigram, indicating +// dont-care, Latin1 likely, Latin2 likely, and Latin7 (ISO-8859-13) likely +int TrigramValue(const uint8* trisrc) { + int byte0_p = kMapToFiveBits[trisrc[0]]; + int byte1_p = kMapToFiveBits[trisrc[1]]; + int byte2_p = kMapToFiveBits[trisrc[2]]; + int subscr = ((byte0_p) << 5) | byte1_p; + int temp = static_cast((kLatin127Trigrams[subscr] >> (byte2_p * 2))); + //printf("%s=%d ", Latin127Str((subscr << 5) | byte2_p), temp & 3); + return temp & 3; +} + + +// Put out trigrams for surrounding 32 bytes for Latin encodings +// Return true if more Latin2 & 7 than Latin1 +bool BoostLatin127Trigrams(int tri_block_offset, + DetectEncodingState* destatep) { + //printf("BoostLatin127Trigrams[%06x]\n", tri_block_offset); + int excess_latin27 = 0; + int srclen = destatep->limit_src - destatep->initial_src; + int hi_limit = minint(tri_block_offset + 32, srclen - 2); + const uint8* trisrc = &destatep->initial_src[tri_block_offset]; + const uint8* trisrclimit = &destatep->initial_src[hi_limit]; + while (trisrc < trisrclimit) { + // Selectively boost Latin1, Latin2, or Latin7 and friends + int trigram_val = TrigramValue(trisrc); + if (trigram_val != 0) { + if (FLAGS_enc_detect_source) { + PsHighlight(trisrc, destatep->initial_src, trigram_val, 1); + } + if (trigram_val == kTriLatin1Likely) { + Boost(destatep, F_Latin1, kTrigramBoost); + Boost(destatep, F_CP1252, kTrigramBoost); + // We don't want to upset the relative rank of a declared 8859-15 + Boost(destatep, F_ISO_8859_15, kTrigramBoost); + --excess_latin27; + } else if (trigram_val == kTriLatin2Likely) { + Boost(destatep, F_Latin2, kTrigramBoost); + Boost(destatep, F_CP1250, kTrigramBoost); + ++excess_latin27; + } else if (trigram_val == kTriLatin7Likely) { + Boost(destatep, F_ISO_8859_13, kTrigramBoost); + Boost(destatep, F_CP1257, kTrigramBoost); + // We don't want to upset the relative rank of a declared 8859-4 or -6 + // for Estonian + Boost(destatep, F_Latin4, kTrigramBoost); + Boost(destatep, F_Latin6, kTrigramBoost); + ++excess_latin27; + } + } + + ++trisrc; + } + //printf("\n"); + + return (0 < excess_latin27); +} + + + +// Boost any encodings that need extra detection help, then prune +// src is first unscanned byte +// slowend means extra pruning when dropping out of initial slow scan +// final means last call -- no bigram at src +void BoostPrune(const uint8* src, DetectEncodingState* destatep, + int prunereason) { + int delta_asciipairs = destatep->next_interesting_pair[AsciiPair] - + destatep->prior_interesting_pair[AsciiPair]; + int delta_otherpairs = destatep->next_interesting_pair[OtherPair] - + destatep->prior_interesting_pair[OtherPair]; + + if (prunereason == PRUNE_FINAL) { + // We are about done + // If we get here with very little accumulated data, the initial hints + // were too strong, so we derate them to n+1 / 12 for n bigrams + if (!destatep->hints_derated && + (destatep->next_interesting_pair[OtherPair] < kDerateHintsBelow)) { + int n = destatep->next_interesting_pair[OtherPair]; + + // Map N pairs to (N+1)/12 portions of the initial hints, etc. + // Floor of 3/12 -- 1/12 and 2/12 are too easy to overcome + int m = maxint(3, (n + 1)); + for (int i = 0; i < NUM_RANKEDENCODING; ++i) { + int original_delta = destatep->hint_prob[i]; + int scaled_delta = (original_delta * m) / kDerateHintsBelow; + destatep->enc_prob[i] -= original_delta; + destatep->enc_prob[i] += scaled_delta; + } + destatep->hints_derated = true; + if (destatep->debug_data != NULL) { + // Show derated-hint result + char buff[32]; + snprintf(buff, sizeof(buff), "Hints %d/%d", m, kDerateHintsBelow); + SetDetailsEncLabel(destatep, buff); + } + } + } + + + ++destatep->prune_count; + + if (prunereason != PRUNE_FINAL) { + // Early outs + if (destatep->rankedencoding_list_len <= 1) { // nothing to prune + destatep->done = true; + return; + } + + if ((destatep->prune_count > 0) && + (delta_asciipairs + delta_otherpairs) == 0) { + // Nothing to do; must have just been called earlier + return; + } + } + + + + // INCREMENT + // ==================== + // Accumulate OtherPair probibilities over all active families + // AsciiPair probibilities are all done in ActiveSpecialBoostWhack + uint8 prior_bad_byte1 = ' '; // won't match first bad pair + uint8 prior_bad_byte2 = ' '; // won't match first bad pair + uint8 or_byte1 = 0; // Track if any current pair has a high bit + int counted_otherpairs = 0; + uint8 prior_byte1x2x = 0; + for (int i = 0; i < delta_otherpairs; ++i) { + int watch1_incr = 0; + int watch2_incr = 0; + int next_pair = destatep->prior_interesting_pair[OtherPair] + i; + + uint8 byte1 = destatep->interesting_pairs[OtherPair][next_pair * 2 + 0]; + uint8 byte2 = destatep->interesting_pairs[OtherPair][next_pair * 2 + 1]; + uint8 byte1x2x = (byte1 & 0xf0) | ((byte2 >> 4) & 0x0f); + int weightshift = destatep->interesting_weightshift[OtherPair][next_pair]; + + int offset_byte12 = destatep->interesting_offsets[OtherPair][next_pair]; + + // To help distinguish some Cyrillic, Arabic, Greek, Hebrew, Thai + // Remember if this is a CDEF pair immediately following the previous pair + // 8xxx CxCx or CxCx 8xxx + bool next_pair_consec_hi = false; + if (ConsecutivePair(destatep, next_pair)) { + if ((byte1x2x & 0xcc) == 0xcc) { // 8xxx CxCx + next_pair_consec_hi = true; + } else if ((prior_byte1x2x & 0xcc) == 0xcc) { // CxCx 8xxx + next_pair_consec_hi = true; + } + } + //printf("prior/cur/consec %02x %02x %d\n", + // prior_byte1x2x, byte1x2x, next_pair_consec_hi); + prior_byte1x2x = byte1x2x; + + or_byte1 |= byte1; + uint8 byte1f = byte1; + // Flip top bit of subscript to better separate quadrant 4 (esp. for Hebrew) + byte1f ^= (byte2 & 0x80); + + // If the same bigram occurred recently, don't increment again + bool pair_used = false; + if (!RepeatedBigram(destatep, byte1, byte2)) { + ++counted_otherpairs; + pair_used = true; + // Boost both charset= declared encodings, so + // Nearly-same probability nearby encoding doesn't drift to the top + if (!FLAGS_demo_nodefault) { + destatep->enc_prob[destatep->declared_enc_1] += kDeclaredEncBoost >> weightshift; + destatep->enc_prob[destatep->declared_enc_2] += kDeclaredEncBoost >> weightshift; + } + bool was_bad_pair = false; + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + int incr_shift = 0; + int rankedencoding = destatep->rankedencoding_list[j]; + Encoding enc = kMapToEncoding[rankedencoding]; + + // For binary, Skip over repeated marker bytes, such as 02, FF, etc. + if ((rankedencoding == F_BINARY) && + RepeatedBinary(destatep, byte1, byte2)) { + incr_shift = 2; // count 1/4 as much if repeated + } + + // If byte 1x2x for this encoding is exactly zero, illegal byte pair + // Don't increment, but instead penalize + const UnigramEntry* ue = &unigram_table[rankedencoding]; + if (ue->b12[byte1x2x] == 0) { + // Don't whack consecutive duplicate bad pairs -- overkill + if ((byte1 != prior_bad_byte1) || (byte2 != prior_bad_byte2)) { + // Extra whack for illegal pair in this encoding + Whack(destatep, rankedencoding, kBadPairWhack >> weightshift); + was_bad_pair = true; + } + } else { + // OK to do the real increment + int incr = ue->b1[byte1f] + ue->b2[byte2] + ue->b12[byte1x2x]; + if ((ue->b12[byte1x2x] & 0x01) != 0) { + // Use a more-precise table + int byte32x32 = ((byte1 & 0x1f) << 5) | (byte2 & 0x1f); + int hiressub = (byte2 & 0x60) >> 5; // select w/bits 5&6 of byte 2 + DCHECK(ue->hires[hiressub] != NULL); + incr += ue->hires[hiressub][byte32x32]; + } else { + // Default final offset + incr += ue->so; + } + incr >>= incr_shift; + + incr >>= weightshift; + destatep->enc_prob[rankedencoding] += incr; // The actual increment + + if (FLAGS_enc_detect_detail2) { + if (watch1_rankedenc == rankedencoding) {watch1_incr = incr;} + if (watch2_rankedenc == rankedencoding) {watch2_incr = incr;} + } + } + + + // If consecutive pair of high bytes, give slight boost to one-byte + // encodings that have a full alphabet in the high bytes + if (next_pair_consec_hi && HighAlphaEncoding(enc)) { + Boost(destatep, rankedencoding, kDeclaredEncBoost >> weightshift); + } + } // End for j < rankedencoding_list_len + + if (was_bad_pair) { + prior_bad_byte1 = byte1; + prior_bad_byte2 = byte2; + } + + // Fold in per-bigram most likely encoding for first N bigrams + if (next_pair < kBestPairsCount) { + int best_enc = kMostLikelyEncoding[(byte1 << 8) + byte2]; + Boost(destatep, best_enc, kBestEncBoost >> weightshift); + } + + // Possibly score 32 trigrams around a bigram to better separate + // Latin1 from Latin2 and Latin7. Especially helpful for detecting + // mis-labelled Hungarian latin2. + // If looking and at bigram 0,8,16,... do full scoring, else just 1 tri + if (destatep->do_latin_trigrams || + destatep->looking_for_latin_trigrams) { + // If just looking, do full scan every 8 times + // Just look up one trigram the other 7 and do full scan if Latin2,7 + bool scan32 = false; + const uint8* trisrc = &destatep->initial_src[offset_byte12 - 1]; + if (!destatep->do_latin_trigrams) { + if ((i & 7) == 0 || trisrc + 3 > destatep->limit_src) { + scan32 = true; + } else { + scan32 = (kTriLatin1Likely < TrigramValue(trisrc)); + } + } + if (destatep->do_latin_trigrams || scan32) { + // Just score each block of 32 bytes once + int tri_block_offset = offset_byte12 & ~0x1f; + if (destatep->trigram_highwater_mark <= tri_block_offset) { + bool turnon = BoostLatin127Trigrams(tri_block_offset, destatep); + if (FLAGS_counts && !destatep->do_latin_trigrams && turnon) { + ++doing_used; // First time + } + if (FLAGS_enc_detect_source) { + if (!destatep->do_latin_trigrams && turnon) { + // First time + PsHighlight(trisrc, destatep->initial_src, 0, 2); + } + } + destatep->do_latin_trigrams |= turnon; + destatep->trigram_highwater_mark = tri_block_offset + 32; + } + } + } + + } // end if RepeatedBigram() + + // Keep track of initial byte high 3 bits + ++destatep->byte32_count[byte1 >> 5]; + + + // TODO: boost subset/superset also + // Boost(destatep, kRelatedEncoding[best_enc], kBestEncBoost); + + if (destatep->debug_data != NULL) { + // Show detail entry for this bigram + char buff[16]; + snprintf(buff, sizeof(buff), "%c%02x%02x%c%c", + pair_used ? ' ' : '[', + byte1, + byte2, + pair_used ? ' ' : ']', + (weightshift == 0) ? ' ' : '-'); + + SetDetailsEncProb(destatep, + destatep->interesting_offsets[OtherPair][next_pair], + kMostLikelyEncoding[(byte1 << 8) + byte2], + buff); + } + if (FLAGS_enc_detect_detail2) { + if ((watch1_incr != 0) || (watch2_incr != 0)) { + // Show increment detail for this encoding + char buff[32]; + snprintf(buff, sizeof(buff), "%c%d %c%d", + (watch1_incr < 0) ? '-' : '+', watch1_incr, + (watch2_incr < 0) ? '-' : '+', watch2_incr); + SetDetailsEncLabel(destatep, buff); + } + } + } // End for i + + + // If no high bit on, demote all the two-byte codes + // WAS BUG. This was inside the loop above and should be outside + if ((counted_otherpairs > 0) && ((or_byte1 & 0x80) == 0)) { + // No high bit in this group (just 02xx, etc.). Whack 2-byte codes + // This keeps SJS from creeping past Latin1 on illegal C0 bytes + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + int rankedencoding = destatep->rankedencoding_list[j]; + Encoding enc = kMapToEncoding[rankedencoding]; + if (TwoByteEncoding(enc)) { + Whack(destatep, rankedencoding, kGentlePairWhack * counted_otherpairs); + } + } + } + + + // BOOST + // ==================== + if (AnyActive(destatep)) { + ActiveSpecialBoostWhack(src, destatep); + } + + // Update for next time + destatep->prior_src = src; + destatep->prior_interesting_pair[AsciiPair] = + destatep->next_interesting_pair[AsciiPair]; + destatep->prior_interesting_pair[OtherPair] = + destatep->next_interesting_pair[OtherPair]; + + + // Do any pre-prune final adjustments + // ==================== + if (prunereason == PRUNE_FINAL) { + // If UTF8 not in base state, whack + if (destatep->next_utf8_ministate != 0) { + Whack(destatep, F_UTF8, kGentlePairWhack * 2 * 1); + } + // If UTF8UTF8 not in base state, whack + if (destatep->next_utf8utf8_ministate != 0) { + Whack(destatep, F_UTF8UTF8, kGentlePairWhack * 2 * 1); + } + + // If no valid UTF-8 char ever seen, whack + if (destatep->utf8_minicount[5] == 0) { + Whack(destatep, F_UTF8, kBadPairWhack * 8); // No sequence + Whack(destatep, F_UTF8UTF8, kBadPairWhack * 8); // No sequence + } + + // If no valid UTF8UTF8 char ever seen, whack + if (destatep->utf8utf8_minicount[5] == 0) { + Whack(destatep, F_UTF8UTF8, kBadPairWhack * 8); // No sequence + } + + // If not all four binary quadrants, whack BINARY; + // worth 2 pair if 3 quads, 4 pair if 1 or 2 quads + if (destatep->binary_quadrants_count < 4) { + if (destatep->binary_quadrants_count == 3) { + Whack(destatep, F_BINARY, kBadPairWhack * 2); + } else { + Whack(destatep, F_BINARY, kBadPairWhack * 4); + } + } + + // If 1st pair is 1b24, choose between ISO-2022-xx + // $ ) C ISO-2022-KR [1b 24 29 43] + // $ ) A ISO-2022-CN [1b 24 29 41] + // $ ) G ISO-2022-CN [1b 24 29 47] + // $ * H ISO-2022-CN [1b 24 2a 48] + // ( B ISO-2022-JP [1b 28 42] to ASCII + // ( J ISO-2022-JP [1b 28 4a] to X0201 + // $ @ ISO-2022-JP [1b 24 40] to X0208-78 twobyte + // $ B ISO-2022-JP [1b 24 42] to X0208-83 twobyte + if ((destatep->next_interesting_pair[OtherPair] >= 1) && + Iso2022Active(destatep)) { + if ((destatep->interesting_pairs[OtherPair][0] == 0x1b) && + (destatep->interesting_pairs[OtherPair][1] == 0x24)) { + int offset = destatep->interesting_offsets[OtherPair][0]; + const uint8* esc_src = destatep->initial_src + offset; + if ((destatep->initial_src + offset) < (destatep->limit_src - 3)) { + if ((esc_src[2] == ')') && (esc_src[3] == 'C')) { + Boost(destatep, F_ISO_2022_KR, kBoostOnePair); + Whack(destatep, F_ISO_2022_CN, kBadPairWhack); + Whack(destatep, F_JIS, kBadPairWhack); + } else if ((esc_src[2] == ')') && ((esc_src[3] == 'A') || + (esc_src[3] == 'G'))) { + Boost(destatep, F_ISO_2022_CN, kBoostOnePair); + Whack(destatep, F_ISO_2022_KR, kBadPairWhack); + Whack(destatep, F_JIS, kBadPairWhack); + } else if ((esc_src[2] == '@') || (esc_src[2] == 'B')) { + Boost(destatep, F_JIS, kBoostOnePair); + Whack(destatep, F_ISO_2022_CN, kBadPairWhack); + Whack(destatep, F_ISO_2022_KR, kBadPairWhack); + } + } else { + // Incomplete escape sequence. Whack them all + Whack(destatep, F_JIS, kBadPairWhack); + Whack(destatep, F_ISO_2022_CN, kBadPairWhack); + Whack(destatep, F_ISO_2022_KR, kBadPairWhack); + } + } + } + if (destatep->debug_data != NULL) { + SetDetailsEncLabel(destatep, "pre-final"); + } + } + + // PRUNE + // ==================== + // Find current top two rankedencoding probabilities + ReRank(destatep); + + if (prunereason == PRUNE_SLOWEND) { + if (destatep->debug_data != NULL) { + SetDetailsEncLabel(destatep, "slow-end"); + } + } + + // Keep every rankedencoding with probablity >= top_prob - prune_difference + int prune_diff = destatep->prune_difference; + // If the top encoding is BINARY, it might be overstated, and we might + // therefore prune away the real encoding. Make the pruning delta + // twice as big. + if (destatep->top_rankedencoding == F_BINARY) { + prune_diff *= 2; + } + int keep_prob = destatep->top_prob - prune_diff; + + // Tighten pruning difference (we start wide) for next time + if (destatep->prune_difference > kFinalPruneDifference) { + int decrement = kPruneDiffDecrement; + // If only ASCII pairs, small tighten; if some non-ASCII, full tighten + if (counted_otherpairs == 0) { + decrement >>= 1; + } + destatep->prune_difference -= decrement; + } + + // Prune the list of active encoding families + destatep->active_special = 0; + int k = 0; + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + bool keep = true; + int rankedencoding = destatep->rankedencoding_list[j]; + + // If count is too low, ditch it + if (destatep->enc_prob[rankedencoding] < keep_prob) { + keep = false; + } + + // If at end of slow section, ditch any 7-bit with zero evidence so far + if ((prunereason == PRUNE_SLOWEND) && + SevenBitEncoding(kMapToEncoding[rankedencoding]) && + (destatep->enc_prob[rankedencoding] <= 0) && + (rankedencoding != destatep->top_rankedencoding)) { + keep = false; + } + + // Keep it. This will always keep at least top_prob rankedencoding + if (keep) { + destatep->active_special |= kSpecialMask[kMapToEncoding[rankedencoding]]; + destatep->rankedencoding_list[k++] = rankedencoding; + } + } + + if (destatep->debug_data != NULL) { + char buff[32]; + snprintf(buff, sizeof(buff), "%d prune", prune_diff / XLOG2); + SetDetailsEncLabel(destatep, buff); + } + destatep->rankedencoding_list_len = k; + + + + // Force final result in some cases + // Do any post-prune final adjustments + if (prunereason == PRUNE_FINAL) { + // If no high-byte pairs, result is ASCII7, BINARY, UTF7, 2022, or HZ + if (destatep->next_interesting_pair[OtherPair] == 0) { + if ((destatep->top_rankedencoding != F_BINARY) && + (destatep->top_rankedencoding != F_UTF7) && + (destatep->top_rankedencoding != F_ISO_2022_CN) && + (destatep->top_rankedencoding != F_ISO_2022_KR) && + (destatep->top_rankedencoding != F_JIS) && + (destatep->top_rankedencoding != F_HZ_GB_2312)) { + destatep->top_rankedencoding = F_ASCII_7_bit; + Boost(destatep, F_ASCII_7_bit, kBoostOnePair * 2); + } + } + + // If some 89 pairs, not ISO_8859_x and vice versa + if (destatep->byte32_count[4] > 0) { + switch (destatep->top_rankedencoding) { + case F_ASCII: // ISO-8859-1 + destatep->top_rankedencoding = F_CP1252; + // Better: destatep->enc_prob[F_ASCII] <==> destatep->enc_prob[F_CP1252] + Boost(destatep, F_CP1252, kBoostOnePair * 2); + break; + case F_Latin2: // ISO-8859-2 + // Don't swap back; not superset + //destatep->top_rankedencoding = F_CP1250; + //Boost(destatep, F_CP1250, kBoostOnePair * 2); + break; + case F_Arabic: // ISO-8859-6 + destatep->top_rankedencoding = F_CP1256; + Boost(destatep, F_CP1256, kBoostOnePair * 2); + break; + case F_Greek: // ISO-8859-7 + // Don't swap -- not proper superset + // Capital Alpha tonos at 0xB6 in ISO-8859-7, 0xA2 in CP1253 + //destatep->top_rankedencoding = F_CP1253; + //Boost(destatep, F_CP1253, kBoostOnePair * 2); + break; + case F_Hebrew: // ISO-8859-8 + // Don't swap -- visual vs. logical + //destatep->top_rankedencoding = F_CP1255; + //Boost(destatep, F_CP1255, kBoostOnePair * 2); + break; + case F_Latin5: // ISO-8859-9 + destatep->top_rankedencoding = F_CP1254; + Boost(destatep, F_CP1254, kBoostOnePair * 2); + break; + case F_ISO_8859_11: // ISO-8859-11 + destatep->top_rankedencoding = F_CP874; + Boost(destatep, F_CP874, kBoostOnePair * 2); + break; + } + } else { + switch (destatep->top_rankedencoding) { + case F_CP1252: // ISO-8859-1 + destatep->top_rankedencoding = F_ASCII; + Boost(destatep, F_ASCII, kBoostOnePair * 2); + break; + case F_CP1250: // ISO-8859-2 + // Don't swap back; not superset + //destatep->top_rankedencoding = F_Latin2; + //Boost(destatep, F_Latin2, kBoostOnePair * 2); + break; + case F_CP1256: // ISO-8859-6 + // Don't swap back -- not proper superset + //destatep->top_rankedencoding = F_Arabic; + //Boost(destatep, F_Arabic, kBoostOnePair * 2); + break; + case F_CP1253: // ISO-8859-7 + // Don't swap back -- not proper superset + //destatep->top_rankedencoding = F_Greek; + //Boost(destatep, F_Greek, kBoostOnePair * 2); + break; + case F_CP1255: // ISO-8859-8 + // Don't swap back -- not proper superset + //destatep->top_rankedencoding = F_Hebrew; + //Boost(destatep, F_Hebrew, kBoostOnePair * 2); + break; + case F_CP1254: // ISO-8859-9 + destatep->top_rankedencoding = F_Latin5; + Boost(destatep, F_Latin5, kBoostOnePair * 2); + break; + case F_CP874: // ISO-8859-11 + destatep->top_rankedencoding = F_ISO_8859_11; + Boost(destatep, F_ISO_8859_11, kBoostOnePair * 2); + break; + } + } + + if (destatep->debug_data != NULL) { + char buff[32]; + snprintf(buff, sizeof(buff), "final %d", + static_cast(src - destatep->initial_src)); + SetDetailsEncLabel(destatep, buff); + + // Show winning encoding and its delta log base2 from 2nd-best + // Divide delta by XLOG2 to get log base 2 + int delta = destatep->top_prob - destatep->second_top_prob; + if (delta < (2 * XLOG2)) { + delta /= XDECILOG2; + snprintf(buff, sizeof(buff), "+%d.%d %s ", + delta / 10, delta % 10, + MyEncodingName(kMapToEncoding[destatep->top_rankedencoding])); + } else if (delta < (50 * XLOG2)) { + delta /= XLOG2; + snprintf(buff, sizeof(buff), "+%d %s", + delta, + MyEncodingName(kMapToEncoding[destatep->top_rankedencoding])); + } else { + snprintf(buff, sizeof(buff), "%s", + MyEncodingName(kMapToEncoding[destatep->top_rankedencoding])); + } + SetDetailsEncProbCopyOffset(destatep, destatep->top_rankedencoding, buff); + } + } + + + // FINISH + // ==================== + // Eventual encoding result is reliable if big difference in top two, or if + // only Ascii7 ever encountered + // Also reliable if exactly one OtherPair and it's best encoding matches top + destatep->reliable = false; + if (destatep->next_interesting_pair[OtherPair] == 0) { + // Only 7-bit ASCII + destatep->reliable = true; + } + if ((destatep->top_prob - destatep->second_top_prob) >= + FLAGS_ced_reliable_difference) { + destatep->reliable = true; + } + if (destatep->next_interesting_pair[OtherPair] == 1) { + uint8 byte1 = destatep->interesting_pairs[OtherPair][0]; + uint8 byte2 = destatep->interesting_pairs[OtherPair][1]; + int best_enc = kMostLikelyEncoding[(byte1 << 8) + byte2]; + if (best_enc == destatep->top_rankedencoding) { + destatep->reliable = true; + } + } + + // If we pruned to one encoding, we are done + if (destatep->rankedencoding_list_len == 1) { + destatep->reliable = true; + destatep->done = true; + } + + // If we pruned to two or three encodings in the same *superset/subset + // rankedencoding* and enough pairs, we are done. Else keep going + if (destatep->rankedencoding_list_len == 2) { + Encoding enc0 = kMapToEncoding[destatep->rankedencoding_list[0]]; + Encoding enc1 = kMapToEncoding[destatep->rankedencoding_list[1]]; + if (kMapEncToBaseEncoding[enc0] == kMapEncToBaseEncoding[enc1]) { + if (destatep->prune_count >= 3) { + destatep->reliable = true; + destatep->done = true; + } + } + } else if (destatep->rankedencoding_list_len == 3) { + Encoding enc0 = kMapToEncoding[destatep->rankedencoding_list[0]]; + Encoding enc1 = kMapToEncoding[destatep->rankedencoding_list[1]]; + Encoding enc2 = kMapToEncoding[destatep->rankedencoding_list[2]]; + Encoding base0 = kMapEncToBaseEncoding[enc0]; + Encoding base1 = kMapEncToBaseEncoding[enc1]; + Encoding base2 = kMapEncToBaseEncoding[enc2]; + + if ((base0 == base1) && (base0 == base2)) { + if (destatep->prune_count >= 3) { + destatep->reliable = true; + destatep->done = true; + } + } + } +} + + +// Accumulate aligned byte-pair at src +// Occasionally, calc boost for some encodings and then prune the active list +// weightshift is used to give low weight some text, such as inside tags +// Returns true if pruning occurred +bool IncrementAndBoostPrune(const uint8* src, + int remaining_length, + DetectEncodingState* destatep, + int weightshift, + int exit_reason) { + destatep->last_pair = src; + // Pick up byte pair, or very last byte plus 0x20 + uint8 byte1 = src[0]; + uint8 byte2 = 0x20; + if (1 < remaining_length) {byte2 = src[1];} + + // whatset=0 for Ascii + ~, 1 for all others; see kTestPrintableAsciiTildePlus + int whatset = exit_reason - 1; + int next_pair = destatep->next_interesting_pair[whatset]; + + if (next_pair > 16) { + // If not clear by 16 bigrams, stop accumulating + ~ 00 + if (byte1 == '+') {return false;} + if (byte1 == '~') {return false;} + if (byte1 == 0x00) {return false;} + } + + // Remember pair in appropriate list + if (next_pair >= kMaxPairs) { + // We have filled up our alloted space for interesting pairs with no + // decision. If ASCII pairs full, just skip until end of slow loop; if + // non-Ascii pairs full, force done + if (whatset == OtherPair) { + destatep->done = true; + } + } else { + int offset = static_cast(src - destatep->initial_src); + destatep->interesting_pairs[whatset][next_pair * 2 + 0] = byte1; + destatep->interesting_pairs[whatset][next_pair * 2 + 1] = byte2; + destatep->interesting_offsets[whatset][next_pair] = offset; + destatep->interesting_weightshift[whatset][next_pair] = weightshift; + ++destatep->next_interesting_pair[whatset]; + ++next_pair; + } + + // Prune now and then , but always if forced to be done + if (destatep->done || ((next_pair & kPruneMask) == 0)) { // Prune every M + BoostPrune(src + 2, destatep, PRUNE_NORMAL); // src+2 first unscanned byte + // may be off end of input + return true; + } + return false; +} + +void DumpSummary(DetectEncodingState* destatep, int whatset, int n) { + printf(" %sSummary[%2d]: ", kWhatSetName[whatset], + destatep->next_interesting_pair[whatset]); + int limit = minint(n, destatep->next_interesting_pair[whatset]); + for (int i = 0; i < limit; ++i) { + printf("%02x%02x ", + destatep->interesting_pairs[whatset][i * 2 + 0], + destatep->interesting_pairs[whatset][i * 2 + 1]); + if ((i & 7) == 7) {printf(" ");} + } + printf("\n"); +} + +void BeginDetail(DetectEncodingState* destatep) { + fprintf(stderr, "%d [", NUM_RANKEDENCODING); + for (int e = 0; e < NUM_RANKEDENCODING; ++e) { + fprintf(stderr, "(%s)", MyRankedEncName(e)); + if ((e % 10) == 9) {fprintf(stderr, "\n ");} + } + fprintf(stderr, "] size-detail\n"); + destatep->next_detail_entry = 0; +} + +// Single character to represent (printable ASCII) gap between bigrams +char DetailOffsetChar(int delta) { + if (delta == 0) {return ' ';} + if (delta <= 2) {return '=';} + if (delta <= 15) {return '_';} + if (delta <= 31) {return '+';} + {return ' ';} +} + +void DumpDetail(DetectEncodingState* destatep) { + // Turn all counts into delta from previous entry + fprintf(stderr, "%d count-detail\n", destatep->next_detail_entry); + // Rewrite, recording deltas + for (int z = destatep->next_detail_entry - 1; z > 0; --z) { + destatep->debug_data[z].offset -= destatep->debug_data[z - 1].offset; + for (int e = 0; e < NUM_RANKEDENCODING; ++e) { + destatep->debug_data[z].detail_enc_prob[e] -= + destatep->debug_data[z - 1].detail_enc_prob[e]; + } + } + // Now print + for (int z = 0; z < destatep->next_detail_entry; ++z) { + // Highlight some entries ending in '!' with light red underbar + int len = destatep->debug_data[z].label.size(); + if (destatep->debug_data[z].label[len - 1] == '!') { + fprintf(stderr, "1 0.9 0.9 do-flag\n"); + } + fprintf(stderr, "(%c%s) %d [", + DetailOffsetChar(destatep->debug_data[z].offset), + destatep->debug_data[z].label.c_str(), + destatep->debug_data[z].best_enc); + for (int e = 0; e < NUM_RANKEDENCODING; ++e) { + fprintf(stderr, "%d ", destatep->debug_data[z].detail_enc_prob[e]); + if ((e % 10) == 9) {fprintf(stderr, " ");} + } + fprintf(stderr, "] do-detail-e\n"); + } + // Get ready for next time,if any + destatep->next_detail_entry = 0; +} + +void PsRecurse(const char* buff) { + fprintf(stderr, "() end-detail (%s) start-detail\n\n", buff); +} + +void DumpReliable(DetectEncodingState* destatep) { + printf("Not reliable: "); + + // Find center of gravity of OtherPair list + int x_sum = 0; + int y_sum = 0; + int count = destatep->next_interesting_pair[OtherPair]; + for (int i = 0; i < count; ++i) { + uint8 byte1 = destatep->interesting_pairs[OtherPair][i * 2 + 0]; + uint8 byte2 = destatep->interesting_pairs[OtherPair][i * 2 + 1]; + x_sum += byte2; + y_sum += byte1; + } + if (count == 0) {count = 1;} // adoid zdiv + int x_bar = x_sum / count; + int y_bar = y_sum / count; + printf("center %02X,%02X\n", x_bar, y_bar); + + double closest_dist = 999.0; + int closest = 0; + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + int rankedencoding = destatep->rankedencoding_list[j]; + const UnigramEntry* ue = &unigram_table[rankedencoding]; + printf(" %8s = %4d at %02x,%02x +/- %02X,%02X ", + MyEncodingName(kMapToEncoding[rankedencoding]), + destatep->enc_prob[rankedencoding], + ue->x_bar, ue->y_bar, + ue->x_stddev, ue->y_stddev); + double x_diff = x_bar - ue->x_bar; + double y_diff = y_bar - ue->y_bar; + double dist = sqrt((x_diff * x_diff) + (y_diff * y_diff)); + printf("(%3.1f)\n", dist); + + if (closest_dist > dist) { + closest_dist = dist; + closest = rankedencoding; + } + } + printf("Closest=%s (%3.1f)\n", + MyEncodingName(kMapToEncoding[closest]), closest_dist); + + for (int i = 0; i < 8; ++i) { + // Demote by distance to CG and see if that helps, or just quit + } +} + +// Scan short single lines quickly for all printable ASCII +// Return true if all bytes are in [20..7F], false otherwise +bool QuickPrintableAsciiScan(const char* text, int text_length) { + const uint8* src = reinterpret_cast(text); + const uint8* srclimit = src + text_length; + const uint8* srclimit8 = srclimit - 7; + while (src < srclimit8) { + // Exits on any byte outside [0x20..0x7E] range (HT LF CR exit) + uint8 mask = 0; + for (int i = 0; i < 8; ++i) mask |= (src[i]-0x20)|(src[i]+0x01); + if ((mask & 0x80) != 0) break; + src += 8; + } + while (src < srclimit) { + uint8 uc = *src++; + if (kIsPrintableAscii[uc] == 0) {return false;} + } + return true; +} + +static const int kMaxScanBack = 192; +static const int kMaxScanForward = 64; + +// Return true if text is inside a tag or JS comment +bool TextInsideTag(const uint8* isrc, const uint8* src, const uint8* srclimit) { + const uint8* srcbacklimit = src - kMaxScanBack; + if (srcbacklimit < isrc) { + srcbacklimit = isrc; + } + const uint8* ss = src - 1; + while (srcbacklimit <= ss) { + uint8 c = *ss--; + if ((c & ~0x02) == '<') { + // We found preceding < 3C or > 3E nearby + // Even cheaper: if inside a tag, we don't care what tag; return true + if (c == '<') { + return true; + } + // See if we are just after ... + if ((c == '>') && (isrc <= (ss - 5)) && + (ss[-5] == '<') && + ((ss[-4] | 0x20) == 't') && + ((ss[-3] | 0x20) == 'i') && + ((ss[-2] | 0x20) == 't') && + ((ss[-1] | 0x20) == 'l') && + ((ss[-0] | 0x20) == 'e')) { + return true; + } + // See if we are just after <SCRIPT language=javascript>... + if ((c == '>') && (isrc <= (ss - 5)) && + (ss[-5] == 's') && + ((ss[-4] | 0x20) == 'c') && + ((ss[-3] | 0x20) == 'r') && + ((ss[-2] | 0x20) == 'i') && + ((ss[-1] | 0x20) == 'p') && + ((ss[-0] | 0x20) == 't')) { + return true; + } + // Not in a tag + return false; + // See if we are just after JavaScript comment /* ... + } else if (c == '/') { + if (((ss + 2) < srclimit) && (ss[2] == '*')) { + // We backscanned to /* + return true; + } + } + } + + return false; +} + +const uint8* SkipToTagEnd(const uint8* isrc, const uint8* src, const uint8* srclimit) { + const uint8* ss = src + 1; + while (ss <= srclimit) { + uint8 c = *ss++; + if ((c == '<') || (c == '>')) { + return ss; + } + } + return src + 2; // Always make progress, Otherwise we get an infinite loop +} + + +// Take a watch string and map to a ranked encoding. If no match, return -1 +int LookupWatchEnc(const string& watch_str) { + int watchval = -1; + // Mixed encoding maps to enc=UTF8UTF8 + if (watch_str == "UTF8UTF8") { + watchval = F_UTF8UTF8; + } else { + Encoding enc; + if (EncodingFromName(watch_str.c_str(), &enc)) { + watchval = CompactEncDet::BackmapEncodingToRankedEncoding(enc); + } + } + return watchval; +} + +// Return true if enc and enc2 are equal or one is a subset of the other +// or either is UNKNOWN +// also UTF8UTF8 is compatible with both Latin1 and UTF8 +bool CompatibleEnc(Encoding enc, Encoding enc2) { + if (enc < 0) {return false;} + if (NUM_ENCODINGS <= enc) {return false;} + if (enc2 < 0) {return false;} + if (NUM_ENCODINGS <= enc2) {return false;} + if (enc == enc2) {return true;} + if (kMapEncToBaseEncoding[enc] == kMapEncToBaseEncoding[enc2]) {return true;} + + if (enc == ASCII_7BIT) {return true;} + if (enc2 == ASCII_7BIT) {return true;} + if (enc == UNKNOWN_ENCODING) {return true;} + if (enc2 == UNKNOWN_ENCODING) {return true;} + if (enc == UTF8UTF8) { + if (enc2 == UTF8) {return true;} + if (kMapEncToBaseEncoding[enc2] == ISO_8859_1) {return true;} + } + if (enc2 == UTF8UTF8) { + if (enc == UTF8) {return true;} + if (kMapEncToBaseEncoding[enc] == ISO_8859_1) {return true;} + } + + return false; +} + +// Return superset of enc and enc2, which must be compatible +Encoding SupersetEnc(Encoding enc, Encoding enc2) { + //printf(" SupersetEnc (%s, ", MyEncodingName(enc)); // TEMP + //printf("%s) ", MyEncodingName(enc2)); + //printf("= %s\n", + // MyEncodingName(kMapEncToSuperLevel[enc] >= kMapEncToSuperLevel[enc2] ? + // enc :enc2)); + if (kMapEncToSuperLevel[enc] >= kMapEncToSuperLevel[enc2]) { + return enc; + } + return enc2; +} + + +// If unreliable, try rescoring to separate some encodings +Encoding Rescore(Encoding enc, const uint8* isrc, + const uint8* srctextlimit, DetectEncodingState* destatep) { + if (FLAGS_counts) {++rescore_used;} + Encoding new_enc = enc; + + bool rescore_change = false; + + int count = destatep->next_interesting_pair[OtherPair]; + int text_length = srctextlimit - isrc; + for (int i = 0; i < count; ++i) { + int bigram_offset = destatep->interesting_offsets[OtherPair][i]; + uint8 byte0 = (0 < bigram_offset) ? + isrc[bigram_offset - 1] : 0x20; + uint8 byte1 = isrc[bigram_offset + 0]; // Known to have high bit on + uint8 byte2 = ((bigram_offset + 1) < text_length) ? + isrc[bigram_offset + 1] : 0x20; + uint8 byte3 = ((bigram_offset + 2) < text_length) ? + isrc[bigram_offset + 2] : 0x20; + int high_hash = ((byte0 & 0xc0) >> 0) | + ((byte1 & 0xc0) >> 1) | + ((byte2 & 0xc0) >> 4) | + ((byte3 & 0xc0) >> 6); // 00112233 + + // Boost HighAccent encodings for Ascii bit patterns + // 0x1x 0x0x + // 1010 1010 + // 0010 0000 + // + if ((high_hash & 0xaa) == 0x20) { + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + int rankedencoding = destatep->rankedencoding_list[j]; + if (HighAccentEncoding(kMapToEncoding[rankedencoding])) { + // TODO: also want to boost Shift-JIS here if byte1 is Ax..Dx + // TEMP + //printf(" Rescore[%02x] %s +%d\n", + // high_hash, MyRankedEncName(rankedencoding), kGentlePairBoost); + Boost(destatep, rankedencoding, kGentlePairBoost); + rescore_change = true; + } + } + } + + // Whack HighAccent encodings for high bit patterns + // 1x1x 1x1x + // 1010 1010 + // 1010 1010 + // + if ((high_hash & 0xaa) == 0xaa) { + for (int j = 0; j < destatep->rankedencoding_list_len; j++) { + int rankedencoding = destatep->rankedencoding_list[j]; + if (HighAccentEncoding(kMapToEncoding[rankedencoding])) { + // TEMP + //printf(" Rescore[%02x] %s -%d\n", + // high_hash, MyRankedEncName(rankedencoding), kGentlePairBoost); + Whack(destatep, rankedencoding, kGentlePairBoost); + rescore_change = true; + } + } + } + + } + + if (rescore_change) { + ReRank(destatep); + new_enc = kMapToEncoding[destatep->top_rankedencoding]; + + if (destatep->debug_data != NULL) { + char buff[32]; + snprintf(buff, sizeof(buff), "=Rescore %s", MyEncodingName(new_enc)); + SetDetailsEncProb(destatep, + 0, + CompactEncDet::BackmapEncodingToRankedEncoding(new_enc), + buff); + //// DumpDetail(destatep); + } + + SimplePrune(destatep, kFinalPruneDifference); + CalcReliable(destatep); + } + + //if (new_enc != enc) { + // // TEMP + // printf(" Rescore new top encoding = %s\n", + // MyRankedEncName(destatep->top_rankedencoding)); + //} + + return new_enc; +} + + +// Given an encoding, add its corresponding ranked encoding to the set +void AddToSet(Encoding enc, int* list_len, int* list) { + // TEMP print + int item = CompactEncDet::BackmapEncodingToRankedEncoding(enc); + for (int i = 0; i < *list_len; ++i) { + if (list[i] == item) { + return; // Already in the set; don't add again + } + } + list[(*list_len)++] = item; +} + + +static const int kMinRobustBigramCount = 1000; +static const int kMinKBToRobustScan = 64; +static const int kMaxKBToRobustScan = 256; + +// Scan the first 64K or so, just doing raw bigram increments on given +// probability list. +// No fancy duplicate filtering or anything else here. +// Returns number of bigrams counted +int RobustScan(const char* text, + int text_length, + int robust_renc_list_len, + int* robust_renc_list, + int* robust_renc_probs) { + if (FLAGS_counts) {++robust_used;} + // Zero all the result probabilities + for (int i = 0; i < robust_renc_list_len; ++i) { + robust_renc_probs[i] = 0; + } + int max_fast_len = minint(text_length, (kMaxKBToRobustScan << 10)); + const uint8* isrc = reinterpret_cast<const uint8*>(text); + const uint8* src = isrc; + const uint8* srclimitfast2 = isrc + max_fast_len - 1; + const uint8* srclimitfast4 = isrc + max_fast_len - 3; + + int min_fast_len = minint(text_length, (kMinKBToRobustScan << 10)); + const uint8* srclimitmin = isrc + min_fast_len - 1; + + int bigram_count = 0; + + if (FLAGS_enc_detect_source) { + PsSourceInit(kPsSourceWidth); + fprintf(stderr, "(RobustScan) do-src\n"); + } + + // Sum over a big chunk of the input + // Faster loop, no 7-bit-encodings possible, approx 3000 GB/sec + //==================================== + while (src < srclimitfast2) { + // Skip to next interesting bigram + + while (src < srclimitfast4) { + if (((src[0] | src[1] | src[2] | src[3]) & 0x80) != 0) break; + src += 4; + } + + while (src < srclimitfast2) { + if ((src[0] & 0x80) != 0) break; + src++; + } + + if (src < srclimitfast2) { + // We found a bigram with high bit on + // Next 5 lines commented out so we don't show all the source. + //const uint8* srctextlimit = isrc + text_length; + //if (FLAGS_enc_detect_source) { + // PsSource(src, isrc, srctextlimit); + // PsMark(src, 2, isrc, 0); + //} + + uint8 byte1 = src[0]; + uint8 byte2 = src[1]; + uint8 byte1x2x = (byte1 & 0xf0) | ((byte2 >> 4) & 0x0f); + uint8 byte1f = byte1; + // Flip top bit of subscript to better separate quadrant 4 (esp. for Hebrew) + byte1f ^= (byte2 & 0x80); + + // The real increments + for (int j = 0; j < robust_renc_list_len; ++j) { + int rankedencoding = robust_renc_list[j]; + const UnigramEntry* ue = &unigram_table[rankedencoding]; + int incr = ue->b1[byte1f] + ue->b2[byte2] + ue->b12[byte1x2x]; + if ((ue->b12[byte1x2x] & 0x01) != 0) { + // Use a more-precise table + int byte32x32 = ((byte1 & 0x1f) << 5) | (byte2 & 0x1f); + int hiressub = (byte2 & 0x60) >> 5; // select w/bits 5&6 of byte 2 + DCHECK(ue->hires[hiressub] != NULL); + incr += ue->hires[hiressub][byte32x32]; + } else { + // Default final offset + incr += ue->so; + } + robust_renc_probs[j] += incr; + } + + src += 2; // Continue after this bigram + ++bigram_count; + + // Stop after 1000 bigrams reached, if at least 64KB scanned + if ((bigram_count > kMinRobustBigramCount) && (src > srclimitmin)) { + break; + } + + } + } + + if (FLAGS_enc_detect_source) { + fprintf(stderr, "( bigram_count = %d) do-src\n", bigram_count); + if (bigram_count == 0) {bigram_count = 1;} // zdiv + for (int i = 0; i < robust_renc_list_len; ++i) { + fprintf(stderr, "( enc[%-12.12s] = %7d (avg %d)) do-src\n", + MyRankedEncName(robust_renc_list[i]), robust_renc_probs[i], + robust_renc_probs[i] / bigram_count); + } + PsSourceFinish(); + } + + return bigram_count; +} + +// If unreliable, rescan middle of document to see if we can get a better +// answer. Rescan is only worthwhile if there are ~200 bytes or more left, +// since the detector takes as much as 96 bytes of bigrams to decide. +Encoding Rescan(Encoding enc, + const uint8* isrc, + const uint8* src, + const uint8* srctextlimit, + const char* url_hint, + const char* http_charset_hint, + const char* meta_charset_hint, + const int encoding_hint, + const Language language_hint, + const CompactEncDet::TextCorpusType corpus_type, + bool ignore_7bit_mail_encodings, + DetectEncodingState* destatep) { + bool enc_is_reliable = destatep->reliable; + Encoding new_enc = enc; + Encoding second_best_enc = + kMapToEncoding[destatep->second_top_rankedencoding]; + + if (FLAGS_counts) {++rescan_used;} + + int scanned_bytes = src - isrc; + int unscanned_bytes = srctextlimit - src; + int text_length = srctextlimit - isrc; + bool empty_rescan = true; + + // See if enough bytes left to bother doing rescan + if (kMinRescanLength < unscanned_bytes) { + const char* text = reinterpret_cast<const char*>(isrc); + + Encoding one_hint = destatep->http_hint; + if ((one_hint == UNKNOWN_ENCODING) && + (destatep->meta_hint != UNKNOWN_ENCODING)) { + one_hint = destatep->meta_hint; + } + if ((one_hint == UNKNOWN_ENCODING) && + (destatep->bom_hint != UNKNOWN_ENCODING)) { + one_hint = destatep->bom_hint; + } + + // Go to an even offset to keep UTF-16 in synch + int middle_offset = (scanned_bytes + (unscanned_bytes / 2)) & ~1; + CHECK(middle_offset <= text_length); + + // Look back a bit for a low byte to synchronize, else hope for the best. + const uint8* srcbacklimit = isrc + middle_offset - kMaxScanBack; + if (srcbacklimit < src) { + srcbacklimit = src; + } + const uint8* ss = isrc + middle_offset - 1; + while (srcbacklimit <= ss) { + if ((*ss & 0x80) == 0) {break;} + --ss; + } + // Leave middle offset unchanged unless we found a low byte + if (srcbacklimit <= ss) { + // Align to low byte or high byte just after it, whichever is even + middle_offset = (ss - isrc + 1) & ~1; // Even to keep UTF-16 in sync + } + CHECK(middle_offset <= text_length); + + if (destatep->debug_data != NULL) { + SetDetailsEncLabel(destatep, ">> Rescan"); + // Print the current chart before recursive call + DumpDetail(destatep); + + char buff[32]; + snprintf(buff, sizeof(buff), ">> Rescan[%d..%d]", + middle_offset, text_length); + PsRecurse(buff); + } + + int mid_bytes_consumed; + bool mid_is_reliable; + Encoding mid_second_best_enc; + CEDInternalFlags newflags = static_cast<CEDInternalFlags>( + kCEDRescanning + kCEDForceTags); + // Recursive call for rescan of half of remaining + Encoding mid_enc = InternalDetectEncoding( + newflags, + text + middle_offset, + text_length - middle_offset, + url_hint, + http_charset_hint, + meta_charset_hint, + encoding_hint, + language_hint, // User interface lang + corpus_type, + ignore_7bit_mail_encodings, + &mid_bytes_consumed, + &mid_is_reliable, + &mid_second_best_enc); + destatep->reliable = mid_is_reliable; + + empty_rescan = (mid_enc == ASCII_7BIT); + + // Not the right decision if, e.g. enc=Greek, mid=ASCII7, one=KSC + // hence the !empty_rescan term + if (!empty_rescan && CompatibleEnc(one_hint, mid_enc)) { + // Encoding we just found is compatible with the + // single hint (if any); return superset + new_enc = SupersetEnc(one_hint, mid_enc); + } + + // If original and mid are compatible, and both reliable, + // return new_enc = SupersetEnc(enc, mid_enc) + // + // This avoids too much weight on a bogus hint causing a RobustScan + // that gets the wrong answer + if (!empty_rescan && mid_is_reliable && enc_is_reliable && + CompatibleEnc(enc, mid_enc)) { + new_enc = SupersetEnc(enc, mid_enc); + return new_enc; + } + + // if mid unreliable, robustscan + // if mid empty, robustscan + // if original and mid not compatible, robustscan + // if mid and one_hint not compatible, robustscan + + // If we found conflicting data, drop back and do a robust scan of a big + // chunk of the input over a set of candidate encodings + // + if (!mid_is_reliable || + empty_rescan || + !CompatibleEnc(enc, mid_enc) || + !CompatibleEnc(one_hint, mid_enc)) { + int robust_renc_list_len; // Number of active encodings + int robust_renc_list[NUM_RANKEDENCODING]; // List of ranked encodings + int robust_renc_probs[NUM_RANKEDENCODING]; // List of matching probs + + robust_renc_list_len = 0; + AddToSet(enc, &robust_renc_list_len, robust_renc_list); + AddToSet(second_best_enc, &robust_renc_list_len, robust_renc_list); + AddToSet(mid_enc, &robust_renc_list_len, robust_renc_list); + AddToSet(mid_second_best_enc, &robust_renc_list_len, robust_renc_list); + if (destatep->http_hint != UNKNOWN_ENCODING) { + AddToSet(destatep->http_hint, &robust_renc_list_len, robust_renc_list); + } + if (destatep->meta_hint != UNKNOWN_ENCODING) { + AddToSet(destatep->meta_hint, &robust_renc_list_len, robust_renc_list); + } + if (destatep->bom_hint != UNKNOWN_ENCODING) { + AddToSet(destatep->bom_hint, &robust_renc_list_len, robust_renc_list); + } + if (destatep->tld_hint != UNKNOWN_ENCODING) { + AddToSet(destatep->tld_hint, &robust_renc_list_len, robust_renc_list); + } + + // Separate simple scan + // ===================== + if (destatep->debug_data != NULL) { + SetDetailsEncLabel(destatep, ">> RobustScan"); + // Print the current chart before recursive call + DumpDetail(destatep); + + char buff[32]; + snprintf(buff, sizeof(buff), ">> RobustScan[0..%d]", text_length); + PsRecurse(buff); + } + + int bigram_count = RobustScan(text, text_length, + robust_renc_list_len, robust_renc_list, robust_renc_probs); + + // Default to new_enc and update if something better was found + int best_prob = -1; + // TEMP print + for (int i = 0; i < robust_renc_list_len; ++i) { + if (best_prob < robust_renc_probs[i]) { + best_prob = robust_renc_probs[i]; + new_enc = kMapToEncoding[robust_renc_list[i]]; + } + } + + if (destatep->debug_data != NULL) { + char buff[32]; + snprintf(buff, sizeof(buff), "=Robust[%d] %s", + bigram_count, MyEncodingName(new_enc)); + SetDetailsEncProb(destatep, + 0, + CompactEncDet::BackmapEncodingToRankedEncoding(new_enc), + buff); + } + } + } // End if enough bytes + + return new_enc; +} + +// With no hints at all, and perhaps on rescan, we relax our pickiness +// and go ahead and accept the top multibyte encodings, even though +// strictly their web pages should have declared an explicit encoding to +// avoid the HTML standard's default ISO-8859-1. +bool NoHintsCloseEnoughCompatible(Encoding top_enc) { + // First test accepts degenerate cases plus UTF8 and UTF8UTF8 + if (CompatibleEnc(UTF8, top_enc)) {return true;} + + // The rest look for exact match of base encoding + Encoding base_enc = kMapEncToBaseEncoding[top_enc]; + if (base_enc == JAPANESE_EUC_JP) {return true;} + if (base_enc == JAPANESE_SHIFT_JIS) {return true;} + if (base_enc == CHINESE_BIG5) {return true;} + if (base_enc == CHINESE_GB) {return true;} + if (base_enc == KOREAN_EUC_KR) {return true;} + return false; +} + + + +// Scan raw bytes and detect most likely encoding +// Design goals: +// Skip over big initial stretches of seven-bit ASCII bytes very quickly +// Thread safe +// Works equally well on +// 50-byte queries, +// 5000-byte email and +// 50000-byte web pages +// Length 0 input returns ISO_8859_1 (ASCII) encoding +// Setting ignore_7bit_mail_encodings effectively turns off detection of +// UTF-7, HZ, and ISO-2022-xx +Encoding InternalDetectEncoding( + CEDInternalFlags flags, const char* text, int text_length, + const char* url_hint, const char* http_charset_hint, + const char* meta_charset_hint, const int encoding_hint, + const Language language_hint, // User interface lang + const CompactEncDet::TextCorpusType corpus_type, + bool ignore_7bit_mail_encodings, int* bytes_consumed, bool* is_reliable, + Encoding* second_best_enc) { + *bytes_consumed = 0; + *is_reliable = false; + *second_best_enc = ASCII_7BIT; + + if (text_length == 0) { + // Follow the spec. Text might be NULL. + *is_reliable = true; + return ISO_8859_1; + } + + // For very short (20-50 byte) input strings that are highly likely to be + // all printable ASCII, our startup overhead might dominate. We have to do the + // full detection if the ISO-2022-xx, HZ, or UTF-7 encodings are possible. + // Otherwise, we can do a quick scan for printable ASCII. + if ((text_length <= 500) && ignore_7bit_mail_encodings && + QuickPrintableAsciiScan(text, text_length)) { + *is_reliable = true; + return ASCII_7BIT; + } + + // Go for the full boat detection + DetectEncodingState destate; + InitDetectEncodingState(&destate); + + std::unique_ptr<DetailEntry[]> scoped_debug_data; + if (FLAGS_enc_detect_detail) { + // Allocate max 10 details per bigram + scoped_debug_data.reset(new DetailEntry[kMaxPairs * 10]); + destate.debug_data = scoped_debug_data.get(); + // NOTE: destate and scoped_debug_data have exactly the same scope + // All other FLAGS_enc_detect_detail tests use destate.debug_data != NULL + } + + // Get text length limits + // Typically, we scan the first 16KB looking for all encodings, then + // scan the rest (up to 256KB) a bit faster by no longer looking for + // interesting bytes below 0x80. This allows us to skip over runs of + // 7-bit-ASCII much more quickly. + int slow_len = minint(text_length, (FLAGS_enc_detect_slow_max_kb << 10)); + int fast_len = minint(text_length, (FLAGS_enc_detect_fast_max_kb << 10)); + + // Initialize pointers. + // In general, we do not look at last 3 bytes of input in the fast scan + // We do, however want to look at the last byte or so in the slow scan, + // especilly in the case of a very short text whose only interesting + // information is a 3-byte UTF-8 character in the last three bytes. + // If necessary, we fake a last bigram with 0x20 space as a pad byte. + const uint8* isrc = reinterpret_cast<const uint8*>(text); + const uint8* src = isrc; + const uint8* srctextlimit = isrc + text_length; + const uint8* srclimitslow2 = isrc + slow_len - 1; + const uint8* srclimitfast2 = isrc + fast_len - 1; + const uint8* srclimitfast4 = isrc + fast_len - 3; + if (srclimitslow2 > srclimitfast2) { + srclimitslow2 = srclimitfast2; + } + destate.initial_src = isrc; + destate.limit_src = srclimitfast2 + 1; // May include last byte + destate.prior_src = isrc; + destate.last_pair = isrc - 2; + + const char* scan_table = kTestPrintableAsciiTildePlus; + if (ignore_7bit_mail_encodings) { + // Caller wants to ignore UTF-7, HZ, ISO-2022-xx + // Don't stop on + (for UTF-7), nor on ~ (for HZ) + scan_table = kTestPrintableAscii; + } + int exit_reason = 0; + + if (destate.debug_data != NULL) { + BeginDetail(&destate); + // Take any incoming watch encoding name and backmap to the corresponding + // ranked enum value + watch1_rankedenc = LookupWatchEnc(FLAGS_enc_detect_watch1); + if (watch1_rankedenc >= 0) { + fprintf(stderr, "/track-me %d def\n", watch1_rankedenc); + } + + watch2_rankedenc = LookupWatchEnc(FLAGS_enc_detect_watch2); + if (watch2_rankedenc >= 0) { + fprintf(stderr, "/track-me2 %d def\n", watch2_rankedenc); + } + + fprintf(stderr, "%% kDerateHintsBelow = %d\n", kDerateHintsBelow); + } + if (FLAGS_enc_detect_source) { + PsSourceInit(kPsSourceWidth); + PsSource(src, isrc, srctextlimit); + PsMark(src, 4, isrc, 0); + } + + // Apply hints, if any, to probabilities + // NOTE: Encoding probabilites are all zero at this point + ApplyHints(url_hint, + http_charset_hint, + meta_charset_hint, + encoding_hint, + language_hint, + corpus_type, + &destate); + + // NOTE: probabilities up to this point are subject to derating for + // small numbers of bigrams. + // Probability changes after this point are not derated. + + // Do first 4 bytes to pick off strong markers + InitialBytesBoost(isrc, text_length, &destate); + + bool ignored_some_tag_text = false; + int tag_text_bigram_count = 0; + + // Slower loop, approx 500 MB/sec (2.8 GHz P4) + // ASSERT(srclimitslow2 <= srclimitfast2); + //==================================== + DoMoreSlowLoop: + while (src < srclimitslow2) { + // Skip to next interesting byte (this is the slower part) + while (src < srclimitslow2) { + uint8 uc = *src++; + if (scan_table[uc] != 0) {exit_reason = scan_table[uc]; src--; break;} + } + + if (src < srclimitslow2) { + if (FLAGS_enc_detect_source) { + PsSource(src, isrc, srctextlimit); // don't mark yet + } + + int weightshift = 0; + // In the first 16KB, derate new text run inside <title>... and + // inside + if (////((destate.last_pair + 6) <= src) && // if beyond last one + ////(tag_text_bigram_count < kMaxBigramsTagTitleText) && + (corpus_type == CompactEncDet::WEB_CORPUS) && // and web page + !CEDFlagForceTags(flags)) { // and OK to skip + ////if (TextInsideTag(destate.last_pair + 2, src, srclimitslow2)) { + if (TextInsideTag(isrc, src, srclimitslow2)) { + if (tag_text_bigram_count >= kMaxBigramsTagTitleText) { + ignored_some_tag_text = true; + src = SkipToTagEnd(destate.last_pair + 2, src, srclimitslow2); + continue; + } else { + weightshift = kWeightshiftForTagTitleText; + ++tag_text_bigram_count; + } + } + } + if (FLAGS_enc_detect_source) { + PsMark(src, 2, isrc, weightshift); + } + // Saves byte pair and offset + bool pruned = IncrementAndBoostPrune(src, srctextlimit - src, + &destate, weightshift, exit_reason); + // Advance; if inside tag, advance to end of tag + if (weightshift == 0) { + src += exit_reason; // 1 Ascii, 2 other + } else { + src += exit_reason; // 1 Ascii, 2 other + //// src = SkipToTagEnd(destate.last_pair, src, srclimitslow2); + } + + if (pruned) { + // Scoring and active encodings have been updated + if (destate.done) {break;} + // Check if all the reasons for the slow loop have been pruned + // If so, go to fast loop + if (!SevenBitActive(&destate)) {break;} + } + } + } + //==================================== + + // We reached the end of a slow scan, possibly because no more SevenBitActive, + // or possibly are at end of source. + // If we are exactly at the end of the source, make sure we look at the very + // last byte. + bool very_last_byte_incremented = false; + if (src == (srctextlimit - 1)) { + exit_reason = scan_table[*src]; + if (exit_reason != 0) { + // The very last byte is an interesting byte + // Saves byte pair and offset + //printf("Interesting very last slow byte = 0x%02x\n", *src); + IncrementAndBoostPrune(src, srctextlimit - src, &destate, 0, exit_reason); + very_last_byte_incremented = true; + } + } + + if (FLAGS_enc_detect_source) { + PsSource(src, isrc, srctextlimit); + PsMark(src, 2, isrc, 0); + } + // Force a pruning based on whatever we have + // Delete the seven-bit encodings if there is no evidence of them so far + BoostPrune(src, &destate, PRUNE_SLOWEND); + + if (!destate.done) { + // If not clear yet on 7-bit-encodings and more bytes, do more slow + if (SevenBitActive(&destate) && (src < srclimitfast2)) { + // Increment limit by another xxxK + slow_len += (FLAGS_enc_detect_slow_max_kb << 10); + srclimitslow2 = isrc + slow_len - 1; + if (srclimitslow2 > srclimitfast2) { + srclimitslow2 = srclimitfast2; + } + if (!UTF7OrHzActive(&destate)) { + // We can switch to table that does not stop on + ~ + scan_table = kTestPrintableAscii; + } + goto DoMoreSlowLoop; + } + + + exit_reason = 2; + // Faster loop, no 7-bit-encodings possible, approx 3000 GB/sec + //==================================== + while (src < srclimitfast2) { + // Skip to next interesting byte (this is the faster part) + while (src < srclimitfast4) { + if (((src[0] | src[1] | src[2] | src[3]) & 0x80) != 0) break; + src += 4; + } + + while (src < srclimitfast2) { + if ((src[0] & 0x80) != 0) break; + src++; + } + + if (src < srclimitfast2) { + if (FLAGS_enc_detect_source) { + PsSource(src, isrc, srctextlimit); + PsMark(src, 2, isrc, 0); + } + // saves byte pair and offset + bool pruned = IncrementAndBoostPrune(src, srctextlimit - src, + &destate, 0, exit_reason); + src += exit_reason; // 1 Ascii, 2 other + if (pruned) { + // Scoring and active encodings have been updated + if (destate.done) {break;} + } + } + } + //==================================== + // We reached the end of fast scan + + // If we are exactly at the end of the source, make sure we look at the very + // last byte. + if (src == (srctextlimit - 1) && !very_last_byte_incremented) { + exit_reason = scan_table[*src]; + if (exit_reason != 0) { + // The very last byte is an interesting byte + // Saves byte pair and offset + //printf("Interesting very last fast byte = 0x%02x\n", *src); + IncrementAndBoostPrune(src, srctextlimit - src, &destate, 0, exit_reason); + very_last_byte_incremented = true; + } + } + + } // End if !done + + if (FLAGS_enc_detect_source) { + PsSource(src, isrc, srctextlimit); + PsMark(src, 2, isrc, 0); + } + // Force a pruning based on whatever we have + BoostPrune(src, &destate, PRUNE_FINAL); + + if (FLAGS_enc_detect_summary) { + DumpSummary(&destate, AsciiPair, 32); + DumpSummary(&destate, OtherPair, 32); + } + if (FLAGS_enc_detect_source) { + PsSourceFinish(); + } + if (destate.debug_data != NULL) { + //// DumpDetail(&destate); + } + + + if (ignored_some_tag_text && + (kMapToEncoding[destate.top_rankedencoding] == ASCII_7BIT)) { + // There were some interesting bytes, but only in tag text. + // Recursive call to reprocess looking at the tags this time. + + if (destate.debug_data != NULL) { + SetDetailsEncLabel(&destate, ">> Recurse/tags"); + // Print the current chart before recursive call + DumpDetail(&destate); + + char buff[32]; + snprintf(buff, sizeof(buff), ">> Recurse for tags"); + PsRecurse(buff); + } + + // Recursive call for high bytes in tags [no longer used, 1/16 tag score] + Encoding enc2 = InternalDetectEncoding( + kCEDForceTags, // force + text, + text_length, + url_hint, + http_charset_hint, + meta_charset_hint, + encoding_hint, + language_hint, + corpus_type, + ignore_7bit_mail_encodings, + bytes_consumed, + is_reliable, + second_best_enc); + + if (destate.debug_data != NULL) { + // Show winning encoding and dump PostScript + char buff[32]; + snprintf(buff, sizeof(buff), "=2 %s", MyEncodingName(enc2)); + SetDetailsEncProb(&destate, + 0, + CompactEncDet::BackmapEncodingToRankedEncoding(enc2), + buff); + DumpDetail(&destate); + } + + return enc2; + } + + + // If the detected encoding does not match default/hints, or if the hints + // conflict with each other, mark as unreliable. This can be used to trigger + // further scoring. + // Three buckets of input documents; + // ~19% of the web no hints, and top == 7bit, Latin1, or CP1252 + // ~79% of the web one or more hints, all same encoding X and top == X + // ~ 2% of the web one or more hints that are inconsistent + + Encoding top_enc = kMapToEncoding[destate.top_rankedencoding]; + Encoding one_hint = destate.http_hint; + if ((one_hint == UNKNOWN_ENCODING) && + (destate.meta_hint != UNKNOWN_ENCODING)) { + one_hint = destate.meta_hint; + } + if ((one_hint == UNKNOWN_ENCODING) && + (destate.bom_hint != UNKNOWN_ENCODING)) { + one_hint = destate.bom_hint; + } + + bool found_compatible_encoding = true; + if (one_hint == UNKNOWN_ENCODING) { + // [~14% of the web] No hints, and top == 7bit, Latin1, or CP1252 + if (!CompatibleEnc(ISO_8859_1, top_enc)) { + found_compatible_encoding = false; + // If there is nothing but a TLD hint and its top encoding matches, OK + if ((destate.tld_hint != UNKNOWN_ENCODING) && + CompatibleEnc(destate.tld_hint, top_enc)) { + found_compatible_encoding = true; + } + } + } else if (CompatibleEnc(one_hint, destate.http_hint) && + CompatibleEnc(one_hint, destate.meta_hint) && + CompatibleEnc(one_hint, destate.bom_hint)) { + // [~83% of the web] One or more hints, all same encoding X and top == X + if (!CompatibleEnc(one_hint, top_enc)) { + // [~ 2% of the web] Oops, not the declared encoding + found_compatible_encoding = false; + } + } else { + // [~ 3% of the web] Two or more hints that are inconsistent + one_hint = UNKNOWN_ENCODING; + found_compatible_encoding = false; + } + + // If we turned Latin1 into Latin2 or 7 via trigrams, don't fail it here + if (destate.do_latin_trigrams) { + if (CompatibleEnc(kMapToEncoding[F_Latin1], top_enc) || + CompatibleEnc(kMapToEncoding[F_Latin2], top_enc) || + CompatibleEnc(kMapToEncoding[F_CP1250], top_enc) || + CompatibleEnc(kMapToEncoding[F_ISO_8859_13], top_enc)) { + found_compatible_encoding = true; + destate.reliable = true; + } + } + + // If top encoding is not compatible with the hints, but it is reliably + // UTF-8, accept it anyway. + // This will perform badly with mixed UTF-8 prefix plus another encoding in + // the body if done too early, so we want to be rescanning. + if (!found_compatible_encoding && + destate.reliable && + NoHintsCloseEnoughCompatible(top_enc) && + (destate.next_interesting_pair[OtherPair] >= kStrongPairs) && + CEDFlagRescanning(flags)) { + found_compatible_encoding = true; + } + + // Hold off on this so Rescan() can see if the original encoding was reliable + //if (!found_compatible_encoding) { + // destate.reliable = false; + //} + + // If unreliable, try rescoring to separate some encodings + if (!destate.reliable || !found_compatible_encoding) { + top_enc = Rescore(top_enc, isrc, srctextlimit, &destate); + } + + *second_best_enc = kMapToEncoding[destate.second_top_rankedencoding]; + + // If unreliable, and not already rescanning, + // rescan middle of document to see if we can get a better + // answer. Rescan is only worthwhile if there are ~200 bytes or more left, + // since the detector takes as much as 96 bytes of bigrams to decide. + // + // CANNOT retry ISO-2022-xx HZ etc. because no declaration escape at the front + // or we may land in the middle of some partial state. Skip them all. + // + if ((!destate.reliable || !found_compatible_encoding) && + !CEDFlagRescanning(flags) && + !SevenBitEncoding(top_enc)) { + top_enc = Rescan(top_enc, + isrc, + src, + srctextlimit, + url_hint, + http_charset_hint, + meta_charset_hint, + encoding_hint, + language_hint, + corpus_type, + ignore_7bit_mail_encodings, + &destate); + } else { + if (!found_compatible_encoding) { + destate.reliable = false; + } + } + + if (destate.debug_data != NULL) { + // Dump PostScript + DumpDetail(&destate); + } + + *bytes_consumed = src - isrc + 1; // We looked 1 byte beyond src + *is_reliable = destate.reliable; + return top_enc; +} + +Encoding CompactEncDet::DetectEncoding( + const char* text, int text_length, const char* url_hint, + const char* http_charset_hint, const char* meta_charset_hint, + const int encoding_hint, + const Language language_hint, // User interface lang + const TextCorpusType corpus_type, bool ignore_7bit_mail_encodings, + int* bytes_consumed, bool* is_reliable) { + if (FLAGS_ced_echo_input) { + string temp(text, text_length); + fprintf(stderr, "CompactEncDet::DetectEncoding()\n%s\n\n", temp.c_str()); + } + + if (FLAGS_counts) { + encdet_used = 0; + rescore_used = 0; + rescan_used = 0; + robust_used = 0; + looking_used = 0; + doing_used = 0; + ++encdet_used; + } + if (FLAGS_dirtsimple) { + // Just count first 64KB bigram encoding probabilities for each encoding + int robust_renc_list_len; // Number of active encodings + int robust_renc_list[NUM_RANKEDENCODING]; // List of ranked encodings + int robust_renc_probs[NUM_RANKEDENCODING]; // List of matching probs + + for (int i = 0; i < NUM_RANKEDENCODING; ++i) { + robust_renc_list[i] = i; + } + robust_renc_list_len = NUM_RANKEDENCODING; + + RobustScan(text, text_length, + robust_renc_list_len, robust_renc_list, robust_renc_probs); + + // Pick off best encoding + int best_prob = -1; + Encoding enc = UNKNOWN_ENCODING; + for (int i = 0; i < robust_renc_list_len; ++i) { + if (best_prob < robust_renc_probs[i]) { + best_prob = robust_renc_probs[i]; + enc = kMapToEncoding[robust_renc_list[i]]; + } + } + + *bytes_consumed = minint(text_length, (kMaxKBToRobustScan << 10)); + *is_reliable = true; + if (FLAGS_counts) { + printf("CEDcounts "); + while (encdet_used--) {printf("encdet ");} + while (rescore_used--) {printf("rescore ");} + while (rescan_used--) {printf("rescan ");} + while (robust_used--) {printf("robust ");} + while (looking_used--) {printf("looking ");} + while (doing_used--) {printf("doing ");} + printf("\n"); + } + + return enc; + } + + Encoding second_best_enc; + Encoding enc = InternalDetectEncoding(kCEDNone, + text, + text_length, + url_hint, + http_charset_hint, + meta_charset_hint, + encoding_hint, + language_hint, // User interface lang + corpus_type, + ignore_7bit_mail_encodings, + bytes_consumed, + is_reliable, + &second_best_enc); + if (FLAGS_counts) { + printf("CEDcounts "); + while (encdet_used--) {printf("encdet ");} + while (rescore_used--) {printf("rescore ");} + while (rescan_used--) {printf("rescan ");} + while (robust_used--) {printf("robust ");} + while (looking_used--) {printf("looking ");} + while (doing_used--) {printf("doing ");} + printf("\n"); + } + +#if defined(HTML5_MODE) + // Map all the Shift-JIS variants to Shift-JIS when used in Japanese locale. + if (language_hint == JAPANESE && IsShiftJisOrVariant(enc)) { + enc = JAPANESE_SHIFT_JIS; + } + + // 7-bit encodings (except ISO-2022-JP), and some obscure encodings not + // supported in WHATWG encoding standard are marked as ASCII to keep the raw + // bytes intact. + switch (enc) { + case ISO_2022_KR: + case ISO_2022_CN: + case HZ_GB_2312: + case UTF7: + case UTF16LE: + case UTF16BE: + + case CHINESE_EUC_DEC: + case CHINESE_CNS: + case CHINESE_BIG5_CP950: + case JAPANESE_CP932: + case MSFT_CP874: + case TSCII: + case TAMIL_MONO: + case TAMIL_BI: + case JAGRAN: + case BHASKAR: + case HTCHANAKYA: + case BINARYENC: + case UTF8UTF8: + case TAM_ELANGO: + case TAM_LTTMBARANI: + case TAM_SHREE: + case TAM_TBOOMIS: + case TAM_TMNEWS: + case TAM_WEBTAMIL: + case KDDI_SHIFT_JIS: + case DOCOMO_SHIFT_JIS: + case SOFTBANK_SHIFT_JIS: + case KDDI_ISO_2022_JP: + case SOFTBANK_ISO_2022_JP: + enc = ASCII_7BIT; + break; + default: + break; + } +#endif + + return enc; +} + + +// Return top encoding hint for given string +Encoding CompactEncDet::TopEncodingOfLangHint(const char* name) { + string normalized_lang = MakeChar8(string(name)); + int n = HintBinaryLookup8(kLangHintProbs, kLangHintProbsSize, + normalized_lang.c_str()); + if (n < 0) {return UNKNOWN_ENCODING;} + + // Charset is eight bytes, probability table is eight bytes + int toprankenc = + TopCompressedProb(&kLangHintProbs[n].key_prob[kMaxLangKey], + kMaxLangVector); + return kMapToEncoding[toprankenc]; +} + +// Return top encoding hint for given string +Encoding CompactEncDet::TopEncodingOfTLDHint(const char* name) { + string normalized_tld = MakeChar4(string(name)); + int n = HintBinaryLookup4(kTLDHintProbs, kTLDHintProbsSize, + normalized_tld.c_str()); + if (n < 0) {return UNKNOWN_ENCODING;} + + // TLD is four bytes, probability table is 12 bytes + int toprankenc = + TopCompressedProb(&kTLDHintProbs[n].key_prob[kMaxTldKey], + kMaxTldVector); + return kMapToEncoding[toprankenc]; +} + +// Return top encoding hint for given string +Encoding CompactEncDet::TopEncodingOfCharsetHint(const char* name) { + string normalized_charset = MakeChar44(string(name)); + int n = HintBinaryLookup8(kCharsetHintProbs, kCharsetHintProbsSize, + normalized_charset.c_str()); + if (n < 0) {return UNKNOWN_ENCODING;} + + // Charset is eight bytes, probability table is eight bytes + int toprankenc = + TopCompressedProb(&kCharsetHintProbs[n].key_prob[kMaxCharsetKey], + kMaxCharsetVector); + return kMapToEncoding[toprankenc]; +} + +const char* CompactEncDet::Version(void) { + return kVersion; +} diff --git a/ced/compact_enc_det/compact_enc_det.h b/ced/compact_enc_det/compact_enc_det.h new file mode 100644 index 0000000..d43e9a4 --- /dev/null +++ b/ced/compact_enc_det/compact_enc_det.h @@ -0,0 +1,83 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef COMPACT_ENC_DET_COMPACT_ENC_DET_H_ +#define COMPACT_ENC_DET_COMPACT_ENC_DET_H_ + +#include "util/encodings/encodings.h" // for Encoding +#include "util/languages/languages.h" // for Language + +#include + +namespace CompactEncDet { + // We may want different statistics, depending on whether the text being + // identfied is from the web, from email, etc. This is currently ignored, + // except WEB_CORPUS enables ignoring chars inside tags. + enum TextCorpusType { + WEB_CORPUS, + XML_CORPUS, + QUERY_CORPUS, // Use this for vanilla plaintext + EMAIL_CORPUS, + NUM_CORPA, // always last + }; + + // Scan raw bytes and detect most likely encoding + // Design goals: + // Skip over big initial stretches of seven-bit ASCII bytes very quickly + // Thread safe + // Works equally well on + // 50-byte queries, + // 5000-byte email and + // 50000-byte web pages + // Length 0 input returns ASCII (aka ISO-8859-1 or Latin1) + // + // Inputs: text and text_length + // web page's url (preferred) or just + // top-level domain name (e.g. "com") or NULL as a hint + // web page's HTTPheader charset= string (e.g. "Latin1") or NULL as a hint + // web page's tag charset= string (e.g. "utf-8") or NULL as a hint + // an Encoding or UNKNOWN_ENCODING as a hint + // a Language or UNKNOWN_LANGUAGE as a hint + // corpus type from the list above. Currently ignored; may select + // different probability tables in the future + // ignore_7bit if true says to NOT return the pure seven-bit encodings + // ISO-2022-JP (aka JIS), ISO-2022-CN, ISO-2022-KR, HZ, and UTF-7. + // This may save a little scoring time on pure printable ASCII input text + // Outputs: bytes_consumed says how much of text_length was actually examined + // is_reliable set true if the returned encoding is at least 2**10 time more + // probable then the second-best encoding + // Return value: the most likely encoding for the input text + // + // Setting ignore_7bit_mail_encodings effectively turns off detection of + // UTF-7, HZ, and ISO-2022-xx. It is recommended that this flag be true + // when corpus_type is QUERY_CORPUS. + Encoding DetectEncoding( + const char* text, int text_length, const char* url_hint, + const char* http_charset_hint, const char* meta_charset_hint, + const int encoding_hint, + const Language language_hint, // User interface lang + const TextCorpusType corpus_type, bool ignore_7bit_mail_encodings, + int* bytes_consumed, bool* is_reliable); + + // Support functions for unit test program + int BackmapEncodingToRankedEncoding(Encoding enc); + Encoding TopEncodingOfLangHint(const char* name); + Encoding TopEncodingOfTLDHint(const char* name); + Encoding TopEncodingOfCharsetHint(const char* name); + const char* Version(void); +}; // End namespace CompactEncDet + +#endif // COMPACT_ENC_DET_COMPACT_ENC_DET_H_ diff --git a/ced/compact_enc_det/compact_enc_det_generated_tables.h b/ced/compact_enc_det/compact_enc_det_generated_tables.h new file mode 100644 index 0000000..317afb6 --- /dev/null +++ b/ced/compact_enc_det/compact_enc_det_generated_tables.h @@ -0,0 +1,6326 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef COMPACT_ENC_DET_COMPACT_ENC_DET_GENERATED_TABLES_H_ +#define COMPACT_ENC_DET_COMPACT_ENC_DET_GENERATED_TABLES_H_ + +#include "compact_enc_det/compact_enc_det.h" +#include "compact_enc_det/compact_enc_det_generated_tables2.h" +#include "util/basictypes.h" +#include "util/encodings/encodings.pb.h" + +enum RankedEncoding { + F_ASCII_7_bit, // [0] encoding 24 + F_Latin1, // [1] encoding 0 + F_UTF8, // [2] encoding 22 + F_GB, // [3] encoding 14 + F_CP1252, // [4] encoding 27 + F_KSC, // [5] encoding 16 + F_SJS, // [6] encoding 11 + F_EUC_JP, // [7] encoding 10 + F_BIG5, // [8] encoding 13 + F_Latin2, // [9] encoding 1 + F_CP1251, // [10] encoding 26 + F_CP1256, // [11] encoding 35 + F_CP1250, // [12] encoding 29 + F_Latin5, // [13] encoding 8 + F_ISO_8859_11, // [14] encoding 33 + F_ISO_8859_15, // [15] encoding 30 + F_CP1257, // [16] encoding 32 + F_CP1255, // [17] encoding 36 + F_KOI8R, // [18] encoding 25 + F_GBK, // [19] encoding 45 + F_Greek, // [20] encoding 6 + F_JIS, // [21] encoding 12 + F_CP1254, // [22] encoding 31 + F_CP1253, // [23] encoding 41 + F_CP932, // [24] encoding 21 + F_Hebrew, // [25] encoding 7 + F_KOI8U, // [26] encoding 28 + F_ISO_8859_5, // [27] encoding 4 + F_CP874, // [28] encoding 34 + F_ISO_8859_13, // [29] encoding 43 + F_Latin4, // [30] encoding 3 + F_MACINTOSH, // [31] encoding 53 + F_GB18030, // [32] encoding 46 + F_CP852, // [33] encoding 39 + F_Arabic, // [34] encoding 5 + F_BIG5_HKSCS, // [35] encoding 47 + F_CP866, // [36] encoding 42 + F_UTF_16BE, // [37] encoding 57 + F_Latin3, // [38] encoding 2 + F_UTF_16LE, // [39] encoding 58 + F_HZ_GB_2312, // [40] encoding 62 + F_CSN_369103, // [41] encoding 40 + F_ISO_2022_KR, // [42] encoding 44 + F_Latin6, // [43] encoding 9 + F_UTF7, // [44] encoding 54 + F_ISO_2022_CN, // [45] encoding 48 + F_BIG5_CP950, // [46] encoding 20 + F_JAGRAN, // [47] encoding 52 + F_BHASKAR, // [48] encoding 55 + F_HTCHANAKYA, // [49] encoding 56 + F_TSCII, // [50] encoding 49 + F_TAM, // [51] encoding 50 + F_TAB, // [52] encoding 51 + F_EUC_CN, // [53] encoding 15 + F_EUC, // [54] encoding 18 + F_CNS, // [55] encoding 19 + F_UTF_32BE, // [56] encoding 59 + F_UTF_32LE, // [57] encoding 60 + F_X_BINARYENC, // [58] encoding 61 + F_X_UTF8UTF8, // [59] encoding 63 + F_X_TAM_ELANGO, // [60] encoding 64 + F_X_TAM_LTTMBARANI, // [61] encoding 65 + F_X_TAM_SHREE, // [62] encoding 66 + F_X_TAM_TBOOMIS, // [63] encoding 67 + F_X_TAM_TMNEWS, // [64] encoding 68 + F_X_TAM_WEBTAMIL, // [65] encoding 69 + F_UTF8CP1252, // [66] encoding 63 + NUM_RANKEDENCODING +}; + +static const Encoding kMapToEncoding[NUM_RANKEDENCODING] = { + ASCII_7BIT, // encoding 24 + ISO_8859_1, // encoding 0 + UTF8, // encoding 22 + CHINESE_GB, // encoding 14 + MSFT_CP1252, // encoding 27 + KOREAN_EUC_KR, // encoding 16 + JAPANESE_SHIFT_JIS, // encoding 11 + JAPANESE_EUC_JP, // encoding 10 + CHINESE_BIG5, // encoding 13 + ISO_8859_2, // encoding 1 + RUSSIAN_CP1251, // encoding 26 + MSFT_CP1256, // encoding 35 + MSFT_CP1250, // encoding 29 + ISO_8859_9, // encoding 8 + ISO_8859_11, // encoding 33 + ISO_8859_15, // encoding 30 + MSFT_CP1257, // encoding 32 + MSFT_CP1255, // encoding 36 + RUSSIAN_KOI8_R, // encoding 25 + GBK, // encoding 45 + ISO_8859_7, // encoding 6 + JAPANESE_JIS, // encoding 12 + MSFT_CP1254, // encoding 31 + MSFT_CP1253, // encoding 41 + JAPANESE_CP932, // encoding 21 + ISO_8859_8, // encoding 7 + RUSSIAN_KOI8_RU, // encoding 28 + ISO_8859_5, // encoding 4 + MSFT_CP874, // encoding 34 + ISO_8859_13, // encoding 43 + ISO_8859_4, // encoding 3 + MACINTOSH_ROMAN, // encoding 53 + GB18030, // encoding 46 + CZECH_CP852, // encoding 39 + ISO_8859_6, // encoding 5 + BIG5_HKSCS, // encoding 47 + RUSSIAN_CP866, // encoding 42 + UTF16BE, // encoding 57 + ISO_8859_3, // encoding 2 + UTF16LE, // encoding 58 + HZ_GB_2312, // encoding 62 + CZECH_CSN_369103, // encoding 40 + ISO_2022_KR, // encoding 44 + ISO_8859_10, // encoding 9 + UTF7, // encoding 54 + ISO_2022_CN, // encoding 48 + CHINESE_BIG5_CP950, // encoding 20 + JAGRAN, // encoding 52 + BHASKAR, // encoding 55 + HTCHANAKYA, // encoding 56 + TSCII, // encoding 49 + TAMIL_MONO, // encoding 50 + TAMIL_BI, // encoding 51 + CHINESE_EUC_CN, // encoding 15 + CHINESE_EUC_DEC, // encoding 18 + CHINESE_CNS, // encoding 19 + UTF32BE, // encoding 59 + UTF32LE, // encoding 60 + BINARYENC, // encoding 61 + UTF8UTF8, // encoding 63 + TAM_ELANGO, // encoding 64 + TAM_LTTMBARANI, // encoding 65 + TAM_SHREE, // encoding 66 + TAM_TBOOMIS, // encoding 67 + TAM_TMNEWS, // encoding 68 + TAM_WEBTAMIL, // encoding 69 + UTF8UTF8, // encoding 63 +}; + +// Massaged TLD or charset, followed by packed encoding probs +typedef struct { + char key_prob[20]; +} HintEntry; + +static const HintEntry kLangHintProbs[] = { // MaxRange 192 + {{0x61,0x62,0x6b,0x68,0x61,0x7a,0x69,0x61, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "abkhazia" + // UTF8=191 [top UTF8] + {{0x61,0x66,0x61,0x72,0x5f,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "afar____" + // UTF8=191 [top UTF8] + {{0x61,0x66,0x72,0x69,0x6b,0x61,0x61,0x6e, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "afrikaan" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x61,0x6c,0x62,0x61,0x6e,0x69,0x61,0x6e, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "albanian" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x61,0x6d,0x68,0x61,0x72,0x69,0x63,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "amharic_" + // UTF8=191 [top UTF8] + {{0x61,0x72,0x61,0x62,0x69,0x63,0x5f,0x5f, 0x03,0x84,0x53,0xa2,0x11,0x3b,0x62,0xbc,0x34,0x10,0x51,0x83,}}, // "arabic__" + // ASCII-7-bit=132 Latin1=83 UTF8=162 CP1252=59 CP1256=188 CP1250=52 Arabic=131 [top CP1256] + {{0x61,0x72,0x6d,0x65,0x6e,0x69,0x61,0x6e, 0x01,0x5f,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "armenian" + // ASCII-7-bit=95 UTF8=190 [top UTF8] + {{0x61,0x73,0x73,0x61,0x6d,0x65,0x73,0x65, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "assamese" + // UTF8=191 [top UTF8] + {{0x61,0x79,0x6d,0x61,0x72,0x61,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "aymara__" + // UTF8=191 [top UTF8] + {{0x61,0x7a,0x65,0x72,0x62,0x61,0x69,0x6a, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "azerbaij" + // UTF8=191 [top UTF8] + {{0x62,0x61,0x73,0x68,0x6b,0x69,0x72,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bashkir_" + // UTF8=191 [top UTF8] + {{0x62,0x61,0x73,0x71,0x75,0x65,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "basque__" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x62,0x65,0x6c,0x61,0x72,0x75,0x73,0x69, 0xa1,0xb5,0x71,0xa1,0x72,0x97,0xab,0x81,0x8d,0x00,0x00,0x00,}}, // "belarusi" + // CP1251=181 KOI8R=161 KOI8U=151 ISO-8859-5=171 CP866=141 [top CP1251] + {{0x62,0x65,0x6e,0x67,0x61,0x6c,0x69,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bengali_" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x62,0x69,0x68,0x61,0x72,0x69,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bihari__" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x62,0x69,0x73,0x6c,0x61,0x6d,0x61,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bislama_" + // UTF8=191 [top UTF8] + {{0x62,0x6f,0x73,0x6e,0x69,0x61,0x6e,0x5f, 0x91,0xaf,0x21,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bosnian_" + // Latin2=175 CP1250=185 [top CP1250] + {{0x62,0x72,0x65,0x74,0x6f,0x6e,0x5f,0x5f, 0x11,0xb5,0x21,0x97,0x81,0xab,0x11,0xa1,0x00,0x00,0x00,0x00,}}, // "breton__" + // Latin1=181 CP1252=151 Latin5=171 ISO-8859-15=161 [top Latin1] + {{0x62,0x75,0x6c,0x67,0x61,0x72,0x69,0x61, 0x03,0x70,0x47,0xad,0x11,0x45,0x51,0xb5,0x71,0x95,0x81,0x9f,}}, // "bulgaria" + // ASCII-7-bit=112 Latin1=71 UTF8=173 CP1252=69 CP1251=181 KOI8R=149 ISO-8859-5=159 [top CP1251] + {{0x62,0x75,0x72,0x6d,0x65,0x73,0x65,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "burmese_" + // UTF8=191 [top UTF8] + {{0x63,0x61,0x74,0x61,0x6c,0x61,0x6e,0x5f, 0x03,0x8b,0xb8,0xa0,0x11,0xa4,0xa1,0x96,0x10,0x61,0x31,0x00,}}, // "catalan_" + // ASCII-7-bit=139 Latin1=184 UTF8=160 CP1252=164 ISO-8859-15=150 Latin3=49 [top Latin1] + {{0x63,0x68,0x65,0x72,0x6f,0x6b,0x65,0x65, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cherokee" + // UTF8=191 [top UTF8] + {{0x63,0x68,0x69,0x6e,0x65,0x73,0x65,0x5f, 0x01,0x5c,0x12,0xa8,0xbb,0x11,0x74,0x21,0x6d,0xa1,0x7d,0x00,}}, // "chinese_" + // ASCII-7-bit=92 UTF8=168 GB=187 KSC=116 BIG5=109 GBK=125 [top GB] + {{0x63,0x68,0x69,0x6e,0x65,0x73,0x65,0x74, 0x06,0x73,0x5f,0xad,0x59,0x43,0x36,0x21,0xb9,0x10,0xa1,0x38,}}, // "chineset" + // ASCII-7-bit=115 Latin1=95 UTF8=173 GB=89 CP1252=67 KSC=54 BIG5=185 BIG5_HKSCS=56 [top BIG5] + {{0x63,0x6f,0x72,0x73,0x69,0x63,0x61,0x6e, 0x12,0xaf,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "corsican" + // Latin1=175 UTF8=185 [top UTF8] + {{0x63,0x72,0x65,0x6f,0x6c,0x65,0x73,0x61, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "creolesa" + // UTF8=191 [top UTF8] + {{0x63,0x72,0x6f,0x61,0x74,0x69,0x61,0x6e, 0x03,0x91,0x7b,0xa6,0x11,0x86,0x41,0xac,0x21,0xb4,0x31,0x4d,}}, // "croatian" + // ASCII-7-bit=145 Latin1=123 UTF8=166 CP1252=134 Latin2=172 CP1250=180 CP1257=77 [top CP1250] + {{0x63,0x7a,0x65,0x63,0x68,0x5f,0x5f,0x5f, 0x01,0x89,0x11,0xb1,0x61,0x98,0x21,0xb5,0x10,0x41,0x7d,0x00,}}, // "czech___" + // ASCII-7-bit=137 UTF8=177 Latin2=152 CP1250=181 CP852=125 [top CP1250] + {{0x64,0x61,0x6e,0x69,0x73,0x68,0x5f,0x5f, 0x03,0x99,0xb8,0xa6,0x11,0x9a,0x41,0x38,0x21,0x32,0x21,0x84,}}, // "danish__" + // ASCII-7-bit=153 Latin1=184 UTF8=166 CP1252=154 Latin2=56 CP1250=50 ISO-8859-15=132 [top Latin1] + {{0x64,0x68,0x69,0x76,0x65,0x68,0x69,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "dhivehi_" + // UTF8=191 [top UTF8] + {{0x64,0x75,0x74,0x63,0x68,0x5f,0x5f,0x5f, 0x03,0xb1,0xae,0xa3,0x11,0xa1,0x41,0x41,0x21,0x44,0x21,0x7f,}}, // "dutch___" + // ASCII-7-bit=177 Latin1=174 UTF8=163 CP1252=161 Latin2=65 CP1250=68 ISO-8859-15=127 [top ASCII-7-bit] + {{0x64,0x7a,0x6f,0x6e,0x67,0x6b,0x68,0x61, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "dzongkha" + // UTF8=191 [top UTF8] + {{0x65,0x6e,0x67,0x6c,0x69,0x73,0x68,0x5f, 0x06,0xb9,0xa0,0xa2,0x5d,0x94,0x55,0x21,0x56,0x61,0x69,0x00,}}, // "english_" + // ASCII-7-bit=185 Latin1=160 UTF8=162 GB=93 CP1252=148 KSC=85 BIG5=86 ISO-8859-15=105 [top ASCII-7-bit] + {{0x65,0x73,0x70,0x65,0x72,0x61,0x6e,0x74, 0x03,0x89,0xb4,0xa2,0x12,0xaa,0x45,0x61,0x4c,0x21,0xa0,0x00,}}, // "esperant" + // ASCII-7-bit=137 Latin1=180 UTF8=162 CP1252=170 KSC=69 CP1250=76 ISO-8859-15=160 [top Latin1] + {{0x65,0x73,0x74,0x6f,0x6e,0x69,0x61,0x6e, 0x03,0x90,0xab,0xb1,0x11,0x91,0xa2,0x7e,0xa3,0xc2,0x8e,0x98,}}, // "estonian" + // ASCII-7-bit=144 Latin1=171 UTF8=177 CP1252=145 ISO-8859-15=126 CP1257=163 ISO-8859-13=142 Latin4=152 [top UTF8] + {{0x66,0x61,0x72,0x6f,0x65,0x73,0x65,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "faroese_" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x66,0x69,0x6a,0x69,0x61,0x6e,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "fijian__" + // UTF8=191 [top UTF8] + {{0x66,0x69,0x6e,0x6e,0x69,0x73,0x68,0x5f, 0x03,0x96,0xb7,0xa9,0x11,0x9c,0x71,0x42,0x22,0x8b,0x39,0x00,}}, // "finnish_" + // ASCII-7-bit=150 Latin1=183 UTF8=169 CP1252=156 CP1250=66 ISO-8859-15=139 CP1257=57 [top Latin1] + {{0x66,0x72,0x65,0x6e,0x63,0x68,0x5f,0x5f, 0x03,0x99,0xb6,0xaa,0x11,0xa0,0x62,0x4f,0x46,0x21,0x86,0x00,}}, // "french__" + // ASCII-7-bit=153 Latin1=182 UTF8=170 CP1252=160 CP1256=79 CP1250=70 ISO-8859-15=134 [top Latin1] + {{0x66,0x72,0x69,0x73,0x69,0x61,0x6e,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "frisian_" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x67,0x61,0x6c,0x69,0x63,0x69,0x61,0x6e, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "galician" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x67,0x61,0x6e,0x64,0x61,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ganda___" + // UTF8=191 [top UTF8] + {{0x67,0x65,0x6f,0x72,0x67,0x69,0x61,0x6e, 0x01,0x6c,0x11,0xbe,0x11,0x1c,0x10,0x21,0x1c,0x00,0x00,0x00,}}, // "georgian" + // ASCII-7-bit=108 UTF8=190 CP1252=28 CP1253=28 [top UTF8] + {{0x67,0x65,0x72,0x6d,0x61,0x6e,0x5f,0x5f, 0x03,0xa2,0xb7,0xa6,0x11,0x9b,0x41,0x56,0x21,0x5d,0x21,0x7c,}}, // "german__" + // ASCII-7-bit=162 Latin1=183 UTF8=166 CP1252=155 Latin2=86 CP1250=93 ISO-8859-15=124 [top Latin1] + {{0x67,0x72,0x65,0x65,0x6b,0x5f,0x5f,0x5f, 0x03,0x81,0x54,0xad,0x11,0x52,0xd1,0x31,0x11,0xb4,0x21,0xa6,}}, // "greek___" + // ASCII-7-bit=129 Latin1=84 UTF8=173 CP1252=82 KOI8R=49 Greek=180 CP1253=166 [top Greek] + {{0x67,0x72,0x65,0x65,0x6e,0x6c,0x61,0x6e, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "greenlan" + // UTF8=191 [top UTF8] + {{0x67,0x75,0x61,0x72,0x61,0x6e,0x69,0x5f, 0x11,0xb9,0x20,0x91,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "guarani_" + // Latin1=185 Latin6=175 [top Latin1] + {{0x67,0x75,0x6a,0x61,0x72,0x61,0x74,0x69, 0x03,0x79,0xb6,0x76,0x11,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,}}, // "gujarati" + // ASCII-7-bit=121 Latin1=182 UTF8=118 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x68,0x61,0x69,0x74,0x69,0x61,0x6e,0x63, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "haitianc" + // UTF8=191 [top UTF8] + {{0x68,0x61,0x75,0x73,0x61,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "hausa___" + // UTF8=191 [top UTF8] + {{0x68,0x65,0x62,0x72,0x65,0x77,0x5f,0x5f, 0x03,0x76,0x46,0xab,0x11,0x3b,0x51,0x32,0x61,0xb8,0x71,0x9f,}}, // "hebrew__" + // ASCII-7-bit=118 Latin1=70 UTF8=171 CP1252=59 CP1251=50 CP1255=184 Hebrew=159 [top CP1255] + {{0x68,0x69,0x6e,0x64,0x69,0x5f,0x5f,0x5f, 0x11,0xb5,0x21,0xab,0xa1,0xa1,0x10,0xf3,0x97,0x8d,0x83,0x00,}}, // "hindi___" + // Latin1=181 CP1252=171 ISO-8859-15=161 JAGRAN=151 BHASKAR=141 HTCHANAKYA=131 [top Latin1] + {{0x68,0x75,0x6e,0x67,0x61,0x72,0x69,0x61, 0x03,0x93,0x9f,0xad,0x11,0x6f,0x41,0xae,0x21,0xa9,0x21,0x40,}}, // "hungaria" + // ASCII-7-bit=147 Latin1=159 UTF8=173 CP1252=111 Latin2=174 CP1250=169 ISO-8859-15=64 [top Latin2] + {{0x69,0x63,0x65,0x6c,0x61,0x6e,0x64,0x69, 0x03,0x7f,0xb8,0x9c,0x11,0xa4,0x11,0x1d,0x51,0x2f,0x21,0x99,}}, // "icelandi" + // ASCII-7-bit=127 Latin1=184 UTF8=156 CP1252=164 SJS=29 CP1250=47 ISO-8859-15=153 [top Latin1] + {{0x69,0x6e,0x64,0x6f,0x6e,0x65,0x73,0x69, 0x03,0xb2,0xae,0x99,0x11,0xa2,0x11,0x5b,0x41,0x70,0x31,0x91,}}, // "indonesi" + // ASCII-7-bit=178 Latin1=174 UTF8=153 CP1252=162 SJS=91 CP1256=112 ISO-8859-15=145 [top ASCII-7-bit] + {{0x69,0x6e,0x74,0x65,0x72,0x6c,0x69,0x6e, 0x12,0xb0,0xb0,0x11,0xa6,0xa1,0x9c,0x00,0x00,0x00,0x00,0x00,}}, // "interlin" + // Latin1=176 UTF8=176 CP1252=166 ISO-8859-15=156 [top Latin1] + {{0x69,0x6e,0x75,0x6b,0x74,0x69,0x74,0x75, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "inuktitu" + // UTF8=191 [top UTF8] + {{0x69,0x6e,0x75,0x70,0x69,0x61,0x6b,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "inupiak_" + // UTF8=191 [top UTF8] + {{0x69,0x72,0x69,0x73,0x68,0x5f,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "irish___" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x69,0x74,0x61,0x6c,0x69,0x61,0x6e,0x5f, 0x03,0xa7,0xb4,0xa4,0x11,0xa4,0x41,0x4d,0x21,0x55,0x21,0x78,}}, // "italian_" + // ASCII-7-bit=167 Latin1=180 UTF8=164 CP1252=164 Latin2=77 CP1250=85 ISO-8859-15=120 [top Latin1] + {{0x6a,0x61,0x70,0x61,0x6e,0x65,0x73,0x65, 0x01,0x68,0x11,0xa7,0x32,0xb4,0xad,0xd1,0x78,0x21,0x62,0x00,}}, // "japanese" + // ASCII-7-bit=104 UTF8=167 SJS=180 EUC-JP=173 JIS=120 CP932=98 [top SJS] + {{0x6a,0x61,0x76,0x61,0x6e,0x65,0x73,0x65, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "javanese" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x6b,0x61,0x6e,0x6e,0x61,0x64,0x61,0x5f, 0x03,0x65,0xb6,0x81,0x11,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,}}, // "kannada_" + // ASCII-7-bit=101 Latin1=182 UTF8=129 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x6b,0x61,0x73,0x68,0x6d,0x69,0x72,0x69, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kashmiri" + // UTF8=191 [top UTF8] + {{0x6b,0x61,0x7a,0x61,0x6b,0x68,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kazakh__" + // UTF8=191 [top UTF8] + {{0x6b,0x68,0x61,0x73,0x69,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "khasi___" + // UTF8=191 [top UTF8] + {{0x6b,0x68,0x6d,0x65,0x72,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "khmer___" + // UTF8=191 [top UTF8] + {{0x6b,0x69,0x6e,0x79,0x61,0x72,0x77,0x61, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kinyarwa" + // UTF8=191 [top UTF8] + {{0x6b,0x6f,0x72,0x65,0x61,0x6e,0x5f,0x5f, 0x06,0x5d,0x34,0x9d,0x20,0x1a,0xbd,0x11,0x0c,0x20,0x21,0x76,}}, // "korean__" + // ASCII-7-bit=93 Latin1=52 UTF8=157 GB=32 CP1252=26 KSC=189 EUC-JP=12 ISO-2022-KR=118 [top KSC] + {{0x6b,0x75,0x72,0x64,0x69,0x73,0x68,0x5f, 0xb1,0xb9,0x10,0x61,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kurdish_" + // CP1256=185 Arabic=175 [top CP1256] + {{0x6b,0x79,0x72,0x67,0x79,0x7a,0x5f,0x5f, 0x10,0x61,0xaf,0x41,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kyrgyz__" + // CP1254=175 ISO-8859-5=185 [top ISO-8859-5] + {{0x6c,0x61,0x6f,0x74,0x68,0x69,0x61,0x6e, 0x01,0x40,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "laothian" + // ASCII-7-bit=64 UTF8=190 [top UTF8] + {{0x6c,0x61,0x74,0x69,0x6e,0x5f,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "latin___" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x6c,0x61,0x74,0x76,0x69,0x61,0x6e,0x5f, 0x03,0x80,0x55,0xac,0x11,0x64,0xb1,0xb4,0xc2,0x99,0xa3,0x00,}}, // "latvian_" + // ASCII-7-bit=128 Latin1=85 UTF8=172 CP1252=100 CP1257=180 ISO-8859-13=153 Latin4=163 [top CP1257] + {{0x6c,0x69,0x6d,0x62,0x75,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "limbu___" + // UTF8=191 [top UTF8] + {{0x6c,0x69,0x6e,0x67,0x61,0x6c,0x61,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lingala_" + // UTF8=191 [top UTF8] + {{0x6c,0x69,0x74,0x68,0x75,0x61,0x6e,0x69, 0x03,0x7c,0x5d,0xaa,0x11,0x73,0xb1,0xb7,0xc2,0x94,0x9d,0x00,}}, // "lithuani" + // ASCII-7-bit=124 Latin1=93 UTF8=170 CP1252=115 CP1257=183 ISO-8859-13=148 Latin4=157 [top CP1257] + {{0x6c,0x75,0x78,0x65,0x6d,0x62,0x6f,0x75, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "luxembou" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x6d,0x61,0x63,0x65,0x64,0x6f,0x6e,0x69, 0x03,0x7a,0x54,0xa9,0x11,0x4b,0x51,0xb3,0x71,0x9e,0x81,0xa8,}}, // "macedoni" + // ASCII-7-bit=122 Latin1=84 UTF8=169 CP1252=75 CP1251=179 KOI8R=158 ISO-8859-5=168 [top CP1251] + {{0x6d,0x61,0x6c,0x61,0x67,0x61,0x73,0x79, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "malagasy" + // UTF8=191 [top UTF8] + {{0x6d,0x61,0x6c,0x61,0x79,0x5f,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "malay___" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x6d,0x61,0x6c,0x61,0x79,0x61,0x6c,0x61, 0x03,0x48,0xb6,0x81,0x11,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,}}, // "malayala" + // ASCII-7-bit=72 Latin1=182 UTF8=129 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x6d,0x61,0x6c,0x74,0x65,0x73,0x65,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "maltese_" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x6d,0x61,0x6e,0x78,0x5f,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "manx____" + // UTF8=191 [top UTF8] + {{0x6d,0x61,0x6f,0x72,0x69,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "maori___" + // UTF8=191 [top UTF8] + {{0x6d,0x61,0x72,0x61,0x74,0x68,0x69,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "marathi_" + // UTF8=191 [top UTF8] + {{0x6d,0x6f,0x6c,0x64,0x61,0x76,0x69,0x61, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "moldavia" + // UTF8=191 [top UTF8] + {{0x6d,0x6f,0x6e,0x67,0x6f,0x6c,0x69,0x61, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mongolia" + // CP1251=191 [top CP1251] + {{0x6e,0x61,0x75,0x72,0x75,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "nauru___" + // UTF8=191 [top UTF8] + {{0x6e,0x65,0x70,0x61,0x6c,0x69,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "nepali__" + // UTF8=191 [top UTF8] + {{0x6e,0x6f,0x72,0x77,0x65,0x67,0x69,0x61, 0x03,0x92,0xb8,0xa8,0x11,0x9c,0x41,0x30,0x31,0x24,0x11,0x8e,}}, // "norwegia" + // ASCII-7-bit=146 Latin1=184 UTF8=168 CP1252=156 Latin2=48 Latin5=36 ISO-8859-15=142 [top Latin1] + {{0x6f,0x63,0x63,0x69,0x74,0x61,0x6e,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "occitan_" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x6f,0x72,0x69,0x79,0x61,0x5f,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "oriya___" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x6f,0x72,0x6f,0x6d,0x6f,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "oromo___" + // UTF8=191 [top UTF8] + {{0x70,0x61,0x73,0x68,0x74,0x6f,0x5f,0x5f, 0xb1,0xb9,0x10,0x61,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "pashto__" + // CP1256=185 Arabic=175 [top CP1256] + {{0x70,0x65,0x72,0x73,0x69,0x61,0x6e,0x5f, 0x12,0x44,0xb6,0x11,0x33,0x62,0xae,0x19,0x10,0x51,0x9f,0x00,}}, // "persian_" + // Latin1=68 UTF8=182 CP1252=51 CP1256=174 CP1250=25 Arabic=159 [top UTF8] + {{0x70,0x6f,0x6c,0x69,0x73,0x68,0x5f,0x5f, 0x05,0x85,0x6c,0xa8,0x26,0x57,0x41,0xb9,0x21,0x99,0x31,0x23,}}, // "polish__" + // ASCII-7-bit=133 Latin1=108 UTF8=168 GB=38 CP1252=87 Latin2=185 CP1250=153 CP1257=35 [top Latin2] + {{0x70,0x6f,0x72,0x74,0x75,0x67,0x75,0x65, 0x03,0x96,0xb9,0xa6,0x11,0x9a,0x11,0x30,0x51,0x36,0x21,0x86,}}, // "portugue" + // ASCII-7-bit=150 Latin1=185 UTF8=166 CP1252=154 SJS=48 CP1250=54 ISO-8859-15=134 [top Latin1] + {{0x70,0x75,0x6e,0x6a,0x61,0x62,0x69,0x5f, 0x03,0x42,0xb6,0x7b,0x11,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,}}, // "punjabi_" + // ASCII-7-bit=66 Latin1=182 UTF8=123 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x71,0x75,0x65,0x63,0x68,0x75,0x61,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "quechua_" + // UTF8=191 [top UTF8] + {{0x72,0x68,0x61,0x65,0x74,0x6f,0x72,0x6f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "rhaetoro" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x72,0x6f,0x6d,0x61,0x6e,0x69,0x61,0x6e, 0x03,0xb2,0x9d,0xa5,0x11,0x92,0x42,0xa7,0x51,0x11,0x99,0x00,}}, // "romanian" + // ASCII-7-bit=178 Latin1=157 UTF8=165 CP1252=146 Latin2=167 CP1251=81 CP1250=153 [top ASCII-7-bit] + {{0x72,0x75,0x6e,0x64,0x69,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "rundi___" + // UTF8=191 [top UTF8] + {{0x72,0x75,0x73,0x73,0x69,0x61,0x6e,0x5f, 0x01,0x74,0x11,0xa9,0x71,0xb9,0x71,0x99,0x81,0x82,0x81,0x6d,}}, // "russian_" + // ASCII-7-bit=116 UTF8=169 CP1251=185 KOI8R=153 ISO-8859-5=130 CP866=109 [top CP1251] + {{0x73,0x61,0x6d,0x6f,0x61,0x6e,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "samoan__" + // UTF8=191 [top UTF8] + {{0x73,0x61,0x6e,0x67,0x6f,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sango___" + // UTF8=191 [top UTF8] + {{0x73,0x61,0x6e,0x73,0x6b,0x72,0x69,0x74, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sanskrit" + // UTF8=191 [top UTF8] + {{0x73,0x63,0x6f,0x74,0x73,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "scots___" + // UTF8=191 [top UTF8] + {{0x73,0x63,0x6f,0x74,0x73,0x67,0x61,0x65, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "scotsgae" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x73,0x65,0x72,0x62,0x69,0x61,0x6e,0x5f, 0x03,0x93,0x77,0xad,0x11,0x85,0x42,0xad,0x52,0x12,0xae,0x4a,}}, // "serbian_" + // ASCII-7-bit=147 Latin1=119 UTF8=173 CP1252=133 Latin2=173 CP1251=82 CP1250=174 Latin5=74 [top CP1250] + {{0x73,0x65,0x72,0x62,0x6f,0x63,0x72,0x6f, 0x91,0xaf,0x21,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "serbocro" + // Latin2=175 CP1250=185 [top CP1250] + {{0x73,0x65,0x73,0x6f,0x74,0x68,0x6f,0x5f, 0x11,0xb9,0x21,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sesotho_" + // Latin1=185 CP1252=175 [top Latin1] + {{0x73,0x68,0x6f,0x6e,0x61,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "shona___" + // UTF8=191 [top UTF8] + {{0x73,0x69,0x6e,0x64,0x68,0x69,0x5f,0x5f, 0xb1,0xb9,0x10,0x61,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sindhi__" + // CP1256=185 Arabic=175 [top CP1256] + {{0x73,0x69,0x6e,0x68,0x61,0x6c,0x65,0x73, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sinhales" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x73,0x69,0x73,0x77,0x61,0x6e,0x74,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "siswant_" + // UTF8=191 [top UTF8] + {{0x73,0x6c,0x6f,0x76,0x61,0x6b,0x5f,0x5f, 0x03,0x88,0x6e,0xaf,0x11,0x67,0x41,0xa5,0x21,0xb3,0x00,0x00,}}, // "slovak__" + // ASCII-7-bit=136 Latin1=110 UTF8=175 CP1252=103 Latin2=165 CP1250=179 [top CP1250] + {{0x73,0x6c,0x6f,0x76,0x65,0x6e,0x69,0x61, 0x03,0x8e,0x71,0xb2,0x11,0x80,0x42,0xaa,0x39,0x11,0xad,0x00,}}, // "slovenia" + // ASCII-7-bit=142 Latin1=113 UTF8=178 CP1252=128 Latin2=170 CP1251=57 CP1250=173 [top UTF8] + {{0x73,0x6f,0x6d,0x61,0x6c,0x69,0x5f,0x5f, 0x11,0xb9,0x21,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "somali__" + // Latin1=185 CP1252=175 [top Latin1] + {{0x73,0x70,0x61,0x6e,0x69,0x73,0x68,0x5f, 0x03,0x9b,0xb8,0xa7,0x11,0x98,0x41,0x45,0x21,0x45,0x21,0x77,}}, // "spanish_" + // ASCII-7-bit=155 Latin1=184 UTF8=167 CP1252=152 Latin2=69 CP1250=69 ISO-8859-15=119 [top Latin1] + {{0x73,0x75,0x6e,0x64,0x61,0x6e,0x65,0x73, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sundanes" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x73,0x77,0x61,0x68,0x69,0x6c,0x69,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "swahili_" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x73,0x77,0x65,0x64,0x69,0x73,0x68,0x5f, 0x03,0x90,0xba,0xa4,0x11,0x8d,0x41,0x2c,0x21,0x2c,0x21,0x7a,}}, // "swedish_" + // ASCII-7-bit=144 Latin1=186 UTF8=164 CP1252=141 Latin2=44 CP1250=44 ISO-8859-15=122 [top Latin1] + {{0x73,0x79,0x72,0x69,0x61,0x63,0x5f,0x5f, 0x01,0x6a,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "syriac__" + // ASCII-7-bit=106 UTF8=190 [top UTF8] + {{0x74,0x61,0x67,0x61,0x6c,0x6f,0x67,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tagalog_" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x74,0x61,0x6a,0x69,0x6b,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tajik___" + // UTF8=191 [top UTF8] + {{0x74,0x61,0x6d,0x69,0x6c,0x5f,0x5f,0x5f, 0x12,0xb4,0x8e,0x11,0xaa,0xa1,0xa0,0x20,0x23,0x96,0x8c,0x82,}}, // "tamil___" + // Latin1=180 UTF8=142 CP1252=170 ISO-8859-15=160 TSCII=150 TAM=140 TAB=130 [top Latin1] + {{0x74,0x61,0x74,0x61,0x72,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tatar___" + // UTF8=191 [top UTF8] + {{0x74,0x65,0x6c,0x75,0x67,0x75,0x5f,0x5f, 0x03,0x66,0xb6,0x90,0x11,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,}}, // "telugu__" + // ASCII-7-bit=102 Latin1=182 UTF8=144 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x74,0x68,0x61,0x69,0x5f,0x5f,0x5f,0x5f, 0x05,0x7a,0x53,0xa2,0x24,0x46,0x91,0xba,0xd1,0x9e,0x21,0x29,}}, // "thai____" + // ASCII-7-bit=122 Latin1=83 UTF8=162 GB=36 CP1252=70 ISO-8859-11=186 CP874=158 MACINTOSH=41 [top ISO-8859-11] + {{0x74,0x69,0x62,0x65,0x74,0x61,0x6e,0x5f, 0x01,0x42,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tibetan_" + // ASCII-7-bit=66 UTF8=190 [top UTF8] + {{0x74,0x69,0x67,0x72,0x69,0x6e,0x79,0x61, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tigrinya" + // UTF8=191 [top UTF8] + {{0x74,0x6f,0x6e,0x67,0x61,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tonga___" + // UTF8=191 [top UTF8] + {{0x74,0x73,0x6f,0x6e,0x67,0x61,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tsonga__" + // UTF8=191 [top UTF8] + {{0x74,0x73,0x77,0x61,0x6e,0x61,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tswana__" + // UTF8=191 [top UTF8] + {{0x74,0x75,0x72,0x6b,0x69,0x73,0x68,0x5f, 0x03,0x81,0x7f,0xa5,0x11,0x6e,0x81,0xba,0x11,0x3d,0x61,0x95,}}, // "turkish_" + // ASCII-7-bit=129 Latin1=127 UTF8=165 CP1252=110 Latin5=186 ISO-8859-15=61 CP1254=149 [top Latin5] + {{0x74,0x75,0x72,0x6b,0x6d,0x65,0x6e,0x5f, 0x91,0xb9,0x21,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "turkmen_" + // Latin2=185 CP1250=175 [top Latin2] + {{0x74,0x77,0x69,0x5f,0x5f,0x5f,0x5f,0x5f, 0x11,0xac,0x21,0xb6,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "twi_____" + // Latin1=172 CP1252=182 ISO-8859-15=162 [top CP1252] + {{0x75,0x69,0x67,0x68,0x75,0x72,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "uighur__" + // UTF8=191 [top UTF8] + {{0x75,0x6b,0x72,0x61,0x69,0x6e,0x69,0x61, 0x21,0xa0,0x71,0xb7,0x71,0x91,0x72,0x98,0xa2,0x81,0x84,0x00,}}, // "ukrainia" + // UTF8=160 CP1251=183 KOI8R=145 KOI8U=152 ISO-8859-5=162 CP866=132 [top CP1251] + {{0x75,0x72,0x64,0x75,0x5f,0x5f,0x5f,0x5f, 0xb1,0xb9,0x10,0x61,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "urdu____" + // CP1256=185 Arabic=175 [top CP1256] + {{0x75,0x7a,0x62,0x65,0x6b,0x5f,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "uzbek___" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x76,0x69,0x65,0x74,0x6e,0x61,0x6d,0x65, 0x03,0x81,0xa8,0xb7,0x11,0x9e,0xa1,0x94,0x00,0x00,0x00,0x00,}}, // "vietname" + // ASCII-7-bit=129 Latin1=168 UTF8=183 CP1252=158 ISO-8859-15=148 [top UTF8] + {{0x76,0x6f,0x6c,0x61,0x70,0x75,0x6b,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "volapuk_" + // UTF8=191 [top UTF8] + {{0x77,0x65,0x6c,0x73,0x68,0x5f,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "welsh___" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x77,0x6f,0x6c,0x6f,0x66,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wolof___" + // UTF8=191 [top UTF8] + {{0x78,0x68,0x6f,0x73,0x61,0x5f,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "xhosa___" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] + {{0x79,0x69,0x64,0x64,0x69,0x73,0x68,0x5f, 0x10,0x11,0xb9,0x71,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "yiddish_" + // CP1255=185 Hebrew=175 [top CP1255] + {{0x79,0x6f,0x72,0x75,0x62,0x61,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "yoruba__" + // UTF8=191 [top UTF8] + {{0x7a,0x68,0x75,0x61,0x6e,0x67,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "zhuang__" + // UTF8=191 [top UTF8] + {{0x7a,0x75,0x6c,0x75,0x5f,0x5f,0x5f,0x5f, 0x11,0xb6,0x21,0xac,0xa1,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "zulu____" + // Latin1=182 CP1252=172 ISO-8859-15=162 [top Latin1] +}; + +static const int kLangHintProbsSize = 151; + +static const HintEntry kTLDHintProbs[] = { // MaxRange 192 + {{0x5f,0x5f,0x5f,0x5f, 0x0f,0xa8,0xa1,0xa3,0xa0,0x8e,0x8e,0x8a,0x7e,0xa8,0x77,0x7b,0x8b,0x75,0x79,0x7e,}}, // "____" + // ASCII-7-bit=168 Latin1=161 UTF8=163 GB=160 CP1252=142 KSC=142 SJS=138 EUC-JP=126 BIG5=168 Latin2=119 CP1251=123 CP1256=139 CP1250=117 Latin5=121 ISO-8859-11=126 [top ASCII-7-bit] + {{0x61,0x63,0x5f,0x5f, 0x08,0xa0,0x9a,0xa1,0x65,0x92,0x8f,0xb1,0xa2,0x22,0x56,0x8a,0x21,0x56,0x61,0x87,}}, // "ac__" + // ASCII-7-bit=160 Latin1=154 UTF8=161 GB=101 CP1252=146 KSC=143 SJS=177 EUC-JP=162 CP1251=86 CP1256=138 ISO-8859-11=86 JIS=135 [top SJS] + {{0x61,0x64,0x5f,0x5f, 0x03,0xa6,0xb6,0x93,0x11,0xa8,0x11,0x74,0x81,0x5d,0x81,0x5d,0x00,0x00,0x00,0x00,}}, // "ad__" + // ASCII-7-bit=166 Latin1=182 UTF8=147 CP1252=168 SJS=116 ISO-8859-15=93 CP932=93 [top Latin1] + {{0x61,0x65,0x5f,0x5f, 0x05,0xa4,0x81,0xac,0x42,0x86,0x11,0x5b,0x25,0x4f,0x4a,0xb5,0x3b,0x52,0x00,0x00,}}, // "ae__" + // ASCII-7-bit=164 Latin1=129 UTF8=172 GB=66 CP1252=134 SJS=91 Latin2=79 CP1251=74 CP1256=181 CP1250=59 Latin5=82 [top CP1256] + {{0x61,0x65,0x72,0x6f, 0x03,0xaf,0xab,0xab,0x12,0x98,0x6a,0x11,0x6a,0x21,0x96,0x21,0x6a,0x00,0x00,0x00,}}, // "aero" + // ASCII-7-bit=175 Latin1=171 UTF8=171 CP1252=152 KSC=106 EUC-JP=106 CP1251=150 Latin5=106 [top ASCII-7-bit] + {{0x61,0x66,0x5f,0x5f, 0x03,0xb6,0x95,0xaf,0x11,0x8c,0x61,0x80,0x11,0x62,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "af__" + // ASCII-7-bit=182 Latin1=149 UTF8=175 CP1252=140 CP1256=128 Latin5=98 [top ASCII-7-bit] + {{0x61,0x67,0x5f,0x5f, 0x03,0xa8,0xb4,0xa2,0x11,0x9a,0x12,0x95,0x86,0x21,0x60,0x41,0x7a,0x00,0x00,0x00,}}, // "ag__" + // ASCII-7-bit=168 Latin1=180 UTF8=162 CP1252=154 SJS=149 EUC-JP=134 CP1251=96 ISO-8859-15=122 [top Latin1] + {{0x61,0x69,0x5f,0x5f, 0x03,0xb8,0x8f,0x9b,0x11,0x9d,0x12,0x8c,0x97,0x11,0x90,0xb1,0x67,0x00,0x00,0x00,}}, // "ai__" + // ASCII-7-bit=184 Latin1=143 UTF8=155 CP1252=157 SJS=140 EUC-JP=151 Latin2=144 JIS=103 [top ASCII-7-bit] + {{0x61,0x6c,0x5f,0x5f, 0x03,0xac,0x99,0xae,0x11,0xa1,0x31,0x57,0x41,0x57,0x21,0xa7,0x31,0x57,0x00,0x00,}}, // "al__" + // ASCII-7-bit=172 Latin1=153 UTF8=174 CP1252=161 BIG5=87 Latin5=87 CP1257=167 Greek=87 [top UTF8] + {{0x61,0x6d,0x5f,0x5f, 0x08,0xac,0x9a,0xab,0x68,0x9d,0x58,0x82,0x56,0x22,0xac,0x5a,0x00,0x00,0x00,0x00,}}, // "am__" + // ASCII-7-bit=172 Latin1=154 UTF8=171 GB=104 CP1252=157 KSC=88 SJS=130 EUC-JP=86 CP1251=172 CP1256=90 [top ASCII-7-bit] + {{0x61,0x6e,0x5f,0x5f, 0x03,0xb6,0xad,0x94,0x11,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "an__" + // ASCII-7-bit=182 Latin1=173 UTF8=148 CP1252=153 [top ASCII-7-bit] + {{0x61,0x6f,0x5f,0x5f, 0x03,0x9f,0xb5,0xab,0x11,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ao__" + // ASCII-7-bit=159 Latin1=181 UTF8=171 CP1252=159 [top Latin1] + {{0x61,0x71,0x5f,0x5f, 0x03,0xb7,0xa9,0x9c,0x11,0x8a,0x51,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "aq__" + // ASCII-7-bit=183 Latin1=169 UTF8=156 CP1252=138 CP1251=151 [top ASCII-7-bit] + {{0x61,0x72,0x5f,0x5f, 0x03,0xa0,0xb9,0x9e,0x13,0x98,0x55,0x2c,0x13,0x28,0x26,0x27,0x11,0x2e,0x21,0x42,}}, // "ar__" + // ASCII-7-bit=160 Latin1=185 UTF8=158 CP1252=152 KSC=85 SJS=44 BIG5=40 Latin2=38 CP1251=39 CP1250=46 ISO-8859-15=66 [top Latin1] + {{0x61,0x73,0x5f,0x5f, 0x03,0xa9,0xb7,0x9f,0x11,0x94,0x11,0x52,0x22,0x64,0x52,0x12,0x7d,0x74,0x21,0x52,}}, // "as__" + // ASCII-7-bit=169 Latin1=183 UTF8=159 CP1252=148 SJS=82 Latin2=100 CP1251=82 CP1250=125 Latin5=116 CP1257=82 [top Latin1] + {{0x61,0x74,0x5f,0x5f, 0x03,0xa1,0xb8,0xa5,0x11,0x9a,0x11,0x48,0x21,0x51,0x13,0x45,0x53,0x4a,0x11,0x62,}}, // "at__" + // ASCII-7-bit=161 Latin1=184 UTF8=165 CP1252=154 SJS=72 Latin2=81 CP1256=69 CP1250=83 Latin5=74 ISO-8859-15=98 [top Latin1] + {{0x61,0x75,0x5f,0x5f, 0x09,0xb8,0xa3,0x9f,0x4e,0x9a,0x55,0x54,0x3e,0x5e,0x22,0x30,0x3d,0x21,0x36,0x00,}}, // "au__" + // ASCII-7-bit=184 Latin1=163 UTF8=159 GB=78 CP1252=154 KSC=85 SJS=84 EUC-JP=62 BIG5=94 CP1256=48 CP1250=61 ISO-8859-15=54 [top ASCII-7-bit] + {{0x61,0x77,0x5f,0x5f, 0x03,0xb6,0xa2,0xaa,0x11,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "aw__" + // ASCII-7-bit=182 Latin1=162 UTF8=170 CP1252=153 [top ASCII-7-bit] + {{0x61,0x78,0x5f,0x5f, 0x03,0x9d,0xba,0xa2,0x11,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ax__" + // ASCII-7-bit=157 Latin1=186 UTF8=162 CP1252=144 [top Latin1] + {{0x61,0x7a,0x5f,0x5f, 0x03,0x9a,0x7d,0xb8,0x11,0x86,0x54,0xa8,0x54,0x54,0x91,0x41,0x4c,0x31,0x6c,0x00,}}, // "az__" + // ASCII-7-bit=154 Latin1=125 UTF8=184 CP1252=134 CP1251=168 CP1256=84 CP1250=84 Latin5=145 KOI8R=76 CP1254=108 [top UTF8] + {{0x62,0x61,0x5f,0x5f, 0x03,0xa0,0x7e,0xb2,0x11,0x78,0x44,0x89,0x66,0x49,0xb1,0x00,0x00,0x00,0x00,0x00,}}, // "ba__" + // ASCII-7-bit=160 Latin1=126 UTF8=178 CP1252=120 Latin2=137 CP1251=102 CP1256=73 CP1250=177 [top UTF8] + {{0x62,0x62,0x5f,0x5f, 0x03,0xba,0xa0,0x7f,0x11,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bb__" + // ASCII-7-bit=186 Latin1=160 UTF8=127 CP1252=160 [top ASCII-7-bit] + {{0x62,0x64,0x5f,0x5f, 0x03,0xbd,0x94,0x8c,0x11,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bd__" + // ASCII-7-bit=189 Latin1=148 UTF8=140 CP1252=138 [top ASCII-7-bit] + {{0x62,0x65,0x5f,0x5f, 0x03,0xb1,0xb0,0xa1,0x11,0x9d,0x11,0x5f,0x22,0x4e,0x50,0x12,0x4d,0x59,0x11,0x5f,}}, // "be__" + // ASCII-7-bit=177 Latin1=176 UTF8=161 CP1252=157 SJS=95 Latin2=78 CP1251=80 CP1250=77 Latin5=89 ISO-8859-15=95 [top ASCII-7-bit] + {{0x62,0x66,0x5f,0x5f, 0x03,0x9f,0xb9,0x63,0x11,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bf__" + // ASCII-7-bit=159 Latin1=185 UTF8=99 CP1252=166 [top Latin1] + {{0x62,0x67,0x5f,0x5f, 0x05,0x96,0x70,0xab,0x4a,0x74,0x51,0xb9,0x11,0x4f,0x51,0x44,0x31,0x45,0x41,0x54,}}, // "bg__" + // ASCII-7-bit=150 Latin1=112 UTF8=171 GB=74 CP1252=116 CP1251=185 CP1250=79 KOI8R=68 CP1254=69 ISO-8859-5=84 [top CP1251] + {{0x62,0x68,0x5f,0x5f, 0x03,0x9f,0x94,0xa5,0x11,0x84,0x11,0x53,0x41,0xb8,0x10,0x61,0x70,0x00,0x00,0x00,}}, // "bh__" + // ASCII-7-bit=159 Latin1=148 UTF8=165 CP1252=132 SJS=83 CP1256=184 Arabic=112 [top CP1256] + {{0x62,0x69,0x5f,0x5f, 0x03,0xa4,0xa5,0xb8,0x12,0x82,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bi__" + // ASCII-7-bit=164 Latin1=165 UTF8=184 CP1252=130 KSC=101 [top UTF8] + {{0x62,0x69,0x7a,0x5f, 0x0e,0xae,0xa5,0xa1,0x77,0x96,0x7f,0x95,0x9c,0x7a,0x8e,0x8b,0x80,0x80,0x92,0x00,}}, // "biz_" + // ASCII-7-bit=174 Latin1=165 UTF8=161 GB=119 CP1252=150 KSC=127 SJS=149 EUC-JP=156 BIG5=122 Latin2=142 CP1251=139 CP1256=128 CP1250=128 Latin5=146 [top ASCII-7-bit] + {{0x62,0x6a,0x5f,0x5f, 0x03,0x9b,0xb6,0x8a,0x11,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bj__" + // ASCII-7-bit=155 Latin1=182 UTF8=138 CP1252=175 [top Latin1] + {{0x62,0x6d,0x5f,0x5f, 0x05,0xbb,0x95,0xa0,0x5a,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bm__" + // ASCII-7-bit=187 Latin1=149 UTF8=160 GB=90 CP1252=149 [top ASCII-7-bit] + {{0x62,0x6e,0x5f,0x5f, 0x05,0xb8,0x98,0xa6,0x6d,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bn__" + // ASCII-7-bit=184 Latin1=152 UTF8=166 GB=109 CP1252=160 [top ASCII-7-bit] + {{0x62,0x6f,0x5f,0x5f, 0x03,0x9a,0xba,0x9f,0x11,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bo__" + // ASCII-7-bit=154 Latin1=186 UTF8=159 CP1252=156 [top Latin1] + {{0x62,0x72,0x5f,0x5f, 0x07,0x9c,0xba,0x9c,0x1f,0x95,0x21,0x43,0x15,0x1c,0x20,0x17,0x0e,0x2b,0x21,0x5a,}}, // "br__" + // ASCII-7-bit=156 Latin1=186 UTF8=156 GB=31 CP1252=149 KSC=33 SJS=67 BIG5=28 Latin2=32 CP1251=23 CP1256=14 CP1250=43 ISO-8859-15=90 [top Latin1] + {{0x62,0x73,0x5f,0x5f, 0x03,0xb2,0xb4,0x9c,0x11,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bs__" + // ASCII-7-bit=178 Latin1=180 UTF8=156 CP1252=118 [top Latin1] + {{0x62,0x74,0x5f,0x5f, 0x03,0xb9,0x96,0xa7,0x11,0x94,0x11,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bt__" + // ASCII-7-bit=185 Latin1=150 UTF8=167 CP1252=148 SJS=111 [top ASCII-7-bit] + {{0x62,0x77,0x5f,0x5f, 0x03,0xbb,0x9b,0x88,0x11,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bw__" + // ASCII-7-bit=187 Latin1=155 UTF8=136 CP1252=157 [top ASCII-7-bit] + {{0x62,0x79,0x5f,0x5f, 0x03,0x8a,0x7b,0xa4,0x11,0x74,0x42,0x5d,0xb6,0x11,0x4b,0x21,0x5f,0x21,0xa9,0x00,}}, // "by__" + // ASCII-7-bit=138 Latin1=123 UTF8=164 CP1252=116 Latin2=93 CP1251=182 CP1250=75 ISO-8859-15=95 KOI8R=169 [top CP1251] + {{0x62,0x7a,0x5f,0x5f, 0x03,0xaf,0x9f,0xa1,0x19,0x90,0x89,0xa4,0x9e,0x8c,0x65,0x8d,0x64,0x70,0x51,0x7e,}}, // "bz__" + // ASCII-7-bit=175 Latin1=159 UTF8=161 CP1252=144 KSC=137 SJS=164 EUC-JP=158 BIG5=140 Latin2=101 CP1251=141 CP1256=100 CP1250=112 KOI8R=126 [top ASCII-7-bit] + {{0x63,0x61,0x5f,0x5f, 0x07,0xb3,0xac,0xa0,0x5b,0x9b,0x5f,0x49,0x15,0x56,0x3c,0x5d,0x48,0x42,0x21,0x94,}}, // "ca__" + // ASCII-7-bit=179 Latin1=172 UTF8=160 GB=91 CP1252=155 KSC=95 SJS=73 BIG5=86 Latin2=60 CP1251=93 CP1256=72 CP1250=66 ISO-8859-15=148 [top ASCII-7-bit] + {{0x63,0x61,0x74,0x5f, 0x03,0x9a,0xb4,0xad,0x11,0x9f,0x11,0x30,0x31,0x30,0x32,0x30,0x6e,0x00,0x00,0x00,}}, // "cat_" + // ASCII-7-bit=154 Latin1=180 UTF8=173 CP1252=159 SJS=48 CP1251=48 ISO-8859-11=48 ISO-8859-15=110 [top Latin1] + {{0x63,0x63,0x5f,0x5f, 0x09,0x9d,0xab,0xad,0x9b,0x86,0x80,0x90,0x9e,0x92,0x21,0x8a,0x11,0x7a,0x51,0x75,}}, // "cc__" + // ASCII-7-bit=157 Latin1=171 UTF8=173 GB=155 CP1252=134 KSC=128 SJS=144 EUC-JP=158 BIG5=146 CP1256=138 Latin5=122 GBK=117 [top UTF8] + {{0x63,0x64,0x5f,0x5f, 0x09,0xae,0xa2,0xb2,0x5a,0x95,0x5a,0x8f,0x64,0x5a,0x11,0x7d,0x11,0x74,0x11,0x5a,}}, // "cd__" + // ASCII-7-bit=174 Latin1=162 UTF8=178 GB=90 CP1252=149 KSC=90 SJS=143 EUC-JP=100 BIG5=90 CP1251=125 CP1250=116 ISO-8859-11=90 [top UTF8] + {{0x63,0x67,0x5f,0x5f, 0x03,0x83,0x8d,0xbe,0x11,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cg__" + // ASCII-7-bit=131 Latin1=141 UTF8=190 CP1252=131 [top UTF8] + {{0x63,0x68,0x5f,0x5f, 0x05,0xaa,0xb6,0xa1,0x4c,0x9a,0x11,0x46,0x25,0x49,0x3e,0x41,0x44,0x43,0x11,0x66,}}, // "ch__" + // ASCII-7-bit=170 Latin1=182 UTF8=161 GB=76 CP1252=154 SJS=70 Latin2=73 CP1251=62 CP1256=65 CP1250=68 Latin5=67 ISO-8859-15=102 [top Latin1] + {{0x63,0x69,0x5f,0x5f, 0x03,0x9c,0xae,0xb3,0x11,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ci__" + // ASCII-7-bit=156 Latin1=174 UTF8=179 CP1252=161 [top UTF8] + {{0x63,0x6b,0x5f,0x5f, 0x03,0xba,0x9c,0x9e,0x11,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ck__" + // ASCII-7-bit=186 Latin1=156 UTF8=158 CP1252=154 [top ASCII-7-bit] + {{0x63,0x6c,0x5f,0x5f, 0x03,0xa4,0xb9,0x9c,0x11,0x97,0x11,0x3e,0x27,0x1b,0x1b,0x2d,0x34,0x2b,0x21,0x3b,}}, // "cl__" + // ASCII-7-bit=164 Latin1=185 UTF8=156 CP1252=151 SJS=62 Latin2=27 CP1251=27 CP1256=45 CP1250=52 Latin5=43 ISO-8859-11=33 ISO-8859-15=59 [top Latin1] + {{0x63,0x6d,0x5f,0x5f, 0x03,0x93,0xbd,0x64,0x11,0x97,0xa1,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cm__" + // ASCII-7-bit=147 Latin1=189 UTF8=100 CP1252=151 ISO-8859-15=108 [top Latin1] + {{0x63,0x6e,0x5f,0x5f, 0x09,0x8c,0x5c,0xa7,0xba,0x4f,0x48,0x57,0x3c,0x8d,0x12,0x4e,0x4f,0x71,0x64,0x00,}}, // "cn__" + // ASCII-7-bit=140 Latin1=92 UTF8=167 GB=186 CP1252=79 KSC=72 SJS=87 EUC-JP=60 BIG5=141 CP1251=78 CP1256=79 GBK=100 [top GB] + {{0x63,0x6f,0x5f,0x5f, 0x03,0xa8,0xb7,0xa3,0x12,0x91,0x27,0x31,0x3f,0x13,0x2f,0x2a,0x2a,0x61,0x27,0x00,}}, // "co__" + // ASCII-7-bit=168 Latin1=183 UTF8=163 CP1252=145 KSC=39 Latin2=63 CP1256=47 CP1250=42 Latin5=42 Greek=39 [top Latin1] + {{0x63,0x6f,0x6d,0x5f, 0x09,0xb2,0xa5,0xa7,0x94,0x94,0x87,0x87,0x7d,0x82,0x12,0x6e,0x89,0x12,0x7f,0x70,}}, // "com_" + // ASCII-7-bit=178 Latin1=165 UTF8=167 GB=148 CP1252=148 KSC=135 SJS=135 EUC-JP=125 BIG5=130 CP1251=110 CP1256=137 Latin5=127 ISO-8859-11=112 [top ASCII-7-bit] + {{0x63,0x6f,0x6f,0x70, 0x03,0xaf,0xa8,0xa0,0x14,0x9c,0x75,0xa7,0x86,0x71,0x78,0x00,0x00,0x00,0x00,0x00,}}, // "coop" + // ASCII-7-bit=175 Latin1=168 UTF8=160 CP1252=156 KSC=117 SJS=167 EUC-JP=134 ISO-8859-15=120 [top ASCII-7-bit] + {{0x63,0x72,0x5f,0x5f, 0x03,0x99,0xb7,0xad,0x11,0x84,0x81,0x28,0x11,0x28,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cr__" + // ASCII-7-bit=153 Latin1=183 UTF8=173 CP1252=132 Latin5=40 ISO-8859-15=40 [top Latin1] + {{0x63,0x75,0x5f,0x5f, 0x03,0xa0,0xb7,0x9f,0x11,0xa6,0x53,0x31,0x45,0x45,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cu__" + // ASCII-7-bit=160 Latin1=183 UTF8=159 CP1252=166 CP1251=49 CP1256=69 CP1250=69 [top Latin1] + {{0x63,0x76,0x5f,0x5f, 0x03,0x90,0xbc,0x8f,0x11,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cv__" + // ASCII-7-bit=144 Latin1=188 UTF8=143 CP1252=152 [top Latin1] + {{0x63,0x78,0x5f,0x5f, 0x03,0xae,0xa2,0xa5,0x15,0x87,0x76,0x9f,0x9a,0x83,0x41,0x85,0x11,0x7e,0x51,0x99,}}, // "cx__" + // ASCII-7-bit=174 Latin1=162 UTF8=165 CP1252=135 KSC=118 SJS=159 EUC-JP=154 BIG5=131 Latin5=133 ISO-8859-15=126 JIS=153 [top ASCII-7-bit] + {{0x63,0x79,0x5f,0x5f, 0x03,0xaa,0x88,0xac,0x11,0x86,0x51,0x63,0x21,0x5c,0x61,0x9e,0x12,0x52,0xae,0x00,}}, // "cy__" + // ASCII-7-bit=170 Latin1=136 UTF8=172 CP1252=134 CP1251=99 Latin5=92 Greek=158 CP1254=82 CP1253=174 [top CP1253] + {{0x63,0x7a,0x5f,0x5f, 0x03,0x8f,0x74,0xb2,0x11,0x56,0x42,0x8c,0x4a,0x11,0xb5,0x10,0x21,0x3f,0x11,0x41,}}, // "cz__" + // ASCII-7-bit=143 Latin1=116 UTF8=178 CP1252=86 Latin2=140 CP1251=74 CP1250=181 MACINTOSH=63 CP852=65 [top CP1250] + {{0x64,0x65,0x5f,0x5f, 0x06,0xa4,0xb7,0xa4,0x40,0x9a,0x36,0x35,0x4b,0x4d,0x43,0x4d,0x4f,0x11,0x79,0x00,}}, // "de__" + // ASCII-7-bit=164 Latin1=183 UTF8=164 GB=64 CP1252=154 KSC=54 Latin2=75 CP1251=77 CP1256=67 CP1250=77 Latin5=79 ISO-8859-15=121 [top Latin1] + {{0x64,0x6a,0x5f,0x5f, 0x08,0xa3,0xad,0xa9,0x90,0xa2,0x7d,0x7a,0x68,0x21,0xa0,0x11,0x5e,0xb1,0x5e,0x00,}}, // "dj__" + // ASCII-7-bit=163 Latin1=173 UTF8=169 GB=144 CP1252=162 KSC=125 SJS=122 EUC-JP=104 CP1251=160 CP1250=94 CP932=94 [top Latin1] + {{0x64,0x6b,0x5f,0x5f, 0x03,0x9d,0xb8,0xa7,0x11,0x93,0x11,0x39,0x25,0x38,0x34,0x57,0x43,0x3d,0x11,0x54,}}, // "dk__" + // ASCII-7-bit=157 Latin1=184 UTF8=167 CP1252=147 SJS=57 Latin2=56 CP1251=52 CP1256=87 CP1250=67 Latin5=61 ISO-8859-15=84 [top Latin1] + {{0x64,0x6d,0x5f,0x5f, 0x03,0xbc,0x76,0xa3,0x11,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "dm__" + // ASCII-7-bit=188 Latin1=118 UTF8=163 CP1252=131 [top ASCII-7-bit] + {{0x64,0x6f,0x5f,0x5f, 0x05,0xa4,0xb6,0xa9,0x6b,0x93,0x31,0x43,0x61,0x57,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "do__" + // ASCII-7-bit=164 Latin1=182 UTF8=169 GB=107 CP1252=147 BIG5=67 ISO-8859-15=87 [top Latin1] + {{0x64,0x7a,0x5f,0x5f, 0x03,0x9e,0xb6,0x8d,0x11,0xa1,0x62,0xa6,0x4e,0x10,0x51,0x58,0x00,0x00,0x00,0x00,}}, // "dz__" + // ASCII-7-bit=158 Latin1=182 UTF8=141 CP1252=161 CP1256=166 CP1250=78 Arabic=88 [top Latin1] + {{0x65,0x63,0x5f,0x5f, 0x03,0xa2,0xba,0x9c,0x11,0x96,0x35,0x3c,0x32,0x5a,0x32,0x3c,0x00,0x00,0x00,0x00,}}, // "ec__" + // ASCII-7-bit=162 Latin1=186 UTF8=156 CP1252=150 BIG5=60 Latin2=50 CP1251=90 CP1256=50 CP1250=60 [top Latin1] + {{0x65,0x64,0x75,0x5f, 0x07,0xbb,0x97,0x99,0x51,0x94,0x6b,0x49,0x11,0x4e,0x21,0x4f,0x13,0x4c,0x41,0x44,}}, // "edu_" + // ASCII-7-bit=187 Latin1=151 UTF8=153 GB=81 CP1252=148 KSC=107 SJS=73 BIG5=78 CP1256=79 Latin5=76 ISO-8859-11=65 ISO-8859-15=68 [top ASCII-7-bit] + {{0x65,0x65,0x5f,0x5f, 0x03,0x97,0xaf,0xb4,0x11,0x95,0x42,0x6f,0x78,0x42,0x82,0x87,0xc2,0x5e,0x65,0x00,}}, // "ee__" + // ASCII-7-bit=151 Latin1=175 UTF8=180 CP1252=149 Latin2=111 CP1251=120 ISO-8859-15=130 CP1257=135 ISO-8859-13=94 Latin4=101 [top UTF8] + {{0x65,0x67,0x5f,0x5f, 0x05,0x9f,0x7a,0xa7,0x55,0x7d,0x61,0xb9,0x32,0x28,0x28,0x61,0x28,0x00,0x00,0x00,}}, // "eg__" + // ASCII-7-bit=159 Latin1=122 UTF8=167 GB=85 CP1252=125 CP1256=185 ISO-8859-15=40 CP1257=40 CP1253=40 [top CP1256] + {{0x65,0x73,0x5f,0x5f, 0x05,0x9f,0xb8,0xa8,0x22,0x91,0x11,0x2b,0x15,0x18,0x33,0x4d,0x31,0x23,0x21,0x6c,}}, // "es__" + // ASCII-7-bit=159 Latin1=184 UTF8=168 GB=34 CP1252=145 SJS=43 BIG5=24 Latin2=51 CP1251=77 CP1256=49 CP1250=35 ISO-8859-15=108 [top Latin1] + {{0x65,0x74,0x5f,0x5f, 0x03,0xb5,0x9a,0xa8,0x11,0xa6,0x11,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "et__" + // ASCII-7-bit=181 Latin1=154 UTF8=168 CP1252=166 SJS=126 [top ASCII-7-bit] + {{0x65,0x75,0x5f,0x5f, 0x03,0xa8,0xa4,0xb5,0x11,0x91,0x42,0x8d,0x69,0x12,0x8b,0x6a,0x11,0x78,0x41,0x78,}}, // "eu__" + // ASCII-7-bit=168 Latin1=164 UTF8=181 CP1252=145 Latin2=141 CP1251=105 CP1250=139 Latin5=106 ISO-8859-15=120 Greek=120 [top UTF8] + {{0x66,0x69,0x5f,0x5f, 0x03,0x9e,0xb7,0xaa,0x11,0x96,0x51,0x46,0x11,0x31,0x22,0x69,0x31,0x00,0x00,0x00,}}, // "fi__" + // ASCII-7-bit=158 Latin1=183 UTF8=170 CP1252=150 CP1251=70 CP1250=49 ISO-8859-15=105 CP1257=49 [top Latin1] + {{0x66,0x6a,0x5f,0x5f, 0x05,0xba,0x8b,0x9f,0x59,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "fj__" + // ASCII-7-bit=186 Latin1=139 UTF8=159 GB=89 CP1252=160 [top ASCII-7-bit] + {{0x66,0x6b,0x5f,0x5f, 0x02,0xba,0xa6,0x21,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "fk__" + // ASCII-7-bit=186 Latin1=166 CP1252=150 [top ASCII-7-bit] + {{0x66,0x6d,0x5f,0x5f, 0x03,0x91,0x92,0xbc,0x11,0x82,0x12,0x7d,0x6d,0x12,0x86,0x6a,0x51,0x67,0x00,0x00,}}, // "fm__" + // ASCII-7-bit=145 Latin1=146 UTF8=188 CP1252=130 SJS=125 EUC-JP=109 Latin2=134 CP1251=106 CP1257=103 [top UTF8] + {{0x66,0x6f,0x5f,0x5f, 0x03,0x93,0xbc,0x9c,0x11,0x8c,0x71,0x57,0x21,0x51,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "fo__" + // ASCII-7-bit=147 Latin1=188 UTF8=156 CP1252=140 CP1250=87 ISO-8859-15=81 [top Latin1] + {{0x66,0x72,0x5f,0x5f, 0x03,0x9f,0xb3,0xaf,0x11,0x99,0x17,0x37,0x32,0x32,0x35,0x41,0x4f,0x35,0x21,0x77,}}, // "fr__" + // ASCII-7-bit=159 Latin1=179 UTF8=175 CP1252=153 SJS=55 EUC-JP=50 BIG5=50 Latin2=53 CP1251=65 CP1256=79 CP1250=53 ISO-8859-15=119 [top Latin1] + {{0x67,0x61,0x5f,0x5f, 0x03,0xa8,0xb6,0xa5,0x11,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ga__" + // ASCII-7-bit=168 Latin1=182 UTF8=165 CP1252=149 [top Latin1] + {{0x67,0x64,0x5f,0x5f, 0x05,0xb5,0xac,0x9a,0x80,0x8a,0x81,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gd__" + // ASCII-7-bit=181 Latin1=172 UTF8=154 GB=128 CP1252=138 Latin5=151 [top ASCII-7-bit] + {{0x67,0x65,0x5f,0x5f, 0x03,0xa5,0x7d,0xba,0x11,0x8d,0x21,0x58,0x21,0x8b,0x11,0x71,0x21,0x4f,0xb1,0x4c,}}, // "ge__" + // ASCII-7-bit=165 Latin1=125 UTF8=186 CP1252=141 EUC-JP=88 CP1251=139 CP1250=113 ISO-8859-15=79 ISO-8859-5=76 [top UTF8] + {{0x67,0x67,0x5f,0x5f, 0x03,0xad,0xa9,0xb0,0x11,0x95,0x11,0x60,0x81,0x93,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gg__" + // ASCII-7-bit=173 Latin1=169 UTF8=176 CP1252=149 SJS=96 ISO-8859-15=147 [top UTF8] + {{0x67,0x68,0x5f,0x5f, 0x03,0xac,0xb3,0x99,0x11,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gh__" + // ASCII-7-bit=172 Latin1=179 UTF8=153 CP1252=166 [top Latin1] + {{0x67,0x69,0x5f,0x5f, 0x03,0xb3,0xa1,0xa1,0x11,0x9c,0xa1,0xa8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gi__" + // ASCII-7-bit=179 Latin1=161 UTF8=161 CP1252=156 ISO-8859-15=168 [top ASCII-7-bit] + {{0x67,0x6c,0x5f,0x5f, 0x03,0xa7,0xb2,0xaa,0x11,0xa1,0x11,0x43,0x11,0x4d,0x61,0x70,0x00,0x00,0x00,0x00,}}, // "gl__" + // ASCII-7-bit=167 Latin1=178 UTF8=170 CP1252=161 SJS=67 BIG5=77 ISO-8859-15=112 [top Latin1] + {{0x67,0x6d,0x5f,0x5f, 0x03,0xb8,0x89,0xa0,0x11,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gm__" + // ASCII-7-bit=184 Latin1=137 UTF8=160 CP1252=167 [top ASCII-7-bit] + {{0x67,0x6e,0x5f,0x5f, 0x03,0xaa,0xb8,0x89,0x11,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gn__" + // ASCII-7-bit=170 Latin1=184 UTF8=137 CP1252=157 [top Latin1] + {{0x67,0x6f,0x76,0x5f, 0x05,0xbd,0x92,0x94,0x22,0x87,0x11,0x2e,0x33,0x36,0x15,0x2e,0x13,0x14,0x1f,0x0e,}}, // "gov_" + // ASCII-7-bit=189 Latin1=146 UTF8=148 GB=34 CP1252=135 SJS=46 CP1251=54 CP1256=21 CP1250=46 ISO-8859-11=20 ISO-8859-15=31 CP1257=14 [top ASCII-7-bit] + {{0x67,0x70,0x5f,0x5f, 0x03,0x98,0x9f,0xbb,0x11,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gp__" + // ASCII-7-bit=152 Latin1=159 UTF8=187 CP1252=131 [top UTF8] + {{0x67,0x72,0x5f,0x5f, 0x05,0xa1,0x7f,0xa8,0x45,0x80,0x42,0x49,0x54,0x12,0x44,0x45,0x61,0xb5,0x21,0x9e,}}, // "gr__" + // ASCII-7-bit=161 Latin1=127 UTF8=168 GB=69 CP1252=128 Latin2=73 CP1251=84 CP1250=68 Latin5=69 Greek=181 CP1253=158 [top Greek] + {{0x67,0x73,0x5f,0x5f, 0x05,0xb0,0x93,0x98,0x68,0x88,0x13,0xa2,0xa7,0x75,0x42,0x99,0x98,0x91,0x66,0x00,}}, // "gs__" + // ASCII-7-bit=176 Latin1=147 UTF8=152 GB=104 CP1252=136 SJS=162 EUC-JP=167 BIG5=117 Latin5=153 ISO-8859-11=152 CP932=102 [top ASCII-7-bit] + {{0x67,0x74,0x5f,0x5f, 0x03,0xa3,0xb6,0xa9,0x12,0x95,0x3d,0x91,0x3d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gt__" + // ASCII-7-bit=163 Latin1=182 UTF8=169 CP1252=149 KSC=61 ISO-8859-15=61 [top Latin1] + {{0x67,0x75,0x5f,0x5f, 0x03,0xb9,0xa0,0x7d,0x11,0xa5,0x11,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gu__" + // ASCII-7-bit=185 Latin1=160 UTF8=125 CP1252=165 SJS=125 [top ASCII-7-bit] + {{0x67,0x79,0x5f,0x5f, 0x03,0xbc,0x82,0xa2,0x11,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gy__" + // ASCII-7-bit=188 Latin1=130 UTF8=162 CP1252=135 [top ASCII-7-bit] + {{0x68,0x6b,0x5f,0x5f, 0x07,0xa6,0x6c,0xa3,0xa0,0x6b,0x38,0x53,0x11,0xb5,0xa1,0x73,0xc1,0x3d,0x21,0x49,}}, // "hk__" + // ASCII-7-bit=166 Latin1=108 UTF8=163 GB=160 CP1252=107 KSC=56 SJS=83 BIG5=181 GBK=115 GB18030=61 BIG5_HKSCS=73 [top BIG5] + {{0x68,0x6d,0x5f,0x5f, 0x05,0xa8,0x9e,0xaa,0x67,0x67,0x13,0xac,0x9f,0x95,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "hm__" + // ASCII-7-bit=168 Latin1=158 UTF8=170 GB=103 CP1252=103 SJS=172 EUC-JP=159 BIG5=149 [top SJS] + {{0x68,0x6e,0x5f,0x5f, 0x03,0xa1,0xb7,0xa6,0x11,0x9c,0x51,0x4d,0x31,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "hn__" + // ASCII-7-bit=161 Latin1=183 UTF8=166 CP1252=156 CP1251=77 ISO-8859-11=77 [top Latin1] + {{0x68,0x72,0x5f,0x5f, 0x03,0x99,0x67,0xa7,0x11,0x67,0x42,0x9d,0x20,0x11,0xb8,0x10,0x21,0x26,0x11,0x32,}}, // "hr__" + // ASCII-7-bit=153 Latin1=103 UTF8=167 CP1252=103 Latin2=157 CP1251=32 CP1250=184 MACINTOSH=38 CP852=50 [top CP1250] + {{0x68,0x74,0x5f,0x5f, 0x03,0x95,0x97,0xbc,0x11,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ht__" + // ASCII-7-bit=149 Latin1=151 UTF8=188 CP1252=146 [top UTF8] + {{0x68,0x75,0x5f,0x5f, 0x05,0xa2,0xa4,0xad,0x33,0x76,0x11,0x3d,0x25,0xa7,0x4a,0x40,0xa7,0x35,0x11,0x3a,}}, // "hu__" + // ASCII-7-bit=162 Latin1=164 UTF8=173 GB=51 CP1252=118 SJS=61 Latin2=167 CP1251=74 CP1256=64 CP1250=167 Latin5=53 ISO-8859-15=58 [top UTF8] + {{0x69,0x64,0x5f,0x5f, 0x07,0xb8,0xab,0x8c,0x24,0x97,0x33,0x46,0x14,0x2c,0x1f,0x1f,0x7b,0x22,0x29,0x4b,}}, // "id__" + // ASCII-7-bit=184 Latin1=171 UTF8=140 GB=36 CP1252=151 KSC=51 SJS=70 BIG5=44 Latin2=31 CP1251=31 CP1256=123 ISO-8859-11=41 ISO-8859-15=75 [top ASCII-7-bit] + {{0x69,0x65,0x5f,0x5f, 0x05,0xb3,0xa6,0xa0,0x45,0x9d,0x11,0x46,0x21,0x67,0x12,0x32,0x4a,0x22,0xa3,0x36,}}, // "ie__" + // ASCII-7-bit=179 Latin1=166 UTF8=160 GB=69 CP1252=157 SJS=70 Latin2=103 CP1256=50 CP1250=74 ISO-8859-15=163 CP1257=54 [top ASCII-7-bit] + {{0x69,0x6c,0x5f,0x5f, 0x03,0x94,0x74,0xa9,0x11,0x6e,0x21,0x3b,0x23,0x79,0x83,0x3d,0x41,0xb8,0x71,0x90,}}, // "il__" + // ASCII-7-bit=148 Latin1=116 UTF8=169 CP1252=110 EUC-JP=59 CP1251=121 CP1256=131 CP1250=61 CP1255=184 Hebrew=144 [top CP1255] + {{0x69,0x6d,0x5f,0x5f, 0x05,0xb7,0x8e,0xaf,0x89,0x7e,0x51,0x48,0x21,0x71,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "im__" + // ASCII-7-bit=183 Latin1=142 UTF8=175 GB=137 CP1252=126 CP1251=72 Latin5=113 [top ASCII-7-bit] + {{0x69,0x6e,0x5f,0x5f, 0x08,0xbb,0x95,0x9c,0x5e,0x99,0x61,0x6f,0x67,0x21,0x60,0x22,0x69,0x4d,0x11,0x4c,}}, // "in__" + // ASCII-7-bit=187 Latin1=149 UTF8=156 GB=94 CP1252=153 KSC=97 SJS=111 EUC-JP=103 CP1251=96 Latin5=105 ISO-8859-11=77 CP1257=76 [top ASCII-7-bit] + {{0x69,0x6e,0x66,0x6f, 0x05,0xac,0xa7,0xa7,0x76,0x94,0x18,0x93,0x82,0x70,0x90,0x91,0x82,0x9c,0x78,0x00,}}, // "info" + // ASCII-7-bit=172 Latin1=167 UTF8=167 GB=118 CP1252=148 SJS=147 EUC-JP=130 BIG5=112 Latin2=144 CP1251=145 CP1256=130 CP1250=156 Latin5=120 [top ASCII-7-bit] + {{0x69,0x6e,0x74,0x5f, 0x05,0xb2,0xa7,0xb0,0x3a,0x84,0x53,0x62,0x55,0x54,0x71,0x45,0x21,0x39,0x31,0x50,}}, // "int_" + // ASCII-7-bit=178 Latin1=167 UTF8=176 GB=58 CP1252=132 CP1251=98 CP1256=85 CP1250=84 Greek=69 CP1253=57 ISO-8859-5=80 [top ASCII-7-bit] + {{0x69,0x6f,0x5f,0x5f, 0x09,0xaf,0x98,0xac,0xa8,0x85,0x77,0x83,0x7b,0x67,0x12,0x88,0x71,0x22,0x77,0x67,}}, // "io__" + // ASCII-7-bit=175 Latin1=152 UTF8=172 GB=168 CP1252=133 KSC=119 SJS=131 EUC-JP=123 BIG5=103 CP1251=136 CP1256=113 ISO-8859-11=119 ISO-8859-15=103 [top ASCII-7-bit] + {{0x69,0x72,0x5f,0x5f, 0x07,0x9e,0x8c,0xb5,0x55,0x7e,0x22,0x3c,0x25,0x32,0x32,0xae,0x36,0x3e,0x81,0x52,}}, // "ir__" + // ASCII-7-bit=158 Latin1=140 UTF8=181 GB=85 CP1252=126 KSC=34 SJS=60 Latin2=50 CP1251=50 CP1256=174 CP1250=54 Latin5=62 CP1254=82 [top UTF8] + {{0x69,0x73,0x5f,0x5f, 0x05,0x8f,0xbc,0xa0,0x1b,0x84,0x15,0x3b,0x1b,0x2f,0x1b,0x25,0x11,0x32,0x21,0x1b,}}, // "is__" + // ASCII-7-bit=143 Latin1=188 UTF8=160 GB=27 CP1252=132 SJS=59 EUC-JP=27 BIG5=47 Latin2=27 CP1251=37 CP1250=50 ISO-8859-15=27 [top Latin1] + {{0x69,0x74,0x5f,0x5f, 0x03,0xac,0xb4,0x9e,0x11,0xa2,0x11,0x35,0x21,0x44,0x21,0x3e,0x21,0x60,0x51,0x55,}}, // "it__" + // ASCII-7-bit=172 Latin1=180 UTF8=158 CP1252=162 SJS=53 Latin2=68 CP1250=62 ISO-8859-15=96 JIS=85 [top Latin1] + {{0x6a,0x65,0x5f,0x5f, 0x03,0xb7,0x8e,0xab,0x11,0x9e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "je__" + // ASCII-7-bit=183 Latin1=142 UTF8=171 CP1252=158 [top ASCII-7-bit] + {{0x6a,0x6d,0x5f,0x5f, 0x03,0xb8,0xa6,0x93,0x11,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "jm__" + // ASCII-7-bit=184 Latin1=166 UTF8=147 CP1252=160 [top ASCII-7-bit] + {{0x6a,0x6f,0x5f,0x5f, 0x03,0xa5,0x73,0xb0,0x11,0x82,0x52,0x3c,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "jo__" + // ASCII-7-bit=165 Latin1=115 UTF8=176 CP1252=130 CP1251=60 CP1256=178 [top CP1256] + {{0x6a,0x6f,0x62,0x73, 0x03,0xb7,0xa1,0xa5,0x11,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "jobs" + // ASCII-7-bit=183 Latin1=161 UTF8=165 CP1252=160 [top ASCII-7-bit] + {{0x6a,0x70,0x5f,0x5f, 0x09,0x9b,0x48,0xa4,0x45,0x42,0x4b,0xb3,0xad,0x48,0x51,0x1e,0x61,0x73,0x21,0x63,}}, // "jp__" + // ASCII-7-bit=155 Latin1=72 UTF8=164 GB=69 CP1252=66 KSC=75 SJS=179 EUC-JP=173 BIG5=72 ISO-8859-11=30 JIS=115 CP932=99 [top SJS] + {{0x6b,0x65,0x5f,0x5f, 0x03,0xb9,0x9a,0xa1,0x13,0x9e,0x4b,0x5b,0x11,0x4b,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ke__" + // ASCII-7-bit=185 Latin1=154 UTF8=161 CP1252=158 KSC=75 SJS=91 BIG5=75 [top ASCII-7-bit] + {{0x6b,0x67,0x5f,0x5f, 0x05,0x94,0x71,0x9f,0x67,0x83,0x11,0xa8,0x31,0xb7,0x12,0x57,0x57,0x41,0x6f,0x00,}}, // "kg__" + // ASCII-7-bit=148 Latin1=113 UTF8=159 GB=103 CP1252=131 SJS=168 CP1251=183 CP1250=87 Latin5=87 KOI8R=111 [top CP1251] + {{0x6b,0x68,0x5f,0x5f, 0x05,0xb6,0xa1,0xa1,0x53,0xa5,0x12,0x74,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kh__" + // ASCII-7-bit=182 Latin1=161 UTF8=161 GB=83 CP1252=165 SJS=116 EUC-JP=115 [top ASCII-7-bit] + {{0x6b,0x69,0x5f,0x5f, 0x03,0xb8,0xac,0x98,0x11,0x82,0x81,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ki__" + // ASCII-7-bit=184 Latin1=172 UTF8=152 CP1252=130 Latin5=97 [top ASCII-7-bit] + {{0x6b,0x6e,0x5f,0x5f, 0x01,0xba,0x11,0x89,0x11,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kn__" + // ASCII-7-bit=186 UTF8=137 CP1252=170 [top ASCII-7-bit] + {{0x6b,0x72,0x5f,0x5f, 0x09,0x80,0x39,0x92,0x43,0x2e,0xbe,0x5f,0x3a,0x3d,0x31,0x0c,0x00,0x00,0x00,0x00,}}, // "kr__" + // ASCII-7-bit=128 Latin1=57 UTF8=146 GB=67 CP1252=46 KSC=190 SJS=95 EUC-JP=58 BIG5=61 CP1250=12 [top KSC] + {{0x6b,0x77,0x5f,0x5f, 0x03,0x91,0x69,0xb2,0x11,0x71,0x61,0xb5,0x11,0x40,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kw__" + // ASCII-7-bit=145 Latin1=105 UTF8=178 CP1252=113 CP1256=181 Latin5=64 [top CP1256] + {{0x6b,0x79,0x5f,0x5f, 0x03,0xab,0x9d,0xb6,0x11,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ky__" + // ASCII-7-bit=171 Latin1=157 UTF8=182 CP1252=154 [top UTF8] + {{0x6b,0x7a,0x5f,0x5f, 0x03,0x8d,0x7b,0xb1,0x12,0x74,0x3d,0x41,0xb5,0x21,0x4a,0x41,0x8b,0x81,0x4a,0x00,}}, // "kz__" + // ASCII-7-bit=141 Latin1=123 UTF8=177 CP1252=116 KSC=61 CP1251=181 Latin5=74 KOI8R=139 ISO-8859-5=74 [top CP1251] + {{0x6c,0x61,0x5f,0x5f, 0x05,0xa8,0x8e,0xab,0xab,0x71,0x13,0x9f,0x6a,0x99,0x41,0x77,0x51,0x64,0x41,0x7e,}}, // "la__" + // ASCII-7-bit=168 Latin1=142 UTF8=171 GB=171 CP1252=113 SJS=159 EUC-JP=106 BIG5=153 Latin5=119 GBK=100 CP932=126 [top UTF8] + {{0x6c,0x62,0x5f,0x5f, 0x03,0xb3,0x95,0xaf,0x11,0x90,0x11,0x35,0x41,0x9f,0x10,0x61,0x3f,0x00,0x00,0x00,}}, // "lb__" + // ASCII-7-bit=179 Latin1=149 UTF8=175 CP1252=144 SJS=53 CP1256=159 Arabic=63 [top ASCII-7-bit] + {{0x6c,0x63,0x5f,0x5f, 0x02,0xab,0xa8,0x21,0xb5,0x11,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lc__" + // ASCII-7-bit=171 Latin1=168 CP1252=181 SJS=127 [top CP1252] + {{0x6c,0x69,0x5f,0x5f, 0x05,0xad,0xb5,0x9d,0x72,0x93,0x12,0x5f,0x53,0x22,0x89,0x64,0x11,0x5f,0x51,0x53,}}, // "li__" + // ASCII-7-bit=173 Latin1=181 UTF8=157 GB=114 CP1252=147 SJS=95 EUC-JP=83 CP1251=137 CP1256=100 Latin5=95 GBK=83 [top Latin1] + {{0x6c,0x6b,0x5f,0x5f, 0x03,0xb9,0x9e,0x9d,0x11,0xa1,0x12,0x47,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lk__" + // ASCII-7-bit=185 Latin1=158 UTF8=157 CP1252=161 SJS=71 EUC-JP=71 [top ASCII-7-bit] + {{0x6c,0x72,0x5f,0x5f, 0x03,0xad,0xac,0x8a,0x11,0xb1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lr__" + // ASCII-7-bit=173 Latin1=172 UTF8=138 CP1252=177 [top CP1252] + {{0x6c,0x73,0x5f,0x5f, 0x03,0xb7,0xa3,0x97,0x11,0xa8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ls__" + // ASCII-7-bit=183 Latin1=163 UTF8=151 CP1252=168 [top ASCII-7-bit] + {{0x6c,0x74,0x5f,0x5f, 0x06,0x8c,0x64,0xae,0x3b,0x6d,0x5d,0x32,0x48,0x71,0x11,0x55,0x31,0xb8,0xc1,0x6e,}}, // "lt__" + // ASCII-7-bit=140 Latin1=100 UTF8=174 GB=59 CP1252=109 KSC=93 Latin2=72 CP1251=113 CP1250=85 CP1257=184 ISO-8859-13=110 [top CP1257] + {{0x6c,0x75,0x5f,0x5f, 0x05,0xa6,0xb2,0xad,0x47,0x9f,0x41,0x42,0x22,0x54,0x3f,0x11,0x53,0x10,0x51,0x3b,}}, // "lu__" + // ASCII-7-bit=166 Latin1=178 UTF8=173 GB=71 CP1252=159 Latin2=66 CP1250=84 Latin5=63 ISO-8859-15=83 UTF-16BE=59 [top Latin1] + {{0x6c,0x76,0x5f,0x5f, 0x03,0x97,0x6d,0xb5,0x11,0x6b,0x51,0x92,0x51,0xb0,0x11,0x4e,0xa2,0x5f,0x52,0x00,}}, // "lv__" + // ASCII-7-bit=151 Latin1=109 UTF8=181 CP1252=107 CP1251=146 CP1257=176 KOI8R=78 ISO-8859-13=95 Latin4=82 [top UTF8] + {{0x6c,0x79,0x5f,0x5f, 0x07,0xa4,0x77,0xb0,0x59,0x8c,0x92,0x59,0x32,0x59,0xb1,0x00,0x00,0x00,0x00,0x00,}}, // "ly__" + // ASCII-7-bit=164 Latin1=119 UTF8=176 GB=89 CP1252=140 KSC=146 SJS=89 CP1251=89 CP1256=177 [top CP1256] + {{0x6d,0x61,0x5f,0x5f, 0x03,0xa2,0xb3,0xa6,0x11,0xa0,0x62,0x9e,0x5d,0x22,0x7d,0x4b,0x10,0x11,0x47,0x00,}}, // "ma__" + // ASCII-7-bit=162 Latin1=179 UTF8=166 CP1252=160 CP1256=158 CP1250=93 ISO-8859-15=125 CP1257=75 Arabic=71 [top Latin1] + {{0x6d,0x63,0x5f,0x5f, 0x03,0x87,0xbe,0x73,0x11,0x89,0xa1,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mc__" + // ASCII-7-bit=135 Latin1=190 UTF8=115 CP1252=137 ISO-8859-15=71 [top Latin1] + {{0x6d,0x64,0x5f,0x5f, 0x03,0xa4,0x82,0xad,0x11,0x86,0x11,0x61,0x15,0x61,0x74,0xae,0x6e,0x99,0x51,0x9d,}}, // "md__" + // ASCII-7-bit=164 Latin1=130 UTF8=173 CP1252=134 SJS=97 BIG5=97 Latin2=116 CP1251=174 CP1256=110 CP1250=153 KOI8R=157 [top CP1251] + {{0x6d,0x67,0x5f,0x5f, 0x03,0x99,0xba,0x85,0x11,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mg__" + // ASCII-7-bit=153 Latin1=186 UTF8=133 CP1252=166 [top Latin1] + {{0x6d,0x69,0x6c,0x5f, 0x03,0xba,0x9a,0x9a,0x13,0x9a,0x44,0x50,0x11,0x24,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mil_" + // ASCII-7-bit=186 Latin1=154 UTF8=154 CP1252=154 KSC=68 SJS=80 BIG5=36 [top ASCII-7-bit] + {{0x6d,0x6b,0x5f,0x5f, 0x03,0x95,0x72,0xab,0x11,0x73,0x42,0x3f,0xa0,0x11,0x66,0x51,0xb6,0x81,0x56,0x00,}}, // "mk__" + // ASCII-7-bit=149 Latin1=114 UTF8=171 CP1252=115 Latin2=63 CP1251=160 CP1250=102 KOI8R=182 ISO-8859-5=86 [top KOI8R] + {{0x6d,0x6c,0x5f,0x5f, 0x03,0x85,0xbd,0x85,0x11,0x96,0x81,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ml__" + // ASCII-7-bit=133 Latin1=189 UTF8=133 CP1252=150 Latin5=89 [top Latin1] + {{0x6d,0x6d,0x5f,0x5f, 0x03,0xb5,0xa1,0x7d,0x11,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mm__" + // ASCII-7-bit=181 Latin1=161 UTF8=125 CP1252=175 [top ASCII-7-bit] + {{0x6d,0x6e,0x5f,0x5f, 0x07,0x9f,0x7f,0xb8,0x79,0x7d,0x4f,0x5f,0x11,0x56,0x11,0xa7,0x00,0x00,0x00,0x00,}}, // "mn__" + // ASCII-7-bit=159 Latin1=127 UTF8=184 GB=121 CP1252=125 KSC=79 SJS=95 BIG5=86 CP1251=167 [top UTF8] + {{0x6d,0x6f,0x5f,0x5f, 0x05,0xa0,0x9e,0xaa,0x9e,0x86,0x11,0x4a,0x11,0xb2,0xa1,0x59,0xc1,0x36,0x00,0x00,}}, // "mo__" + // ASCII-7-bit=160 Latin1=158 UTF8=170 GB=158 CP1252=134 SJS=74 BIG5=178 GBK=89 GB18030=54 [top BIG5] + {{0x6d,0x6f,0x62,0x69, 0x08,0xb6,0x95,0xaa,0x7f,0x7d,0x53,0xa0,0x71,0x13,0x65,0x6d,0x78,0xc1,0x73,0x00,}}, // "mobi" + // ASCII-7-bit=182 Latin1=149 UTF8=170 GB=127 CP1252=125 KSC=83 SJS=160 EUC-JP=113 Latin2=101 CP1251=109 CP1256=120 CP932=115 [top ASCII-7-bit] + {{0x6d,0x70,0x5f,0x5f, 0x03,0xbe,0x5a,0x54,0x11,0x5c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mp__" + // ASCII-7-bit=190 Latin1=90 UTF8=84 CP1252=92 [top ASCII-7-bit] + {{0x6d,0x71,0x5f,0x5f, 0x03,0xa3,0xb8,0x95,0x11,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mq__" + // ASCII-7-bit=163 Latin1=184 UTF8=149 CP1252=165 [top Latin1] + {{0x6d,0x72,0x5f,0x5f, 0x03,0x9b,0xab,0x8d,0x11,0x96,0x61,0xb6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mr__" + // ASCII-7-bit=155 Latin1=171 UTF8=141 CP1252=150 CP1256=182 [top CP1256] + {{0x6d,0x73,0x5f,0x5f, 0x03,0xb4,0xae,0x9c,0x18,0x8a,0x73,0x86,0x6f,0x53,0x56,0x6c,0x75,0x11,0x85,0x00,}}, // "ms__" + // ASCII-7-bit=180 Latin1=174 UTF8=156 CP1252=138 KSC=115 SJS=134 EUC-JP=111 BIG5=83 Latin2=86 CP1251=108 CP1256=117 Latin5=133 [top ASCII-7-bit] + {{0x6d,0x74,0x5f,0x5f, 0x05,0xbc,0x87,0x9b,0x5c,0x8b,0x42,0x2c,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mt__" + // ASCII-7-bit=188 Latin1=135 UTF8=155 GB=92 CP1252=139 Latin2=44 CP1251=64 [top ASCII-7-bit] + {{0x6d,0x75,0x5f,0x5f, 0x09,0xb4,0xa4,0xa9,0x57,0x9f,0x4d,0x7e,0x70,0x4d,0x11,0x4d,0x21,0x57,0x11,0x4d,}}, // "mu__" + // ASCII-7-bit=180 Latin1=164 UTF8=169 GB=87 CP1252=159 KSC=77 SJS=126 EUC-JP=112 BIG5=77 CP1251=77 Latin5=87 ISO-8859-15=77 [top ASCII-7-bit] + {{0x6d,0x75,0x73,0x65, 0x07,0xb3,0xa9,0xa6,0x76,0x90,0x56,0x88,0x13,0x8e,0x6a,0x7a,0x00,0x00,0x00,0x00,}}, // "muse" + // ASCII-7-bit=179 Latin1=169 UTF8=166 GB=118 CP1252=144 KSC=86 SJS=136 BIG5=142 Latin2=106 CP1251=122 [top ASCII-7-bit] + {{0x6d,0x76,0x5f,0x5f, 0x03,0xb6,0x98,0xab,0x11,0x9f,0x61,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mv__" + // ASCII-7-bit=182 Latin1=152 UTF8=171 CP1252=159 CP1256=83 [top ASCII-7-bit] + {{0x6d,0x77,0x5f,0x5f, 0x05,0xb7,0xa3,0xa8,0x7f,0x8d,0x11,0x7f,0xc1,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mw__" + // ASCII-7-bit=183 Latin1=163 UTF8=168 GB=127 CP1252=141 SJS=127 GBK=107 [top ASCII-7-bit] + {{0x6d,0x78,0x5f,0x5f, 0x05,0xa7,0xba,0x94,0x45,0x93,0x11,0x1d,0x12,0x25,0x29,0x21,0x27,0x21,0x3c,0x00,}}, // "mx__" + // ASCII-7-bit=167 Latin1=186 UTF8=148 GB=69 CP1252=147 SJS=29 BIG5=37 Latin2=41 CP1250=39 ISO-8859-15=60 [top Latin1] + {{0x6d,0x79,0x5f,0x5f, 0x05,0xb3,0xb3,0x8d,0x6b,0x8f,0x13,0x4d,0x50,0x7f,0x12,0x3f,0x6b,0x12,0x4b,0x3e,}}, // "my__" + // ASCII-7-bit=179 Latin1=179 UTF8=141 GB=107 CP1252=143 SJS=77 EUC-JP=80 BIG5=127 CP1251=63 CP1256=107 Latin5=75 ISO-8859-11=62 [top ASCII-7-bit] + {{0x6d,0x7a,0x5f,0x5f, 0x03,0x8e,0xaf,0xb7,0x11,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mz__" + // ASCII-7-bit=142 Latin1=175 UTF8=183 CP1252=143 [top UTF8] + {{0x6e,0x61,0x5f,0x5f, 0x03,0xba,0xa1,0x97,0x11,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "na__" + // ASCII-7-bit=186 Latin1=161 UTF8=151 CP1252=156 [top ASCII-7-bit] + {{0x6e,0x61,0x6d,0x65, 0x08,0xb2,0xa4,0xa9,0x8a,0x90,0x7d,0x7c,0x6b,0x15,0x80,0x94,0x6b,0x8b,0x77,0x00,}}, // "name" + // ASCII-7-bit=178 Latin1=164 UTF8=169 GB=138 CP1252=144 KSC=125 SJS=124 EUC-JP=107 Latin2=128 CP1251=148 CP1256=107 CP1250=139 Latin5=119 [top ASCII-7-bit] + {{0x6e,0x63,0x5f,0x5f, 0x03,0xa7,0xb9,0x8c,0x11,0x9e,0x11,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "nc__" + // ASCII-7-bit=167 Latin1=185 UTF8=140 CP1252=158 SJS=114 [top Latin1] + {{0x6e,0x65,0x5f,0x5f, 0x03,0xad,0xb9,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ne__" + // ASCII-7-bit=173 Latin1=185 UTF8=128 [top Latin1] + {{0x6e,0x65,0x74,0x5f, 0x0f,0xac,0xa6,0xa4,0x93,0x93,0x94,0x97,0x83,0x86,0x7e,0x80,0x96,0x7a,0x89,0x73,}}, // "net_" + // ASCII-7-bit=172 Latin1=166 UTF8=164 GB=147 CP1252=147 KSC=148 SJS=151 EUC-JP=131 BIG5=134 Latin2=126 CP1251=128 CP1256=150 CP1250=122 Latin5=137 ISO-8859-11=115 [top ASCII-7-bit] + {{0x6e,0x66,0x5f,0x5f, 0x03,0xb5,0xa9,0xa8,0x11,0x87,0xa1,0x77,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "nf__" + // ASCII-7-bit=181 Latin1=169 UTF8=168 CP1252=135 ISO-8859-15=119 [top ASCII-7-bit] + {{0x6e,0x67,0x5f,0x5f, 0x03,0xbd,0x95,0x89,0x11,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ng__" + // ASCII-7-bit=189 Latin1=149 UTF8=137 CP1252=146 [top ASCII-7-bit] + {{0x6e,0x69,0x5f,0x5f, 0x03,0x9d,0xb3,0xa9,0x11,0xa8,0x81,0x40,0x11,0x36,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ni__" + // ASCII-7-bit=157 Latin1=179 UTF8=169 CP1252=168 Latin5=64 ISO-8859-15=54 [top Latin1] + {{0x6e,0x6c,0x5f,0x5f, 0x05,0xb2,0xae,0xa0,0x32,0xa1,0x36,0x31,0x42,0x39,0x3b,0x33,0x45,0x11,0x6f,0x00,}}, // "nl__" + // ASCII-7-bit=178 Latin1=174 UTF8=160 GB=50 CP1252=161 BIG5=49 Latin2=66 CP1251=57 CP1256=59 CP1250=51 Latin5=69 ISO-8859-15=111 [top ASCII-7-bit] + {{0x6e,0x6f,0x5f,0x5f, 0x05,0x99,0xb8,0xaa,0x47,0x8d,0x11,0x31,0x22,0x34,0x3e,0x42,0x70,0x33,0x00,0x00,}}, // "no__" + // ASCII-7-bit=153 Latin1=184 UTF8=170 GB=71 CP1252=141 SJS=49 Latin2=52 CP1251=62 ISO-8859-15=112 CP1257=51 [top Latin1] + {{0x6e,0x70,0x5f,0x5f, 0x03,0xb2,0x9f,0xa5,0x11,0xac,0x11,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "np__" + // ASCII-7-bit=178 Latin1=159 UTF8=165 CP1252=172 SJS=97 [top ASCII-7-bit] + {{0x6e,0x72,0x5f,0x5f, 0x03,0xbe,0x77,0x7a,0x11,0x62,0x71,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "nr__" + // ASCII-7-bit=190 Latin1=119 UTF8=122 CP1252=98 CP1250=68 [top ASCII-7-bit] + {{0x6e,0x75,0x5f,0x5f, 0x03,0xae,0xb4,0x9e,0x11,0x96,0x12,0x7c,0x76,0x22,0x75,0x62,0xa1,0x65,0x00,0x00,}}, // "nu__" + // ASCII-7-bit=174 Latin1=180 UTF8=158 CP1252=150 SJS=124 EUC-JP=118 CP1251=117 CP1256=98 CP1254=101 [top Latin1] + {{0x6e,0x7a,0x5f,0x5f, 0x0d,0xba,0x97,0xa2,0x5f,0x97,0x5c,0x5a,0x4b,0x4a,0x30,0x47,0x36,0x34,0x21,0x2b,}}, // "nz__" + // ASCII-7-bit=186 Latin1=151 UTF8=162 GB=95 CP1252=151 KSC=92 SJS=90 EUC-JP=75 BIG5=74 Latin2=48 CP1251=71 CP1256=54 CP1250=52 ISO-8859-15=43 [top ASCII-7-bit] + {{0x6f,0x6d,0x5f,0x5f, 0x03,0x9a,0x8a,0x89,0x11,0x87,0x61,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "om__" + // ASCII-7-bit=154 Latin1=138 UTF8=137 CP1252=135 CP1256=188 [top CP1256] + {{0x6f,0x72,0x67,0x5f, 0x0e,0xb5,0x9f,0xac,0x76,0x90,0x7e,0x6e,0x69,0x71,0x6d,0x6a,0x78,0x60,0x73,0x00,}}, // "org_" + // ASCII-7-bit=181 Latin1=159 UTF8=172 GB=118 CP1252=144 KSC=126 SJS=110 EUC-JP=105 BIG5=113 Latin2=109 CP1251=106 CP1256=120 CP1250=96 Latin5=115 [top ASCII-7-bit] + {{0x70,0x61,0x5f,0x5f, 0x03,0xa3,0xb8,0xa7,0x11,0x87,0x71,0x31,0x21,0x41,0x21,0x31,0x00,0x00,0x00,0x00,}}, // "pa__" + // ASCII-7-bit=163 Latin1=184 UTF8=167 CP1252=135 CP1250=49 ISO-8859-15=65 KOI8R=49 [top Latin1] + {{0x70,0x65,0x5f,0x5f, 0x05,0xa8,0xb8,0x9d,0x3a,0x99,0x11,0x2e,0x13,0x2e,0x1e,0x1e,0x11,0x32,0x00,0x00,}}, // "pe__" + // ASCII-7-bit=168 Latin1=184 UTF8=157 GB=58 CP1252=153 SJS=46 BIG5=46 Latin2=30 CP1251=30 CP1250=50 [top Latin1] + {{0x70,0x66,0x5f,0x5f, 0x03,0xa2,0xb5,0xa3,0x11,0xa7,0x11,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "pf__" + // ASCII-7-bit=162 Latin1=181 UTF8=163 CP1252=167 SJS=99 [top Latin1] + {{0x70,0x67,0x5f,0x5f, 0x05,0xb8,0xa6,0x81,0x6a,0xa5,0x11,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "pg__" + // ASCII-7-bit=184 Latin1=166 UTF8=129 GB=106 CP1252=165 SJS=112 [top ASCII-7-bit] + {{0x70,0x68,0x5f,0x5f, 0x03,0xb5,0x9e,0x99,0x15,0xac,0x57,0x65,0x4f,0x51,0x31,0x31,0x11,0x4b,0xd1,0x29,}}, // "ph__" + // ASCII-7-bit=181 Latin1=158 UTF8=153 CP1252=172 KSC=87 SJS=101 EUC-JP=79 BIG5=81 CP1250=49 ISO-8859-11=75 CP874=41 [top ASCII-7-bit] + {{0x70,0x6b,0x5f,0x5f, 0x03,0xb9,0x9b,0x8c,0x11,0xa3,0x11,0x33,0x11,0x99,0x21,0x29,0x00,0x00,0x00,0x00,}}, // "pk__" + // ASCII-7-bit=185 Latin1=155 UTF8=140 CP1252=163 SJS=51 BIG5=153 CP1256=41 [top ASCII-7-bit] + {{0x70,0x6c,0x5f,0x5f, 0x03,0x89,0x62,0xa8,0x11,0x4b,0x42,0xba,0x40,0x11,0x92,0xe1,0x3e,0x00,0x00,0x00,}}, // "pl__" + // ASCII-7-bit=137 Latin1=98 UTF8=168 CP1252=75 Latin2=186 CP1251=64 CP1250=146 ISO-8859-5=62 [top Latin2] + {{0x70,0x6e,0x5f,0x5f, 0x06,0xbb,0xa1,0x99,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "pn__" + // ASCII-7-bit=187 Latin1=161 UTF8=153 GB=102 CP1252=102 KSC=102 [top ASCII-7-bit] + {{0x70,0x72,0x5f,0x5f, 0x03,0x9b,0xb5,0xaf,0x11,0x94,0x41,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "pr__" + // ASCII-7-bit=155 Latin1=181 UTF8=175 CP1252=148 Latin2=101 [top Latin1] + {{0x70,0x72,0x6f,0x5f, 0x03,0xb3,0x9e,0xad,0x11,0x87,0x13,0x65,0x6f,0x65,0x11,0x9f,0x21,0x79,0x00,0x00,}}, // "pro_" + // ASCII-7-bit=179 Latin1=158 UTF8=173 CP1252=135 SJS=101 EUC-JP=111 BIG5=101 CP1251=159 Latin5=121 [top ASCII-7-bit] + {{0x70,0x73,0x5f,0x5f, 0x03,0x99,0x8f,0x9d,0x11,0x9f,0x61,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ps__" + // ASCII-7-bit=153 Latin1=143 UTF8=157 CP1252=159 CP1256=185 [top CP1256] + {{0x70,0x74,0x5f,0x5f, 0x05,0x99,0xb5,0xad,0x1d,0x95,0x11,0x21,0x52,0x36,0x40,0x12,0x90,0x23,0x51,0x1d,}}, // "pt__" + // ASCII-7-bit=153 Latin1=181 UTF8=173 GB=29 CP1252=149 SJS=33 CP1250=54 Latin5=64 ISO-8859-15=144 CP1257=35 CP1254=29 [top Latin1] + {{0x70,0x79,0x5f,0x5f, 0x03,0x9f,0xbb,0x90,0x13,0x97,0x49,0x35,0x21,0x35,0x51,0x5a,0x00,0x00,0x00,0x00,}}, // "py__" + // ASCII-7-bit=159 Latin1=187 UTF8=144 CP1252=151 KSC=73 SJS=53 Latin2=53 ISO-8859-15=90 [top Latin1] + {{0x71,0x61,0x5f,0x5f, 0x03,0x9a,0x89,0xb0,0x11,0x82,0x61,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "qa__" + // ASCII-7-bit=154 Latin1=137 UTF8=176 CP1252=130 CP1256=181 [top CP1256] + {{0x72,0x65,0x5f,0x5f, 0x03,0x8a,0xb4,0xb1,0x11,0x97,0xa1,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "re__" + // ASCII-7-bit=138 Latin1=180 UTF8=177 CP1252=151 ISO-8859-15=138 [top Latin1] + {{0x72,0x6f,0x5f,0x5f, 0x08,0xb4,0xa0,0xa4,0x3c,0x94,0x57,0x2e,0x29,0x14,0xa2,0x3a,0x33,0x8b,0x21,0x37,}}, // "ro__" + // ASCII-7-bit=180 Latin1=160 UTF8=164 GB=60 CP1252=148 KSC=87 SJS=46 EUC-JP=41 Latin2=162 CP1251=58 CP1256=51 CP1250=139 ISO-8859-15=55 [top ASCII-7-bit] + {{0x72,0x75,0x5f,0x5f, 0x05,0x8d,0x6d,0xa1,0x56,0x67,0x31,0x43,0x12,0xba,0x46,0x61,0x9b,0x72,0x46,0x48,}}, // "ru__" + // ASCII-7-bit=141 Latin1=109 UTF8=161 GB=86 CP1252=103 BIG5=67 CP1251=186 CP1256=70 KOI8R=155 KOI8U=70 ISO-8859-5=72 [top CP1251] + {{0x72,0x77,0x5f,0x5f, 0x03,0xb7,0xa2,0xa4,0x11,0xa0,0x61,0x5e,0x31,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "rw__" + // ASCII-7-bit=183 Latin1=162 UTF8=164 CP1252=160 CP1256=94 ISO-8859-15=110 [top ASCII-7-bit] + {{0x73,0x61,0x5f,0x5f, 0x05,0x91,0x5b,0xac,0x3f,0x69,0x11,0x1f,0x41,0xb9,0x11,0x1f,0x00,0x00,0x00,0x00,}}, // "sa__" + // ASCII-7-bit=145 Latin1=91 UTF8=172 GB=63 CP1252=105 SJS=31 CP1256=185 Latin5=31 [top CP1256] + {{0x73,0x62,0x5f,0x5f, 0x03,0xb8,0x8a,0xad,0x11,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sb__" + // ASCII-7-bit=184 Latin1=138 UTF8=173 CP1252=139 [top ASCII-7-bit] + {{0x73,0x63,0x5f,0x5f, 0x03,0xb5,0x9e,0xad,0x11,0x85,0x12,0x8d,0x88,0x23,0x57,0x4d,0x5c,0x00,0x00,0x00,}}, // "sc__" + // ASCII-7-bit=181 Latin1=158 UTF8=173 CP1252=133 SJS=141 EUC-JP=136 CP1251=87 CP1256=77 CP1250=92 [top ASCII-7-bit] + {{0x73,0x64,0x5f,0x5f, 0x03,0x9b,0x77,0x8a,0x11,0x6d,0x61,0xbd,0x10,0x61,0x73,0x00,0x00,0x00,0x00,0x00,}}, // "sd__" + // ASCII-7-bit=155 Latin1=119 UTF8=138 CP1252=109 CP1256=189 Arabic=115 [top CP1256] + {{0x73,0x65,0x5f,0x5f, 0x05,0x96,0xbb,0xa0,0x23,0x82,0x36,0x23,0x2e,0x25,0x3b,0x43,0x22,0x11,0x4c,0x00,}}, // "se__" + // ASCII-7-bit=150 Latin1=187 UTF8=160 GB=35 CP1252=130 BIG5=35 Latin2=46 CP1251=37 CP1256=59 CP1250=67 Latin5=34 ISO-8859-15=76 [top Latin1] + {{0x73,0x67,0x5f,0x5f, 0x09,0xb8,0x9c,0xa6,0x84,0x94,0x4c,0x6e,0x50,0x71,0x31,0x41,0x11,0x48,0xd1,0x3a,}}, // "sg__" + // ASCII-7-bit=184 Latin1=156 UTF8=166 GB=132 CP1252=148 KSC=76 SJS=110 EUC-JP=80 BIG5=113 CP1250=65 ISO-8859-11=72 CP874=58 [top ASCII-7-bit] + {{0x73,0x68,0x5f,0x5f, 0x0a,0xaa,0x9b,0xa1,0xa9,0x84,0x77,0xa1,0x98,0x9b,0x5d,0x51,0x6d,0x31,0x6f,0x00,}}, // "sh__" + // ASCII-7-bit=170 Latin1=155 UTF8=161 GB=169 CP1252=132 KSC=119 SJS=161 EUC-JP=152 BIG5=155 Latin2=93 ISO-8859-15=109 GBK=111 [top ASCII-7-bit] + {{0x73,0x69,0x5f,0x5f, 0x03,0x95,0x6b,0xb7,0x11,0x6e,0x42,0x9f,0x3d,0x11,0xa9,0x21,0x17,0x10,0x11,0x24,}}, // "si__" + // ASCII-7-bit=149 Latin1=107 UTF8=183 CP1252=110 Latin2=159 CP1251=61 CP1250=169 ISO-8859-15=23 CP852=36 [top UTF8] + {{0x73,0x6b,0x5f,0x5f, 0x03,0x95,0x74,0xb0,0x11,0x60,0x36,0x53,0x92,0x55,0x47,0xb5,0x3f,0x10,0x11,0x3a,}}, // "sk__" + // ASCII-7-bit=149 Latin1=116 UTF8=176 CP1252=96 BIG5=83 Latin2=146 CP1251=85 CP1256=71 CP1250=181 Latin5=63 MACINTOSH=58 [top CP1250] + {{0x73,0x6c,0x5f,0x5f, 0x03,0xac,0x85,0x8f,0x11,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sl__" + // ASCII-7-bit=172 Latin1=133 UTF8=143 CP1252=185 [top CP1252] + {{0x73,0x6d,0x5f,0x5f, 0x03,0xa8,0xa7,0xb1,0x11,0xa8,0x91,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sm__" + // ASCII-7-bit=168 Latin1=167 UTF8=177 CP1252=168 ISO-8859-11=111 [top UTF8] + {{0x73,0x6e,0x5f,0x5f, 0x03,0x9d,0xb8,0x9f,0x11,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sn__" + // ASCII-7-bit=157 Latin1=184 UTF8=159 CP1252=162 [top Latin1] + {{0x73,0x72,0x5f,0x5f, 0x03,0xa6,0xad,0xb2,0x12,0x9d,0x6a,0x61,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sr__" + // ASCII-7-bit=166 Latin1=173 UTF8=178 CP1252=157 KSC=106 CP1250=132 [top UTF8] + {{0x73,0x74,0x5f,0x5f, 0x03,0xb4,0xab,0x9d,0x15,0x88,0x79,0x99,0x94,0x7e,0x31,0x61,0x81,0x4e,0x21,0x6d,}}, // "st__" + // ASCII-7-bit=180 Latin1=171 UTF8=157 CP1252=136 KSC=121 SJS=153 EUC-JP=148 BIG5=126 CP1250=97 JIS=78 CP932=109 [top ASCII-7-bit] + {{0x73,0x75,0x5f,0x5f, 0x03,0xa4,0x6f,0xa0,0x11,0x70,0x51,0xb9,0x71,0x94,0x71,0x44,0x00,0x00,0x00,0x00,}}, // "su__" + // ASCII-7-bit=164 Latin1=111 UTF8=160 CP1252=112 CP1251=185 KOI8R=148 KOI8U=68 [top CP1251] + {{0x73,0x76,0x5f,0x5f, 0x03,0x9d,0xb9,0xa5,0x11,0x8f,0x41,0x3c,0x51,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sv__" + // ASCII-7-bit=157 Latin1=185 UTF8=165 CP1252=143 Latin2=60 ISO-8859-15=60 [top Latin1] + {{0x73,0x79,0x5f,0x5f, 0x03,0x82,0x5e,0x90,0x11,0x5d,0x61,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sy__" + // ASCII-7-bit=130 Latin1=94 UTF8=144 CP1252=93 CP1256=190 [top CP1256] + {{0x73,0x7a,0x5f,0x5f, 0x03,0xb7,0xac,0x6c,0x11,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sz__" + // ASCII-7-bit=183 Latin1=172 UTF8=108 CP1252=161 [top ASCII-7-bit] + {{0x74,0x63,0x5f,0x5f, 0x08,0xa9,0xaa,0x9b,0x62,0x74,0x8d,0x8f,0x7a,0x21,0x67,0x22,0xab,0x9b,0x41,0x70,}}, // "tc__" + // ASCII-7-bit=169 Latin1=170 UTF8=155 GB=98 CP1252=116 KSC=141 SJS=143 EUC-JP=122 CP1251=103 Latin5=171 ISO-8859-11=155 GBK=112 [top Latin5] + {{0x74,0x66,0x5f,0x5f, 0x02,0xa3,0xbc,0x21,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tf__" + // ASCII-7-bit=163 Latin1=188 CP1252=113 [top Latin1] + {{0x74,0x67,0x5f,0x5f, 0x03,0xb0,0xb3,0x7e,0x11,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tg__" + // ASCII-7-bit=176 Latin1=179 UTF8=126 CP1252=165 [top Latin1] + {{0x74,0x68,0x5f,0x5f, 0x09,0x96,0x61,0x93,0x3e,0x67,0x2f,0x52,0x38,0x23,0x11,0x35,0x31,0xbd,0xd1,0x76,}}, // "th__" + // ASCII-7-bit=150 Latin1=97 UTF8=147 GB=62 CP1252=103 KSC=47 SJS=82 EUC-JP=56 BIG5=35 CP1251=53 ISO-8859-11=189 CP874=118 [top ISO-8859-11] + {{0x74,0x6a,0x5f,0x5f, 0x03,0xab,0x74,0xb1,0x11,0x67,0x51,0xae,0x71,0x84,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tj__" + // ASCII-7-bit=171 Latin1=116 UTF8=177 CP1252=103 CP1251=174 KOI8R=132 [top UTF8] + {{0x74,0x6b,0x5f,0x5f, 0x03,0xbc,0x94,0x9d,0x11,0x6b,0x12,0x74,0x6b,0x12,0x53,0x46,0x12,0x74,0x6d,0x00,}}, // "tk__" + // ASCII-7-bit=188 Latin1=148 UTF8=157 CP1252=107 SJS=116 EUC-JP=107 Latin2=83 CP1251=70 CP1250=116 Latin5=109 [top ASCII-7-bit] + {{0x74,0x6c,0x5f,0x5f, 0x05,0xb1,0xb0,0x88,0x61,0x83,0xa1,0xa8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tl__" + // ASCII-7-bit=177 Latin1=176 UTF8=136 GB=97 CP1252=131 ISO-8859-15=168 [top ASCII-7-bit] + {{0x74,0x6d,0x5f,0x5f, 0x03,0xb4,0x84,0xad,0x11,0x82,0x42,0x5a,0xa4,0x12,0x5a,0x5a,0x00,0x00,0x00,0x00,}}, // "tm__" + // ASCII-7-bit=180 Latin1=132 UTF8=173 CP1252=130 Latin2=90 CP1251=164 CP1250=90 Latin5=90 [top ASCII-7-bit] + {{0x74,0x6e,0x5f,0x5f, 0x03,0x9f,0xa2,0xac,0x11,0x9d,0x11,0x4b,0x21,0x3b,0x11,0xb0,0x10,0x61,0x3b,0x00,}}, // "tn__" + // ASCII-7-bit=159 Latin1=162 UTF8=172 CP1252=157 SJS=75 Latin2=59 CP1256=176 Arabic=59 [top CP1256] + {{0x74,0x6f,0x5f,0x5f, 0x03,0xa5,0xa2,0xa5,0x15,0x89,0x8a,0xac,0x99,0x9b,0x31,0x70,0x21,0x87,0x51,0x6c,}}, // "to__" + // ASCII-7-bit=165 Latin1=162 UTF8=165 CP1252=137 KSC=138 SJS=172 EUC-JP=153 BIG5=155 CP1250=112 ISO-8859-15=135 JIS=108 [top SJS] + {{0x74,0x70,0x5f,0x5f, 0x03,0x95,0x9e,0xad,0x11,0x67,0x12,0xb3,0x99,0xd1,0x67,0x21,0x67,0x00,0x00,0x00,}}, // "tp__" + // ASCII-7-bit=149 Latin1=158 UTF8=173 CP1252=103 SJS=179 EUC-JP=153 JIS=103 CP932=103 [top SJS] + {{0x74,0x72,0x5f,0x5f, 0x03,0x8d,0x6c,0xa6,0x11,0x61,0x11,0x3c,0x32,0x3c,0x4a,0x11,0xba,0x81,0x91,0x00,}}, // "tr__" + // ASCII-7-bit=141 Latin1=108 UTF8=166 CP1252=97 SJS=60 CP1251=60 CP1256=74 Latin5=186 CP1254=145 [top Latin5] + {{0x74,0x72,0x61,0x76, 0x05,0xa9,0xa3,0xa7,0x97,0x95,0x11,0xac,0x13,0x74,0x7f,0x6b,0x11,0x63,0x00,0x00,}}, // "trav" + // ASCII-7-bit=169 Latin1=163 UTF8=167 GB=151 CP1252=149 SJS=172 BIG5=116 Latin2=127 CP1251=107 CP1250=99 [top SJS] + {{0x74,0x74,0x5f,0x5f, 0x07,0xb5,0xaf,0x9a,0x49,0x92,0x59,0x49,0x61,0x75,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tt__" + // ASCII-7-bit=181 Latin1=175 UTF8=154 GB=73 CP1252=146 KSC=89 SJS=73 Latin5=117 [top ASCII-7-bit] + {{0x74,0x76,0x5f,0x5f, 0x0e,0xa7,0xa6,0xad,0x89,0x94,0x85,0x9e,0x8d,0x7b,0x74,0x7c,0x88,0x7b,0x81,0x00,}}, // "tv__" + // ASCII-7-bit=167 Latin1=166 UTF8=173 GB=137 CP1252=148 KSC=133 SJS=158 EUC-JP=141 BIG5=123 Latin2=116 CP1251=124 CP1256=136 CP1250=123 Latin5=129 [top UTF8] + {{0x74,0x77,0x5f,0x5f, 0x05,0x85,0x52,0xab,0x5d,0x57,0x13,0x50,0x2e,0xba,0x31,0x23,0x61,0x2e,0xf1,0x21,}}, // "tw__" + // ASCII-7-bit=133 Latin1=82 UTF8=171 GB=93 CP1252=87 SJS=80 EUC-JP=46 BIG5=186 CP1250=35 GBK=46 BIG5_HKSCS=33 [top BIG5] + {{0x74,0x7a,0x5f,0x5f, 0x03,0xae,0xb5,0x8b,0x13,0xa0,0x4c,0x4c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tz__" + // ASCII-7-bit=174 Latin1=181 UTF8=139 CP1252=160 KSC=76 SJS=76 [top Latin1] + {{0x75,0x61,0x5f,0x5f, 0x03,0x87,0x61,0xa2,0x11,0x57,0x44,0x4d,0xbb,0x35,0x48,0x51,0x80,0x72,0x8c,0x3d,}}, // "ua__" + // ASCII-7-bit=135 Latin1=97 UTF8=162 CP1252=87 Latin2=77 CP1251=187 CP1256=53 CP1250=72 KOI8R=128 KOI8U=140 ISO-8859-5=61 [top CP1251] + {{0x75,0x67,0x5f,0x5f, 0x03,0xb8,0x9a,0xa0,0x11,0xa6,0x11,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ug__" + // ASCII-7-bit=184 Latin1=154 UTF8=160 CP1252=166 SJS=104 [top ASCII-7-bit] + {{0x75,0x6b,0x5f,0x5f, 0x05,0xb7,0xa7,0x9e,0x62,0x97,0x27,0x58,0x62,0x51,0x53,0x62,0x64,0x54,0x11,0x6f,}}, // "uk__" + // ASCII-7-bit=183 Latin1=167 UTF8=158 GB=98 CP1252=151 EUC-JP=88 BIG5=98 Latin2=81 CP1251=83 CP1256=98 CP1250=100 Latin5=84 ISO-8859-15=111 [top ASCII-7-bit] + {{0x75,0x73,0x5f,0x5f, 0x06,0xba,0x94,0xa5,0x45,0x92,0x48,0x24,0x54,0x47,0x5a,0x56,0x11,0x66,0x11,0x40,}}, // "us__" + // ASCII-7-bit=186 Latin1=148 UTF8=165 GB=69 CP1252=146 KSC=72 BIG5=84 Latin2=71 CP1251=90 CP1256=86 Latin5=102 ISO-8859-15=64 [top ASCII-7-bit] + {{0x75,0x79,0x5f,0x5f, 0x03,0xa2,0xba,0x96,0x11,0x9a,0x72,0x2c,0x2c,0x11,0x52,0x00,0x00,0x00,0x00,0x00,}}, // "uy__" + // ASCII-7-bit=162 Latin1=186 UTF8=150 CP1252=154 CP1250=44 Latin5=44 ISO-8859-15=82 [top Latin1] + {{0x75,0x7a,0x5f,0x5f, 0x05,0x91,0x68,0xb1,0x39,0x88,0x54,0xb5,0x43,0x39,0x6e,0x41,0x7c,0x00,0x00,0x00,}}, // "uz__" + // ASCII-7-bit=145 Latin1=104 UTF8=177 GB=57 CP1252=136 CP1251=181 CP1256=67 CP1250=57 Latin5=110 KOI8R=124 [top CP1251] + {{0x76,0x61,0x5f,0x5f, 0x03,0xae,0xb3,0x8f,0x11,0xa7,0xb1,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "va__" + // ASCII-7-bit=174 Latin1=179 UTF8=143 CP1252=167 CP1257=74 [top Latin1] + {{0x76,0x63,0x5f,0x5f, 0x08,0xba,0x7a,0x9a,0x5e,0x79,0x4a,0x9a,0x95,0x12,0x54,0x7f,0x81,0x4a,0x00,0x00,}}, // "vc__" + // ASCII-7-bit=186 Latin1=122 UTF8=154 GB=94 CP1252=121 KSC=74 SJS=154 EUC-JP=149 Latin2=84 CP1251=127 GBK=74 [top ASCII-7-bit] + {{0x76,0x65,0x5f,0x5f, 0x05,0x97,0xbc,0x8c,0x14,0x9b,0x11,0x14,0x11,0x1e,0x31,0x42,0x21,0x55,0x31,0x24,}}, // "ve__" + // ASCII-7-bit=151 Latin1=188 UTF8=140 GB=20 CP1252=155 SJS=20 BIG5=30 CP1250=66 ISO-8859-15=85 GBK=36 [top Latin1] + {{0x76,0x67,0x5f,0x5f, 0x05,0xac,0xb2,0x9e,0x6d,0x97,0x13,0x95,0x81,0x95,0x11,0x69,0x21,0x63,0x61,0x59,}}, // "vg__" + // ASCII-7-bit=172 Latin1=178 UTF8=158 GB=109 CP1252=151 SJS=149 EUC-JP=129 BIG5=149 CP1251=105 Latin5=99 Greek=89 [top Latin1] + {{0x76,0x69,0x5f,0x5f, 0x03,0xb9,0x90,0xaa,0x11,0x93,0x11,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "vi__" + // ASCII-7-bit=185 Latin1=144 UTF8=170 CP1252=147 SJS=104 [top ASCII-7-bit] + {{0x76,0x6e,0x5f,0x5f, 0x03,0x94,0x92,0xbd,0x12,0x83,0x22,0x21,0x2c,0x32,0x26,0x2e,0x00,0x00,0x00,0x00,}}, // "vn__" + // ASCII-7-bit=148 Latin1=146 UTF8=189 CP1252=131 KSC=34 BIG5=44 CP1250=38 Latin5=46 [top UTF8] + {{0x76,0x75,0x5f,0x5f, 0x03,0xae,0xb6,0x97,0x11,0x7b,0x11,0x5b,0x31,0x6a,0x41,0x4e,0x71,0x90,0x00,0x00,}}, // "vu__" + // ASCII-7-bit=174 Latin1=182 UTF8=151 CP1252=123 SJS=91 CP1251=106 ISO-8859-15=78 CP1253=144 [top Latin1] + {{0x77,0x73,0x5f,0x5f, 0x05,0xae,0xaa,0xa6,0x6c,0x91,0x18,0x76,0x69,0x7c,0x78,0x99,0x9d,0x7d,0x70,0x00,}}, // "ws__" + // ASCII-7-bit=174 Latin1=170 UTF8=166 GB=108 CP1252=145 SJS=118 EUC-JP=105 BIG5=124 Latin2=120 CP1251=153 CP1256=157 CP1250=125 Latin5=112 [top ASCII-7-bit] + {{0x79,0x65,0x5f,0x5f, 0x03,0x9e,0x94,0xab,0x11,0x8b,0x61,0xb6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ye__" + // ASCII-7-bit=158 Latin1=148 UTF8=171 CP1252=139 CP1256=182 [top CP1256] + {{0x79,0x75,0x5f,0x5f, 0x03,0xa4,0x7f,0xaf,0x11,0x78,0x42,0x87,0x80,0x12,0xb3,0x2c,0xd1,0x60,0x00,0x00,}}, // "yu__" + // ASCII-7-bit=164 Latin1=127 UTF8=175 CP1252=120 Latin2=135 CP1251=128 CP1250=179 Latin5=44 ISO-8859-5=96 [top CP1250] + {{0x7a,0x61,0x5f,0x5f, 0x05,0xb8,0xa3,0x97,0x42,0xa1,0x11,0x30,0x11,0x4e,0x13,0x3a,0x4f,0x41,0x21,0x42,}}, // "za__" + // ASCII-7-bit=184 Latin1=163 UTF8=151 GB=66 CP1252=161 SJS=48 BIG5=78 CP1251=58 CP1256=79 CP1250=65 ISO-8859-15=66 [top ASCII-7-bit] + {{0x7a,0x6d,0x5f,0x5f, 0x03,0xb8,0x8e,0x9c,0x11,0xa9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "zm__" + // ASCII-7-bit=184 Latin1=142 UTF8=156 CP1252=169 [top ASCII-7-bit] + {{0x7a,0x77,0x5f,0x5f, 0x05,0xbb,0x95,0x9b,0x59,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "zw__" + // ASCII-7-bit=187 Latin1=149 UTF8=155 GB=89 CP1252=154 [top ASCII-7-bit] +}; + +static const int kTLDHintProbsSize = 247; + +static const HintEntry kCharsetHintProbs[] = { // MaxRange 192 + {{0x5f,0x5f,0x5f,0x5f,0x30,0x36,0x34,0x36, 0x02,0xbd,0x7f,0x21,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____0646" + // ASCII-7-bit=189 Latin1=127 CP1252=149 [top ASCII-7-bit] + {{0x5f,0x5f,0x5f,0x5f,0x31,0x32,0x35,0x30, 0x01,0x96,0xb1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____1250" + // ASCII-7-bit=150 CP1250=190 [top CP1250] + {{0x5f,0x5f,0x5f,0x5f,0x31,0x32,0x35,0x31, 0x01,0x7a,0x91,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____1251" + // ASCII-7-bit=122 CP1251=190 [top CP1251] + {{0x5f,0x5f,0x5f,0x5f,0x31,0x32,0x35,0x32, 0x02,0x99,0x9d,0x21,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____1252" + // ASCII-7-bit=153 Latin1=157 CP1252=188 [top CP1252] + {{0x5f,0x5f,0x5f,0x5f,0x31,0x32,0x35,0x33, 0x01,0x79,0x10,0x61,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____1253" + // ASCII-7-bit=121 CP1253=190 [top CP1253] + {{0x5f,0x5f,0x5f,0x5f,0x31,0x32,0x35,0x34, 0x01,0x71,0xc1,0xaf,0x81,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____1254" + // ASCII-7-bit=113 Latin5=175 CP1254=185 [top CP1254] + {{0x5f,0x5f,0x5f,0x5f,0x31,0x32,0x35,0x35, 0x01,0x86,0x10,0x01,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____1255" + // ASCII-7-bit=134 CP1255=190 [top CP1255] + {{0x5f,0x5f,0x5f,0x5f,0x31,0x32,0x35,0x36, 0x01,0x78,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____1256" + // ASCII-7-bit=120 CP1256=190 [top CP1256] + {{0x5f,0x5f,0x5f,0x5f,0x31,0x32,0x35,0x37, 0x01,0x79,0xf1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____1257" + // ASCII-7-bit=121 CP1257=190 [top CP1257] + {{0x5f,0x5f,0x5f,0x5f,0x31,0x38,0x30,0x30, 0x10,0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____1800" + // KOI8R=191 [top KOI8R] + {{0x5f,0x5f,0x5f,0x5f,0x33,0x36,0x30,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____3600" + // CP1250=191 [top CP1250] + {{0x5f,0x5f,0x5f,0x5f,0x33,0x36,0x39,0x39, 0x01,0xad,0x11,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____3699" + // ASCII-7-bit=173 UTF8=185 [top UTF8] + {{0x5f,0x5f,0x5f,0x5f,0x34,0x34,0x30,0x30, 0x02,0xbc,0x87,0x21,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____4400" + // ASCII-7-bit=188 Latin1=135 CP1252=164 [top ASCII-7-bit] + {{0x5f,0x5f,0x5f,0x5f,0x35,0x30,0x30,0x31, 0x01,0x9a,0x11,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____5001" + // ASCII-7-bit=154 UTF8=189 [top UTF8] + {{0x5f,0x5f,0x5f,0x5f,0x35,0x39,0x31,0x35, 0x02,0xa8,0xa6,0x21,0xa7,0xa1,0xb2,0x00,0x00,0x00,0x00,0x00,}}, // "____5915" + // ASCII-7-bit=168 Latin1=166 CP1252=167 ISO-8859-15=178 [top ISO-8859-15] + {{0x5f,0x5f,0x5f,0x5f,0x36,0x34,0x36,0x5f, 0x02,0xbe,0x8e,0x21,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____646_" + // ASCII-7-bit=190 Latin1=142 CP1252=129 [top ASCII-7-bit] + {{0x5f,0x5f,0x5f,0x5f,0x38,0x35,0x39,0x31, 0x02,0xae,0xb8,0x21,0x94,0xa1,0x2f,0x00,0x00,0x00,0x00,0x00,}}, // "____8591" + // ASCII-7-bit=174 Latin1=184 CP1252=148 ISO-8859-15=47 [top Latin1] + {{0x5f,0x5f,0x5f,0x5f,0x38,0x35,0x39,0x32, 0x01,0x8c,0x81,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____8592" + // ASCII-7-bit=140 Latin2=190 [top Latin2] + {{0x5f,0x5f,0x5f,0x5f,0x38,0x35,0x39,0x34, 0x10,0xe1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____8594" + // Latin4=191 [top Latin4] + {{0x5f,0x5f,0x5f,0x5f,0x38,0x35,0x39,0x35, 0x01,0x6f,0x10,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____8595" + // ASCII-7-bit=111 ISO-8859-5=190 [top ISO-8859-5] + {{0x5f,0x5f,0x5f,0x5f,0x38,0x35,0x39,0x37, 0x10,0x41,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____8597" + // Greek=191 [top Greek] + {{0x5f,0x5f,0x5f,0x5f,0x38,0x35,0x39,0x39, 0x01,0x72,0xc1,0xbe,0x81,0x7b,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____8599" + // ASCII-7-bit=114 Latin5=190 CP1254=123 [top Latin5] + {{0x5f,0x5f,0x5f,0x5f,0x38,0x38,0x36,0x31, 0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____8861" + // Latin2=191 [top Latin2] + {{0x5f,0x5f,0x5f,0x5f,0x38,0x5f,0x5f,0x5f, 0x03,0x98,0x5d,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "____8___" + // ASCII-7-bit=152 Latin1=93 UTF8=189 [top UTF8] + {{0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x07,0xb1,0xaa,0x9c,0x95,0x96,0x8e,0x8c,0x11,0x82,0x00,0x00,}}, // "________" + // ASCII-7-bit=177 Latin1=170 UTF8=156 GB=149 CP1252=150 KSC=142 SJS=140 BIG5=130 [top ASCII-7-bit] + {{0x61,0x6e,0x73,0x69,0x33,0x34,0x5f,0x5f, 0x02,0xbe,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ansi34__" + // ASCII-7-bit=190 Latin1=110 [top ASCII-7-bit] + {{0x61,0x6e,0x73,0x69,0x5f,0x5f,0x5f,0x5f, 0x02,0xa2,0xb9,0x21,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ansi____" + // ASCII-7-bit=162 Latin1=185 CP1252=164 [top Latin1] + {{0x61,0x72,0x72,0x61,0x5f,0x5f,0x5f,0x5f, 0x01,0x90,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "arra____" + // ASCII-7-bit=144 CP1256=190 [top CP1256] + {{0x61,0x73,0x63,0x69,0x5f,0x5f,0x5f,0x5f, 0x02,0xbe,0x72,0x21,0x71,0xa1,0x53,0x00,0x00,0x00,0x00,0x00,}}, // "asci____" + // ASCII-7-bit=190 Latin1=114 CP1252=113 ISO-8859-15=83 [top ASCII-7-bit] + {{0x61,0x75,0x74,0x6f,0x5f,0x5f,0x5f,0x5f, 0x01,0x9b,0x51,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "auto____" + // ASCII-7-bit=155 SJS=189 [top SJS] + {{0x62,0x67,0x5f,0x5f,0x32,0x33,0x31,0x32, 0x01,0x93,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bg__2312" + // ASCII-7-bit=147 GB=190 [top GB] + {{0x62,0x68,0x61,0x73,0x5f,0x5f,0x5f,0x5f, 0x30,0x01,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bhas____" + // BHASKAR=191 [top BHASKAR] + {{0x62,0x69,0x67,0x5f,0x35,0x5f,0x5f,0x5f, 0x01,0x84,0x71,0xbe,0x10,0xa1,0x2f,0x00,0x00,0x00,0x00,0x00,}}, // "big_5___" + // ASCII-7-bit=132 BIG5=190 BIG5_HKSCS=47 [top BIG5] + {{0x62,0x69,0x67,0x5f,0x38,0x35,0x39,0x31, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "big_8591" + // Latin1=191 [top Latin1] + {{0x62,0x69,0x67,0x68,0x35,0x5f,0x5f,0x5f, 0x01,0x88,0x71,0xae,0x10,0xa1,0xb8,0x00,0x00,0x00,0x00,0x00,}}, // "bigh5___" + // ASCII-7-bit=136 BIG5=174 BIG5_HKSCS=184 [top BIG5_HKSCS] + {{0x62,0x69,0x6e,0x61,0x5f,0x5f,0x5f,0x5f, 0x30,0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bina____" + // X-BINARYENC=191 [top X-BINARYENC] + {{0x62,0x6f,0x74,0x5f,0x5f,0x5f,0x5f,0x5f, 0xd1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bot_____" + // Latin5=191 [top Latin5] + {{0x62,0x73,0x5f,0x5f,0x34,0x37,0x33,0x30, 0x02,0xb8,0xa8,0x21,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "bs__4730" + // ASCII-7-bit=184 Latin1=168 CP1252=163 [top ASCII-7-bit] + {{0x63,0x68,0x61,0x72,0x5f,0x5f,0x5f,0x5f, 0x02,0xa5,0xbb,0x21,0x91,0xa1,0x28,0x00,0x00,0x00,0x00,0x00,}}, // "char____" + // ASCII-7-bit=165 Latin1=187 CP1252=145 ISO-8859-15=40 [top Latin1] + {{0x63,0x6e,0x73,0x5f,0x5f,0x5f,0x5f,0x5f, 0x30,0x71,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cns_____" + // CNS=191 [top CNS] + {{0x63,0x6f,0x6e,0x66,0x5f,0x5f,0x5f,0x5f, 0x01,0x9f,0x11,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "conf____" + // ASCII-7-bit=159 UTF8=189 [top UTF8] + {{0x63,0x6f,0x6e,0x74,0x5f,0x5f,0x5f,0x5f, 0x01,0xa4,0x11,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cont____" + // ASCII-7-bit=164 UTF8=188 [top UTF8] + {{0x63,0x70,0x5f,0x5f,0x31,0x32,0x35,0x30, 0x01,0x97,0xb1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cp__1250" + // ASCII-7-bit=151 CP1250=190 [top CP1250] + {{0x63,0x70,0x5f,0x5f,0x31,0x32,0x35,0x31, 0x01,0x7c,0x91,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cp__1251" + // ASCII-7-bit=124 CP1251=190 [top CP1251] + {{0x63,0x70,0x5f,0x5f,0x31,0x32,0x35,0x32, 0x02,0xab,0xa9,0x21,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cp__1252" + // ASCII-7-bit=171 Latin1=169 CP1252=181 [top CP1252] + {{0x63,0x70,0x5f,0x5f,0x31,0x32,0x35,0x33, 0x01,0x79,0x10,0x31,0x7f,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,}}, // "cp__1253" + // ASCII-7-bit=121 Greek=127 CP1253=190 [top CP1253] + {{0x63,0x70,0x5f,0x5f,0x31,0x32,0x35,0x34, 0x01,0x5b,0xc1,0xaf,0x81,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cp__1254" + // ASCII-7-bit=91 Latin5=175 CP1254=185 [top CP1254] + {{0x63,0x70,0x5f,0x5f,0x31,0x32,0x35,0x35, 0x01,0x86,0x10,0x01,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cp__1255" + // ASCII-7-bit=134 CP1255=190 [top CP1255] + {{0x63,0x70,0x5f,0x5f,0x31,0x32,0x35,0x36, 0x01,0x5e,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cp__1256" + // ASCII-7-bit=94 CP1256=190 [top CP1256] + {{0x63,0x70,0x5f,0x5f,0x31,0x32,0x35,0x37, 0x01,0xa8,0xf1,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cp__1257" + // ASCII-7-bit=168 CP1257=187 [top CP1257] + {{0x63,0x70,0x5f,0x5f,0x38,0x35,0x30,0x5f, 0x02,0x97,0x98,0x21,0x8c,0xa1,0xbc,0x00,0x00,0x00,0x00,0x00,}}, // "cp__850_" + // ASCII-7-bit=151 Latin1=152 CP1252=140 ISO-8859-15=188 [top ISO-8859-15] + {{0x63,0x70,0x5f,0x5f,0x38,0x35,0x32,0x5f, 0x01,0x8f,0x20,0x01,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cp__852_" + // ASCII-7-bit=143 CP852=190 [top CP852] + {{0x63,0x70,0x5f,0x5f,0x38,0x36,0x36,0x5f, 0x01,0xa2,0x20,0x31,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cp__866_" + // ASCII-7-bit=162 CP866=188 [top CP866] + {{0x63,0x70,0x63,0x5f,0x39,0x34,0x33,0x5f, 0x01,0x26,0x51,0xbe,0x10,0x11,0x68,0x00,0x00,0x00,0x00,0x00,}}, // "cpc_943_" + // ASCII-7-bit=38 SJS=190 CP932=104 [top SJS] + {{0x63,0x70,0x63,0x7a,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cpcz1250" + // CP1250=191 [top CP1250] + {{0x63,0x73,0x69,0x73,0x5f,0x5f,0x5f,0x5f, 0x01,0x9c,0x10,0x01,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "csis____" + // ASCII-7-bit=156 CP1255=189 [top CP1255] + {{0x63,0x73,0x6e,0x5f,0x39,0x31,0x30,0x33, 0x20,0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "csn_9103" + // CSN_369103=191 [top CSN_369103] + {{0x63,0x73,0x73,0x68,0x5f,0x5f,0x5f,0x5f, 0x01,0x7f,0x51,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cssh____" + // ASCII-7-bit=127 SJS=190 [top SJS] + {{0x63,0x73,0x77,0x69,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cswi1250" + // CP1250=191 [top CP1250] + {{0x63,0x73,0x77,0x69,0x33,0x31,0x5f,0x5f, 0x61,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "cswi31__" + // SJS=191 [top SJS] + {{0x63,0x7a,0x77,0x69,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "czwi1250" + // CP1250=191 [top CP1250] + {{0x64,0x61,0x64,0x6b,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "dadk8591" + // Latin1=190 CP1252=125 [top Latin1] + {{0x64,0x61,0x69,0x73,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x21,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "dais8591" + // ASCII-7-bit=111 Latin1=190 CP1252=111 [top Latin1] + {{0x64,0x65,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x02,0x9d,0xbc,0x21,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "de______" + // ASCII-7-bit=157 Latin1=188 CP1252=149 [top Latin1] + {{0x64,0x65,0x61,0x73,0x5f,0x5f,0x5f,0x5f, 0x02,0x8f,0xbd,0x21,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "deas____" + // ASCII-7-bit=143 Latin1=189 CP1252=146 [top Latin1] + {{0x64,0x65,0x64,0x65,0x38,0x35,0x39,0x31, 0x02,0x92,0xbe,0x21,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "dede8591" + // ASCII-7-bit=146 Latin1=190 CP1252=135 [top Latin1] + {{0x64,0x65,0x66,0x61,0x5f,0x5f,0x5f,0x5f, 0x02,0xbc,0x9f,0x21,0x89,0xa1,0x6b,0x00,0x00,0x00,0x00,0x00,}}, // "defa____" + // ASCII-7-bit=188 Latin1=159 CP1252=137 ISO-8859-15=107 [top ASCII-7-bit] + {{0x64,0x65,0x69,0x73,0x35,0x39,0x31,0x35, 0x11,0x83,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "deis5915" + // Latin1=131 ISO-8859-15=190 [top ISO-8859-15] + {{0x64,0x65,0x69,0x73,0x38,0x35,0x39,0x31, 0x02,0x92,0xbd,0x21,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "deis8591" + // ASCII-7-bit=146 Latin1=189 CP1252=137 [top Latin1] + {{0x64,0x65,0x6c,0x65,0x5f,0x5f,0x5f,0x5f, 0x02,0xa9,0xba,0x21,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "dele____" + // ASCII-7-bit=169 Latin1=186 CP1252=146 [top Latin1] + {{0x64,0x65,0x75,0x74,0x5f,0x5f,0x5f,0x5f, 0x02,0x74,0xb8,0x21,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "deut____" + // ASCII-7-bit=116 Latin1=184 CP1252=175 [top Latin1] + {{0x64,0x6f,0x6f,0x72,0x31,0x32,0x35,0x32, 0x11,0x79,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "door1252" + // Latin1=121 CP1252=190 [top CP1252] + {{0x65,0x63,0x75,0x6a,0x5f,0x5f,0x5f,0x5f, 0x71,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ecuj____" + // EUC-JP=191 [top EUC-JP] + {{0x65,0x63,0x75,0x6b,0x5f,0x5f,0x5f,0x5f, 0x01,0x71,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ecuk____" + // ASCII-7-bit=113 KSC=190 [top KSC] + {{0x65,0x65,0x6d,0x73,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eems1250" + // CP1250=191 [top CP1250] + {{0x65,0x6e,0x5f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "en__8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x65,0x6e,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x02,0xbe,0x92,0x21,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "en______" + // ASCII-7-bit=190 Latin1=146 CP1252=130 [top ASCII-7-bit] + {{0x65,0x6e,0x63,0x6f,0x5f,0x5f,0x5f,0x5f, 0x01,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "enco____" + // ASCII-7-bit=191 [top ASCII-7-bit] + {{0x65,0x6e,0x67,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x8b,0x71,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eng_____" + // ASCII-7-bit=139 BIG5=190 [top BIG5] + {{0x65,0x6e,0x67,0x62,0x5f,0x5f,0x5f,0x5f, 0x02,0xbe,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "engb____" + // ASCII-7-bit=190 Latin1=125 [top ASCII-7-bit] + {{0x65,0x6e,0x69,0x73,0x38,0x35,0x39,0x31, 0x02,0x96,0xbc,0x21,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "enis8591" + // ASCII-7-bit=150 Latin1=188 CP1252=154 [top Latin1] + {{0x65,0x6e,0x75,0x6b,0x38,0x35,0x39,0x31, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "enuk8591" + // Latin1=191 [top Latin1] + {{0x65,0x6e,0x75,0x6b,0x5f,0x5f,0x5f,0x5f, 0x51,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "enuk____" + // KSC=191 [top KSC] + {{0x65,0x6e,0x75,0x73,0x35,0x39,0x31,0x35, 0x02,0x6f,0x7f,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "enus5915" + // ASCII-7-bit=111 Latin1=127 ISO-8859-15=190 [top ISO-8859-15] + {{0x65,0x6e,0x75,0x73,0x38,0x35,0x39,0x31, 0x02,0x9c,0xbc,0x21,0x9b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "enus8591" + // ASCII-7-bit=156 Latin1=188 CP1252=155 [top Latin1] + {{0x65,0x6e,0x75,0x73,0x5f,0x5f,0x5f,0x5f, 0x02,0xbb,0xa1,0x21,0x9e,0xa1,0x68,0x00,0x00,0x00,0x00,0x00,}}, // "enus____" + // ASCII-7-bit=187 Latin1=161 CP1252=158 ISO-8859-15=104 [top ASCII-7-bit] + {{0x65,0x6e,0x75,0x74,0x38,0x5f,0x5f,0x5f, 0x01,0x81,0xf1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "enut8___" + // ASCII-7-bit=129 CP1257=190 [top CP1257] + {{0x65,0x73,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x02,0xb4,0xb3,0x21,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "es______" + // ASCII-7-bit=180 Latin1=179 CP1252=157 [top ASCII-7-bit] + {{0x65,0x73,0x65,0x73,0x38,0x35,0x39,0x31, 0x02,0x82,0xbe,0x21,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eses8591" + // ASCII-7-bit=130 Latin1=190 CP1252=110 [top Latin1] + {{0x65,0x73,0x65,0x73,0x5f,0x5f,0x5f,0x5f, 0x02,0xa6,0xba,0x21,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eses____" + // ASCII-7-bit=166 Latin1=186 CP1252=150 [top Latin1] + {{0x65,0x73,0x69,0x73,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "esis8591" + // Latin1=190 CP1252=135 [top Latin1] + {{0x65,0x74,0x65,0x65,0x38,0x35,0x39,0x31, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "etee8591" + // Latin1=191 [top Latin1] + {{0x65,0x74,0x69,0x73,0x38,0x35,0x39,0x31, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "etis8591" + // Latin1=191 [top Latin1] + {{0x65,0x75,0x63,0x5f,0x32,0x5f,0x5f,0x5f, 0x01,0xbe,0x31,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "euc_2___" + // ASCII-7-bit=190 CP1252=114 [top ASCII-7-bit] + {{0x65,0x75,0x63,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x7d,0x61,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "euc_____" + // ASCII-7-bit=125 EUC-JP=190 [top EUC-JP] + {{0x65,0x75,0x63,0x63,0x5f,0x5f,0x5f,0x5f, 0x01,0x6f,0x30,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eucc____" + // ASCII-7-bit=111 EUC-CN=190 [top EUC-CN] + {{0x65,0x75,0x63,0x64,0x5f,0x5f,0x5f,0x5f, 0x30,0x61,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eucd____" + // EUC=191 [top EUC] + {{0x65,0x75,0x63,0x6a,0x5f,0x5f,0x5f,0x5f, 0x01,0x68,0x61,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eucj____" + // ASCII-7-bit=104 EUC-JP=190 [top EUC-JP] + {{0x65,0x75,0x63,0x6b,0x5f,0x5f,0x5f,0x5f, 0x01,0x6d,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "euck____" + // ASCII-7-bit=109 KSC=190 [top KSC] + {{0x65,0x75,0x63,0x75,0x5f,0x5f,0x5f,0x5f, 0x01,0x6d,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eucu____" + // ASCII-7-bit=109 KSC=190 [top KSC] + {{0x65,0x75,0x6b,0x6b,0x5f,0x5f,0x5f,0x5f, 0x51,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eukk____" + // KSC=191 [top KSC] + {{0x65,0x75,0x72,0x6b,0x5f,0x5f,0x5f,0x5f, 0x01,0x71,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "eurk____" + // ASCII-7-bit=113 KSC=190 [top KSC] + {{0x66,0x65,0x61,0x74,0x5f,0x5f,0x5f,0x5f, 0x41,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "feat____" + // CP1252=191 [top CP1252] + {{0x66,0x66,0x5f,0x5f,0x30,0x5f,0x5f,0x5f, 0x02,0x9e,0xba,0x21,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ff__0___" + // ASCII-7-bit=158 Latin1=186 CP1252=165 [top Latin1] + {{0x66,0x69,0x66,0x69,0x38,0x35,0x39,0x31, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "fifi8591" + // Latin1=191 [top Latin1] + {{0x66,0x72,0x66,0x72,0x38,0x35,0x39,0x31, 0x02,0x79,0xbc,0x21,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "frfr8591" + // ASCII-7-bit=121 Latin1=188 CP1252=163 [top Latin1] + {{0x66,0x72,0x66,0x72,0x38,0x5f,0x5f,0x5f, 0x02,0xa6,0xad,0x21,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "frfr8___" + // ASCII-7-bit=166 Latin1=173 CP1252=181 [top CP1252] + {{0x66,0x72,0x69,0x73,0x38,0x35,0x39,0x31, 0x02,0x80,0xbd,0x21,0x9e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "fris8591" + // ASCII-7-bit=128 Latin1=189 CP1252=158 [top Latin1] + {{0x66,0x72,0x75,0x74,0x38,0x5f,0x5f,0x5f, 0x02,0x8c,0xb3,0x21,0xb5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "frut8___" + // ASCII-7-bit=140 Latin1=179 CP1252=181 [top CP1252] + {{0x67,0x62,0x5f,0x5f,0x31,0x32,0x35,0x31, 0x01,0x6f,0x91,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gb__1251" + // ASCII-7-bit=111 CP1251=190 [top CP1251] + {{0x67,0x62,0x5f,0x5f,0x32,0x31,0x33,0x32, 0x01,0x91,0x21,0xbe,0xf1,0x70,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gb__2132" + // ASCII-7-bit=145 GB=190 GBK=112 [top GB] + {{0x67,0x62,0x5f,0x5f,0x32,0x33,0x31,0x32, 0x01,0x7a,0x21,0xbe,0xf1,0x5c,0xc1,0x37,0x00,0x00,0x00,0x00,}}, // "gb__2312" + // ASCII-7-bit=122 GB=190 GBK=92 GB18030=55 [top GB] + {{0x67,0x62,0x5f,0x5f,0x32,0x33,0x32,0x31, 0x01,0x7d,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gb__2321" + // ASCII-7-bit=125 GB=190 [top GB] + {{0x67,0x62,0x5f,0x5f,0x33,0x32,0x31,0x32, 0x01,0x92,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gb__3212" + // ASCII-7-bit=146 GB=190 [top GB] + {{0x67,0x62,0x5f,0x5f,0x38,0x30,0x33,0x30, 0x01,0x73,0x21,0xaf,0xf1,0x59,0xc1,0xb9,0x00,0x00,0x00,0x00,}}, // "gb__8030" + // ASCII-7-bit=115 GB=175 GBK=89 GB18030=185 [top GB18030] + {{0x67,0x62,0x5f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x7f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gb__8591" + // ASCII-7-bit=127 Latin1=190 [top Latin1] + {{0x67,0x62,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x71,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gb______" + // ASCII-7-bit=113 GB=190 [top GB] + {{0x67,0x62,0x6b,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x76,0x21,0xaf,0xf1,0xb9,0xc1,0x13,0x00,0x00,0x00,0x00,}}, // "gbk_____" + // ASCII-7-bit=118 GB=175 GBK=185 GB18030=19 [top GBK] + {{0x67,0x64,0x5f,0x5f,0x32,0x33,0x31,0x32, 0x01,0x56,0x21,0xbe,0xf1,0x72,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gd__2312" + // ASCII-7-bit=86 GB=190 GBK=114 [top GB] + {{0x67,0x65,0x69,0x73,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "geis8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x67,0x65,0x6e,0x65,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "gene1251" + // CP1251=191 [top CP1251] + {{0x67,0x69,0x73,0x6f,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "giso8591" + // Latin1=190 CP1252=111 [top Latin1] + {{0x67,0x72,0x65,0x65,0x5f,0x5f,0x5f,0x5f, 0x01,0x90,0x10,0x31,0xbe,0x21,0x86,0x00,0x00,0x00,0x00,0x00,}}, // "gree____" + // ASCII-7-bit=144 Greek=190 CP1253=134 [top Greek] + {{0x68,0x72,0x77,0x69,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "hrwi1250" + // CP1250=191 [top CP1250] + {{0x68,0x74,0x63,0x68,0x5f,0x5f,0x5f,0x5f, 0x30,0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "htch____" + // HTCHANAKYA=191 [top HTCHANAKYA] + {{0x68,0x74,0x6d,0x6c,0x5f,0x5f,0x5f,0x5f, 0x01,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "html____" + // ASCII-7-bit=191 [top ASCII-7-bit] + {{0x68,0x74,0x74,0x70,0x5f,0x5f,0x5f,0x5f, 0x02,0xbb,0xa4,0x21,0x8d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "http____" + // ASCII-7-bit=187 Latin1=164 CP1252=141 [top ASCII-7-bit] + {{0x68,0x7a,0x67,0x62,0x32,0x33,0x31,0x32, 0x01,0x85,0x20,0x71,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "hzgb2312" + // ASCII-7-bit=133 HZ-GB-2312=190 [top HZ-GB-2312] + {{0x69,0x5f,0x5f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "i___8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x69,0x61,0x6e,0x6f,0x35,0x5f,0x5f,0x5f, 0x02,0xbe,0x61,0x21,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iano5___" + // ASCII-7-bit=190 Latin1=97 CP1252=84 [top ASCII-7-bit] + {{0x69,0x62,0x6d,0x5f,0x38,0x35,0x32,0x5f, 0x01,0xac,0x20,0x01,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ibm_852_" + // ASCII-7-bit=172 CP852=186 [top CP852] + {{0x69,0x62,0x6d,0x5f,0x38,0x36,0x36,0x5f, 0x01,0x84,0x20,0x31,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ibm_866_" + // ASCII-7-bit=132 CP866=190 [top CP866] + {{0x69,0x62,0x6d,0x5f,0x39,0x34,0x32,0x5f, 0x61,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ibm_942_" + // SJS=191 [top SJS] + {{0x69,0x63,0x6f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x79,0xbb,0x21,0xa9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ico_8591" + // ASCII-7-bit=121 Latin1=187 CP1252=169 [top Latin1] + {{0x69,0x6e,0x64,0x6f,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "indo1251" + // CP1251=191 [top CP1251] + {{0x69,0x6e,0x73,0x6f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "inso8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x69,0x6f,0x73,0x5f,0x38,0x35,0x39,0x31, 0x02,0x97,0xbd,0x21,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ios_8591" + // ASCII-7-bit=151 Latin1=189 CP1252=110 [top Latin1] + {{0x69,0x6f,0x73,0x6f,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ioso8591" + // Latin1=190 CP1252=121 [top Latin1] + {{0x69,0x73,0x5f,0x5f,0x35,0x39,0x31,0x35, 0x11,0x7f,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "is__5915" + // Latin1=127 ISO-8859-15=190 [top ISO-8859-15] + {{0x69,0x73,0x5f,0x5f,0x38,0x35,0x39,0x31, 0x02,0xad,0xb7,0x21,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "is__8591" + // ASCII-7-bit=173 Latin1=183 CP1252=159 [top Latin1] + {{0x69,0x73,0x5f,0x5f,0x38,0x35,0x39,0x32, 0x01,0x78,0x81,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "is__8592" + // ASCII-7-bit=120 Latin2=190 [top Latin2] + {{0x69,0x73,0x5f,0x5f,0x38,0x35,0x39,0x37, 0x10,0x41,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "is__8597" + // Greek=191 [top Greek] + {{0x69,0x73,0x5f,0x5f,0x38,0x35,0x39,0x38, 0x01,0x6f,0x10,0x81,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "is__8598" + // ASCII-7-bit=111 Hebrew=190 [top Hebrew] + {{0x69,0x73,0x5f,0x5f,0x38,0x35,0x39,0x39, 0xd1,0xbe,0x81,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "is__8599" + // Latin5=190 CP1254=136 [top Latin5] + {{0x69,0x73,0x61,0x5f,0x35,0x39,0x31,0x35, 0x02,0x86,0x89,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isa_5915" + // ASCII-7-bit=134 Latin1=137 ISO-8859-15=190 [top ISO-8859-15] + {{0x69,0x73,0x64,0x5f,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isd_8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x69,0x73,0x64,0x6f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isdo8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x69,0x73,0x6e,0x5f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isn_8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x30,0x36,0x34,0x36, 0x02,0xb8,0xaa,0x21,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_0646" + // ASCII-7-bit=184 Latin1=170 CP1252=163 [top ASCII-7-bit] + {{0x69,0x73,0x6f,0x5f,0x31,0x30,0x34,0x30, 0x02,0x98,0xb2,0x21,0xb4,0xa1,0x5e,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1040" + // ASCII-7-bit=152 Latin1=178 CP1252=180 ISO-8859-15=94 [top CP1252] + {{0x69,0x73,0x6f,0x5f,0x31,0x32,0x35,0x30, 0x01,0x90,0xb1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1250" + // ASCII-7-bit=144 CP1250=190 [top CP1250] + {{0x69,0x73,0x6f,0x5f,0x31,0x32,0x35,0x31, 0x01,0x78,0x91,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1251" + // ASCII-7-bit=120 CP1251=190 [top CP1251] + {{0x69,0x73,0x6f,0x5f,0x31,0x32,0x35,0x32, 0x02,0xad,0x9e,0x21,0xb7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1252" + // ASCII-7-bit=173 Latin1=158 CP1252=183 [top CP1252] + {{0x69,0x73,0x6f,0x5f,0x31,0x32,0x35,0x33, 0x10,0x41,0x83,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1253" + // Greek=131 CP1253=190 [top CP1253] + {{0x69,0x73,0x6f,0x5f,0x31,0x32,0x35,0x34, 0xd1,0x9b,0x81,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1254" + // Latin5=155 CP1254=189 [top CP1254] + {{0x69,0x73,0x6f,0x5f,0x31,0x32,0x35,0x35, 0x01,0x79,0x10,0x01,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1255" + // ASCII-7-bit=121 CP1255=190 [top CP1255] + {{0x69,0x73,0x6f,0x5f,0x31,0x32,0x35,0x36, 0x01,0x6f,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1256" + // ASCII-7-bit=111 CP1256=190 [top CP1256] + {{0x69,0x73,0x6f,0x5f,0x31,0x32,0x35,0x37, 0x01,0x7f,0xf1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1257" + // ASCII-7-bit=127 CP1257=190 [top CP1257] + {{0x69,0x73,0x6f,0x5f,0x31,0x5f,0x5f,0x5f, 0x02,0x85,0xb5,0x21,0xb3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_1___" + // ASCII-7-bit=133 Latin1=181 CP1252=179 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x32,0x30,0x32,0x32, 0x01,0x97,0x51,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_2022" + // ASCII-7-bit=151 SJS=190 [top SJS] + {{0x69,0x73,0x6f,0x5f,0x35,0x35,0x39,0x31, 0x02,0xa9,0xb8,0x21,0xa4,0xa1,0x3c,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5591" + // ASCII-7-bit=169 Latin1=184 CP1252=164 ISO-8859-15=60 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x35,0x35,0x39,0x32, 0x02,0x9a,0xbd,0x21,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5592" + // ASCII-7-bit=154 Latin1=189 CP1252=146 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x35,0x38,0x39,0x31, 0x02,0xa1,0xbc,0x21,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5891" + // ASCII-7-bit=161 Latin1=188 CP1252=139 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x35,0x39,0x31,0x30, 0x01,0xaa,0x20,0xa1,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5910" + // ASCII-7-bit=170 Latin6=186 [top Latin6] + {{0x69,0x73,0x6f,0x5f,0x35,0x39,0x31,0x31, 0x01,0x86,0xd1,0xbe,0xd1,0x66,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5911" + // ASCII-7-bit=134 ISO-8859-11=190 CP874=102 [top ISO-8859-11] + {{0x69,0x73,0x6f,0x5f,0x35,0x39,0x31,0x33, 0x01,0x9c,0xf1,0xa1,0xc1,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5913" + // ASCII-7-bit=156 CP1257=161 ISO-8859-13=187 [top ISO-8859-13] + {{0x69,0x73,0x6f,0x5f,0x35,0x39,0x31,0x34, 0x02,0x93,0xbd,0x21,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5914" + // ASCII-7-bit=147 Latin1=189 CP1252=149 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x35,0x39,0x31,0x35, 0x02,0x98,0xad,0x21,0x81,0xa1,0xb7,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5915" + // ASCII-7-bit=152 Latin1=173 CP1252=129 ISO-8859-15=183 [top ISO-8859-15] + {{0x69,0x73,0x6f,0x5f,0x35,0x39,0x31,0x36, 0x01,0xae,0xb1,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5916" + // ASCII-7-bit=174 CP1250=185 [top CP1250] + {{0x69,0x73,0x6f,0x5f,0x35,0x39,0x32,0x32, 0x01,0xa7,0x81,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_5922" + // ASCII-7-bit=167 Latin2=187 [top Latin2] + {{0x69,0x73,0x6f,0x5f,0x36,0x33,0x39,0x32, 0x02,0x7e,0xbe,0x21,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_6392" + // ASCII-7-bit=126 Latin1=190 CP1252=130 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x36,0x33,0x39,0x5f, 0x01,0xa6,0xa1,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_639_" + // ASCII-7-bit=166 CP1256=188 [top CP1256] + {{0x69,0x73,0x6f,0x5f,0x36,0x34,0x36,0x31, 0x02,0x7d,0xbe,0x21,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_6461" + // ASCII-7-bit=125 Latin1=190 CP1252=104 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x31,0x31, 0x02,0xb0,0xb7,0x21,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8511" + // ASCII-7-bit=176 Latin1=183 CP1252=146 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x36,0x31, 0x02,0x9f,0xba,0x21,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8561" + // ASCII-7-bit=159 Latin1=186 CP1252=165 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x38,0x31, 0x01,0x8d,0x51,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8581" + // ASCII-7-bit=141 SJS=190 [top SJS] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x30, 0x02,0x99,0xbc,0x21,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8590" + // ASCII-7-bit=153 Latin1=188 CP1252=156 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x31, 0x02,0xae,0xb8,0x21,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8591" + // ASCII-7-bit=174 Latin1=184 CP1252=153 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x32, 0x01,0x95,0x81,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8592" + // ASCII-7-bit=149 Latin2=190 [top Latin2] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x33, 0x01,0x9f,0x20,0x51,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8593" + // ASCII-7-bit=159 Latin3=189 [top Latin3] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x34, 0x01,0xac,0x10,0xd1,0xba,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8594" + // ASCII-7-bit=172 Latin4=186 [top Latin4] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x35, 0x01,0xa6,0x10,0xa1,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8595" + // ASCII-7-bit=166 ISO-8859-5=188 [top ISO-8859-5] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x36, 0x01,0xae,0x20,0x11,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8596" + // ASCII-7-bit=174 Arabic=185 [top Arabic] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x37, 0x01,0x96,0x10,0x31,0xbd,0x21,0x8f,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8597" + // ASCII-7-bit=150 Greek=189 CP1253=143 [top Greek] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x38, 0x01,0x9b,0x10,0x81,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8598" + // ASCII-7-bit=155 Hebrew=189 [top Hebrew] + {{0x69,0x73,0x6f,0x5f,0x38,0x35,0x39,0x39, 0x01,0x7a,0xc1,0xbe,0x81,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8599" + // ASCII-7-bit=122 Latin5=190 CP1254=126 [top Latin5] + {{0x69,0x73,0x6f,0x5f,0x38,0x36,0x30,0x31, 0x02,0xba,0x94,0x21,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8601" + // ASCII-7-bit=186 Latin1=148 CP1252=166 [top ASCII-7-bit] + {{0x69,0x73,0x6f,0x5f,0x38,0x36,0x39,0x31, 0x02,0xad,0xb9,0x21,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8691" + // ASCII-7-bit=173 Latin1=185 CP1252=131 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x38,0x36,0x39,0x32, 0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8692" + // Latin2=191 [top Latin2] + {{0x69,0x73,0x6f,0x5f,0x38,0x38,0x35,0x31, 0x02,0xac,0xb7,0x21,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8851" + // ASCII-7-bit=172 Latin1=183 CP1252=159 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x38,0x38,0x35,0x39, 0x02,0xaa,0xba,0x21,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8859" + // ASCII-7-bit=170 Latin1=186 CP1252=128 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x38,0x38,0x39,0x39, 0xd1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8899" + // Latin5=191 [top Latin5] + {{0x69,0x73,0x6f,0x5f,0x38,0x39,0x31,0x31, 0x02,0x8c,0xbd,0x21,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8911" + // ASCII-7-bit=140 Latin1=189 CP1252=154 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x38,0x39,0x31,0x5f, 0x01,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_891_" + // ASCII-7-bit=191 [top ASCII-7-bit] + {{0x69,0x73,0x6f,0x5f,0x38,0x39,0x35,0x31, 0x02,0xa3,0xbc,0x21,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_8951" + // ASCII-7-bit=163 Latin1=188 CP1252=145 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x39,0x30,0x30,0x31, 0x02,0x75,0xa7,0x21,0x85,0xa1,0xbb,0x00,0x00,0x00,0x00,0x00,}}, // "iso_9001" + // ASCII-7-bit=117 Latin1=167 CP1252=133 ISO-8859-15=187 [top ISO-8859-15] + {{0x69,0x73,0x6f,0x5f,0x39,0x35,0x35,0x31, 0x01,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_9551" + // ASCII-7-bit=191 [top ASCII-7-bit] + {{0x69,0x73,0x6f,0x5f,0x39,0x35,0x39,0x31, 0x02,0x72,0xbe,0x21,0x7b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_9591" + // ASCII-7-bit=114 Latin1=190 CP1252=123 [top Latin1] + {{0x69,0x73,0x6f,0x5f,0x39,0x35,0x39,0x32, 0x01,0x7f,0x81,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_9592" + // ASCII-7-bit=127 Latin2=190 [top Latin2] + {{0x69,0x73,0x6f,0x5f,0x39,0x35,0x39,0x39, 0x01,0x84,0xc1,0xbb,0x81,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iso_9599" + // ASCII-7-bit=132 Latin5=187 CP1254=166 [top Latin5] + {{0x69,0x73,0x6f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x02,0x99,0xbc,0x21,0x96,0xa1,0x2e,0x00,0x00,0x00,0x00,0x00,}}, // "iso_____" + // ASCII-7-bit=153 Latin1=188 CP1252=150 ISO-8859-15=46 [top Latin1] + {{0x69,0x73,0x6f,0x61,0x38,0x35,0x39,0x31, 0x02,0x9a,0xbd,0x21,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoa8591" + // ASCII-7-bit=154 Latin1=189 CP1252=138 [top Latin1] + {{0x69,0x73,0x6f,0x62,0x38,0x35,0x39,0x31, 0x02,0x86,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isob8591" + // ASCII-7-bit=134 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x63,0x32,0x30,0x32,0x32, 0x20,0xd1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoc2022" + // ISO_2022_CN=191 [top ISO_2022_CN] + {{0x69,0x73,0x6f,0x63,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoc8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x63,0x38,0x35,0x39,0x32, 0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoc8592" + // Latin2=191 [top Latin2] + {{0x69,0x73,0x6f,0x64,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isod8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x65,0x38,0x35,0x39,0x31, 0x02,0x93,0xbd,0x21,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoe8591" + // ASCII-7-bit=147 Latin1=189 CP1252=139 [top Latin1] + {{0x69,0x73,0x6f,0x66,0x35,0x39,0x31,0x35, 0x11,0x6f,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isof5915" + // Latin1=111 ISO-8859-15=190 [top ISO-8859-15] + {{0x69,0x73,0x6f,0x68,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoh8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x69,0x36,0x5f,0x5f,0x5f, 0x02,0xbe,0x92,0x21,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoi6___" + // ASCII-7-bit=190 Latin1=146 CP1252=127 [top ASCII-7-bit] + {{0x69,0x73,0x6f,0x69,0x38,0x35,0x39,0x31, 0x02,0xa2,0xbc,0x21,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoi8591" + // ASCII-7-bit=162 Latin1=188 CP1252=140 [top Latin1] + {{0x69,0x73,0x6f,0x69,0x38,0x35,0x39,0x32, 0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoi8592" + // Latin2=191 [top Latin2] + {{0x69,0x73,0x6f,0x69,0x38,0x35,0x39,0x35, 0x01,0xa4,0x10,0xa1,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoi8595" + // ASCII-7-bit=164 ISO-8859-5=188 [top ISO-8859-5] + {{0x69,0x73,0x6f,0x69,0x38,0x35,0x39,0x36, 0x01,0x79,0x20,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoi8596" + // ASCII-7-bit=121 Arabic=190 [top Arabic] + {{0x69,0x73,0x6f,0x69,0x38,0x35,0x39,0x38, 0x01,0x83,0x10,0x01,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoi8598" + // ASCII-7-bit=131 CP1255=190 [top CP1255] + {{0x69,0x73,0x6f,0x69,0x38,0x35,0x39,0x39, 0xd1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoi8599" + // Latin5=191 [top Latin5] + {{0x69,0x73,0x6f,0x69,0x38,0x38,0x35,0x39, 0x02,0xae,0xb7,0x21,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoi8859" + // ASCII-7-bit=174 Latin1=183 CP1252=154 [top Latin1] + {{0x69,0x73,0x6f,0x69,0x38,0x39,0x5f,0x5f, 0xb1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoi89__" + // CP1256=191 [top CP1256] + {{0x69,0x73,0x6f,0x6a,0x32,0x30,0x30,0x32, 0x71,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoj2002" + // EUC-JP=191 [top EUC-JP] + {{0x69,0x73,0x6f,0x6a,0x32,0x30,0x32,0x32, 0x01,0x44,0x10,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoj2022" + // ASCII-7-bit=68 JIS=190 [top JIS] + {{0x69,0x73,0x6f,0x6a,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoj8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x6b,0x32,0x30,0x30,0x32, 0x01,0x7a,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isok2002" + // ASCII-7-bit=122 KSC=190 [top KSC] + {{0x69,0x73,0x6f,0x6b,0x32,0x30,0x32,0x32, 0x20,0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isok2022" + // ISO-2022-KR=191 [top ISO-2022-KR] + {{0x69,0x73,0x6f,0x6c,0x31,0x5f,0x5f,0x5f, 0x01,0xa6,0x11,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isol1___" + // ASCII-7-bit=166 UTF8=188 [top UTF8] + {{0x69,0x73,0x6f,0x6c,0x35,0x39,0x31,0x31, 0x01,0x83,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isol5911" + // ASCII-7-bit=131 ISO-8859-11=190 [top ISO-8859-11] + {{0x69,0x73,0x6f,0x6c,0x37,0x5f,0x5f,0x5f, 0x02,0xa4,0xb8,0x21,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isol7___" + // ASCII-7-bit=164 Latin1=184 CP1252=167 [top Latin1] + {{0x69,0x73,0x6f,0x6c,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isol8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x6d,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isom8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x6e,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ison8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x6f,0x38,0x35,0x39,0x31, 0x02,0x6e,0xbe,0x21,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoo8591" + // ASCII-7-bit=110 Latin1=190 CP1252=110 [top Latin1] + {{0x69,0x73,0x6f,0x70,0x35,0x39,0x31,0x35, 0xf1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isop5915" + // ISO-8859-15=191 [top ISO-8859-15] + {{0x69,0x73,0x6f,0x70,0x38,0x35,0x39,0x31, 0x02,0x91,0xbe,0x21,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isop8591" + // ASCII-7-bit=145 Latin1=190 CP1252=111 [top Latin1] + {{0x69,0x73,0x6f,0x73,0x38,0x35,0x39,0x31, 0x02,0x84,0xbe,0x21,0x8d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isos8591" + // ASCII-7-bit=132 Latin1=190 CP1252=141 [top Latin1] + {{0x69,0x73,0x6f,0x75,0x36,0x34,0x36,0x31, 0x02,0xa6,0xb9,0x21,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isou6461" + // ASCII-7-bit=166 Latin1=185 CP1252=161 [top Latin1] + {{0x69,0x73,0x6f,0x75,0x36,0x34,0x36,0x5f, 0x01,0xbe,0x31,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isou646_" + // ASCII-7-bit=190 CP1252=142 [top ASCII-7-bit] + {{0x69,0x73,0x6f,0x75,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isou8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x75,0x38,0x5f,0x5f,0x5f, 0x02,0xa2,0xbc,0x21,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isou8___" + // ASCII-7-bit=162 Latin1=188 CP1252=140 [top Latin1] + {{0x69,0x73,0x6f,0x77,0x31,0x32,0x35,0x30, 0x01,0x6e,0xb1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isow1250" + // ASCII-7-bit=110 CP1250=190 [top CP1250] + {{0x69,0x73,0x6f,0x77,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isow1251" + // CP1251=191 [top CP1251] + {{0x69,0x73,0x6f,0x77,0x31,0x32,0x35,0x33, 0x01,0x6f,0x10,0x61,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isow1253" + // ASCII-7-bit=111 CP1253=190 [top CP1253] + {{0x69,0x73,0x6f,0x77,0x38,0x35,0x39,0x31, 0x02,0x89,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isow8591" + // ASCII-7-bit=137 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x78,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isox8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x69,0x73,0x6f,0x7a,0x38,0x35,0x39,0x31, 0x02,0x8b,0xbe,0x21,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isoz8591" + // ASCII-7-bit=139 Latin1=190 CP1252=121 [top Latin1] + {{0x69,0x73,0x70,0x5f,0x38,0x35,0x39,0x31, 0x02,0x86,0xbe,0x21,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isp_8591" + // ASCII-7-bit=134 Latin1=190 CP1252=111 [top Latin1] + {{0x69,0x73,0x73,0x5f,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iss_8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x69,0x73,0x73,0x6f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isso8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x69,0x73,0x74,0x5f,0x35,0x39,0x31,0x35, 0x01,0x79,0xe1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ist_5915" + // ASCII-7-bit=121 ISO-8859-15=190 [top ISO-8859-15] + {{0x69,0x73,0x74,0x6f,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "isto8591" + // Latin1=190 CP1252=111 [top Latin1] + {{0x69,0x74,0x69,0x73,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x21,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "itis8591" + // ASCII-7-bit=111 Latin1=190 CP1252=134 [top Latin1] + {{0x69,0x74,0x69,0x74,0x35,0x39,0x31,0x35, 0x41,0x79,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "itit5915" + // CP1252=121 ISO-8859-15=190 [top ISO-8859-15] + {{0x69,0x74,0x69,0x74,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "itit8591" + // Latin1=190 CP1252=143 [top Latin1] + {{0x69,0x74,0x69,0x74,0x5f,0x5f,0x5f,0x5f, 0x02,0xb7,0xab,0x21,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "itit____" + // ASCII-7-bit=183 Latin1=171 CP1252=164 [top ASCII-7-bit] + {{0x69,0x75,0x5f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iu__8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x69,0x77,0x69,0x6e,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iwin1250" + // CP1250=191 [top CP1250] + {{0x69,0x77,0x69,0x6e,0x31,0x32,0x35,0x37, 0x10,0x01,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iwin1257" + // CP1257=191 [top CP1257] + {{0x69,0x79,0x73,0x6f,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "iyso8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x6a,0x61,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x78,0x51,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ja______" + // ASCII-7-bit=120 SJS=190 [top SJS] + {{0x6a,0x61,0x67,0x72,0x5f,0x5f,0x5f,0x5f, 0x20,0xf1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "jagr____" + // JAGRAN=191 [top JAGRAN] + {{0x6a,0x69,0x73,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x81,0x10,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "jis_____" + // ASCII-7-bit=129 JIS=190 [top JIS] + {{0x6b,0x61,0x6d,0x63,0x5f,0x5f,0x5f,0x5f, 0x20,0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kamc____" + // CP852=191 [top CP852] + {{0x6b,0x6f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x7c,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ko______" + // ASCII-7-bit=124 KSC=190 [top KSC] + {{0x6b,0x6f,0x69,0x5f,0x37,0x5f,0x5f,0x5f, 0x01,0xbe,0x31,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "koi_7___" + // ASCII-7-bit=190 CP1252=107 [top ASCII-7-bit] + {{0x6b,0x6f,0x69,0x72,0x38,0x5f,0x5f,0x5f, 0x01,0x8b,0x10,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "koir8___" + // ASCII-7-bit=139 KOI8R=190 [top KOI8R] + {{0x6b,0x6f,0x69,0x75,0x38,0x5f,0x5f,0x5f, 0x01,0x77,0x10,0x91,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "koiu8___" + // ASCII-7-bit=119 KOI8U=190 [top KOI8U] + {{0x6b,0x6f,0x6b,0x72,0x5f,0x5f,0x5f,0x5f, 0x01,0x4b,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kokr____" + // ASCII-7-bit=75 KSC=190 [top KSC] + {{0x6b,0x6f,0x6b,0x73,0x35,0x36,0x30,0x31, 0x01,0x75,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "koks5601" + // ASCII-7-bit=117 KSC=190 [top KSC] + {{0x6b,0x6f,0x72,0x65,0x5f,0x5f,0x5f,0x5f, 0x01,0x4e,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kore____" + // ASCII-7-bit=78 KSC=190 [top KSC] + {{0x6b,0x72,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x74,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "kr______" + // ASCII-7-bit=116 KSC=190 [top KSC] + {{0x6b,0x72,0x63,0x5f,0x35,0x36,0x30,0x31, 0x01,0x74,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "krc_5601" + // ASCII-7-bit=116 KSC=190 [top KSC] + {{0x6b,0x73,0x63,0x5f,0x35,0x35,0x30,0x31, 0x51,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ksc_5501" + // KSC=191 [top KSC] + {{0x6b,0x73,0x63,0x5f,0x35,0x36,0x30,0x31, 0x01,0x62,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ksc_5601" + // ASCII-7-bit=98 KSC=190 [top KSC] + {{0x6b,0x73,0x63,0x5f,0x36,0x30,0x30,0x31, 0x51,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ksc_6001" + // KSC=191 [top KSC] + {{0x6c,0x61,0x73,0x74,0x5f,0x5f,0x5f,0x5f, 0x02,0xb7,0xaf,0x21,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "last____" + // ASCII-7-bit=183 Latin1=175 CP1252=144 [top ASCII-7-bit] + {{0x6c,0x61,0x74,0x69,0x31,0x5f,0x5f,0x5f, 0x02,0xa3,0xbb,0x21,0x9b,0xa1,0x73,0x00,0x00,0x00,0x00,0x00,}}, // "lati1___" + // ASCII-7-bit=163 Latin1=187 CP1252=155 ISO-8859-15=115 [top Latin1] + {{0x6c,0x61,0x74,0x69,0x32,0x5f,0x5f,0x5f, 0x01,0x94,0x81,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lati2___" + // ASCII-7-bit=148 Latin2=190 [top Latin2] + {{0x6c,0x61,0x74,0x69,0x35,0x5f,0x5f,0x5f, 0x01,0x7c,0xc1,0xbe,0x81,0x87,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lati5___" + // ASCII-7-bit=124 Latin5=190 CP1254=135 [top Latin5] + {{0x6c,0x61,0x74,0x69,0x38,0x35,0x39,0x31, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lati8591" + // Latin1=191 [top Latin1] + {{0x6c,0x61,0x74,0x69,0x38,0x38,0x35,0x39, 0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lati8859" + // Latin2=191 [top Latin2] + {{0x6c,0x69,0x6e,0x75,0x31,0x32,0x35,0x32, 0x11,0x79,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "linu1252" + // Latin1=121 CP1252=190 [top CP1252] + {{0x6c,0x6f,0x67,0x69,0x5f,0x5f,0x5f,0x5f, 0x01,0x88,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "logi____" + // ASCII-7-bit=136 UTF8=190 [top UTF8] + {{0x6c,0x73,0x6f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lso_8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x6c,0x74,0x6f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "lto_8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x6c,0x74,0x77,0x69,0x31,0x32,0x35,0x37, 0x10,0x01,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ltwi1257" + // CP1257=191 [top CP1257] + {{0x6d,0x61,0x63,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x82,0x91,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mac_____" + // ASCII-7-bit=130 CP1251=190 [top CP1251] + {{0x6d,0x61,0x63,0x63,0x5f,0x5f,0x5f,0x5f, 0x01,0x94,0x10,0xe1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "macc____" + // ASCII-7-bit=148 MACINTOSH=190 [top MACINTOSH] + {{0x6d,0x61,0x63,0x69,0x5f,0x5f,0x5f,0x5f, 0x02,0xbd,0x93,0x21,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "maci____" + // ASCII-7-bit=189 Latin1=147 CP1252=139 [top ASCII-7-bit] + {{0x6d,0x61,0x63,0x72,0x5f,0x5f,0x5f,0x5f, 0x01,0xaf,0x10,0xe1,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "macr____" + // ASCII-7-bit=175 MACINTOSH=185 [top MACINTOSH] + {{0x6d,0x73,0x5f,0x5f,0x38,0x37,0x34,0x5f, 0x01,0x80,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ms__874_" + // ASCII-7-bit=128 ISO-8859-11=190 [top ISO-8859-11] + {{0x6d,0x73,0x5f,0x5f,0x39,0x33,0x32,0x5f, 0x01,0x91,0x51,0xbe,0x10,0x11,0x82,0x00,0x00,0x00,0x00,0x00,}}, // "ms__932_" + // ASCII-7-bit=145 SJS=190 CP932=130 [top SJS] + {{0x6d,0x73,0x5f,0x5f,0x39,0x34,0x39,0x5f, 0x01,0x49,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ms__949_" + // ASCII-7-bit=73 KSC=190 [top KSC] + {{0x6d,0x73,0x5f,0x5f,0x39,0x35,0x30,0x5f, 0x01,0x75,0x71,0xbe,0x10,0xa1,0x43,0x00,0x00,0x00,0x00,0x00,}}, // "ms__950_" + // ASCII-7-bit=117 BIG5=190 BIG5_HKSCS=67 [top BIG5] + {{0x6d,0x73,0x63,0x70,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mscp1250" + // CP1250=191 [top CP1250] + {{0x6d,0x73,0x68,0x6b,0x39,0x35,0x30,0x5f, 0x01,0x82,0x71,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mshk950_" + // ASCII-7-bit=130 BIG5=190 [top BIG5] + {{0x6d,0x73,0x77,0x69,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mswi1250" + // CP1250=191 [top CP1250] + {{0x6d,0x73,0x77,0x69,0x31,0x32,0x35,0x33, 0x10,0x41,0x8f,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mswi1253" + // Greek=143 CP1253=190 [top CP1253] + {{0x6d,0x78,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "mx______" + // UTF8=191 [top UTF8] + {{0x6e,0x65,0x77,0x5f,0x5f,0x5f,0x5f,0x5f, 0x02,0xab,0xb2,0x21,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "new_____" + // ASCII-7-bit=171 Latin1=178 CP1252=175 [top Latin1] + {{0x6e,0x66,0x7a,0x5f,0x32,0x30,0x31,0x30, 0x02,0x80,0xbc,0x21,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "nfz_2010" + // ASCII-7-bit=128 Latin1=188 CP1252=163 [top Latin1] + {{0x6e,0x69,0x73,0x6f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "niso8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x6e,0x6c,0x61,0x69,0x38,0x35,0x39,0x31, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "nlai8591" + // Latin1=191 [top Latin1] + {{0x6e,0x6c,0x6e,0x6c,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "nlnl8591" + // Latin1=190 CP1252=111 [top Latin1] + {{0x6e,0x6f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0xa4,0x71,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "no______" + // ASCII-7-bit=164 BIG5=188 [top BIG5] + {{0x6e,0x6f,0x69,0x73,0x38,0x35,0x39,0x31, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "nois8591" + // Latin1=191 [top Latin1] + {{0x6e,0x6f,0x6e,0x65,0x5f,0x5f,0x5f,0x5f, 0x01,0x9b,0x51,0xbd,0x10,0x11,0x70,0x00,0x00,0x00,0x00,0x00,}}, // "none____" + // ASCII-7-bit=155 SJS=189 CP932=112 [top SJS] + {{0x6e,0x75,0x6c,0x6c,0x5f,0x5f,0x5f,0x5f, 0x01,0x92,0x71,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "null____" + // ASCII-7-bit=146 BIG5=190 [top BIG5] + {{0x6f,0x5f,0x5f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "o___8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x6f,0x6e,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "on______" + // UTF8=191 [top UTF8] + {{0x6f,0x73,0x69,0x5f,0x35,0x39,0x31,0x35, 0x01,0x6f,0xe1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "osi_5915" + // ASCII-7-bit=111 ISO-8859-15=190 [top ISO-8859-15] + {{0x6f,0x73,0x6f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "oso_8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x6f,0x73,0x70,0x5f,0x38,0x35,0x39,0x38, 0x01,0x6f,0x10,0x81,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "osp_8598" + // ASCII-7-bit=111 Hebrew=190 [top Hebrew] + {{0x6f,0x77,0x69,0x6e,0x31,0x32,0x35,0x36, 0xb1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "owin1256" + // CP1256=191 [top CP1256] + {{0x70,0x61,0x72,0x5f,0x5f,0x5f,0x5f,0x5f, 0x02,0x6e,0xb8,0x21,0xaf,0xa1,0x64,0x00,0x00,0x00,0x00,0x00,}}, // "par_____" + // ASCII-7-bit=110 Latin1=184 CP1252=175 ISO-8859-15=100 [top Latin1] + {{0x70,0x63,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "pc______" + // UTF8=191 [top UTF8] + {{0x70,0x6c,0x69,0x73,0x38,0x35,0x39,0x32, 0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "plis8592" + // Latin2=191 [top Latin2] + {{0x70,0x6c,0x70,0x6c,0x38,0x35,0x39,0x32, 0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "plpl8592" + // Latin2=191 [top Latin2] + {{0x70,0x72,0x65,0x64,0x5f,0x5f,0x5f,0x5f, 0x02,0xb4,0xa3,0x21,0xb1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "pred____" + // ASCII-7-bit=180 Latin1=163 CP1252=177 [top ASCII-7-bit] + {{0x70,0x74,0x62,0x72,0x38,0x35,0x39,0x31, 0x02,0x6e,0xbd,0x21,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ptbr8591" + // ASCII-7-bit=110 Latin1=189 CP1252=154 [top Latin1] + {{0x70,0x74,0x62,0x72,0x5f,0x5f,0x5f,0x5f, 0x01,0x79,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ptbr____" + // ASCII-7-bit=121 UTF8=190 [top UTF8] + {{0x70,0x74,0x69,0x73,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ptis8591" + // Latin1=190 CP1252=126 [top Latin1] + {{0x70,0x74,0x70,0x74,0x35,0x39,0x31,0x35, 0x11,0x89,0x21,0x6f,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ptpt5915" + // Latin1=137 CP1252=111 ISO-8859-15=190 [top ISO-8859-15] + {{0x72,0x66,0x63,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x87,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "rfc_____" + // ASCII-7-bit=135 UTF8=190 [top UTF8] + {{0x72,0x6f,0x69,0x73,0x38,0x35,0x39,0x31, 0x02,0x83,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "rois8591" + // ASCII-7-bit=131 Latin1=190 [top Latin1] + {{0x72,0x6f,0x72,0x6f,0x38,0x35,0x39,0x32, 0x01,0x99,0x81,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "roro8592" + // ASCII-7-bit=153 Latin2=189 [top Latin2] + {{0x72,0x75,0x72,0x75,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ruru1251" + // CP1251=191 [top CP1251] + {{0x72,0x75,0x77,0x69,0x31,0x32,0x35,0x31, 0x01,0x6f,0x91,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ruwi1251" + // ASCII-7-bit=111 CP1251=190 [top CP1251] + {{0x73,0x65,0x65,0x6d,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "seem8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x73,0x65,0x74,0x63,0x5f,0x5f,0x5f,0x5f, 0x01,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "setc____" + // ASCII-7-bit=191 [top ASCII-7-bit] + {{0x73,0x68,0x69,0x66,0x31,0x32,0x35,0x32, 0x02,0x86,0x6f,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "shif1252" + // ASCII-7-bit=134 Latin1=111 CP1252=190 [top CP1252] + {{0x73,0x68,0x69,0x66,0x5f,0x5f,0x5f,0x5f, 0x01,0x6e,0x51,0xbe,0x10,0x11,0x6b,0x00,0x00,0x00,0x00,0x00,}}, // "shif____" + // ASCII-7-bit=110 SJS=190 CP932=107 [top SJS] + {{0x73,0x69,0x66,0x74,0x5f,0x5f,0x5f,0x5f, 0x01,0x72,0x51,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "sift____" + // ASCII-7-bit=114 SJS=190 [top SJS] + {{0x73,0x6a,0x69,0x73,0x5f,0x5f,0x5f,0x5f, 0x01,0x79,0x51,0xbe,0x10,0x11,0x5d,0x00,0x00,0x00,0x00,0x00,}}, // "sjis____" + // ASCII-7-bit=121 SJS=190 CP932=93 [top SJS] + {{0x73,0x6b,0x77,0x69,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "skwi1250" + // CP1250=191 [top CP1250] + {{0x73,0x6f,0x5f,0x5f,0x35,0x39,0x31,0x35, 0x02,0x86,0x6f,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "so__5915" + // ASCII-7-bit=134 Latin1=111 ISO-8859-15=190 [top ISO-8859-15] + {{0x73,0x6f,0x5f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x9a,0xbd,0x21,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "so__8591" + // ASCII-7-bit=154 Latin1=189 CP1252=139 [top Latin1] + {{0x73,0x6f,0x5f,0x5f,0x38,0x35,0x39,0x32, 0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "so__8592" + // Latin2=191 [top Latin2] + {{0x73,0x76,0x73,0x65,0x38,0x35,0x39,0x31, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "svse8591" + // Latin1=191 [top Latin1] + {{0x74,0x61,0x62,0x5f,0x5f,0x5f,0x5f,0x5f, 0x30,0x41,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tab_____" + // TAB=191 [top TAB] + {{0x74,0x61,0x6d,0x5f,0x5f,0x5f,0x5f,0x5f, 0x30,0x31,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tam_____" + // TAM=191 [top TAM] + {{0x74,0x65,0x78,0x74,0x5f,0x5f,0x5f,0x5f, 0x02,0xac,0xb7,0x21,0xa0,0xa1,0x49,0x00,0x00,0x00,0x00,0x00,}}, // "text____" + // ASCII-7-bit=172 Latin1=183 CP1252=160 ISO-8859-15=73 [top Latin1] + {{0x74,0x69,0x73,0x5f,0x36,0x31,0x38,0x5f, 0x01,0x75,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tis_618_" + // ASCII-7-bit=117 ISO-8859-11=190 [top ISO-8859-11] + {{0x74,0x69,0x73,0x5f,0x36,0x32,0x30,0x5f, 0x01,0x82,0xd1,0xbe,0xd1,0x7b,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tis_620_" + // ASCII-7-bit=130 ISO-8859-11=190 CP874=123 [top ISO-8859-11] + {{0x74,0x72,0x5f,0x5f,0x38,0x35,0x39,0x39, 0xd1,0xbe,0x81,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tr__8599" + // Latin5=190 CP1254=111 [top Latin5] + {{0x74,0x72,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0xd1,0xbe,0x81,0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tr______" + // Latin5=190 CP1254=95 [top Latin5] + {{0x74,0x72,0x69,0x73,0x38,0x35,0x39,0x39, 0xd1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tris8599" + // Latin5=191 [top Latin5] + {{0x74,0x73,0x63,0x69,0x5f,0x5f,0x5f,0x5f, 0x30,0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "tsci____" + // TSCII=191 [top TSCII] + {{0x75,0x63,0x73,0x5f,0x32,0x5f,0x5f,0x5f, 0x02,0xb8,0xa7,0x21,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "ucs_2___" + // ASCII-7-bit=184 Latin1=167 CP1252=163 [top ASCII-7-bit] + {{0x75,0x66,0x74,0x5f,0x38,0x5f,0x5f,0x5f, 0x01,0xb0,0x11,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "uft_8___" + // ASCII-7-bit=176 UTF8=184 [top UTF8] + {{0x75,0x69,0x73,0x6f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "uiso8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] + {{0x75,0x6e,0x69,0x63,0x31,0x31,0x5f,0x5f, 0x01,0xa7,0x11,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "unic11__" + // ASCII-7-bit=167 UTF8=187 [top UTF8] + {{0x75,0x6e,0x69,0x63,0x5f,0x5f,0x5f,0x5f, 0x02,0xbe,0x90,0x21,0x85,0xa1,0x45,0x00,0x00,0x00,0x00,0x00,}}, // "unic____" + // ASCII-7-bit=190 Latin1=144 CP1252=133 ISO-8859-15=69 [top ASCII-7-bit] + {{0x75,0x6e,0x6b,0x6e,0x38,0x5f,0x5f,0x5f, 0x02,0xa2,0xbb,0x21,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "unkn8___" + // ASCII-7-bit=162 Latin1=187 CP1252=149 [top Latin1] + {{0x75,0x6e,0x6b,0x6e,0x5f,0x5f,0x5f,0x5f, 0x01,0x9c,0x51,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "unkn____" + // ASCII-7-bit=156 SJS=189 [top SJS] + {{0x75,0x70,0x66,0x5f,0x38,0x5f,0x5f,0x5f, 0x21,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "upf_8___" + // UTF8=191 [top UTF8] + {{0x75,0x73,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f, 0x02,0xbe,0x7d,0x21,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "us______" + // ASCII-7-bit=190 Latin1=125 CP1252=125 [top ASCII-7-bit] + {{0x75,0x73,0x61,0x73,0x5f,0x5f,0x5f,0x5f, 0x02,0xbe,0x83,0x21,0x6a,0xa1,0x38,0x00,0x00,0x00,0x00,0x00,}}, // "usas____" + // ASCII-7-bit=190 Latin1=131 CP1252=106 ISO-8859-15=56 [top ASCII-7-bit] + {{0x75,0x73,0x65,0x6e,0x5f,0x5f,0x5f,0x5f, 0x02,0xb8,0x94,0x21,0xad,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "usen____" + // ASCII-7-bit=184 Latin1=148 CP1252=173 [top ASCII-7-bit] + {{0x75,0x73,0x65,0x72,0x5f,0x5f,0x5f,0x5f, 0x02,0xb9,0x9e,0x21,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "user____" + // ASCII-7-bit=185 Latin1=158 CP1252=167 [top ASCII-7-bit] + {{0x75,0x73,0x69,0x73,0x38,0x35,0x39,0x31, 0x02,0x78,0xbe,0x21,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "usis8591" + // ASCII-7-bit=120 Latin1=190 CP1252=120 [top Latin1] + {{0x75,0x73,0x6f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x79,0xbc,0x21,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "uso_8591" + // ASCII-7-bit=121 Latin1=188 CP1252=165 [top Latin1] + {{0x75,0x74,0x66,0x5f,0x31,0x36,0x5f,0x5f, 0x01,0xb0,0x11,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utf_16__" + // ASCII-7-bit=176 UTF8=184 [top UTF8] + {{0x75,0x74,0x66,0x5f,0x33,0x32,0x5f,0x5f, 0x02,0xb5,0xa9,0x21,0x9f,0xa1,0xa1,0x00,0x00,0x00,0x00,0x00,}}, // "utf_32__" + // ASCII-7-bit=181 Latin1=169 CP1252=159 ISO-8859-15=161 [top ASCII-7-bit] + {{0x75,0x74,0x66,0x5f,0x35,0x39,0x31,0x35, 0x11,0x90,0xd1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utf_5915" + // Latin1=144 ISO-8859-15=190 [top ISO-8859-15] + {{0x75,0x74,0x66,0x5f,0x37,0x5f,0x5f,0x5f, 0x01,0x88,0x20,0xb1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utf_7___" + // ASCII-7-bit=136 UTF7=190 [top UTF7] + {{0x75,0x74,0x66,0x5f,0x38,0x35,0x39,0x31, 0x02,0x95,0xbd,0x21,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utf_8591" + // ASCII-7-bit=149 Latin1=189 CP1252=140 [top Latin1] + {{0x75,0x74,0x66,0x5f,0x38,0x35,0x39,0x39, 0xd1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utf_8599" + // Latin5=191 [top Latin5] + {{0x75,0x74,0x66,0x5f,0x38,0x5f,0x5f,0x5f, 0x01,0xae,0x11,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utf_8___" + // ASCII-7-bit=174 UTF8=185 [top UTF8] + {{0x75,0x74,0x66,0x5f,0x5f,0x5f,0x5f,0x5f, 0x02,0xbe,0x8a,0x21,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utf_____" + // ASCII-7-bit=190 Latin1=138 CP1252=116 [top ASCII-7-bit] + {{0x75,0x74,0x66,0x62,0x31,0x36,0x5f,0x5f, 0x01,0xa5,0x20,0x41,0xbc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utfb16__" + // ASCII-7-bit=165 UTF-16BE=188 [top UTF-16BE] + {{0x75,0x74,0x66,0x62,0x33,0x32,0x5f,0x5f, 0x30,0x81,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utfb32__" + // UTF-32BE=191 [top UTF-32BE] + {{0x75,0x74,0x66,0x69,0x38,0x35,0x39,0x31, 0x02,0x99,0xbd,0x21,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utfi8591" + // ASCII-7-bit=153 Latin1=189 CP1252=135 [top Latin1] + {{0x75,0x74,0x66,0x6c,0x31,0x36,0x5f,0x5f, 0x20,0x71,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utfl16__" + // UTF-16LE=191 [top UTF-16LE] + {{0x75,0x74,0x66,0x6c,0x33,0x32,0x5f,0x5f, 0x30,0x91,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utfl32__" + // UTF-32LE=191 [top UTF-32LE] + {{0x75,0x74,0x66,0x75,0x38,0x38,0x5f,0x5f, 0x30,0xb1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "utfu88__" + // X-UTF8UTF8=191 [top X-UTF8UTF8] + {{0x76,0x61,0x6c,0x75,0x5f,0x5f,0x5f,0x5f, 0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "valu____" + // Latin1=191 [top Latin1] + {{0x76,0x69,0x73,0x75,0x5f,0x5f,0x5f,0x5f, 0x01,0x84,0x10,0x81,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "visu____" + // ASCII-7-bit=132 Hebrew=190 [top Hebrew] + {{0x77,0x61,0x69,0x6e,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wain1250" + // CP1250=191 [top CP1250] + {{0x77,0x65,0x69,0x73,0x35,0x39,0x31,0x35, 0x02,0x9f,0x7d,0x21,0x84,0xa1,0xbc,0x00,0x00,0x00,0x00,0x00,}}, // "weis5915" + // ASCII-7-bit=159 Latin1=125 CP1252=132 ISO-8859-15=188 [top ISO-8859-15] + {{0x77,0x65,0x69,0x73,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "weis8591" + // Latin1=190 CP1252=126 [top Latin1] + {{0x77,0x65,0x73,0x74,0x31,0x32,0x35,0x32, 0x01,0x6f,0x31,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "west1252" + // ASCII-7-bit=111 CP1252=190 [top CP1252] + {{0x77,0x65,0x73,0x74,0x38,0x35,0x39,0x31, 0x02,0x79,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "west8591" + // ASCII-7-bit=121 Latin1=190 [top Latin1] + {{0x77,0x65,0x73,0x74,0x5f,0x5f,0x5f,0x5f, 0x02,0xa9,0x9d,0x21,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "west____" + // ASCII-7-bit=169 Latin1=157 CP1252=185 [top CP1252] + {{0x77,0x69,0x64,0x6e,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "widn1250" + // CP1250=191 [top CP1250] + {{0x77,0x69,0x64,0x6f,0x31,0x32,0x35,0x30, 0x01,0x7c,0xb1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wido1250" + // ASCII-7-bit=124 CP1250=190 [top CP1250] + {{0x77,0x69,0x64,0x6f,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wido1251" + // CP1251=191 [top CP1251] + {{0x77,0x69,0x64,0x6f,0x31,0x32,0x35,0x32, 0x11,0xa9,0x21,0xbb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wido1252" + // Latin1=169 CP1252=187 [top CP1252] + {{0x77,0x69,0x64,0x6f,0x31,0x32,0x35,0x36, 0xb1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wido1256" + // CP1256=191 [top CP1256] + {{0x77,0x69,0x6d,0x64,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wimd1251" + // CP1251=191 [top CP1251] + {{0x77,0x69,0x6e,0x5f,0x31,0x32,0x35,0x30, 0x01,0x8d,0xb1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_1250" + // ASCII-7-bit=141 CP1250=190 [top CP1250] + {{0x77,0x69,0x6e,0x5f,0x31,0x32,0x35,0x31, 0x01,0x8f,0x91,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_1251" + // ASCII-7-bit=143 CP1251=190 [top CP1251] + {{0x77,0x69,0x6e,0x5f,0x31,0x32,0x35,0x32, 0x02,0xac,0xa4,0x21,0xb6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_1252" + // ASCII-7-bit=172 Latin1=164 CP1252=182 [top CP1252] + {{0x77,0x69,0x6e,0x5f,0x31,0x32,0x35,0x33, 0x10,0x41,0x85,0x21,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_1253" + // Greek=133 CP1253=190 [top CP1253] + {{0x77,0x69,0x6e,0x5f,0x31,0x32,0x35,0x34, 0x01,0x6f,0xc1,0xaf,0x81,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_1254" + // ASCII-7-bit=111 Latin5=175 CP1254=185 [top CP1254] + {{0x77,0x69,0x6e,0x5f,0x31,0x32,0x35,0x35, 0x10,0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_1255" + // CP1255=191 [top CP1255] + {{0x77,0x69,0x6e,0x5f,0x31,0x32,0x35,0x36, 0x01,0x7f,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_1256" + // ASCII-7-bit=127 CP1256=190 [top CP1256] + {{0x77,0x69,0x6e,0x5f,0x31,0x32,0x35,0x37, 0x01,0x8c,0xf1,0xbe,0xc1,0x77,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_1257" + // ASCII-7-bit=140 CP1257=190 ISO-8859-13=119 [top CP1257] + {{0x77,0x69,0x6e,0x5f,0x38,0x37,0x34,0x5f, 0x01,0x56,0xd1,0xaf,0xd1,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_874_" + // ASCII-7-bit=86 ISO-8859-11=175 CP874=185 [top CP874] + {{0x77,0x69,0x6e,0x5f,0x5f,0x5f,0x5f,0x5f, 0x01,0x9a,0x91,0xbd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "win_____" + // ASCII-7-bit=154 CP1251=189 [top CP1251] + {{0x77,0x69,0x6e,0x63,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "winc1250" + // CP1250=191 [top CP1250] + {{0x77,0x69,0x6e,0x63,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "winc1251" + // CP1251=191 [top CP1251] + {{0x77,0x69,0x6e,0x64,0x31,0x32,0x33,0x34, 0xb1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind1234" + // CP1256=191 [top CP1256] + {{0x77,0x69,0x6e,0x64,0x31,0x32,0x35,0x30, 0x01,0x88,0xb1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind1250" + // ASCII-7-bit=136 CP1250=190 [top CP1250] + {{0x77,0x69,0x6e,0x64,0x31,0x32,0x35,0x31, 0x01,0x8b,0x91,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind1251" + // ASCII-7-bit=139 CP1251=190 [top CP1251] + {{0x77,0x69,0x6e,0x64,0x31,0x32,0x35,0x32, 0x02,0xa5,0xac,0x21,0xb6,0xa1,0x4f,0x00,0x00,0x00,0x00,0x00,}}, // "wind1252" + // ASCII-7-bit=165 Latin1=172 CP1252=182 ISO-8859-15=79 [top CP1252] + {{0x77,0x69,0x6e,0x64,0x31,0x32,0x35,0x33, 0x01,0x94,0x10,0x31,0xae,0x21,0xb8,0x00,0x00,0x00,0x00,0x00,}}, // "wind1253" + // ASCII-7-bit=148 Greek=174 CP1253=184 [top CP1253] + {{0x77,0x69,0x6e,0x64,0x31,0x32,0x35,0x34, 0x01,0x73,0xc1,0xaf,0x81,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind1254" + // ASCII-7-bit=115 Latin5=175 CP1254=185 [top CP1254] + {{0x77,0x69,0x6e,0x64,0x31,0x32,0x35,0x35, 0x01,0x86,0x10,0x01,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind1255" + // ASCII-7-bit=134 CP1255=190 [top CP1255] + {{0x77,0x69,0x6e,0x64,0x31,0x32,0x35,0x36, 0x01,0x74,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind1256" + // ASCII-7-bit=116 CP1256=190 [top CP1256] + {{0x77,0x69,0x6e,0x64,0x31,0x32,0x35,0x37, 0x01,0x87,0xf1,0xbe,0xc1,0x52,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind1257" + // ASCII-7-bit=135 CP1257=190 ISO-8859-13=82 [top CP1257] + {{0x77,0x69,0x6e,0x64,0x33,0x31,0x5f,0x5f, 0x01,0x62,0x51,0xbe,0x10,0x11,0x5e,0x00,0x00,0x00,0x00,0x00,}}, // "wind31__" + // ASCII-7-bit=98 SJS=190 CP932=94 [top SJS] + {{0x77,0x69,0x6e,0x64,0x38,0x34,0x37,0x5f, 0xe1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind847_" + // ISO-8859-11=191 [top ISO-8859-11] + {{0x77,0x69,0x6e,0x64,0x38,0x35,0x32,0x5f, 0x01,0x79,0x20,0x01,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind852_" + // ASCII-7-bit=121 CP852=190 [top CP852] + {{0x77,0x69,0x6e,0x64,0x38,0x35,0x39,0x31, 0x02,0x9a,0xbd,0x21,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind8591" + // ASCII-7-bit=154 Latin1=189 CP1252=137 [top Latin1] + {{0x77,0x69,0x6e,0x64,0x38,0x35,0x39,0x32, 0x01,0x83,0x81,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind8592" + // ASCII-7-bit=131 Latin2=190 [top Latin2] + {{0x77,0x69,0x6e,0x64,0x38,0x35,0x39,0x36, 0x01,0x6f,0x20,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind8596" + // ASCII-7-bit=111 Arabic=190 [top Arabic] + {{0x77,0x69,0x6e,0x64,0x38,0x35,0x39,0x37, 0x01,0x6f,0x10,0x31,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind8597" + // ASCII-7-bit=111 Greek=190 [top Greek] + {{0x77,0x69,0x6e,0x64,0x38,0x35,0x39,0x39, 0x01,0x6c,0xc1,0xbe,0x81,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind8599" + // ASCII-7-bit=108 Latin5=190 CP1254=108 [top Latin5] + {{0x77,0x69,0x6e,0x64,0x38,0x36,0x36,0x5f, 0x20,0x41,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind866_" + // CP866=191 [top CP866] + {{0x77,0x69,0x6e,0x64,0x38,0x37,0x34,0x5f, 0x01,0x8a,0xd1,0xbe,0xd1,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind874_" + // ASCII-7-bit=138 ISO-8859-11=190 CP874=125 [top ISO-8859-11] + {{0x77,0x69,0x6e,0x64,0x38,0x38,0x35,0x39, 0x02,0x97,0xb6,0x21,0xb1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind8859" + // ASCII-7-bit=151 Latin1=182 CP1252=177 [top Latin1] + {{0x77,0x69,0x6e,0x64,0x38,0x5f,0x5f,0x5f, 0x01,0x93,0x11,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind8___" + // ASCII-7-bit=147 UTF8=190 [top UTF8] + {{0x77,0x69,0x6e,0x64,0x39,0x33,0x32,0x5f, 0x01,0x7d,0x51,0xa4,0x10,0x11,0xbc,0x00,0x00,0x00,0x00,0x00,}}, // "wind932_" + // ASCII-7-bit=125 SJS=164 CP932=188 [top CP932] + {{0x77,0x69,0x6e,0x64,0x39,0x34,0x39,0x5f, 0x01,0x7b,0x41,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind949_" + // ASCII-7-bit=123 KSC=190 [top KSC] + {{0x77,0x69,0x6e,0x64,0x39,0x35,0x30,0x5f, 0x01,0x6f,0x71,0x7f,0x20,0x51,0xbe,0x00,0x00,0x00,0x00,0x00,}}, // "wind950_" + // ASCII-7-bit=111 BIG5=127 BIG5-CP950=190 [top BIG5-CP950] + {{0x77,0x69,0x6e,0x64,0x5f,0x5f,0x5f,0x5f, 0x01,0xb5,0x11,0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wind____" + // ASCII-7-bit=181 UTF8=180 [top ASCII-7-bit] + {{0x77,0x69,0x6e,0x65,0x31,0x32,0x35,0x32, 0x01,0x6f,0x31,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wine1252" + // ASCII-7-bit=111 CP1252=190 [top CP1252] + {{0x77,0x69,0x6e,0x6f,0x31,0x32,0x35,0x30, 0xc1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wino1250" + // CP1250=191 [top CP1250] + {{0x77,0x69,0x6e,0x6f,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wino1251" + // CP1251=191 [top CP1251] + {{0x77,0x69,0x6e,0x73,0x31,0x32,0x35,0x35, 0x10,0x11,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wins1255" + // CP1255=191 [top CP1255] + {{0x77,0x69,0x72,0x64,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wird1251" + // CP1251=191 [top CP1251] + {{0x77,0x69,0x73,0x6f,0x38,0x35,0x39,0x31, 0x11,0xbe,0x21,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wiso8591" + // Latin1=190 CP1252=127 [top Latin1] + {{0x77,0x6e,0x64,0x6f,0x31,0x32,0x35,0x31, 0xa1,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wndo1251" + // CP1251=191 [top CP1251] + {{0x77,0x6e,0x64,0x6f,0x31,0x32,0x35,0x36, 0x01,0x6e,0xa1,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wndo1256" + // ASCII-7-bit=110 CP1256=190 [top CP1256] + {{0x77,0x6f,0x6e,0x64,0x31,0x32,0x35,0x32, 0x41,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "wond1252" + // CP1252=191 [top CP1252] + {{0x77,0x6f,0x72,0x67,0x31,0x32,0x35,0x32, 0x01,0x83,0x31,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "worg1252" + // ASCII-7-bit=131 CP1252=190 [top CP1252] + {{0x79,0x65,0x73,0x5f,0x5f,0x5f,0x5f,0x5f, 0x02,0xbe,0x81,0x21,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "yes_____" + // ASCII-7-bit=190 Latin1=129 CP1252=139 [top ASCII-7-bit] + {{0x79,0x6b,0x74,0x63,0x5f,0x5f,0x5f,0x5f, 0x51,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "yktc____" + // KSC=191 [top KSC] + {{0x7a,0x73,0x6f,0x5f,0x38,0x35,0x39,0x31, 0x02,0x6f,0xbe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}}, // "zso_8591" + // ASCII-7-bit=111 Latin1=190 [top Latin1] +}; + +static const int kCharsetHintProbsSize = 438; + +static const uint8 kDefaultProb[NUM_RANKEDENCODING] = { // MaxRange 192 +177, 170, 156, 149, 150, 142, 140, 124, 130, 127, 124, 118, 127, 118, 109, 104, 98, 93, 96, 82, 84, 81, 80, 64, 61, 57, 53, 47, 42, 28, 24, 22, + 17, 0, 5, 1, 5, 12, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; + +static const int kMaxTldKey = 4; +static const int kMaxTldVector = 16; +static const int kMaxCharsetKey = 8; +static const int kMaxCharsetVector = 12; +static const int kMaxLangKey = 8; +static const int kMaxLangVector = 12; +// Smoothing percentage across encodings with same UTF-8 result: 100% + +static const UnigramEntry unigram_table[NUM_RANKEDENCODING] = { +{ // ASCII-7-bit (788.373M chars) [0] + {NULL, NULL, NULL, NULL}, + 77, 207, 29, 27, 255, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,189,189,0,0,189,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, +}, + +{ // Latin1 (1792.786M chars) [1] + {NULL, NULL, ced_hires_13, ced_hires_13, }, + 87, 217, 37, 20, 128, + {1,0,1,1,0,0,1,0, 0,9,9,0,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 186,137,105,112,140,106,126,145, 132,113,128,124,123,101,126,119, 141,113,107,116,129,113,113,143, 130,105,127,128,103,116,106,128, + 122,138,132,155,161,129,133,190, 124,152,124,119,117,144,120,121, 127,136,122,132,112,139,144,116, 113,101,117,117,145,120,135,114, + 121,138,107,125,163,129,131,190, 120,141,112,110,114,143,115,133, 124,135,126,131,118,141,160,110, 114,104,119,99,148,119,129,117, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 195,159,115,166,155,125,133,156, 130,168,156,159,121,135,150,133, 169,125,135,118,150,113,114,173, 126,107,176,178,97,131,103,170, + 165,209,166,183,211,198,182,194, 193,219,182,153,130,205,161,148, 160,187,142,208,169,167,210,131, 192,122,189,152,212,181,158,185, + 195,214,155,184,212,208,182,181, 183,213,171,154,161,215,150,137, 175,187,162,210,158,168,208,131, 192,156,189,142,199,193,155,120, + }, + {43,13,19,71,0,0,0,0, 0,145,153,0,0,165,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 226,142,175,92,109,120,168,161, 150,151,135,110,183,159,177,142, 146,163,159,149,146,144,137,136, 133,134,166,128,200,102,117,143, + 102,197,188,202,195,190,180,196, 185,179,172,189,202,198,215,195, 185,164,216,206,204,172,190,182, 158,170,181,119,107,136,114,132, + 134,194,189,198,192,189,178,194, 182,176,171,189,201,194,213,194, 181,151,213,203,201,171,189,182, 155,176,182,106,136,85,122,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 187,138,112,113,139,107,128,136, 133,137,118,120,118,129,135,123, 139,125,101,126,128,108,123,140, 131,107,125,133,123,119,104,138, + 133,128,130,187,160,126,123,145, 123,153,122,122,114,136,125,117, 153,141,127,129,107,167,144,114, 113,105,118,118,134,117,122,164, + 130,132,122,187,161,131,122,139, 122,137,119,120,113,138,123,110, 153,141,127,130,133,167,146,104, 117,105,130,109,131,117,133,119, + }, + {128,0,110,142,142,142,142,140, 0,0,142,142,142,142,142,142, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 22,0,2,2,2,2,2,2, 0,0,2,14,2,2,2,2, 46,0,2,14,2,2,2,2, 0,0,2,18,2,4,2,6, + 16,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 42,0,2,10,2,2,2,2, 0,0,2,2,2,2,2,2, + 18,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 38,0,2,6,2,2,2,2, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 164,0,136,164,110,108,108,106, 0,0,190,164,136,134,122,152, 158,0,144,156,112,116,106,106, 0,0,166,212,158,164,146,162, + 90,0,92,96,139,139,94,92, 0,0,148,166,184,176,134,146, 98,0,96,104,139,139,110,110, 0,0,138,172,174,190,154,164, + 130,0,138,126,38,48,135,135, 0,0,130,156,128,148,186,180, 120,0,126,120,48,56,139,141, 0,0,142,156,140,186,166,188, + }, +}, + +{ // UTF8 (16713.069M chars) [2] + {NULL, NULL, NULL, NULL}, + 169, 203, 42, 24, 131, + {197,207,201,202,188,181,180,180, 188,183,184,187,188,182,178,183, 181,179,172,178,182,182,183,183, 181,181,183,180,189,181,175,180, + 182,183,175,177,184,183,183,184, 187,176,181,181,178,186,187,184, 187,177,175,183,184,176,174,177, 196,183,188,186,194,184,180,181, + 0,0,183,211,189,187,147,104, 65,123,87,102,121,13,187,176, 216,203,118,108,88,134,124,193, 206,202,155,161,58,0,119,0, + 181,176,180,213,192,206,202,197, 192,187,165,177,183,170,90,182, 71,0,0,13,1,0,0,0, 0,0,0,0,0,0,0,0, + 119,115,120,96,114,98,104,106, 121,111,96,110,113,105,109,100, 109,107,92,112,112,97,91,102, 110,119,116,99,117,110,104,106, + 133,132,135,130,132,139,129,131, 133,127,121,126,132,128,121,138, 136,128,120,126,145,114,120,123, 132,124,128,122,138,120,117,132, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,64, + }, + {0,0,0,0,0,0,0,0, 0,109,143,0,0,144,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 189,125,169,73,68,107,151,137, 146,147,111,102,152,138,154,129, 142,152,148,137,131,132,127,127, 123,121,139,118,189,98,96,127, + 87,124,119,124,117,115,112,111, 114,127,109,102,114,120,120,114, 120,94,118,122,122,113,106,113, 95,99,88,117,109,125,97,107, + 80,139,113,146,112,126,103,99, 115,147,96,97,118,131,156,123, 132,80,111,140,146,136,107,102, 86,116,85,83,110,84,118,0, + 204,210,207,204,196,192,190,188, 194,187,191,189,194,188,179,187, 184,183,175,181,186,187,183,187, 184,189,185,186,191,184,178,186, + 192,196,179,183,192,185,183,198, 192,196,189,182,182,193,189,192, 199,194,188,195,190,194,185,185, 203,191,196,195,200,196,197,188, + 0,0,121,113,72,69,49,4, 0,0,0,71,0,0,113,107, 113,102,0,0,0,0,19,86, 134,132,91,105,0,0,0,0, + 174,140,150,207,185,199,194,190, 187,181,160,174,177,157,75,176, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 6,0,2,2,2,6,2,2, 0,0,0,0,50,38,2,128, 4,0,2,2,2,4,2,2, 0,0,0,0,54,40,2,128, + 4,0,2,2,2,6,2,2, 0,0,0,0,128,128,128,128, 2,0,2,2,2,2,2,2, 0,0,0,0,128,128,128,128, + 2,0,2,2,2,2,2,2, 0,0,0,0,128,128,128,128, 128,0,118,118,128,128,128,128, 0,0,0,0,128,128,64,128, + 176,0,168,172,172,172,162,164, 120,126,126,116,126,140,134,128, 168,0,170,166,172,170,174,176, 118,122,118,116,142,116,138,128, + 168,0,170,168,168,172,176,174, 110,120,114,112,136,142,140,128, 168,0,172,170,160,166,160,164, 120,126,118,116,140,134,136,128, + 0,0,0,0,0,0,0,0, 116,122,140,128,0,0,0,0, 0,0,0,0,0,0,0,0, 128,120,126,134,0,0,0,0, + 0,0,0,0,0,0,0,0, 134,132,120,126,0,0,0,0, 0,0,0,0,0,0,0,0, 116,152,138,116,0,0,0,0, + }, +}, + +{ // GB (9061.562M chars) [3] + {NULL, ced_hires_3, ced_hires_4, ced_hires_5, }, + 204, 189, 27, 16, 128, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,66,73, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 70,204,125,202,219,216,120,114, 118,156,113,85,96,78,81,79, 190,196,199,195,195,208,196,199, 196,203,195,200,201,197,193,195, + 193,195,190,195,195,183,196,191, 201,197,207,197,197,198,201,199, 201,191,203,201,198,196,202,200, 134,116,114,132,122,124,118,115, + 115,120,116,120,141,121,124,123, 121,120,121,113,125,116,117,110, 117,114,112,113,119,112,124,123, 84,74,83,78,69,83,77,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,93,66,68,84,3,51,0, 116,102,41,61,83,57,66,12, 70,85,73,66,54,64,44,68, 0,3,3,3,54,73,70,54, + 95,66,54,44,66,78,26,37, 57,41,3,57,13,2,0,0, 54,51,0,41,68,70,70,59, 41,70,41,13,0,64,59,80, + 12,3,51,12,13,26,41,3, 0,79,47,61,2,19,66,64, 37,37,13,93,54,13,54,51, 51,12,59,73,89,54,54,94, + }, + {101,14,0,0,0,0,0,0, 16,16,0,0,68,49,44,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 81,56,73,0,0,0,64,71, 49,49,0,84,53,69,60,32, 84,60,49,35,15,19,18,1, 2,0,15,0,92,29,0,0, + 83,69,66,85,103,49,69,51, 56,71,53,83,70,73,65,91, 71,59,61,71,80,77,72,79, 61,69,67,64,66,73,77,73, + 70,75,71,70,86,62,64,69, 71,66,39,69,73,64,74,75, 79,69,71,70,83,80,53,92, 69,66,59,69,69,85,90,3, + 94,72,77,73,64,67,62,71, 80,76,76,72,65,74,80,73, 77,93,79,99,84,69,81,94, 51,35,67,74,49,67,84,78, + 126,196,197,192,196,176,185,184, 195,185,196,194,198,187,184,191, 190,190,180,189,189,194,181,191, 182,191,188,196,189,191,187,192, + 186,174,192,193,203,190,193,194, 190,188,189,195,181,187,196,191, 200,178,184,186,189,186,192,180, 193,176,195,182,185,179,182,186, + 185,187,190,185,183,187,185,186, 177,190,189,192,187,187,181,180, 178,185,188,196,172,177,186,192, 192,182,197,186,178,187,185,0, + }, + {128,0,128,128,128,128,128,128, 128,128,104,128,114,124,128,118, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 46,0,46,50,32,40,40,34, 128,128,26,28,26,30,32,32, 42,0,42,44,26,34,34,28, 128,128,46,50,46,52,54,54, + 44,0,44,46,28,36,36,30, 128,128,48,50,46,52,56,54, 50,0,50,54,34,42,42,38, 128,128,50,52,50,56,58,58, + 128,0,128,128,128,128,128,128, 128,128,58,62,58,64,70,66, 128,0,128,128,128,128,128,128, 128,128,40,42,40,44,48,46, + 0,0,0,0,154,180,164,168, 188,176,128,106,122,124,134,92, 0,0,0,0,128,128,128,136, 128,128,132,130,130,132,130,130, + 0,0,0,0,242,218,218,232, 138,134,137,131,129,117,127,113, 0,0,0,0,202,206,218,216, 110,112,129,127,129,127,127,131, + 0,0,0,0,202,218,218,206, 114,106,122,126,126,128,130,132, 0,0,0,0,210,214,206,206, 120,114,124,128,126,136,122,126, + 0,0,0,0,206,208,200,202, 218,236,136,124,124,122,126,126, 230,194,200,214,190,198,194,216, 192,186,128,122,132,128,130,120, + }, +}, + +{ // CP1252 (408.280M chars) [4] + {NULL, NULL, ced_hires_13, ced_hires_13, }, + 89, 209, 40, 30, 128, + {116,114,130,121,123,133,113,118, 108,96,180,101,111,113,172,102, 63,68,105,82,59,104,73,70, 61,79,141,65,74,59,133,92, + 184,136,106,111,139,104,125,143, 132,111,126,123,121,100,125,118, 143,111,106,114,127,111,112,142, 128,104,127,127,102,114,106,126, + 120,172,132,158,159,131,136,188, 123,153,123,119,120,159,118,120, 127,136,121,131,136,137,143,117, 112,109,131,116,143,151,134,114, + 120,172,130,128,161,130,131,188, 120,143,112,109,119,159,114,131, 122,133,125,130,137,139,158,109, 114,108,131,98,146,151,128,116, + 169,126,98,99,143,148,118,105, 94,83,203,88,113,99,199,98, 95,134,176,160,158,170,169,143, 114,141,201,118,111,110,201,130, + 193,157,113,163,153,123,131,154, 127,166,153,157,119,132,148,131, 167,123,133,115,148,111,112,171, 124,105,174,176,96,128,101,168, + 163,207,164,180,208,196,180,192, 191,217,180,151,128,203,159,146, 158,185,140,206,167,165,207,128, 190,119,187,150,210,179,156,183, + 193,212,152,182,209,206,180,179, 181,211,168,151,159,213,148,135, 173,185,160,208,156,166,206,129, 190,153,187,139,197,191,153,118, + }, + {128,43,4,69,19,0,0,0, 0,146,153,0,0,165,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 226,141,174,92,108,119,170,160, 148,152,134,110,182,158,177,142, 147,162,157,147,145,143,136,135, 132,133,165,129,200,100,121,143, + 118,197,187,200,193,200,178,194, 183,191,170,191,201,196,214,194, 184,162,214,205,205,174,188,180, 157,168,179,122,110,135,115,131, + 133,196,189,196,191,201,176,192, 180,192,169,191,199,192,212,193, 182,149,211,202,203,175,187,180, 153,174,180,105,136,86,122,30, + 113,107,124,132,114,134,112,118, 113,93,171,97,104,105,166,96, 99,108,124,118,117,133,112,109, 102,129,171,117,112,107,166,135, + 183,137,111,110,137,105,126,133, 132,134,125,119,116,126,133,122, 144,123,99,123,127,108,120,139, 128,105,124,131,120,117,103,138, + 130,152,132,184,157,126,125,142, 124,153,120,120,118,183,123,115, 150,138,125,127,107,164,145,111, 111,103,118,117,132,116,120,161, + 130,157,121,184,158,129,123,136, 124,145,121,118,111,183,121,110, 150,139,124,127,130,164,143,101, 116,102,132,106,129,115,130,117, + }, + {32,0,2,24,2,2,2,2, 22,20,16,36,6,24,6,26, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 24,0,2,2,2,2,2,2, 2,2,2,16,2,2,2,4, 46,0,2,16,2,2,2,2, 6,6,2,20,2,6,2,10, + 14,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 38,0,2,6,2,2,2,2, 2,2,2,2,2,2,2,2, + 14,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 34,0,2,4,2,2,2,2, 2,2,2,2,2,2,2,2, + 130,0,106,124,140,126,112,112, 160,134,134,140,180,136,142,134, 134,0,132,126,86,84,140,128, 118,162,132,166,130,138,180,136, + 162,0,136,166,110,110,108,106, 118,138,192,162,130,136,116,152, 158,0,144,154,112,118,106,106, 148,164,166,210,152,164,138,164, + 88,0,92,96,139,141,94,92, 180,136,146,162,174,174,124,144, 98,0,96,104,139,139,110,112, 184,150,134,164,162,186,142,158, + 128,0,138,128,38,48,135,137, 130,178,128,152,118,146,176,178, 120,0,126,120,48,56,139,141, 136,180,140,150,130,184,156,184, + }, +}, + +{ // KSC (5258.976M chars) [5] + {NULL, ced_hires_6, ced_hires_7, ced_hires_8, }, + 203, 186, 27, 9, 128, + {71,109,117,106,108,109,104,107, 110,108,108,112,103,104,106,105, 102,108,101,103,104,107,99,103, 104,99,107,103,102,103,107,98, + 106,206,164,204,164,121,141,122, 146,119,136,130,120,90,91,81, 216,212,164,201,215,207,187,206, 213,208,207,204,210,209,205,216, + 225,214,178,201,188,198,199,213, 199,93,107,104,116,113,115,113, 108,107,109,113,110,97,99,104, 101,113,115,107,110,108,111,117, + 110,108,103,116,115,142,146,136, 118,134,125,131,144,112,112,126, 112,117,107,103,107,103,102,104, 101,114,109,104,105,93,0,0, + 52,0,0,60,0,1,0,0, 0,12,0,0,28,0,18,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,78,41,83,69,52,75,65, 1,50,60,76,0,62,88,58, 79,72,60,68,0,65,54,44, 72,58,78,86,46,82,73,48, + 57,67,58,67,72,57,60,86, 18,31,65,50,69,65,85,79, 52,57,54,34,54,0,41,38, 0,78,82,58,50,78,1,46, + 0,57,68,0,72,67,48,65, 48,41,31,107,18,67,63,0, 12,48,0,52,0,28,85,46, 82,67,44,48,48,1,0,0, + }, + {0,0,0,0,0,0,0,0, 0,44,71,0,0,61,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 117,80,77,0,0,0,66,63, 78,84,0,97,84,72,82,66, 4,74,65,78,51,54,50,9, 24,6,52,5,117,40,0,44, + 63,9,0,52,36,0,9,0, 0,0,0,24,48,0,51,51, 60,1,55,58,40,0,7,6, 59,8,0,81,54,73,75,73, + 57,2,57,35,48,28,1,2, 0,42,0,6,50,1,20,8, 38,0,0,32,57,0,4,2, 35,32,36,56,57,50,89,38, + 66,99,111,102,98,106,96,97, 95,99,98,96,98,104,96,95, 98,97,92,103,92,97,93,96, 95,96,104,97,94,93,92,91, + 157,208,188,195,195,184,194,180, 174,186,184,181,197,195,200,187, 193,181,186,192,167,192,186,169, 205,187,203,199,192,172,174,185, + 186,179,196,199,181,187,182,201, 179,175,184,177,204,183,204,207, 190,189,185,176,191,179,192,189, 182,200,194,190,178,181,182,187, + 177,176,199,166,189,187,186,198, 184,182,174,196,175,194,193,169, 178,186,174,191,161,176,204,191, 198,180,187,178,193,181,149,9, + }, + {128,0,128,128,128,128,128,128, 128,128,80,86,78,94,92,92, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 92,0,42,48,90,68,96,74, 128,128,44,44,42,48,48,50, 58,0,10,16,56,36,58,40, 128,128,42,44,40,46,48,48, + 66,0,18,26,66,44,66,50, 128,128,42,44,42,48,48,50, 128,0,128,128,128,128,128,128, 128,128,50,52,48,58,58,58, + 128,0,108,108,128,128,128,128, 128,128,40,40,38,44,44,46, 128,0,128,128,128,128,128,128, 128,128,54,56,50,60,58,60, + 0,0,0,0,186,204,190,182, 244,244,124,124,72,82,142,64, 0,0,0,0,164,206,174,184, 240,238,122,124,78,80,144,52, + 0,0,0,0,186,200,180,188, 142,140,147,131,99,107,101,91, 0,0,0,0,174,196,184,194, 112,114,125,127,127,125,133,129, + 0,0,0,0,196,204,194,204, 120,108,124,126,130,132,116,128, 0,0,0,0,0,0,0,0, 0,0,124,130,122,130,126,126, + 0,0,0,0,0,0,0,0, 0,0,144,130,102,108,110,110, 0,0,0,0,0,0,0,0, 0,0,126,130,124,124,130,126, + }, +}, + +{ // SJS (6339.756M chars) [6] + {NULL, NULL, NULL, NULL}, + 151, 136, 55, 16, 129, + {50,188,238,215,160,59,66,108, 192,200,192,194,200,199,202,200, 190,190,186,192,182,192,188,186, 101,96,109,95,94,95,102,113, + 84,100,117,108,117,135,81,77, 99,97,99,87,94,104,96,118, 120,115,111,101,96,105,108,108, 111,98,126,107,129,116,102,97, + 121,104,84,106,118,104,105,80, 97,98,110,102,121,108,114,99, 91,90,109,89,86,81,89,103, 106,103,118,100,101,114,121,115, + 114,112,106,111,106,104,109,112, 108,105,167,179,185,80,87,184, 83,79,20,45,22,55,39,0, 21,0,65,55,62,0,0,0, + 0,223,195,229,105,32,59,131, 61,180,189,185,180,185,191,185, 177,167,169,174,171,174,169,172, 163,80,84,78,90,80,80,85, + 59,108,81,89,100,121,105,17, 50,24,63,0,25,17,1,53, 95,61,66,50,0,31,31,81, 122,2,32,1,95,88,0,56, + 61,50,56,0,94,59,44,0, 38,84,50,0,106,63,0,18, 44,63,28,0,24,0,80,50, 56,88,38,24,1,93,98,91, + 113,91,95,105,97,102,91,93, 93,99,91,0,23,0,0,44, 0,76,0,0,7,42,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,15,79,0,0,65,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 113,69,98,19,0,8,69,67, 80,86,51,58,73,87,70,67, 54,73,78,62,54,54,44,46, 38,34,67,70,119,41,36,55, + 200,198,192,189,158,190,180,168, 171,181,178,171,176,161,191,184, 172,169,180,178,178,160,185,181, 191,169,175,200,180,158,184,172, + 177,159,190,176,163,179,174,191, 178,187,183,159,184,168,174,182, 179,167,178,179,178,180,188,176, 172,175,172,178,169,173,171,37, + 175,177,171,172,170,176,176,180, 168,182,188,188,179,179,172,172, 155,178,155,196,173,164,176,173, 162,162,164,156,168,174,177,175, + 179,175,195,159,185,163,180,172, 181,189,191,180,175,184,173,177, 166,185,174,185,165,192,178,192, 167,176,168,178,189,191,180,179, + 167,183,176,162,191,193,192,176, 191,193,177,160,203,189,170,166, 173,161,169,158,174,146,173,170, 162,160,175,166,189,175,165,174, + 186,163,175,177,160,176,185,183, 187,191,188,159,174,173,175,176, 193,187,161,164,151,172,158,144, 152,140,181,168,175,37,20,2, + }, + {46,0,6,6,2,2,2,2, 2,2,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 128,0,126,120,8,12,14,18, 34,38,30,30,26,42,32,42, 128,0,128,126,6,10,10,14, 38,42,34,34,30,46,36,46, + 128,0,128,128,10,14,16,20, 52,56,48,46,42,60,50,60, 128,0,128,128,12,16,18,22, 52,56,48,46,42,60,50,60, + 94,0,52,54,2,2,2,2, 32,38,28,28,24,40,30,40, 128,0,128,128,46,50,52,58, 82,88,78,78,72,94,80,90, + 0,0,0,0,140,140,138,138, 132,130,132,130,134,132,132,128, 0,0,0,0,134,142,142,142, 130,136,134,134,124,134,132,142, + 214,0,248,242,110,114,102,98, 152,140,134,122,120,120,88,72, 182,0,226,234,144,134,80,86, 136,114,134,134,126,154,96,86, + 178,0,234,228,102,112,100,108, 140,126,126,128,112,160,72,74, 180,0,232,230,100,114,108,110, 138,130,120,146,128,142,50,56, + 0,0,0,0,134,146,130,142, 138,144,128,148,64,80,66,78, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, +}, + +{ // EUC-JP (4368.914M chars) [7] + {NULL, ced_hires_0, ced_hires_1, ced_hires_2, }, + 202, 178, 27, 15, 128, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,173,100, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,228,186,180,229,225,122,123, 168,7,2,28,62,133,86,74, 195,190,202,195,193,195,191,198, 201,199,199,204,200,197,198,200, + 200,193,197,196,192,199,202,195, 189,196,201,190,197,197,191,183, 120,107,102,109,112,111,101,113, 107,110,96,107,105,115,111,124, + 116,109,107,105,105,141,147,137, 110,140,100,120,146,102,103,102, 105,112,105,133,84,0,0,0, 0,54,7,43,73,0,9,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {146,59,0,0,61,22,13,0, 60,71,0,0,80,26,61,28, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 83,27,41,0,46,51,35,0, 49,37,24,68,35,38,32,13, 131,42,28,35,34,12,0,0, 63,21,33,0,74,25,11,68, + 61,0,0,0,68,11,0,0, 31,1,1,0,39,0,101,78, 61,83,87,94,79,39,85,70, 76,64,19,86,75,87,77,75, + 72,46,73,78,49,96,75,69, 60,49,27,69,85,65,60,49, 74,36,61,72,76,65,80,67, 67,77,74,64,73,63,88,36, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 164,202,199,199,199,177,202,190, 185,187,195,193,192,191,183,196, 192,181,174,190,182,189,177,195, 190,197,177,183,211,189,184,194, + 186,192,177,195,187,176,192,194, 198,186,201,196,186,188,198,191, 190,186,182,176,189,182,193,190, 188,181,187,183,189,177,189,189, + 180,185,188,180,184,187,184,191, 191,188,197,192,194,179,192,186, 182,187,188,200,180,176,184,190, 174,170,179,160,193,182,193,31, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,44,8,34,20,28,28, 0,0,0,0,0,0,0,0, 2,0,56,14,40,28,34,34, 0,0,0,0,0,0,0,0, + 2,0,60,16,42,30,36,38, 0,0,0,0,0,0,0,0, 92,0,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 70,0,128,88,128,128,128,128, 0,0,0,0,0,0,0,0, 102,0,128,120,128,128,128,128, 0,0,0,0,0,0,0,0, + 0,0,146,186,190,162,182,180, 178,180,134,130,124,136,18,30, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 246,0,174,232,204,218,212,204, 0,0,131,131,129,123,123,117, 250,0,190,230,210,212,216,214, 0,0,125,121,125,131,131,133, + 250,0,192,232,204,216,202,214, 0,0,120,126,124,128,128,132, 244,0,172,236,206,224,218,216, 0,0,126,128,124,130,124,128, + 246,0,202,232,208,214,212,210, 0,0,144,110,104,110,108,108, 238,0,210,224,196,224,210,208, 0,0,118,114,104,116,104,152, + }, +}, + +{ // BIG5 (2431.102M chars) [8] + {NULL, NULL, NULL, NULL}, + 157, 174, 62, 10, 129, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,70,70, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,182,164,130,214,207,204,195, 202,198,207,192,194,201,196,187, 202,189,195,196,188,194,190,181, 194,188,192,185,188,188,191,185, + 184,179,185,186,180,189,110,108, 94,123,111,121,108,113,105,112, 116,103,101,106,110,102,114,99, 88,91,120,98,95,107,108,94, + 113,93,95,93,94,131,139,129, 121,130,93,111,138,87,98,87, 90,89,97,92,97,92,92,96, 102,147,84,82,84,87,88,107, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,216,162,127,212,204,205,192, 184,187,189,191,193,185,187,179, 188,190,183,192,177,189,189,198, 181,189,172,184,183,180,173,165, + 177,175,172,174,167,176,167,100, 42,127,129,92,89,80,107,94, 90,84,93,108,107,102,93,84, 105,100,83,90,94,79,92,95, + 84,84,90,92,77,89,103,113, 89,87,81,74,82,87,92,56, 77,96,70,88,72,107,102,81, 90,70,90,80,91,56,42,19, + }, + {90,0,0,0,0,0,0,0, 0,0,0,0,0,4,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 77,44,72,0,0,0,44,0, 53,54,4,69,21,39,51,1, 78,36,31,5,0,4,0,0, 0,0,5,0,85,0,0,0, + 200,201,188,193,189,168,184,189, 192,178,176,174,183,184,182,191, 186,180,173,170,180,184,162,188, 182,171,166,172,168,185,178,176, + 173,183,178,161,180,180,169,177, 177,186,185,178,177,170,187,186, 184,188,165,193,177,186,185,182, 179,178,178,175,185,176,192,2, + 51,0,0,0,0,0,0,0, 0,0,0,19,0,0,0,14, 52,0,0,0,3,17,19,1, 0,0,0,0,0,0,0,0, + 157,190,169,191,185,175,165,184, 179,175,174,184,175,175,167,166, 181,177,178,189,170,179,183,169, 182,186,200,181,167,183,169,167, + 184,179,171,169,182,173,187,181, 182,184,182,175,183,177,188,186, 186,187,182,194,163,176,175,182, 180,172,184,181,179,176,173,180, + 175,175,178,172,178,181,187,170, 177,191,189,178,186,179,167,176, 165,169,173,182,190,175,181,181, 187,183,185,177,183,178,177,107, + }, + {128,0,128,128,72,86,86,80, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 48,0,42,44,2,2,2,2, 80,76,2,2,2,2,2,2, 54,0,52,52,2,2,2,2, 96,96,2,2,2,2,2,2, + 74,0,76,72,2,2,2,2, 128,128,2,2,2,2,2,2, 128,0,128,128,8,18,18,14, 128,128,28,26,26,26,26,28, + 128,0,128,128,2,4,4,2, 128,128,34,30,30,30,32,32, 128,0,128,128,4,14,12,10, 128,128,38,34,34,34,36,36, + 0,0,0,0,160,160,160,166, 0,0,160,122,152,116,140,114, 0,0,0,0,150,150,150,148, 0,0,148,150,150,150,150,148, + 0,0,0,0,142,138,138,134, 0,0,136,138,134,134,136,134, 0,0,0,0,132,138,142,146, 0,0,136,130,138,138,134,136, + 0,0,0,0,136,146,134,142, 0,0,126,134,134,130,144,140, 0,0,0,0,136,138,138,144, 0,0,142,144,128,136,130,124, + 0,0,0,0,144,140,134,134, 0,0,160,126,108,102,108,106, 224,128,202,216,130,148,132,136, 204,204,126,118,114,144,122,150, + }, +}, + +{ // Latin2 (315.882M chars) [9] + {NULL, NULL, ced_hires_14, ced_hires_14, }, + 90, 204, 45, 27, 127, + {0,0,0,0,0,0,0,0, 0,13,13,0,0,13,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 176,178,79,184,121,96,188,129, 119,153,115,86,132,84,143,152, 125,178,73,182,114,95,188,79, 117,152,115,86,133,93,141,152, + 89,170,119,130,151,109,85,137, 171,147,170,100,153,155,102,118, 87,92,116,171,110,99,128,101, 181,128,158,80,133,126,117,98, + 90,170,94,124,153,103,95,127, 169,141,170,94,155,155,99,117, 81,92,116,171,113,99,148,82, 180,129,154,79,137,126,117,81, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 185,202,72,207,144,140,210,145, 119,178,153,122,170,124,172,196, 158,217,79,211,140,141,210,120, 115,176,151,152,187,124,173,200, + 97,198,155,156,200,127,165,183, 202,208,195,143,194,195,151,143, 149,174,157,197,159,157,199,120, 192,171,178,136,201,170,155,174, + 102,203,144,173,201,101,197,171, 203,203,208,143,202,204,139,150, 148,188,166,199,147,166,197,121, 192,191,178,144,189,182,155,121, + }, + {65,0,0,0,0,0,0,0, 0,129,154,0,0,162,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 228,154,181,85,87,110,164,158, 144,155,125,102,191,153,189,148, 131,145,140,130,127,125,117,115, 113,114,177,135,201,88,123,155, + 81,200,180,210,197,203,168,188, 175,191,170,190,200,190,208,194, 182,141,204,199,200,181,182,186, 146,188,181,102,112,126,100,120, + 110,200,181,209,196,205,167,186, 172,191,169,190,200,189,207,194, 180,135,203,198,199,182,181,191, 143,189,181,91,125,72,102,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 176,176,79,167,122,89,163,118, 119,144,100,124,140,114,142,179, 121,178,71,168,109,88,163,67, 117,144,103,124,140,102,142,179, + 91,160,116,126,149,84,190,132, 166,138,143,91,83,185,105,126, 81,118,127,168,91,58,130,99, 171,124,126,82,122,95,120,153, + 93,161,107,127,150,87,190,124, 167,128,145,91,82,185,102,129, 83,119,127,170,121,59,134,85, 172,125,112,80,118,93,120,85, + }, + {132,0,128,156,156,156,156,154, 0,0,156,156,156,156,156,156, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 10,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 14,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 24,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 24,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 24,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 24,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 132,0,98,130,142,136,102,114, 0,0,172,130,168,162,108,142, 130,0,136,132,52,54,136,130, 0,0,108,174,82,90,170,166, + 98,0,90,98,141,143,100,90, 0,0,164,118,170,178,130,128, 100,0,92,100,139,143,108,110, 0,0,166,92,174,156,128,142, + 134,0,136,134,36,54,135,135, 0,0,114,168,90,144,168,180, 130,0,130,134,40,56,137,141, 0,0,102,170,80,158,172,156, + }, +}, + +{ // CP1251 (2609.249M chars) [10] + {NULL, NULL, ced_hires_10, ced_hires_10, }, + 190, 219, 69, 19, 128, + {61,54,71,50,88,0,0,0, 0,0,73,0,84,68,72,51, 56,82,97,103,74,0,0,0, 0,0,69,0,81,63,70,32, + 175,85,84,108,0,54,0,0, 121,94,119,0,0,89,99,124, 0,0,150,148,47,70,0,0, 121,0,117,0,105,2,0,124, + 203,190,201,189,197,200,175,191, 205,172,201,198,196,207,207,203, 205,207,204,187,179,172,176,183, 172,169,147,176,170,168,160,171, + 201,185,197,186,194,200,174,188, 203,172,197,197,192,205,205,197, 203,204,203,185,172,167,174,181, 170,169,147,176,170,161,157,169, + 31,0,88,0,134,0,0,0, 85,0,28,0,0,0,5,0, 0,100,141,125,124,0,0,0, 1,0,16,0,11,11,33,0, + 184,2,95,21,0,6,0,0, 87,157,63,0,0,123,138,72, 0,0,102,143,7,102,0,0, 126,0,110,0,84,0,0,130, + 157,125,161,130,131,135,111,123, 148,122,140,123,137,137,153,133, 131,147,134,135,118,122,118,114, 110,103,83,118,114,116,116,143, + 193,147,189,166,165,195,131,156, 199,187,178,167,181,169,190,141, 170,175,180,173,120,175,145,137, 140,111,88,180,182,106,164,193, + }, + {0,0,0,0,0,0,0,0, 0,123,152,0,0,158,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 223,147,180,67,83,115,163,151, 135,154,99,111,188,166,187,138, 128,140,138,123,122,123,115,111, 108,109,171,133,198,101,111,143, + 134,133,114,124,118,126,111,112, 113,129,111,108,118,121,114,117, 124,83,116,126,121,108,110,114, 76,103,91,97,102,121,55,113, + 81,143,106,111,119,137,102,102, 116,138,96,102,116,118,119,128, 122,71,118,150,131,126,116,96, 72,98,99,47,123,70,85,0, + 48,44,53,47,0,85,0,0, 0,0,66,0,81,17,64,0, 50,75,98,66,98,71,62,54, 0,60,67,96,81,29,65,16, + 175,84,89,98,74,0,54,89, 125,68,109,58,57,85,81,121, 74,34,155,158,0,74,29,81, 128,29,110,103,98,0,0,121, + 210,181,193,178,187,209,169,174, 206,177,192,194,187,202,211,177, 199,195,203,188,160,171,169,173, 162,156,142,188,185,132,168,185, + 213,184,195,179,188,212,171,176, 208,178,193,197,188,203,215,181, 203,197,205,192,162,172,170,174, 162,157,150,190,185,141,170,186, + }, + {128,0,52,78,128,128,128,128, 128,128,74,82,12,26,10,22, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 42,0,2,6,48,58,46,48, 106,84,22,28,2,2,2,2, 56,0,2,20,64,76,62,64, 128,128,56,64,2,8,2,6, + 2,0,2,2,2,2,2,2, 128,110,26,34,2,2,2,2, 2,0,2,2,2,6,2,2, 128,128,42,50,2,2,2,2, + 2,0,2,2,2,2,2,2, 66,44,2,2,2,2,2,2, 2,0,2,2,2,8,2,2, 80,56,2,4,2,2,2,2, + 130,0,112,138,218,228,196,188, 184,166,182,184,138,132,110,112, 144,0,134,138,190,188,202,204, 196,226,158,170,124,124,124,126, + 174,0,136,170,182,184,172,174, 168,194,204,146,106,102,84,84, 154,0,152,148,150,166,162,138, 158,178,156,166,124,128,130,130, + 146,0,152,154,166,162,144,134, 134,86,98,126,139,139,112,110, 148,0,150,162,176,170,154,134, 130,104,96,128,139,141,112,108, + 150,0,154,148,132,128,120,110, 122,130,92,130,6,4,139,139, 150,0,154,152,96,132,122,106, 124,124,82,130,6,2,139,141, + }, +}, + +{ // CP1256 (4291.965M chars) [11] + {NULL, NULL, NULL, NULL}, + 175, 213, 75, 16, 129, + {89,120,82,85,70,119,81,87, 78,57,0,61,52,107,87,0, 120,88,122,83,73,125,94,89, 114,96,1,85,34,116,73,0, + 173,142,76,85,128,71,110,132, 117,107,30,127,106,73,102,99, 133,84,73,90,108,82,96,130, 115,70,110,116,69,78,76,146, + 37,143,167,196,136,188,168,229, 204,148,208,168,191,193,183,197, 170,203,175,195,189,190,178,101, 181,157,204,175,195,197,193,197, + 97,209,116,216,198,191,209,110, 85,125,90,85,128,210,82,85, 126,99,116,154,99,137,142,85, 146,71,143,75,117,89,124,44, + 157,89,85,86,132,136,106,93, 83,69,0,77,102,72,53,0, 66,103,144,128,127,138,137,111, 67,109,0,87,78,86,35,10, + 182,172,102,152,141,111,120,142, 116,155,25,145,107,121,136,120, 155,111,121,104,137,100,101,159, 112,93,117,165,83,117,88,152, + 26,167,114,129,77,84,119,189, 178,200,192,163,167,160,159,182, 136,190,152,168,143,156,162,117, 154,133,178,121,152,172,165,172, + 181,188,141,190,186,184,180,168, 169,200,157,140,190,187,136,123, 149,117,121,139,145,135,137,118, 122,142,125,128,186,100,134,77, + }, + {116,3,1,0,0,0,0,0, 0,134,143,0,0,157,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 228,134,177,78,100,111,160,151, 140,149,130,106,178,144,169,141, 137,152,147,136,134,132,126,124, 121,123,169,107,200,102,108,114, + 99,132,117,131,120,127,115,113, 116,121,112,109,121,123,118,119, 123,94,122,129,129,117,115,119, 115,108,101,110,97,133,114,122, + 120,160,152,167,156,164,144,156, 150,149,124,140,162,163,170,153, 151,130,177,173,168,136,148,104, 122,130,139,80,126,96,114,0, + 97,97,88,86,83,119,83,85, 98,64,79,60,61,80,88,47, 115,91,101,80,93,122,92,91, 105,117,46,102,80,115,80,37, + 173,163,81,85,125,72,114,122, 119,118,106,104,102,81,117,107, 133,87,73,88,113,82,96,129, 115,78,124,125,69,76,76,152, + 36,168,139,171,153,157,172,218, 198,200,201,168,187,192,186,204, 174,209,179,200,190,181,185,101, 182,157,199,169,196,190,195,192, + 104,226,105,204,209,198,208,118, 101,130,101,80,174,214,92,83, 163,120,130,171,118,155,158,79, 156,70,154,80,108,87,119,81, + }, + {90,0,18,44,128,128,54,56, 102,84,40,60,2,2,2,34, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 42,0,2,2,48,48,10,14, 62,48,10,28,2,2,2,2, 62,0,2,22,72,74,30,34, 80,62,22,42,2,2,2,16, + 2,0,2,2,2,2,2,2, 36,24,2,6,2,2,2,2, 2,0,2,2,2,2,2,2, 48,34,2,16,2,2,2,2, + 2,0,2,2,2,2,2,2, 30,18,2,2,2,2,2,2, 48,0,2,8,54,56,16,20, 64,52,12,30,2,2,2,4, + 178,0,138,160,188,202,138,136, 246,218,168,188,116,124,126,114, 160,0,142,144,184,174,160,162, 212,248,162,204,118,126,126,120, + 168,0,140,164,178,172,140,138, 162,176,200,170,106,100,92,136, 172,0,144,162,174,166,138,138, 212,212,170,220,92,90,90,122, + 142,0,150,150,92,128,44,72, 114,114,114,108,128,130,134,130, 142,0,150,148,114,142,74,80, 126,116,112,110,134,132,130,132, + 140,0,148,142,112,124,154,154, 120,132,116,116,134,132,128,132, 140,0,132,132,126,136,172,174, 158,152,148,140,132,130,128,164, + }, +}, + +{ // CP1250 (456.295M chars) [12] + {NULL, NULL, ced_hires_15, ced_hires_15, }, + 90, 207, 44, 30, 128, + {106,94,109,3,114,124,102,101, 0,71,177,95,143,118,167,98, 48,59,96,73,40,99,64,61, 0,67,141,59,108,83,130,60, + 178,82,81,175,131,134,115,136, 125,101,117,114,114,90,115,134, 133,104,75,173,117,99,105,135, 120,134,117,119,129,95,129,131, + 94,177,121,140,156,127,86,139, 173,151,161,106,170,163,105,122, 92,104,118,172,129,101,131,105, 183,159,162,83,135,145,120,103, + 95,177,123,127,157,116,103,130, 171,145,162,96,170,163,102,121, 83,93,119,172,131,103,150,86, 182,159,158,82,139,145,119,83, + 162,120,91,35,137,141,111,98, 13,75,196,81,168,151,193,131, 88,128,169,153,152,163,162,136, 10,134,194,112,166,184,194,139, + 187,92,75,209,146,163,125,147, 121,160,155,150,112,126,141,198, 160,116,81,213,142,104,106,164, 117,176,153,170,170,126,171,202, + 99,200,157,158,202,129,167,185, 204,210,197,145,196,197,153,145, 151,176,159,199,161,159,201,122, 194,173,180,138,203,172,157,176, + 104,205,146,175,203,103,199,173, 205,205,211,145,204,206,141,152, 150,191,168,201,150,168,199,123, 194,193,180,146,191,184,157,123, + }, + {122,0,0,0,0,0,0,0, 0,143,154,0,0,165,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 227,153,180,86,97,112,169,159, 147,157,128,106,190,155,189,149, 138,150,147,134,133,129,124,123, 120,121,178,134,203,92,128,154, + 110,204,183,200,193,208,171,187, 178,196,172,193,197,190,210,197, 183,143,205,201,201,184,184,176, 150,190,178,114,114,132,107,122, + 115,204,184,198,191,209,169,185, 175,197,172,193,196,187,209,197, 181,137,202,200,201,186,184,176, 145,192,178,94,130,77,114,0, + 105,89,105,77,114,127,87,104, 65,77,167,87,121,154,174,103, 85,93,106,115,112,126,100,99, 71,123,167,110,121,155,174,104, + 177,116,81,166,127,131,117,124, 123,122,102,105,107,115,124,164, 136,109,72,166,119,93,103,132, 119,133,104,122,116,103,122,164, + 93,165,121,130,150,102,158,134, 169,143,144,96,85,190,109,129, 88,98,136,169,98,62,135,101, 172,130,135,83,124,100,121,154, + 95,167,111,128,151,90,158,126, 170,139,146,91,84,191,105,135, 89,99,137,172,123,63,135,88, 173,130,131,81,120,97,121,86, + }, + {28,0,2,18,2,2,2,2, 14,14,14,22,4,16,2,16, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 22,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 32,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 16,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 18,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 16,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 18,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 130,0,104,120,140,130,110,116, 162,132,114,116,180,146,140,112, 134,0,136,128,84,84,138,128, 108,162,124,148,120,118,180,146, + 140,0,112,138,140,134,98,104, 108,128,184,142,144,178,120,158, 136,0,132,138,94,84,138,132, 116,142,142,178,124,144,154,188, + 94,0,90,96,141,143,100,90, 180,114,154,138,170,172,130,124, 96,0,94,98,139,143,108,112, 170,106,170,116,174,152,128,136, + 130,0,138,132,36,52,135,135, 114,180,122,162,92,140,170,174, 128,0,130,132,40,56,137,141, 94,170,112,180,80,154,172,150, + }, +}, + +{ // Latin5 (322.539M chars) [13] + {NULL, NULL, ced_hires_18, ced_hires_18, }, + 96, 232, 51, 21, 128, + {20,0,20,20,20,20,20,20, 20,37,37,20,20,16,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 174,125,94,100,128,93,114,133, 120,100,115,113,111,97,114,106, 129,100,95,102,119,100,101,130, 117,91,117,117,87,95,93,116, + 109,114,123,142,149,117,104,183, 111,140,112,106,104,116,108,107, 147,123,109,109,99,127,169,104, 100,88,100,105,175,189,165,102, + 108,113,104,109,151,116,97,192, 108,128,102,97,101,120,103,120, 178,123,114,107,105,128,165,98, 101,92,102,87,175,201,186,105, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 183,147,103,153,143,113,121,144, 117,156,143,147,109,122,138,121, 157,113,123,105,138,101,102,161, 114,95,164,166,85,118,91,158, + 153,197,154,170,198,186,170,182, 181,207,170,141,118,193,149,136, 201,175,130,196,157,155,197,118, 180,109,177,140,200,218,211,173, + 183,202,142,172,199,196,170,169, 171,201,158,141,149,203,138,125, 202,175,150,198,146,156,196,119, 180,143,177,129,187,238,211,108, + }, + {50,6,11,57,0,0,0,0, 0,144,149,0,0,164,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 226,146,185,81,100,113,168,166, 142,154,126,112,190,161,183,145, 134,151,147,137,134,132,126,124, 121,122,176,137,206,105,128,149, + 92,194,178,190,185,190,170,185, 176,197,160,189,202,193,206,184, 174,152,207,197,198,181,179,170, 146,175,180,111,108,128,102,138, + 127,196,180,195,187,192,172,183, 173,199,158,205,212,204,220,183, 177,140,211,202,199,186,178,170, 143,189,200,94,140,80,111,5, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 175,126,100,100,127,94,116,124, 121,125,106,108,106,120,123,111, 127,113,88,113,118,96,111,128, 119,95,113,121,111,107,92,126, + 118,110,119,175,148,113,108,168, 110,141,110,109,101,124,114,104, 171,129,114,115,94,154,141,101, 100,92,102,106,132,171,177,152, + 114,115,112,174,149,118,107,171, 109,124,108,108,100,125,114,97, 190,129,114,113,120,155,143,91, 105,92,113,100,137,200,199,107, + }, + {130,0,102,144,144,142,108,138, 0,0,154,154,154,154,154,154, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 36,0,2,2,2,2,2,2, 0,0,14,38,8,2,8,2, 62,0,2,22,2,10,2,4, 0,0,20,44,12,6,12,2, + 26,0,2,2,2,2,2,2, 0,0,2,4,2,2,2,2, 14,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 20,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 4,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 164,0,136,160,116,116,104,106, 0,0,202,178,144,126,130,118, 160,0,142,150,118,124,102,106, 0,0,180,246,168,156,154,124, + 90,0,92,92,145,147,90,92, 0,0,156,176,188,168,138,134, 112,0,112,116,141,141,114,116, 0,0,110,138,166,180,166,148, + 132,0,138,122,44,54,131,135, 0,0,130,156,124,128,182,162, 128,0,132,132,50,60,135,133, 0,0,112,120,100,130,142,168, + }, +}, + +{ // ISO-8859-11 (489.481M chars) [14] + {NULL, NULL, NULL, NULL}, + 184, 198, 48, 20, 127, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 175,209,195,88,202,83,128,203, 192,152,191,169,88,166,132,138, 156,134,149,172,200,200,176,200, 176,211,199,194,179,150,192,164, + 175,205,201,213,136,199,75,202, 176,173,203,200,140,209,144,123, 197,203,215,179,198,198,169,189, 190,187,93,39,18,43,4,72, + 210,196,186,186,192,106,151,183, 207,206,151,138,179,120,113,126, 122,127,132,111,120,111,102,99, 96,94,33,88,83,68,64,77, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 184,175,143,82,159,80,91,182, 155,114,141,116,87,135,98,96, 126,88,93,153,172,160,139,156, 134,188,176,156,101,92,163,122, + 113,183,179,173,84,159,74,169, 155,135,151,108,92,170,98,140, 166,90,180,144,149,166,80,79, 133,137,84,1,4,52,40,119, + 116,99,97,96,100,92,161,101, 174,168,108,110,179,87,92,109, 117,117,114,109,105,106,99,96, 94,95,20,89,93,21,54,98, + }, + {70,0,0,46,0,0,0,0, 0,136,148,0,0,160,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 207,129,181,82,82,93,164,157, 152,152,114,111,166,150,188,146, 128,141,136,126,124,123,115,111, 109,109,165,100,202,96,118,126, + 79,118,108,118,109,116,106,106, 104,104,108,101,111,116,105,100, 115,76,111,119,110,92,99,104, 73,98,81,125,114,120,90,106, + 61,105,100,99,109,106,92,82, 92,104,93,95,95,106,105,107, 114,58,104,111,104,93,100,89, 80,71,96,55,132,63,99,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 175,206,190,91,199,78,140,206, 190,148,188,166,92,168,152,144, 148,139,143,179,199,196,177,200, 172,213,199,192,172,143,191,162, + 175,208,201,213,153,202,62,203, 176,170,200,196,121,209,145,145, 194,206,218,188,201,202,172,189, 193,191,94,64,59,63,57,74, + 203,186,178,183,187,119,161,181, 208,206,150,139,187,118,121,123, 127,115,118,111,108,125,108,109, 106,112,71,99,90,69,77,91, + }, + {128,0,148,148,148,148,148,148, 0,0,148,148,148,148,148,148, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,8,8,16,14, 0,0,2,2,2,2,2,36, 2,0,2,2,4,4,14,10, 0,0,2,2,2,2,2,34, + 2,0,2,2,2,2,8,4, 0,0,2,2,2,2,2,32, 2,0,2,2,4,4,14,10, 0,0,2,2,2,2,2,44, + 2,0,2,2,6,6,14,10, 0,0,2,2,2,2,2,42, 68,0,20,30,128,126,128,112, 0,0,16,12,6,8,14,128, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 166,0,158,164,182,174,180,178, 0,0,126,118,128,132,130,78, 158,0,162,160,132,152,142,144, 0,0,120,122,126,134,130,92, + 158,0,162,160,128,160,132,146, 0,0,126,126,124,134,128,90, 166,0,162,160,142,146,146,156, 0,0,134,134,128,68,132,84, + 162,0,162,160,138,154,148,150, 0,0,130,134,132,114,112,128, 158,0,164,148,196,208,204,216, 0,0,84,76,64,52,134,254, + }, +}, + +{ // ISO-8859-15 (27.581M chars) [15] + {NULL, NULL, ced_hires_21, ced_hires_21, }, + 86, 217, 37, 21, 127, + {0,0,0,0,0,0,0,0, 0,85,85,0,0,85,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 187,137,107,112,127,105,104,142, 106,111,127,124,123,101,126,118, 133,112,107,116,117,113,113,142, 111,105,127,127,92,89,91,126, + 121,138,130,159,161,129,133,190, 123,152,123,118,116,144,119,121, 126,135,122,132,111,139,144,115, 113,103,117,117,145,120,135,114, + 121,137,113,131,163,128,131,190, 121,141,112,111,114,143,115,133, 123,135,125,131,110,140,160,110, 114,105,118,101,148,119,129,118, + 0,0,0,0,0,0,0,0, 0,34,33,0,0,33,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 195,159,116,166,180,125,125,156, 145,168,155,159,121,135,150,134, 169,125,135,118,145,114,115,173, 125,108,176,178,138,141,110,170, + 165,209,166,183,211,198,182,194, 193,219,182,153,130,205,161,148, 160,187,142,208,169,167,209,131, 192,122,189,152,212,181,158,185, + 195,214,155,184,212,208,182,181, 183,213,170,154,161,215,150,137, 175,187,162,210,158,168,208,131, 192,156,189,142,199,193,155,120, + }, + {23,0,0,70,0,0,0,0, 0,145,155,0,0,165,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 226,142,175,96,115,116,169,162, 150,154,125,112,184,159,177,144, 147,165,159,150,148,149,139,138, 134,136,166,128,201,103,116,143, + 104,197,188,202,195,190,180,196, 185,179,172,189,202,198,215,195, 185,164,216,206,204,173,190,182, 158,170,181,116,107,135,114,133, + 130,194,189,197,192,189,178,194, 182,176,171,189,201,194,213,194, 181,151,213,203,201,172,189,182, 155,176,182,107,136,90,117,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 187,138,113,113,149,107,108,134, 123,135,117,120,118,129,131,122, 135,125,101,126,120,109,123,140, 113,107,124,133,118,119,101,138, + 132,128,129,187,160,126,122,145, 123,152,121,121,113,136,125,116, 152,141,127,129,106,167,144,114, 113,104,118,117,134,117,122,164, + 130,132,121,187,161,130,119,138, 122,137,119,120,112,137,123,109, 153,141,126,130,124,167,145,104, 116,104,130,109,131,116,130,120, + }, + {178,0,128,156,122,126,124,128, 0,0,168,202,168,202,168,202, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 22,0,2,2,2,2,2,2, 0,0,2,14,2,2,2,2, 50,0,2,18,2,2,2,2, 0,0,2,20,2,2,2,6, + 16,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 42,0,2,8,2,2,2,2, 0,0,2,2,2,2,2,2, + 16,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 38,0,2,4,2,2,2,2, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 160,0,138,164,108,108,102,104, 0,0,190,160,132,134,120,146, 158,0,144,154,112,118,106,110, 0,0,160,218,160,164,148,160, + 88,0,92,94,139,139,94,92, 0,0,152,166,184,176,134,148, 98,0,96,102,139,139,110,110, 0,0,138,172,174,190,154,164, + 128,0,138,126,40,48,135,135, 0,0,130,160,128,148,186,180, 120,0,126,120,48,54,139,141, 0,0,136,160,142,188,166,188, + }, +}, + +{ // CP1257 (41.264M chars) [16] + {NULL, NULL, ced_hires_20, ced_hires_20, }, + 84, 222, 39, 20, 128, + {112,108,100,0,132,119,103,89, 0,78,64,75,0,77,68,67, 11,35,79,71,21,82,53,35, 0,31,45,33,0,0,49,0, + 173,72,85,94,121,69,110,128, 74,94,81,110,109,101,104,75, 124,97,89,88,110,94,97,129, 74,80,81,113,82,88,85,80, + 132,139,163,137,149,121,106,164, 124,141,114,153,127,139,154,153, 181,121,165,109,89,101,125,103, 97,82,78,145,112,85,162,98, + 138,140,163,106,150,118,115,164, 124,135,112,155,125,133,155,153, 179,115,165,109,88,104,145,100, 130,82,79,145,129,84,161,94, + 157,114,85,13,131,136,105,92, 1,81,72,77,10,83,100,70, 81,122,164,148,146,158,157,131, 0,129,85,106,48,81,114,1, + 181,85,101,152,141,118,119,142, 101,154,98,145,107,120,136,92, 155,111,121,103,136,99,100,159, 111,92,101,164,84,116,89,89, + 171,189,211,72,196,184,158,199, 199,205,85,210,168,152,203,176, 211,170,179,194,91,153,195,116, 172,97,91,199,198,89,204,171, + 205,199,217,92,198,194,183,201, 200,199,104,216,166,147,205,177, 211,185,178,196,93,154,194,117, 220,101,91,199,185,90,202,118, + }, + {116,0,0,0,0,0,0,0, 0,139,155,0,0,164,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 228,153,188,77,92,107,206,155, 138,165,122,102,192,146,189,135, 135,150,145,135,132,131,124,123, 120,121,178,143,202,85,105,154, + 107,193,189,191,196,191,164,188, 169,204,198,197,197,192,203,181, 177,134,209,211,206,182,187,168, 142,176,171,109,99,129,101,112, + 100,195,190,187,196,195,162,186, 165,207,198,197,197,192,202,181, 176,126,208,211,206,184,192,168, 136,178,172,83,124,77,109,0, + 117,90,127,119,115,124,85,99, 57,71,0,89,81,86,68,85, 80,86,101,138,134,121,102,96, 36,92,81,109,21,74,91,19, + 173,101,111,88,123,70,112,120, 89,109,84,101,109,115,119,115, 133,107,98,98,116,107,100,128, 113,93,107,121,96,107,110,117, + 136,143,168,99,146,122,112,156, 159,136,103,157,139,159,155,146, 175,101,144,111,83,103,128,97, 149,82,75,140,115,76,159,150, + 138,144,169,93,147,125,112,157, 159,131,104,158,139,160,159,147, 175,102,144,111,84,103,122,91, 149,83,76,143,108,75,158,101, + }, + {100,0,60,88,62,66,62,66, 128,122,100,126,86,90,84,92, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 38,0,2,2,2,2,2,2, 52,46,20,44,6,12,6,14, 70,0,6,34,6,12,6,12, 64,56,32,54,18,22,16,24, + 26,0,2,2,2,2,2,2, 4,2,2,2,2,2,2,2, 22,0,2,2,2,2,2,2, 8,4,2,2,2,2,2,2, + 26,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 24,0,2,2,2,2,2,2, 4,2,2,2,2,2,2,2, + 168,0,132,156,116,128,102,104, 234,200,166,204,168,184,164,158, 152,0,138,142,110,104,124,126, 210,216,166,230,168,168,172,154, + 164,0,130,166,110,108,106,106, 148,164,204,170,130,130,130,128, 164,0,140,158,102,98,106,104, 204,214,178,244,158,162,146,152, + 102,0,88,106,141,141,94,98, 190,154,154,162,178,188,140,126, 102,0,90,98,141,139,114,106, 152,140,118,176,188,174,148,132, + 132,0,134,134,26,40,135,135, 176,186,144,164,96,138,176,190, 126,0,136,122,28,38,135,133, 140,172,130,130,114,154,186,176, + }, +}, + +{ // CP1255 (313.575M chars) [17] + {NULL, NULL, NULL, ced_hires_12, }, + 192, 233, 81, 15, 127, + {98,94,106,111,72,121,83,91, 81,65,26,68,0,71,0,69, 81,85,102,93,99,127,102,95, 75,97,17,87,61,82,71,67, + 175,124,97,90,58,73,104,127, 119,93,86,110,111,82,101,112, 129,87,94,110,112,86,97,132, 116,73,60,114,71,123,75,120, + 119,65,141,119,118,109,112,113, 121,112,61,74,117,67,73,62, 61,98,78,56,68,54,124,148, 38,49,42,32,35,40,36,27, + 211,211,193,200,214,221,187,200, 193,220,109,200,214,125,214,131, 205,198,202,108,201,91,192,199, 210,210,202,32,36,81,108,32, + 159,117,88,89,134,138,108,95, 85,73,57,78,26,89,0,88, 63,104,145,129,128,139,138,112, 83,110,64,88,33,78,35,6, + 184,147,104,154,150,113,122,144, 118,156,77,147,109,123,138,122, 157,113,123,106,139,101,103,161, 114,95,71,167,86,119,91,159, + 81,40,33,27,57,50,53,76, 89,84,40,25,97,25,54,51, 36,79,53,49,25,25,27,56, 26,26,27,24,26,39,25,39, + 181,180,170,178,203,186,155,176, 171,197,173,144,189,203,159,191, 133,169,170,166,142,163,146,172, 192,178,205,35,59,102,136,39, + }, + {118,0,0,0,0,0,0,0, 0,137,146,0,0,165,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 227,155,187,100,97,112,172,178, 136,158,128,132,188,170,183,153, 137,155,149,140,137,135,129,128, 124,127,173,136,203,112,110,154, + 108,138,122,146,128,136,120,118, 124,127,114,112,126,128,125,124, 133,137,129,135,139,118,124,121, 117,118,103,111,143,128,106,131, + 142,144,112,120,123,140,110,110, 119,135,106,107,129,123,126,129, 124,108,122,153,134,129,118,103, 84,104,101,80,145,91,116,0, + 106,72,108,107,84,120,79,80, 98,59,0,68,0,76,0,66, 101,102,115,98,109,128,101,107, 92,118,68,108,103,102,97,114, + 175,126,108,86,95,75,110,121, 124,112,102,101,106,84,113,116, 133,82,132,131,119,84,97,130, 116,74,64,119,72,123,75,135, + 128,83,129,119,124,114,117,127, 127,114,43,82,134,59,75,65, 44,112,90,59,50,58,80,109, 50,44,39,43,41,44,40,43, + 205,205,192,202,209,223,186,199, 192,223,176,195,211,204,206,190, 204,195,200,171,199,162,190,198, 213,203,213,43,41,82,94,46, + }, + {86,0,44,70,130,132,130,122, 110,94,68,88,90,132,2,10, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 36,0,2,2,40,40,40,40, 60,46,16,34,34,72,2,2, 62,0,2,26,74,72,72,70, 70,54,24,42,44,82,2,2, + 60,0,2,22,70,70,68,68, 128,128,100,128,128,128,26,36, 62,0,2,26,66,66,66,68, 128,128,128,128,128,128,48,62, + 2,0,2,2,2,2,2,2, 24,10,2,2,2,34,2,2, 2,0,2,2,2,2,2,2, 34,20,2,10,10,46,2,2, + 170,0,136,156,182,190,170,166, 248,224,180,222,232,172,106,66, 154,0,140,142,176,164,188,188, 214,246,176,224,176,218,104,106, + 166,0,132,164,178,170,168,166, 160,170,204,170,154,182,76,76, 162,0,140,154,182,180,172,168, 224,230,176,228,214,218,94,74, + 172,0,148,146,180,182,188,180, 236,188,168,220,190,202,120,120, 158,0,146,158,180,180,180,178, 162,232,182,208,174,184,68,66, + 146,0,150,148,106,132,122,126, 110,90,74,98,128,90,131,133, 142,0,150,144,92,132,120,128, 78,90,74,72,124,138,133,127, + }, +}, + +{ // KOI8R (315.553M chars) [18] + {NULL, NULL, ced_hires_9, ced_hires_9, }, + 189, 220, 69, 17, 128, + {17,17,17,17,17,17,17,17, 17,39,39,17,17,39,17,17, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 17,17,17,117,17,17,17,17, 17,17,17,17,17,17,17,17, 17,17,17,118,17,25,17,17, 17,17,17,25,17,17,17,47, + 155,199,183,172,193,200,169,185, 168,203,166,197,197,191,205,205, 196,169,201,203,201,186,173,196, 170,177,187,171,168,166,181,137, + 158,201,188,174,195,200,175,189, 171,204,166,200,198,196,207,207, 201,170,204,206,202,187,175,199, 170,177,189,174,172,166,183,137, + 7,7,7,7,7,7,7,7, 7,39,39,7,7,39,7,7, 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, + 7,7,7,123,7,7,7,7, 7,7,7,7,7,7,7,7, 7,7,7,74,7,7,7,7, 7,7,7,7,7,7,7,100, + 164,191,135,141,166,194,118,163, 175,198,187,177,169,182,165,191, 138,192,164,174,180,171,125,189, 179,178,152,139,98,108,139,73, + 131,162,130,110,132,145,129,147, 126,158,123,145,139,148,148,152, 142,148,128,154,139,149,108,167, 114,119,123,105,122,90,109,85, + }, + {0,0,0,0,0,0,0,0, 0,111,171,0,0,149,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 223,146,172,30,25,90,164,138, 116,148,90,87,187,167,194,124, 72,106,101,90,90,85,93,77, 75,75,165,131,188,82,114,147, + 125,92,36,71,49,93,30,0, 64,104,0,30,49,47,61,97, 110,0,62,58,56,11,54,71, 45,83,11,70,85,112,54,106, + 92,94,57,74,51,94,36,30, 66,106,0,34,57,53,67,98, 113,0,67,61,51,49,56,17, 49,84,41,0,111,57,57,0, + 47,49,56,30,0,36,0,0, 0,0,0,25,17,0,0,11, 0,36,17,0,0,0,0,0, 0,0,49,0,0,11,0,0, + 25,0,0,123,0,0,0,0, 0,0,0,0,0,0,0,0, 57,17,45,121,30,57,11,36, 66,11,36,41,36,49,58,53, + 169,212,182,169,188,212,160,181, 172,207,177,191,196,188,203,214, 181,185,201,197,203,191,170,194, 184,189,174,162,139,157,176,118, + 167,209,180,168,186,208,159,179, 171,206,177,190,193,187,201,211, 178,185,198,195,202,188,168,192, 184,187,173,162,133,156,176,117, + }, + {130,0,102,154,154,154,154,154, 154,154,154,154,112,154,116,154, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 92,0,38,74,128,128,128,128, 128,128,128,128,22,34,24,36, 92,0,38,74,128,128,128,128, 128,128,128,128,44,54,46,56, + 2,0,2,2,18,22,26,26, 110,128,40,40,2,2,2,2, 2,0,2,2,22,28,32,30, 128,128,48,50,2,2,2,2, + 2,0,2,2,16,20,24,24, 128,128,76,80,2,2,2,2, 2,0,2,2,20,24,30,28, 128,128,82,84,2,2,2,2, + 154,0,128,178,178,178,178,178, 178,178,178,178,128,178,140,178, 154,0,132,178,178,178,178,178, 178,178,178,178,138,178,178,178, + 146,0,154,136,178,182,180,178, 178,178,180,178,134,146,82,92, 148,0,152,168,180,184,180,178, 178,180,180,180,90,106,136,148, + 154,0,154,152,154,146,152,150, 134,154,138,86,141,141,6,4, 154,0,154,156,114,150,158,160, 166,172,142,122,139,141,2,12, + 136,0,154,156,180,184,184,158, 124,140,110,136,112,106,141,139, 140,0,152,158,180,186,178,172, 130,144,112,138,114,110,139,141, + }, +}, + +{ // GBK (106.219M chars) [19] + {NULL, NULL, NULL, NULL}, + 203, 189, 27, 17, 128, + {80,136,138,128,141,121,130,133, 125,121,114,108,141,130,70,75, 125,127,117,120,119,135,127,109, 133,129,119,130,122,125,128,114, + 74,204,125,202,219,215,119,114, 118,156,113,86,97,79,82,81, 189,196,199,195,195,208,196,199, 196,203,194,200,201,197,193,195, + 192,195,189,194,195,183,196,191, 201,197,207,197,197,197,201,199, 201,191,203,201,198,196,202,200, 134,116,114,132,122,124,118,115, + 115,120,116,120,141,121,124,123, 121,120,121,113,125,116,117,110, 117,114,112,113,119,112,124,123, 85,77,84,80,72,84,79,0, + 135,112,99,113,112,124,117,103, 124,95,92,89,122,95,0,51, 0,0,0,0,0,0,0,0, 25,1,0,0,0,0,0,0, + 1,113,69,80,84,69,59,13, 116,104,61,70,84,69,73,47, 74,88,74,72,72,73,61,73, 51,54,54,59,70,77,75,75, + 96,68,68,66,84,83,47,68, 64,64,44,78,54,61,26,26, 64,64,47,59,70,74,70,66, 64,80,61,44,44,69,66,82, + 51,57,66,57,64,47,64,54, 18,82,68,66,40,66,70,69, 51,70,40,88,37,37,40,59, 59,40,102,70,73,70,68,0, + }, + {0,0,0,0,0,0,0,0, 0,1,60,0,0,64,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 94,78,82,0,0,0,93,107, 64,60,46,107,76,56,82,44, 29,64,73,39,27,27,18,14, 14,15,18,0,111,60,0,46, + 104,95,102,121,118,73,105,75, 96,131,74,109,89,100,103,111, 93,108,98,107,126,103,101,125, 113,99,98,90,89,109,120,88, + 77,85,85,92,91,104,101,109, 101,83,74,90,111,98,98,117, 96,93,127,97,106,100,91,99, 91,102,105,84,114,93,91,17, + 124,109,99,116,90,100,105,89, 96,95,103,108,93,117,111,110, 98,115,123,116,94,82,112,111, 83,97,106,96,74,105,115,121, + 126,196,197,192,196,176,185,184, 195,185,196,194,198,187,184,191, 190,190,180,189,189,194,181,191, 181,191,188,196,189,191,187,192, + 186,174,192,193,202,189,193,194, 190,188,189,195,181,187,196,191, 200,178,184,186,189,186,192,180, 193,176,195,182,185,179,182,186, + 185,187,190,185,183,187,185,186, 177,190,189,191,187,187,181,180, 178,185,188,196,173,177,186,192, 192,182,197,186,177,187,185,0, + }, + {144,0,168,168,120,122,152,128, 124,116,2,2,2,2,4,4, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 78,0,26,38,2,2,12,8, 128,128,22,22,20,24,26,26, 72,0,20,32,2,2,6,2, 128,128,40,42,40,44,46,46, + 74,0,22,34,2,2,6,4, 128,128,40,42,38,44,46,46, 80,0,28,40,6,4,14,10, 128,128,44,46,42,50,52,50, + 128,0,128,128,98,102,124,110, 128,128,46,50,46,54,56,54, 128,0,128,128,128,128,128,128, 128,128,38,40,38,44,46,44, + 0,0,0,0,236,252,250,242, 230,226,122,106,114,124,130,128, 0,0,0,0,252,238,254,254, 240,234,112,116,106,116,144,130, + 0,0,0,0,242,220,220,232, 106,108,136,130,128,116,126,114, 0,0,0,0,206,208,218,216, 82,88,128,126,128,126,126,132, + 0,0,0,0,204,218,220,208, 84,82,122,128,128,128,132,132, 0,0,0,0,212,214,210,210, 92,88,124,128,126,136,120,126, + 0,0,0,0,208,210,204,206, 200,208,136,124,124,122,126,126, 0,0,0,0,198,202,200,218, 200,196,128,122,132,128,130,120, + }, +}, + +{ // Greek (109.816M chars) [20] + {NULL, NULL, ced_hires_11, ced_hires_11, }, + 186, 219, 72, 19, 128, + {0,0,0,0,0,0,0,0, 0,24,24,0,0,24,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 174,64,123,80,13,49,101,123, 114,89,0,152,107,83,76,53, 122,81,71,65,105,84,180,126, 183,174,186,111,183,56,165,168, + 117,206,178,191,194,206,163,186, 183,198,202,195,198,199,165,203, 201,196,56,205,210,185,180,183, 154,177,136,87,180,183,177,186, + 157,202,171,187,188,204,165,188, 183,199,199,194,197,198,161,202, 194,196,154,201,208,185,175,180, 147,179,136,79,183,166,168,0, + 0,0,0,0,0,0,0,0, 0,34,34,0,0,34,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 183,58,94,153,91,63,120,143, 117,155,71,146,108,122,78,71, 156,112,122,105,105,84,83,160, 96,97,84,166,98,118,76,75, + 70,162,129,130,139,152,103,165, 133,144,142,123,130,144,98,158, 139,113,63,159,134,140,122,126, 98,117,81,46,175,143,180,165, + 64,199,125,122,122,176,111,189, 115,196,146,142,141,197,113,188, 137,142,206,133,145,191,115,124, 78,148,115,74,181,161,152,93, + }, + {98,0,0,0,0,0,0,0, 2,135,160,0,67,161,42,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 225,142,174,72,92,107,173,153, 133,152,109,98,183,147,185,142, 132,150,145,135,133,131,124,123, 119,121,167,138,195,117,108,120, + 78,122,108,129,112,120,111,107, 109,113,108,105,115,117,111,121, 118,81,119,121,112,95,108,105, 80,100,85,102,97,121,98,109, + 109,116,101,104,112,116,102,95, 104,115,100,100,121,112,116,124, 116,72,112,117,112,104,110,87, 82,90,98,64,123,66,101,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 174,42,84,78,172,159,104,116, 116,102,153,94,101,82,171,60, 122,76,68,71,118,78,185,127, 180,182,189,143,179,67,177,172, + 111,207,161,179,175,201,159,197, 167,203,190,188,186,197,160,205, 189,198,0,199,200,190,174,173, 145,183,137,110,188,186,184,191, + 66,211,163,182,177,206,160,199, 172,206,192,193,189,200,165,208, 196,203,194,200,201,194,176,176, 146,185,138,110,182,181,174,0, + }, + {146,0,130,170,170,170,170,168, 0,0,166,170,136,168,130,154, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 34,0,2,6,52,58,56,62, 0,0,4,2,2,2,2,2, 4,0,2,2,22,28,24,32, 0,0,14,2,2,2,2,2, + 2,0,2,2,2,2,2,4, 0,0,6,2,2,2,2,2, 2,0,2,2,2,6,2,8, 0,0,2,2,2,2,2,2, + 2,0,2,2,2,2,2,6, 0,0,2,2,2,2,2,2, 2,0,2,2,2,10,6,12, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 166,0,136,172,188,188,186,188, 0,0,186,116,110,106,106,106, 164,0,146,164,180,178,180,174, 0,0,98,100,140,144,98,104, + 146,0,152,154,164,164,162,156, 0,0,52,142,139,137,118,112, 148,0,152,154,150,144,142,134, 0,0,48,136,139,131,120,126, + 150,0,152,146,92,128,132,126, 0,0,144,72,30,124,139,139, 150,0,152,150,88,124,136,128, 0,0,66,76,4,118,141,139, + }, +}, + +{ // JIS (138.804M chars) [21] + {NULL, NULL, NULL, NULL}, + 37, 154, 2, 1, 129, + {0,0,0,0,0,0,0,0, 0,99,99,0,0,99,107,197, 0,0,0,0,0,0,0,0, 0,0,0,254,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {119,0,0,0,0,0,0,0, 0,53,49,0,0,49,0,0, 0,0,0,0,0,0,0,0, 0,0,0,197,0,0,0,0, + 73,56,65,75,246,65,49,49, 243,61,49,49,49,49,49,49, 49,56,61,49,49,49,49,49, 49,49,56,56,49,49,49,49, + 49,49,49,49,49,49,49,49, 49,49,49,49,49,56,143,49, 49,49,97,49,75,49,59,49, 49,49,61,49,49,53,56,53, + 49,98,49,53,49,49,49,94, 49,49,49,49,63,69,74,49, 49,49,53,65,49,49,49,49, 49,49,49,49,49,56,53,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {130,184,30,216,132,172,164,208, 0,0,0,0,0,0,0,0, 128,2,128,38,128,122,124,104, 0,0,0,0,0,0,0,0, + 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, +}, + +{ // CP1254 (20.130M chars) [22] + {NULL, NULL, ced_hires_18, ced_hires_18, }, + 97, 228, 51, 26, 128, + {105,102,117,110,111,122,102,106, 97,93,168,92,91,102,30,86, 53,83,126,96,72,96,70,66, 56,74,134,61,61,50,82,84, + 173,124,96,100,127,93,113,131, 120,100,114,112,110,97,113,106, 131,100,95,101,117,100,100,131, 116,92,116,116,90,96,94,114, + 108,154,124,147,148,125,114,181, 110,139,111,106,104,133,107,106, 146,124,109,108,100,126,167,105, 99,95,111,104,173,187,163,102, + 108,154,121,114,150,117,103,190, 108,128,103,98,103,136,103,119, 177,122,113,108,105,127,163,98, 101,94,113,91,173,200,184,105, + 157,114,89,88,132,136,106,94, 88,90,191,83,103,92,21,83, 80,123,164,148,146,158,157,131, 101,129,189,106,99,97,60,118, + 182,145,102,152,141,111,120,142, 116,154,142,145,107,121,136,120, 155,111,121,104,137,100,101,159, 112,95,162,165,88,117,91,157, + 152,195,152,169,197,184,168,180, 179,205,169,140,116,192,148,134, 200,173,128,194,156,153,196,117, 179,108,175,138,198,216,209,171, + 181,200,141,171,198,195,168,167, 169,200,157,140,147,201,136,123, 200,173,148,196,144,154,194,118, 178,142,175,128,185,237,209,106, + }, + {116,4,4,52,4,0,0,0, 0,144,148,0,0,163,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 225,145,184,86,101,112,168,165, 141,153,125,111,189,160,182,143, 136,151,146,136,133,132,125,124, 121,122,175,136,205,105,128,148, + 108,194,176,188,184,192,169,184, 174,197,159,189,200,191,205,183, 174,151,205,195,198,180,178,169, 146,174,178,113,109,127,105,136, + 126,195,178,194,186,194,171,181, 172,199,157,204,211,202,219,182, 177,139,210,201,200,185,177,168, 141,187,198,94,139,85,111,0, + 103,94,114,122,104,131,103,108, 103,87,157,89,94,91,51,79, 84,99,153,107,139,122,104,101, 94,118,157,108,103,94,118,122, + 173,126,101,99,126,94,115,123, 121,124,114,109,106,119,122,111, 133,112,90,112,118,97,110,129, 118,94,113,120,110,107,93,127, + 117,118,123,173,147,114,112,166, 112,142,110,109,107,167,114,104, 170,127,113,114,95,153,141,101, 99,92,103,107,131,170,176,150, + 116,123,113,173,147,118,110,169, 112,133,111,107,99,168,113,98, 188,128,113,112,119,153,142,91, 104,92,117,99,135,199,197,107, + }, + {84,0,50,70,50,58,42,52, 90,82,80,100,68,64,68,44, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 36,0,2,2,2,2,2,2, 32,24,16,38,6,2,6,2, 62,0,2,22,2,10,2,4, 36,28,22,44,12,8,10,2, + 26,0,2,2,2,2,2,2, 2,2,2,4,2,2,2,2, 16,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 20,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 4,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 140,0,112,126,144,140,106,118, 180,152,152,160,192,130,148,104, 142,0,134,130,100,98,134,132, 138,168,142,178,148,152,184,152, + 164,0,136,162,116,118,104,106, 140,152,204,176,140,126,126,118, 160,0,144,152,118,124,102,106, 174,182,180,238,162,154,150,126, + 92,0,94,92,145,149,90,92, 190,154,156,172,184,168,132,134, 112,0,114,118,143,143,116,118, 140,146,112,138,166,182,162,148, + 132,0,138,124,44,56,131,135, 142,176,130,156,120,128,176,162, 128,0,132,132,50,60,137,135, 130,160,114,122,98,130,138,168, + }, +}, + +{ // CP1253 (37.682M chars) [23] + {NULL, NULL, ced_hires_11, ced_hires_11, }, + 186, 218, 73, 21, 128, + {98,79,82,91,78,122,85,90, 0,82,68,76,0,75,0,65, 79,105,101,115,101,127,107,94, 0,98,0,91,0,78,48,0, + 174,70,182,88,122,76,110,130, 119,95,70,153,108,88,101,71, 130,87,79,77,106,197,107,129, 184,175,187,114,184,75,166,169, + 118,206,179,192,195,207,164,187, 184,199,203,195,198,200,165,203, 202,197,70,205,210,185,180,184, 155,178,137,90,181,184,178,187, + 86,203,172,188,189,203,161,188, 181,199,199,194,198,198,162,203, 195,196,156,202,208,186,176,181, 148,179,137,85,184,167,169,70, + 158,116,88,89,133,138,107,95, 0,84,72,80,9,91,0,87, 58,101,143,127,125,137,136,110, 0,108,60,84,28,75,32,6, + 183,68,95,153,143,112,121,144, 117,156,66,147,109,122,138,78, 157,112,123,105,106,101,102,161, 98,99,87,166,100,118,81,80, + 77,163,130,131,140,152,105,166, 133,145,142,124,131,145,100,159, 140,114,66,160,135,141,123,127, 100,118,86,68,176,144,181,166, + 74,200,125,123,122,177,112,190, 115,197,147,142,142,198,114,189, 137,143,206,134,146,192,116,125, 82,149,116,80,182,162,153,66, + }, + {118,0,0,0,0,0,0,0, 0,138,161,0,0,163,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 226,143,175,80,96,111,174,154, 134,154,123,101,184,149,186,143, 136,152,147,137,135,133,126,125, 122,123,168,139,197,118,114,121, + 107,133,118,132,121,129,117,114, 119,125,113,112,122,124,119,128, 125,97,124,130,131,115,120,120, 116,111,103,108,101,126,102,112, + 111,143,112,125,126,141,110,108, 120,135,105,107,128,122,124,134, 122,86,123,151,133,128,120,103, 90,103,102,77,126,78,111,0, + 91,79,78,82,79,127,85,84, 0,77,0,78,58,76,0,63, 76,87,132,84,113,123,101,97, 0,101,76,105,55,86,59,12, + 175,74,185,85,123,84,113,121, 119,111,74,101,104,87,118,74, 133,87,79,85,119,144,95,130, 181,183,190,144,180,79,178,172, + 112,208,162,180,176,202,160,198, 168,204,190,189,187,198,160,206, 190,199,70,200,200,190,175,174, 145,183,138,111,190,189,185,193, + 80,212,167,183,177,208,161,200, 173,208,193,194,190,201,165,209, 197,204,194,200,202,195,177,177, 147,186,139,111,184,182,175,72, + }, + {120,0,80,110,184,184,160,166, 142,128,86,68,44,50,40,48, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 20,0,2,2,32,36,28,32, 64,50,2,2,2,2,2,2, 2,0,2,2,10,14,6,10, 78,62,14,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 70,56,6,2,2,2,2,2, 2,0,2,2,2,2,2,2, 58,46,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 32,20,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 38,26,2,2,2,2,2,2, + 168,0,138,162,188,202,172,168, 248,222,164,132,100,104,104,108, 150,0,142,148,180,174,188,192, 212,242,158,156,116,114,118,120, + 162,0,136,170,180,178,174,172, 148,160,176,108,132,134,106,104, 162,0,146,164,172,168,166,156, 118,142,100,98,134,138,126,114, + 144,0,152,152,156,152,144,136, 116,120,132,142,139,135,116,112, 146,0,150,152,142,134,126,118, 106,104,132,134,139,131,120,126, + 148,0,152,144,90,118,116,110, 122,122,68,86,30,122,137,139, 150,0,152,148,90,116,122,112, 122,132,66,88,12,118,139,137, + }, +}, + +{ // CP932 (5.390M chars) [24] + {NULL, NULL, NULL, NULL}, + 151, 140, 55, 26, 129, + {73,188,237,214,159,83,84,109, 191,199,191,194,200,199,202,199, 190,190,186,192,182,191,188,186, 105,102,112,102,102,102,107,115, + 101,107,119,112,119,135,100,99, 106,106,107,101,103,109,105,120, 121,117,114,106,104,110,111,112, 114,105,127,110,129,118,108,105, + 123,109,100,111,120,109,109,99, 105,106,114,108,122,112,116,106, 102,102,113,101,100,99,102,108, 110,108,119,107,108,116,122,117, + 117,116,111,115,112,109,113,115, 113,111,167,178,184,104,106,183, 160,142,115,156,149,130,163,163, 184,191,154,133,75,97,94,93, + 0,223,195,229,107,12,47,131, 44,180,189,184,179,185,191,185, 177,166,168,174,170,173,169,172, 162,86,89,86,93,87,87,91, + 99,113,100,104,106,122,111,98, 99,99,99,99,99,99,99,99, 105,99,100,99,98,99,99,102, 124,99,99,99,106,103,99,99, + 100,99,99,98,105,99,99,99, 99,101,99,99,112,99,98,99, 99,100,99,99,99,98,102,99, 99,103,99,99,99,104,106,104, + 115,99,101,108,103,106,99,99, 99,103,97,0,23,91,96,0, 105,107,95,165,148,101,154,130, 96,175,132,116,100,109,98,101, + }, + {87,0,0,0,0,0,0,0, 0,84,91,0,0,87,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 114,86,99,84,84,84,86,86, 90,93,85,89,87,94,87,86, 91,88,89,86,85,85,84,84, 84,84,85,87,119,84,84,84, + 199,198,192,189,158,189,180,168, 171,180,178,171,176,161,191,183, 172,169,179,177,178,160,185,181, 190,169,175,200,180,158,185,172, + 177,159,190,175,162,179,173,191, 177,187,182,158,184,167,174,182, 179,167,177,179,178,179,187,176, 174,176,173,178,169,174,176,0, + 175,177,175,172,170,176,176,180, 169,182,188,188,178,179,172,172, 159,180,158,195,174,169,176,176, 162,162,166,158,168,174,176,177, + 179,175,195,161,185,163,180,172, 181,189,190,180,175,184,173,177, 166,185,175,184,166,192,178,192, 166,176,169,178,190,190,180,180, + 168,183,176,163,192,193,192,176, 191,192,177,162,203,189,171,167, 173,162,169,159,174,148,173,170, 163,160,175,166,188,175,165,174, + 186,163,176,177,162,176,185,182, 187,190,188,161,175,174,179,176, 192,187,162,164,156,172,160,145, 155,145,181,167,175,93,93,93, + }, + {84,0,82,82,2,2,4,6, 2,2,8,8,4,18,2,2, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 128,0,126,120,6,10,10,14, 22,24,18,18,14,28,20,30, 128,0,128,126,2,8,8,12, 22,26,18,18,14,30,20,30, + 128,0,128,128,6,10,12,14, 26,28,22,22,18,32,24,34, 128,0,128,128,8,12,14,16, 26,30,22,22,18,32,24,34, + 68,0,44,44,2,2,2,2, 26,30,24,22,18,34,24,34, 66,0,40,42,2,2,2,2, 2,2,2,2,2,2,2,2, + 0,0,0,0,140,138,140,138, 132,130,132,132,136,132,134,128, 0,0,0,0,134,140,142,142, 130,134,132,134,124,134,132,142, + 222,128,252,248,124,128,128,130, 148,136,134,126,124,132,86,120, 214,128,240,244,136,132,130,132, 136,118,136,132,126,152,84,118, + 212,128,244,242,126,130,132,134, 136,128,130,128,118,156,82,122, 212,128,242,242,126,130,132,134, 136,130,128,144,130,142,66,122, + 0,0,0,0,134,144,136,142, 138,144,128,150,72,88,76,86, 184,180,164,164,126,140,126,154, 134,144,126,132,124,128,136,134, + }, +}, + +{ // Hebrew (10.753M chars) [25] + {NULL, NULL, NULL, NULL}, + 196, 235, 78, 9, 128, + {0,0,0,0,0,0,0,0, 0,63,63,0,0,63,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 165,0,80,80,80,80,80,80, 80,82,80,80,82,89,80,80, 85,80,80,80,86,80,80,82, 80,80,83,80,80,80,80,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,80, + 205,203,189,201,216,218,185,196, 190,220,185,190,212,212,202,200, 199,194,199,175,193,168,187,196, 214,202,217,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,77,77,0,0,77,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 145,0,87,87,105,87,87,87, 88,138,88,88,88,89,105,87, 89,88,88,87,91,87,87,118, 87,87,87,88,88,89,87,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,87, + 194,196,170,172,206,189,164,179, 163,185,130,182,196,152,197,145, 174,174,179,130,174,124,162,174, 179,192,183,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,136,147,0,0,157,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 227,138,183,80,80,95,170,157, 104,163,103,95,150,163,151,133, 86,103,112,90,86,90,87,88, 85,86,126,96,204,95,106,111, + 82,84,81,84,82,82,81,81, 82,84,81,81,81,81,82,82, 82,80,85,94,81,81,80,82, 81,80,82,83,104,130,83,93, + 114,87,82,84,83,83,82,81, 82,88,80,81,82,82,82,86, 83,81,84,85,88,82,81,85, 80,82,80,81,92,108,97,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 165,0,81,80,80,80,80,81, 80,82,80,80,81,81,80,80, 86,80,81,80,85,80,80,83, 80,80,81,80,80,80,80,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,80, + 209,210,192,200,210,223,187,198, 189,223,131,200,211,161,212,142, 207,193,203,135,198,112,191,196, 208,208,204,0,0,0,0,0, + }, + {180,0,128,152,204,204,204,202, 0,0,202,202,0,164,118,124, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 54,0,2,14,128,84,104,102, 0,0,66,128,0,128,2,2, 128,0,36,58,128,128,128,128, 0,0,98,128,0,128,4,16, + 128,0,128,128,128,128,128,128, 0,0,128,128,0,128,128,128, 128,0,76,98,128,128,128,128, 0,0,128,128,0,128,50,62, + 2,0,2,2,16,2,8,10, 0,0,2,38,0,78,2,2, 2,0,2,2,26,10,18,20, 0,0,6,56,0,98,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 154,0,146,158,230,204,230,232, 0,0,186,226,0,186,128,130, 186,0,128,164,228,226,226,226, 0,0,226,226,0,186,118,124, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 164,0,128,152,188,188,188,186, 0,0,186,186,0,148,116,124, + 150,0,150,150,136,142,142,136, 0,0,130,118,0,118,130,132, 154,0,150,154,146,158,148,158, 0,0,124,124,0,122,132,128, + }, +}, + +{ // KOI8U (14.358M chars) [26] + {NULL, NULL, ced_hires_9, ced_hires_9, }, + 189, 220, 69, 18, 129, + {87,87,87,87,87,87,87,87, 87,95,95,87,87,95,87,87, 84,84,84,84,84,84,84,84, 84,84,84,84,84,84,84,84, + 87,87,87,119,129,87,162,137, 87,87,87,87,87,90,87,87, 87,87,87,119,131,87,163,137, 87,87,87,87,87,92,87,87, + 156,198,183,173,193,200,169,185, 168,203,166,197,197,191,205,205, 196,169,201,203,201,185,173,196, 170,177,187,171,168,165,181,137, + 158,200,188,175,195,200,175,189, 171,204,166,200,198,196,207,207, 201,170,204,206,202,187,175,199, 170,177,189,174,172,166,183,137, + 82,82,82,82,82,82,82,82, 82,95,95,82,82,95,82,82, 56,56,56,56,56,56,56,56, 56,56,56,56,56,56,56,56, + 82,82,82,124,131,82,157,142, 82,82,82,82,82,83,82,82, 82,82,82,87,89,82,115,97, 82,82,82,82,82,82,82,103, + 164,191,135,141,166,194,119,163, 175,198,187,177,169,181,165,191, 138,192,163,174,180,171,125,189, 179,178,152,139,101,110,139,87, + 131,161,130,111,132,145,129,147, 126,157,123,145,139,148,148,152, 142,148,128,154,139,149,110,167, 115,120,124,107,123,95,110,92, + }, + {0,0,0,0,0,0,0,0, 0,112,170,0,0,149,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 223,146,172,86,86,96,164,138, 117,148,96,95,187,167,194,124, 88,108,104,96,97,94,99,91, 91,91,165,131,188,92,116,147, + 126,98,86,90,87,99,86,86, 87,107,86,86,86,87,87,101, 112,86,87,87,86,86,87,91, 86,93,86,87,94,113,86,107, + 97,99,87,90,86,99,86,86, 87,108,86,86,87,87,88,102, 114,86,88,87,86,86,87,86, 86,94,86,86,113,86,87,0, + 87,87,87,86,86,86,86,86, 86,86,86,86,86,86,86,86, 86,86,86,86,86,86,86,86, 86,86,86,86,86,86,86,86, + 86,86,86,123,128,86,170,136, 86,86,86,86,86,87,86,86, 88,86,87,121,127,88,168,135, 88,86,86,87,87,87,86,87, + 169,212,182,169,188,211,160,181, 172,207,177,191,196,188,203,214, 181,185,201,197,203,191,170,194, 184,189,174,162,139,157,176,119, + 167,209,179,168,186,208,159,179, 171,205,177,190,193,187,202,210, 178,185,198,195,202,188,168,192, 184,187,173,162,133,156,176,118, + }, + {132,0,98,138,200,200,200,198, 200,200,174,176,92,102,94,104, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 44,0,2,24,84,92,96,96, 128,128,46,48,2,2,2,2, 42,0,2,24,84,90,96,94, 128,128,88,90,14,24,16,26, + 2,0,2,2,10,14,16,16, 36,36,2,2,2,2,2,2, 2,0,2,2,16,20,22,22, 46,46,2,2,2,2,2,2, + 2,0,2,2,8,12,14,14, 128,128,26,28,2,2,2,2, 2,0,2,2,14,16,20,18, 112,128,30,32,2,2,2,2, + 174,0,126,164,224,224,224,222, 224,224,180,182,112,124,116,126, 200,0,128,168,224,224,224,222, 224,224,182,184,114,126,118,128, + 146,0,154,150,184,194,200,194, 224,224,170,142,134,140,78,88, 158,0,142,170,224,224,224,222, 224,224,140,172,104,106,136,142, + 156,0,154,152,148,140,142,142, 118,120,138,74,139,139,16,24, 154,0,154,156,130,146,148,152, 126,124,138,84,139,141,18,30, + 136,0,154,156,180,186,186,174, 116,118,108,138,112,106,141,139, 140,0,152,158,182,184,182,178, 122,122,112,138,114,110,139,141, + }, +}, + +{ // ISO-8859-5 (4.566M chars) [27] + {NULL, NULL, NULL, NULL}, + 178, 203, 63, 18, 128, + {0,0,0,0,0,0,0,0, 0,73,73,0,0,73,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 174,139,153,105,121,99,146,124, 153,123,130,127,103,100,117,115, 203,190,202,193,196,200,173,190, 205,165,202,200,198,206,204,202, + 204,206,200,185,176,172,175,186, 177,166,129,174,167,168,175,170, 198,179,195,186,191,199,170,186, 202,165,197,197,190,203,202,194, + 202,202,199,184,167,167,172,183, 170,164,142,174,169,160,162,170, 145,139,152,104,117,99,146,124, 151,121,129,126,103,100,117,115, + 0,0,0,0,0,0,0,0, 0,96,96,0,0,96,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 183,107,100,119,101,102,114,101, 108,107,102,105,110,123,100,105, 155,132,162,147,135,132,126,125, 144,118,136,128,135,134,143,136, + 129,148,131,134,127,123,119,121, 119,113,118,126,116,118,119,138, 196,133,191,156,166,192,126,148, 197,189,175,160,180,171,185,142, + 170,174,180,171,119,174,145,137, 136,107,110,179,181,109,162,193, 112,129,101,118,119,103,147,123, 126,105,102,131,111,99,125,102, + }, + {0,0,0,0,0,0,0,0, 0,114,146,0,0,157,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 222,138,169,99,103,106,165,146, 132,152,105,105,185,162,182,129, 128,138,133,123,122,122,115,115, 112,113,166,133,204,103,107,138, + 107,127,114,123,114,133,112,117, 112,112,116,112,118,118,113,127, 126,101,118,122,116,107,107,118, 101,108,104,104,106,112,100,115, + 103,127,109,118,116,128,106,107, 105,117,110,111,115,113,118,136, 126,100,117,119,115,110,109,117, 100,113,108,99,124,100,99,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 174,147,138,136,115,100,153,120, 139,118,125,128,109,100,117,138, 209,174,192,178,187,205,163,176, 205,178,190,191,185,200,208,172, + 198,193,199,188,157,168,168,173, 166,150,130,185,182,133,166,183, 215,178,196,181,189,211,165,178, 208,178,192,200,187,202,213,176, + 204,195,202,197,156,173,167,173, 161,154,133,189,185,135,171,185, 146,148,138,136,116,99,155,119, 139,120,128,128,109,103,118,137, + }, + {176,0,130,152,216,216,216,214, 0,0,182,122,134,118,130,216, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 36,0,2,2,42,50,44,50, 0,0,16,2,2,2,2,24, 2,0,2,2,2,2,2,2, 0,0,18,2,2,2,2,26, + 2,0,2,2,2,4,2,4, 0,0,32,2,2,2,2,42, 2,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 2,0,2,2,2,8,2,8, 0,0,2,2,2,2,2,2, 46,0,2,4,54,64,54,64, 0,0,38,2,2,2,2,48, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 178,0,132,168,188,188,180,186, 0,0,192,126,130,94,98,138, 140,0,150,154,182,178,186,182, 0,0,122,138,138,120,116,102, + 146,0,146,160,198,200,184,190, 0,0,126,138,140,118,114,104, 148,0,154,154,116,130,140,130, 0,0,78,28,40,138,138,134, + 156,0,154,148,128,138,132,134, 0,0,88,38,50,138,140,144, 150,0,152,140,186,198,198,204, 0,0,142,88,100,130,142,182, + }, +}, + +{ // CP874 (90.889M chars) [28] + {NULL, NULL, NULL, NULL}, + 183, 197, 49, 21, 127, + {105,102,97,58,82,121,0,91, 87,94,89,61,69,81,0,58, 84,99,96,131,98,112,94,97, 77,90,89,80,56,80,84,0, + 175,209,195,89,202,83,128,203, 192,151,191,169,87,166,132,138, 156,134,149,172,200,200,176,200, 176,211,199,193,179,149,192,164, + 175,205,201,213,136,199,77,202, 175,173,203,200,140,209,144,122, 197,203,215,179,198,198,169,189, 190,187,93,58,56,58,53,74, + 209,196,186,186,191,106,151,183, 207,205,151,138,179,120,113,126, 122,127,132,111,120,111,102,99, 97,95,58,89,84,72,69,79, + 159,116,43,30,27,138,0,65, 1,58,62,0,19,89,0,87, 48,92,134,118,116,128,127,100, 0,39,50,0,17,66,20,0, + 184,175,143,83,159,81,91,181, 155,114,141,116,87,135,98,96, 126,89,93,153,172,160,139,156, 133,188,176,156,101,93,162,122, + 113,182,178,173,85,158,76,169, 155,135,151,108,93,170,98,140, 166,90,179,144,149,166,81,80, 132,137,85,52,53,62,58,119, + 116,99,98,96,101,93,161,101, 173,168,107,110,179,86,93,109, 117,116,114,109,105,106,99,96, 94,95,54,89,94,56,64,98, + }, + {119,0,0,44,0,0,0,0, 0,138,149,0,0,161,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 209,129,181,84,86,94,166,157, 152,153,115,111,167,151,188,147, 133,142,138,128,126,125,117,113, 111,112,165,104,202,96,121,126, + 106,131,115,123,116,126,111,111, 114,120,111,105,118,121,113,118, 121,94,117,127,130,114,114,118, 116,109,100,126,115,121,92,108, + 78,142,110,112,119,136,104,98, 116,133,97,101,116,118,116,127, 119,79,119,150,131,126,114,102, 84,97,98,64,134,70,101,0, + 99,94,75,63,80,121,0,92, 94,84,92,59,78,81,49,49, 77,82,103,84,123,111,96,101, 80,100,87,78,55,86,81,0, + 175,206,190,92,199,79,139,206, 190,148,188,166,94,168,152,144, 148,139,143,179,199,195,177,200, 172,213,199,192,172,143,191,161, + 174,207,201,213,153,202,68,203, 176,170,200,196,121,209,144,145, 194,206,217,188,201,202,172,189, 193,191,94,68,66,68,64,77, + 203,186,177,183,187,119,161,181, 208,206,149,139,187,118,121,123, 127,115,118,111,108,125,108,109, 106,112,74,99,91,72,79,91, + }, + {110,0,78,92,172,172,158,156, 114,122,40,36,30,34,38,118, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 54,48,2,2,2,2,2,36, 2,0,2,2,2,2,2,2, 54,46,2,2,2,2,2,34, + 2,0,2,2,2,2,2,2, 54,46,2,2,2,2,2,34, 2,0,2,2,2,2,2,2, 64,58,2,2,2,2,2,44, + 2,0,2,2,2,2,2,2, 62,56,2,2,2,2,2,42, 66,0,18,30,108,104,86,80, 128,128,16,12,6,8,14,128, + 174,0,152,160,182,202,168,162, 246,218,114,92,92,80,144,174, 156,0,156,144,186,176,196,194, 204,246,128,124,120,72,138,184, + 164,0,158,164,172,166,158,160, 106,118,126,118,128,132,130,82, 156,0,162,160,124,144,118,126, 140,136,120,122,126,134,130,94, + 156,0,162,160,120,152,110,128, 92,114,126,124,126,134,128,90, 164,0,160,162,132,138,124,138, 88,116,134,134,128,66,132,86, + 160,0,160,160,130,146,126,132, 98,116,132,134,134,114,112,128, 156,0,164,148,202,212,190,188, 168,192,88,80,70,70,134,254, + }, +}, + +{ // ISO-8859-13 (0.207M chars) [29] + {NULL, NULL, ced_hires_20, ced_hires_20, }, + 87, 221, 44, 20, 128, + {0,0,0,0,0,0,0,0, 0,140,140,0,0,140,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 172,141,141,141,142,142,141,144, 141,141,141,141,141,141,141,141, 142,141,141,141,141,141,141,144, 141,141,141,142,141,141,141,141, + 145,148,162,142,153,142,141,165, 141,149,141,156,144,147,157,156, 180,141,166,141,141,141,143,141, 141,141,141,151,142,141,162,141, + 145,149,162,141,154,141,141,165, 142,147,141,156,144,146,157,156, 178,141,165,141,141,141,151,141, 142,141,141,151,145,141,162,141, + 0,0,0,0,0,0,0,0, 0,103,103,0,0,103,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 179,147,141,155,148,163,142,148, 141,157,141,149,141,141,147,141, 156,141,143,141,164,141,141,160, 142,141,141,164,141,141,141,141, + 171,188,209,141,195,182,160,197, 197,203,141,208,168,155,202,175, 209,170,178,192,141,156,194,142, 172,141,141,197,196,141,202,170, + 203,197,216,141,196,193,181,199, 198,198,141,215,167,153,203,176, 209,184,177,194,141,156,192,141, 218,141,141,197,184,141,201,147, + }, + {0,0,0,0,0,0,0,0, 0,147,156,0,0,163,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 226,155,187,141,141,141,205,156, 147,165,143,141,191,150,188,145, 145,153,151,146,146,145,143,143, 142,143,177,149,200,141,141,157, + 141,192,188,189,194,190,165,186, 169,203,196,195,196,191,201,180, 177,147,207,210,204,181,186,168, 149,175,171,141,141,143,141,141, + 141,193,189,186,194,193,163,185, 166,205,196,195,195,191,200,180, 175,144,206,209,204,182,190,168, 147,177,171,141,143,141,141,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 172,142,142,141,143,141,142,142, 141,142,141,141,142,141,142,143, 144,141,141,141,144,142,141,144, 142,141,142,143,141,142,142,143, + 146,151,168,141,152,142,142,159, 160,146,141,160,148,161,157,152, 174,141,150,141,141,141,143,141, 154,141,141,149,142,141,160,154, + 147,151,168,141,152,142,142,159, 161,143,141,160,148,161,160,152, 174,141,150,141,141,141,143,141, 154,141,141,150,142,141,160,141, + }, + {158,0,124,150,126,130,126,128, 0,0,170,174,162,166,162,166, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 24,0,2,2,2,2,2,2, 0,0,2,6,2,2,2,2, 30,0,2,2,2,2,2,2, 0,0,6,12,2,2,2,4, + 18,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 16,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 18,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 16,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 162,0,130,160,124,122,116,118, 0,0,184,168,156,160,156,160, 160,0,136,152,118,120,118,120, 0,0,168,176,162,164,162,166, + 112,0,92,110,143,143,98,102, 0,0,160,164,168,178,152,154, 116,0,94,110,143,141,116,110, 0,0,156,162,178,166,152,152, + 130,0,134,134,68,72,135,137, 0,0,158,164,152,156,168,178, 126,0,136,124,74,78,137,135, 0,0,156,162,150,158,178,166, + }, +}, + +{ // Latin4 (1.274M chars) [30] + {NULL, NULL, ced_hires_17, ced_hires_17, }, + 82, 215, 39, 25, 128, + {0,0,0,0,0,0,0,0, 0,115,115,0,0,115,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 173,117,116,117,126,117,148,132, 125,177,162,132,116,116,164,120, 128,118,116,117,124,117,148,116, 124,175,162,130,116,116,163,116, + 157,149,123,151,148,122,117,138, 167,143,123,118,151,148,118,153, 121,162,122,139,120,119,129,118, 117,116,148,118,124,121,142,117, + 157,149,118,127,151,122,117,137, 166,138,123,117,150,149,118,153, 120,162,122,131,121,119,146,117, 118,128,146,116,134,116,142,117, + 0,0,0,0,0,0,0,0, 0,70,70,0,0,70,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 181,199,116,118,142,116,174,142, 124,175,196,171,116,126,169,127, 155,213,117,118,137,116,173,125, 122,173,197,168,117,142,170,118, + 207,195,152,169,196,183,168,186, 199,205,192,140,210,191,148,201, 147,178,118,155,156,154,195,123, 178,174,175,140,198,117,198,171, + 213,200,142,170,197,194,168,195, 200,199,205,141,216,201,138,202, 146,177,121,146,145,154,194,125, 178,220,175,131,185,119,198,126, + }, + {57,0,0,38,0,0,0,0, 0,131,151,0,0,166,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 228,152,180,117,117,121,211,153, 140,167,128,117,189,148,187,138, 132,143,139,132,130,129,124,123, 122,123,176,138,202,117,118,154, + 118,186,190,201,200,189,167,191, 171,184,194,192,197,190,201,180, 181,140,208,211,206,171,184,129, 140,156,180,118,122,126,119,124, + 127,186,190,200,200,192,165,190, 168,185,194,192,197,189,200,179, 179,135,207,211,206,172,186,130, 136,162,180,118,128,117,119,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 173,117,117,117,128,123,146,126, 126,173,155,140,117,124,156,121, 126,119,117,117,121,134,147,117, 125,173,155,141,136,134,156,135, + 164,151,124,120,147,123,118,143, 164,136,118,120,153,166,122,151, 121,140,124,152,118,120,129,119, 117,154,119,117,123,117,140,151, + 164,153,120,117,148,124,119,144, 165,128,118,120,153,167,121,156, 125,142,122,153,127,119,128,121, 118,154,121,117,120,117,144,118, + }, + {162,0,122,152,126,130,126,128, 0,0,168,174,170,184,168,186, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 20,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 24,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 26,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 36,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 26,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 36,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 142,0,104,138,144,136,100,96, 0,0,180,140,178,180,148,160, 132,0,136,126,68,68,138,130, 0,0,140,176,140,152,182,186, + 108,0,90,112,143,143,98,98, 0,0,176,164,182,164,150,154, 118,0,100,112,139,145,112,108, 0,0,180,154,176,174,158,170, + 134,0,132,134,46,52,137,137, 0,0,142,182,140,160,182,166, 120,0,140,126,56,60,127,133, 0,0,152,184,148,180,174,174, + }, +}, + +{ // MACINTOSH (7.890M chars) [31] + {NULL, NULL, NULL, NULL}, + 93, 176, 57, 40, 128, + {157,149,165,157,149,138,123,160, 152,165,162,148,156,168,162,155, 132,145,140,141,135,131,120,139, 145,132,114,87,138,116,126,107, + 122,121,109,120,124,153,124,137, 115,116,118,128,124,104,106,113, 104,117,104,104,109,107,139,107, 126,104,109,117,116,104,105,110, + 111,159,167,120,108,142,122,128, 139,154,202,125,151,121,112,145, 122,135,125,128,127,169,111,105, 105,105,106,131,106,115,157,151, + 178,165,177,166,176,175,150,161, 175,138,169,172,167,178,180,169, 181,177,176,161,145,151,149,162, 150,150,134,154,149,146,136,108, + 187,160,176,222,183,180,186,200, 209,171,190,175,171,176,227,198, 178,155,199,157,162,155,181,198, 159,170,176,133,176,169,177,184, + 153,174,115,162,149,204,131,171, 181,164,183,160,143,100,144,155, 100,123,132,132,125,113,123,102, 131,114,100,143,166,100,142,153, + 167,156,133,122,124,144,123,171, 183,183,202,158,173,141,144,148, 197,182,196,197,174,218,115,99, 113,111,102,198,116,150,173,165, + 163,179,162,158,169,174,179,196, 171,195,195,169,176,142,198,171, 137,149,180,180,122,144,118,130, 126,177,118,147,152,115,134,107, + }, + {42,0,13,0,0,0,0,0, 0,162,166,0,0,180,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 232,145,182,109,125,120,185,162, 148,164,123,123,190,165,187,146, 152,167,161,152,152,149,142,140, 139,140,164,140,212,106,144,148, + 114,197,179,197,187,193,175,187, 174,172,164,164,193,190,204,189, 182,167,202,202,200,165,181,159, 152,152,154,137,122,135,112,138, + 124,201,182,197,188,200,175,187, 178,184,163,166,195,192,204,192, 182,163,203,213,204,179,184,151, 152,150,156,105,146,106,124,0, + 154,118,136,147,125,135,127,149, 150,171,149,158,123,138,165,150, 145,167,173,164,158,153,119,174, 161,141,125,139,166,124,149,128, + 121,135,106,117,127,149,123,154, 119,135,121,131,129,103,106,107, 103,121,103,103,108,106,141,104, 125,103,103,109,119,103,106,107, + 121,146,166,124,112,147,123,119, 142,156,201,137,158,141,109,143, 126,135,114,134,124,136,109,103, 105,103,103,132,103,152,150,164, + 189,156,172,160,169,185,143,151, 179,154,167,169,166,174,187,145, 178,169,174,164,137,148,147,154, 144,138,124,165,164,121,147,108, + }, + {64,0,40,60,48,54,44,48, 40,32,58,74,24,52,16,30, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 30,0,2,2,2,2,2,2, 2,2,2,14,2,2,2,2, 40,0,2,14,2,8,2,2, 14,8,34,52,2,28,2,6, + 2,0,2,2,2,2,2,2, 2,2,2,14,2,2,2,2, 16,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 2,2,2,4,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,14,30,2,8,2,2, + 110,0,128,112,130,132,130,130, 172,160,146,144,140,156,152,144, 116,0,126,118,72,74,142,134, 166,176,152,142,114,142,138,132, + 150,0,140,144,110,108,104,102, 150,144,198,192,158,160,124,142, 118,0,138,130,110,122,126,128, 152,146,184,206,166,166,128,142, + 154,0,132,150,124,122,106,110, 110,102,160,166,174,156,114,104, 126,0,130,136,116,114,128,136, 178,160,156,162,138,174,134,142, + 118,0,122,114,142,144,108,96, 120,128,142,140,104,154,162,162, 124,0,132,118,132,136,124,118, 114,100,130,140,112,150,162,164, + }, +}, + +{ // GB18030 (0.640M chars) [32] + {NULL, NULL, NULL, NULL}, + 202, 189, 30, 18, 127, + {107,143,144,138,146,135,139,141, 137,141,140,132,146,144,130,130, 137,138,134,135,134,142,138,131, 141,139,135,139,136,137,138,133, + 130,205,136,202,219,216,134,132, 133,158,133,130,130,130,130,130, 190,196,199,196,196,209,197,199, 197,204,195,200,202,198,193,195, + 193,196,190,195,196,183,196,192, 202,197,207,198,197,198,202,200, 202,191,204,201,199,197,203,200, 140,132,132,140,134,135,133,131, + 132,133,132,133,146,134,134,134, 133,133,134,132,135,132,132,131, 133,132,131,131,133,132,135,135, 130,130,130,130,130,130,130,0, + 150,126,124,127,127,133,129,124, 132,124,123,123,132,122,120,121, 35,63,39,52,35,68,64,64, 75,69,63,67,52,52,39,65, + 121,121,121,121,122,120,121,121, 126,122,121,120,121,120,121,121, 121,121,121,120,121,121,120,121, 121,121,120,121,122,121,121,121, + 121,121,121,121,121,120,120,120, 121,120,120,121,121,121,121,120, 120,120,121,120,120,120,120,121, 121,121,121,121,121,121,121,121, + 121,120,121,120,121,120,120,120, 121,121,121,121,120,121,120,120, 120,120,120,122,120,120,120,121, 121,121,120,120,121,121,120,0, + }, + {0,0,0,0,0,0,0,0, 0,79,79,0,0,79,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 79,85,79,79,79,79,95,79, 83,83,79,93,93,79,87,79, 126,115,111,106,110,106,103,106, 108,108,79,79,140,83,79,110, + 132,131,132,136,135,131,132,131, 131,141,131,133,131,132,132,133, 131,133,131,132,138,132,132,137, 134,131,131,131,131,133,136,131, + 131,131,131,131,131,132,132,133, 131,131,131,131,134,131,131,135, 131,131,139,131,132,131,131,132, 131,132,132,131,134,131,131,0, + 138,132,131,134,130,131,132,130, 130,130,131,132,131,134,133,133, 131,134,137,134,131,130,133,133, 130,131,132,131,130,132,134,136, + 138,196,198,193,197,176,186,185, 196,185,197,195,199,187,185,192, 190,191,180,190,190,195,182,192, 182,191,188,196,190,191,188,193, + 187,175,193,194,203,190,193,195, 191,189,190,196,182,188,196,192, 200,179,185,187,190,187,193,181, 193,177,196,183,186,180,183,186, + 186,188,190,186,184,188,186,187, 178,191,190,192,188,188,182,181, 179,186,189,196,174,178,187,193, 193,183,197,187,178,188,186,0, + }, + {218,0,240,172,146,146,148,146, 120,44,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 56,0,26,2,2,2,2,2, 74,70,2,2,2,2,2,2, 50,0,20,2,2,2,2,2, 84,76,2,2,2,2,2,2, + 50,0,22,2,2,2,2,2, 86,76,2,2,2,2,2,2, 58,0,28,2,2,2,2,2, 86,76,2,2,2,2,2,2, + 128,0,128,64,36,36,38,38, 86,76,2,2,2,2,2,2, 128,0,128,68,40,40,42,42, 84,76,2,2,2,2,2,2, + 0,0,0,212,188,194,188,186, 180,180,120,114,116,122,126,126, 0,0,0,192,194,188,194,194, 176,176,116,120,116,122,136,128, + 0,0,0,194,206,204,216,214, 118,118,136,130,128,116,126,112, 0,0,0,198,208,208,228,220, 112,112,126,126,128,126,126,130, + 0,0,0,188,210,208,232,222, 112,112,120,126,126,126,130,130, 0,0,0,192,210,208,232,222, 120,120,124,128,126,134,120,124, + 0,0,0,188,210,208,236,222, 176,176,128,122,120,122,124,124, 0,0,0,180,210,208,236,222, 178,178,122,122,122,124,126,124, + }, +}, + +{ // CP852 (9.112M chars) [33] + {NULL, NULL, NULL, NULL}, + 85, 183, 47, 36, 128, + {147,99,153,98,113,162,97,141, 139,113,105,98,99,105,112,106, 117,111,78,82,68,70,92,81, 93,63,63,89,87,89,89,145, + 187,171,114,163,117,105,174,173, 163,149,96,97,180,97,98,99, 96,96,96,96,96,186,101,174, 97,96,96,96,96,99,100,96, + 96,96,96,96,96,96,112,102, 96,96,96,96,96,96,96,96, 97,99,112,109,110,120,170,99, 174,96,96,96,96,98,162,96, + 115,98,115,99,99,120,184,183, 99,167,99,97,153,153,98,101, 97,97,96,97,96,158,99,96, 100,97,97,100,191,191,96,158, + 178,142,216,118,134,202,143,174, 177,140,130,157,125,109,134,147, 194,166,135,125,142,148,164,161, 172,142,141,143,163,165,129,208, + 222,229,177,175,143,129,196,201, 175,165,92,102,208,119,112,129, 92,92,92,92,92,217,114,205, 120,92,92,92,92,119,130,92, + 92,92,92,92,92,92,117,134, 95,95,92,92,92,92,92,99, 100,101,140,134,151,163,210,124, 213,92,92,92,92,116,181,94, + 176,147,127,120,122,171,198,197, 98,182,97,109,208,197,117,134, 100,102,93,126,93,173,129,92, 111,100,112,145,203,203,92,168, + }, + {0,0,0,0,0,0,0,0, 0,124,152,0,0,168,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 234,148,183,99,97,113,164,166, 117,160,105,108,196,160,193,147, 123,151,151,145,144,134,140,137, 123,116,177,135,205,109,140,149, + 99,185,176,199,192,207,123,147, 188,196,177,198,197,199,208,171, 173,98,190,193,202,160,196,129, 101,116,185,101,102,119,97,112, + 97,188,176,199,192,210,124,151, 188,197,178,199,198,199,208,173, 176,98,191,194,203,165,197,129, 100,117,186,97,109,97,97,0, + 127,96,131,106,97,136,102,129, 109,96,96,129,100,96,97,102, 122,147,109,96,96,114,120,101, 101,96,96,149,150,109,105,174, + 176,201,108,134,125,115,179,179, 153,141,96,96,173,96,98,99, 96,96,96,96,96,174,106,99, 96,96,96,96,96,110,110,96, + 96,96,96,96,96,96,98,98, 96,96,96,96,96,96,96,98, 97,97,137,96,141,138,199,98, 99,96,96,96,96,100,136,96, + 108,105,96,97,97,138,174,174, 99,131,100,96,100,100,100,102, 116,100,96,107,96,115,97,96, 100,97,97,99,180,181,96,164, + }, + {92,0,50,80,56,70,54,68, 82,58,30,64,104,40,54,46, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 8,0,2,2,2,2,2,2, 2,2,2,2,6,2,2,2, 20,0,2,2,2,2,2,2, 4,2,2,2,24,2,2,2, + 78,0,10,38,14,28,12,26, 96,60,28,64,128,38,54,46, 26,0,2,2,2,2,2,2, 2,2,2,2,24,2,2,2, + 14,0,2,2,2,2,2,2, 2,2,2,2,24,2,2,2, 8,0,2,2,2,2,2,2, 10,2,2,2,32,2,2,2, + 138,0,138,136,100,100,126,124, 180,178,162,150,190,144,146,142, 122,0,120,134,128,124,134,128, 182,146,170,148,172,110,140,132, + 132,0,132,130,120,106,130,132, 158,170,152,172,148,158,164,162, 86,0,86,90,142,152,50,60, 150,144,154,132,162,132,174,174, + 148,0,132,140,116,136,116,134, 232,176,140,174,232,152,168,164, 128,0,124,124,134,132,122,132, 156,160,164,142,166,136,162,164, + 124,0,124,120,130,132,128,132, 156,156,160,132,156,166,160,146, 118,0,96,134,136,98,136,108, 136,130,160,158,150,168,118,150, + }, +}, + +{ // Arabic (0.205M chars) [34] + {NULL, NULL, NULL, NULL}, + 180, 214, 71, 14, 128, + {0,0,0,0,0,0,0,0, 0,121,121,0,0,121,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 136,0,0,0,136,0,0,0, 0,0,0,0,138,136,0,0, 0,0,0,0,0,0,0,0, 0,0,0,136,0,0,0,152, + 0,151,167,198,147,188,171,230, 205,155,210,171,192,196,187,199, 176,204,173,195,191,195,175,181, 170,203,174,0,0,0,0,0, + 182,201,194,197,213,218,204,199, 211,169,210,171,161,136,141,183, 141,152,136,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,133,133,0,0,133,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 145,0,0,0,145,0,0,0, 0,0,0,0,184,145,0,0, 0,0,0,0,0,0,0,0, 0,0,0,148,0,0,0,159, + 0,171,146,149,145,145,147,191, 180,203,194,168,171,165,164,185, 152,192,159,171,155,163,167,168, 152,175,156,0,0,0,0,0, + 152,177,173,172,190,189,191,184, 173,192,184,156,145,145,146,145, 145,149,145,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,137,171,0,0,150,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 227,142,169,137,137,137,163,144, 137,152,138,137,171,141,178,147, 138,139,137,137,137,138,137,137, 137,137,167,137,194,137,137,137, + 137,137,137,137,137,137,137,137, 137,137,137,137,137,137,137,137, 137,137,137,137,137,137,137,137, 137,137,137,137,138,137,137,142, + 137,137,137,137,137,137,137,137, 137,137,137,137,137,137,137,137, 137,137,137,137,137,137,137,137, 137,137,137,137,137,137,137,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 137,164,151,154,137,159,165,165, 160,155,154,156,173,137,172,165, 170,158,160,163,159,161,154,161, 189,173,179,140,185,172,164,157, + 0,171,144,171,160,163,176,218, 199,202,201,175,192,195,189,204, 182,210,177,202,184,184,183,185, 163,200,179,0,0,0,0,0, + 160,196,197,191,226,205,211,195, 209,178,216,158,137,138,147,151, 146,154,138,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {158,0,126,158,180,178,180,180, 0,0,144,124,130,132,124,178, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 52,0,2,28,50,50,50,52, 0,0,2,2,2,2,2,34, 52,0,2,28,50,50,50,52, 0,0,20,10,2,2,2,56, + 2,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,16, + 2,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 48,0,2,24,46,46,46,48, 0,0,22,12,2,2,2,58, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 166,0,150,140,158,156,158,158, 0,0,146,124,130,132,122,178, 154,0,138,166,170,170,170,170, 0,0,134,162,120,124,114,168, + 134,0,150,152,144,144,144,144, 0,0,106,68,128,132,132,124, 144,0,150,152,154,154,154,154, 0,0,110,76,134,124,130,130, + 156,0,150,144,146,146,146,146, 0,0,140,142,130,128,126,130, 156,0,134,156,178,178,178,178, 0,0,138,116,132,130,128,174, + }, +}, + +{ // BIG5_HKSCS (0.271M chars) [35] + {NULL, NULL, NULL, NULL}, + 157, 175, 62, 14, 128, + {0,0,0,0,0,0,0,0, 108,149,150,140,0,150,152,140, 132,132,131,132,132,132,132,132, 132,132,132,131,131,132,131,130, + 139,181,164,132,214,207,204,195, 203,198,208,192,195,201,196,187, 202,189,195,196,188,194,190,182, 195,188,192,186,188,188,191,185, + 184,180,185,187,180,189,169,181, 135,142,140,142,141,141,140,141, 141,140,140,140,141,140,141,140, 140,140,142,140,140,141,141,140, + 140,140,140,140,140,146,149,145, 143,146,140,141,149,140,140,140, 140,140,140,140,140,140,140,140, 140,151,141,140,141,139,140,0, + 0,0,0,0,0,0,0,0, 134,133,133,134,0,124,134,133, 122,122,122,122,122,122,122,122, 122,122,122,121,121,122,122,121, + 132,216,163,137,212,204,205,192, 184,187,190,192,193,185,187,179, 188,190,183,193,178,189,189,198, 181,189,172,184,183,181,173,166, + 178,176,172,174,168,176,168,176, 163,140,141,134,134,134,135,134, 134,134,135,135,135,135,134,134, 135,135,134,134,134,134,134,134, + 134,134,134,134,134,134,135,136, 134,134,134,134,134,134,135,134, 134,134,134,134,134,136,135,134, 134,134,144,134,134,134,134,0, + }, + {0,0,0,0,0,0,0,0, 0,81,81,0,0,81,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,81,81,81,81,81,81,81, 81,81,81,81,81,81,81,81, 81,81,81,81,81,81,81,81, 81,81,81,81,85,81,81,81, + 200,202,189,193,189,173,185,189, 193,179,177,176,184,185,182,192, 186,181,175,172,181,185,166,189, 183,172,168,173,170,186,179,178, + 174,184,179,166,182,181,171,178, 178,187,186,179,178,172,187,186, 185,189,169,194,178,186,186,183, 180,180,179,177,186,177,193,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 157,191,170,191,186,176,168,184, 181,177,175,185,177,176,169,168, 182,178,179,190,172,180,184,171, 183,186,201,182,169,184,171,170, + 185,180,173,171,183,175,187,182, 183,185,183,177,184,178,189,186, 187,188,183,195,166,177,177,182, 181,174,185,182,180,178,175,181, + 176,176,179,175,179,183,187,172, 179,192,190,179,187,180,169,178, 168,171,175,183,191,176,182,182, 188,183,186,178,183,179,177,0, + }, + {232,0,254,254,110,120,118,114, 128,128,4,2,2,2,2,4, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 40,0,16,16,2,2,2,2, 128,128,2,2,2,2,2,2, 46,0,24,22,2,2,2,2, 128,128,2,2,2,2,2,2, + 66,0,42,40,2,2,2,2, 128,128,2,2,2,2,2,2, 128,0,128,128,2,2,2,2, 128,128,2,2,2,2,2,2, + 128,0,128,128,2,2,2,2, 128,128,2,2,2,2,2,2, 128,0,128,128,2,2,2,2, 128,128,2,2,2,2,2,2, + 0,0,0,0,132,142,144,140, 0,0,140,124,126,126,126,126, 0,0,0,0,134,142,142,138, 0,0,136,134,134,134,134,134, + 0,0,0,0,142,138,138,134, 0,0,136,138,132,132,134,134, 0,0,0,0,132,138,140,144, 0,0,134,128,138,138,132,136, + 0,0,0,0,134,144,136,140, 0,0,126,134,132,132,142,138, 0,0,0,0,134,144,142,138, 0,0,136,134,134,134,136,136, + 0,0,0,0,134,144,142,138, 0,0,144,132,132,132,132,132, 0,0,0,0,136,142,140,138, 0,0,136,132,134,136,134,138, + }, +}, + +{ // CP866 (75.238M chars) [36] + {NULL, NULL, NULL, NULL}, + 144, 168, 54, 34, 129, + {202,189,201,189,198,201,176,191, 205,171,201,198,196,207,207,203, 202,204,202,184,177,168,173,180, 170,166,142,175,168,167,156,168, + 200,185,197,186,194,201,174,188, 204,171,197,197,192,205,205,197, 60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60, + 60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60, + 203,204,203,185,172,167,174,181, 171,168,145,178,171,163,156,169, 122,121,61,61,64,61,61,61, 82,60,60,60,60,60,60,149, + 155,129,160,132,130,136,112,122, 155,123,142,126,140,137,156,133, 109,124,109,108,94,99,94,88, 84,75,58,94,87,91,94,119, + 193,150,189,167,164,195,129,155, 199,188,180,165,183,167,190,143, 55,55,55,55,55,55,55,55, 55,55,55,55,55,55,55,55, + 55,55,55,55,55,55,55,55, 55,55,55,55,55,55,55,55, 55,55,55,55,55,55,55,55, 55,55,55,55,55,55,55,55, + 172,176,181,172,118,175,146,138, 137,99,105,181,182,104,163,194, 90,129,56,55,55,62,55,57, 106,70,89,55,55,55,55,167, + }, + {0,0,0,0,0,0,0,0, 0,118,150,0,0,157,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 221,147,180,74,65,105,160,149, 120,156,94,110,186,165,186,136, 108,128,124,115,112,121,107,104, 100,97,169,132,195,113,104,144, + 134,102,74,101,82,91,78,71, 88,102,80,94,92,80,75,94, 112,60,73,125,77,72,89,82, 78,91,81,80,102,111,73,107, + 93,109,104,99,117,99,90,77, 101,105,109,107,97,101,119,121, 134,59,107,112,113,105,117,82, 72,94,116,60,90,75,74,0, + 210,180,193,179,186,209,168,174, 206,179,191,195,187,202,211,177, 198,196,203,188,161,170,168,174, 161,156,124,189,187,127,169,186, + 213,183,195,180,188,212,170,177, 208,179,193,198,188,204,215,181, 60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60, + 60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60, + 202,198,205,193,164,172,168,175, 162,157,125,191,187,137,171,187, 127,130,61,61,67,67,60,61, 82,60,61,60,66,61,60,147, + }, + {2,0,2,2,50,52,44,42, 12,26,10,176,176,176,22,96, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,4,6,2,2, 2,2,2,68,68,68,2,8, 128,0,58,84,128,128,128,128, 52,68,48,128,128,128,66,128, + 128,0,58,84,128,128,128,128, 52,68,48,128,128,128,66,128, 128,0,58,84,128,128,128,128, 52,68,48,128,128,128,66,128, + 2,0,2,2,16,18,10,10, 2,2,2,86,86,86,2,18, 64,0,4,30,96,98,92,86, 2,2,2,128,128,128,2,62, + 146,0,152,154,174,180,156,152, 138,138,114,116,116,116,110,112, 148,0,150,162,184,184,176,158, 138,140,112,130,130,130,110,118, + 154,0,152,150,150,138,126,128, 10,12,138,118,118,118,138,116, 176,0,132,158,200,200,200,198, 118,136,116,200,200,200,132,200, + 176,0,132,158,200,200,200,198, 118,136,116,200,200,200,132,200, 176,0,132,158,200,200,200,198, 118,136,116,200,200,200,132,200, + 152,0,152,154,122,140,132,122, 10,14,136,132,132,132,138,120, 166,0,126,164,192,204,210,212, 118,118,110,200,200,200,116,224, + }, +}, + +{ // UTF-16BE (921.761M chars) [37] + {NULL, NULL, NULL, NULL}, + 58, 128, 46, 5, 128, + {255,148,128,107,171,104,157,100, 118,108,101,120,124,90,133,117, 110,115,104,101,109,109,114,104, 109,116,118,96,107,107,124,118, + 70,74,71,58,71,66,66,63, 77,54,49,59,103,87,65,64, 97,64,107,90,85,62,70,84, 68,102,96,78,93,84,65,62, + 98,86,102,72,68,106,98,98, 86,95,76,75,78,83,75,75, 86,85,82,77,76,85,76,77, 73,80,63,66,87,93,89,101, + 71,70,54,77,57,100,56,43, 81,50,69,75,59,63,75,80, 86,62,64,76,70,35,84,71, 72,68,83,83,81,83,96,112, + 158,116,117,132,124,138,121,108, 116,113,119,126,121,103,105,108, 120,97,117,112,89,96,106,109, 108,102,107,100,99,84,118,104, + 97,103,109,97,115,85,102,101, 103,94,96,102,108,105,104,111, 112,95,96,109,94,101,100,108, 109,120,113,105,98,89,95,106, + 95,111,93,114,92,107,109,118, 118,105,105,108,86,103,97,102, 101,110,88,98,94,117,109,105, 78,77,73,73,66,78,86,78, + 104,107,89,105,83,121,89,89, 97,107,111,111,101,103,99,100, 88,81,89,122,99,70,98,85, 99,87,106,114,125,103,97,136, + }, + {236,123,89,99,100,109,89,100, 108,198,193,73,119,181,104,83, 99,103,97,99,99,97,82,94, 101,109,110,107,104,93,93,106, + 216,151,203,161,118,166,169,173, 164,164,144,152,168,182,186,198, 189,182,179,173,169,172,169,168, 170,168,177,180,198,196,198,153, + 139,171,167,169,169,168,165,158, 160,167,150,145,164,164,166,162, 165,146,165,168,170,153,155,156, 147,151,149,145,145,143,117,176, + 111,206,186,196,198,208,187,191, 193,205,165,175,201,192,202,201, 195,149,202,203,208,188,183,182, 175,180,162,150,135,150,118,103, + 112,108,111,92,98,93,88,76, 111,111,111,115,106,106,97,112, 115,111,81,95,101,109,110,98, 111,93,99,76,83,70,93,76, + 118,92,84,86,91,83,65,85, 86,99,71,87,101,87,83,95, 96,99,90,82,97,95,62,97, 88,93,93,96,90,93,79,99, + 100,101,86,92,104,90,86,96, 95,94,77,82,107,97,85,85, 105,105,86,90,102,108,87,87, 97,112,82,93,109,99,100,96, + 112,124,97,99,120,103,92,104, 114,131,110,75,88,121,83,84, 84,109,72,116,98,89,110,72, 99,78,96,85,114,106,69,129, + }, + {126,120,126,128,126,126,126,126, 206,210,222,240,224,222,220,216, 122,164,100,126,150,150,112,122, 232,224,222,208,220,232,222,228, + 28,128,42,46,76,82,30,42, 128,128,128,128,128,128,128,128, 18,128,28,34,58,64,18,28, 128,128,128,128,128,128,128,128, + 16,128,26,32,54,62,16,26, 128,128,128,128,128,128,128,128, 22,128,32,38,70,74,22,32, 128,128,128,128,128,128,128,128, + 30,128,42,48,82,88,32,42, 128,128,128,128,128,128,128,128, 90,190,74,128,122,156,100,110, 212,182,194,168,162,186,118,178, + 96,180,78,128,126,140,100,104, 98,96,94,100,98,90,80,92, 108,222,102,132,140,156,114,122, 236,234,220,202,226,226,226,230, + 118,206,78,150,134,154,108,118, 228,218,192,196,192,176,210,224, 112,218,96,148,132,158,110,122, 232,232,220,208,226,212,224,228, + 112,224,102,146,142,156,108,124, 234,232,226,222,226,226,216,222, 114,196,84,148,140,164,110,118, 242,232,196,208,200,198,192,206, + 110,160,74,150,140,156,114,118, 230,224,160,160,162,160,160,220, 124,240,102,144,132,152,106,116, 230,226,200,198,162,174,190,230, + }, +}, + +{ // Latin3 (0.294M chars) [38] + {NULL, NULL, ced_hires_16, ced_hires_16, }, + 99, 202, 43, 23, 128, + {0,0,0,0,0,0,0,0, 0,142,142,0,0,142,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 180,143,143,143,145,0,143,148, 145,143,143,143,143,143,0,146, 147,143,143,143,144,143,143,148, 145,206,195,143,143,143,0,145, + 143,143,143,0,158,143,143,150, 143,151,143,143,143,143,143,143, 0,145,143,162,143,143,147,143, 143,143,143,143,172,143,143,143, + 154,143,143,0,165,177,154,182, 165,150,143,148,143,144,143,145, 0,145,143,162,143,143,157,143, 143,143,143,143,172,144,143,143, + 0,0,0,0,0,0,0,0, 0,112,112,0,0,112,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 188,148,144,162,154,0,145,154, 146,209,160,192,146,145,0,200, 163,148,147,145,151,144,144,167, 145,236,159,192,146,145,0,204, + 161,202,162,87,203,144,144,187, 186,211,176,153,145,198,159,150, 76,180,149,201,165,145,202,146, 144,144,182,153,204,144,144,178, + 188,206,154,0,204,144,144,175, 177,206,166,153,158,208,152,146, 0,180,159,203,157,145,200,146, 144,155,182,149,192,144,144,147, + }, + {86,0,0,0,0,0,0,0, 0,149,151,0,0,159,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 223,146,167,143,143,144,158,154, 152,149,146,143,193,154,169,146, 150,160,164,151,150,149,147,146, 146,146,160,144,200,143,144,146, + 143,194,180,194,186,193,173,187, 178,180,164,179,196,190,207,184, 177,157,206,202,196,184,182,176, 156,184,174,143,143,145,144,143, + 144,192,181,189,184,193,172,184, 175,179,163,204,214,197,221,182, 173,152,217,199,214,184,180,176, 154,186,193,144,147,143,144,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 180,143,143,143,146,164,143,146, 146,145,143,171,143,144,177,162, 146,143,143,143,145,143,143,148, 146,199,202,192,143,143,169,162, + 145,144,145,0,158,143,143,149, 143,151,144,143,143,146,144,143, 0,144,144,146,143,143,148,144, 143,143,143,143,146,143,143,161, + 144,144,144,0,159,143,143,146, 143,147,144,143,143,146,143,143, 0,144,144,147,146,143,150,143, 143,143,144,143,145,143,143,143, + }, + {162,0,130,150,128,132,120,124, 0,0,156,140,170,170,172,172, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 24,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 30,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 26,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 16,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 24,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 144,0,124,142,134,134,124,120, 0,0,174,132,162,162,162,166, 118,0,132,130,74,76,134,134, 0,0,126,164,140,140,140,142, + 118,0,100,110,147,145,94,90, 0,0,152,136,178,170,170,170, 124,0,102,116,143,145,108,108, 0,0,170,132,166,166,164,166, + 134,0,140,130,82,86,131,131, 0,0,168,152,154,156,164,156, 130,0,124,124,92,96,137,137, 0,0,148,152,164,170,166,166, + }, +}, + +{ // UTF-16LE (912.138M chars) [39] + {NULL, NULL, NULL, NULL}, + 58, 128, 46, 4, 127, + {255,146,126,120,177,123,159,99, 110,78,94,116,115,99,130,112, 110,112,82,97,100,94,113,102, 100,94,112,92,103,102,120,113, + 60,84,76,72,67,43,63,72, 75,64,74,96,95,88,83,52, 78,81,96,84,76,57,31,82, 83,85,86,82,92,78,88,68, + 84,91,96,52,84,96,99,105, 89,83,72,65,83,88,84,86, 81,94,75,70,97,95,78,57, 109,82,33,91,80,77,77,75, + 25,59,64,81,47,69,60,19, 96,31,92,30,20,68,72,81, 58,66,54,80,88,55,60,66, 55,40,45,78,55,99,113,116, + 161,117,113,130,127,131,118,108, 119,110,115,123,129,107,105,108, 116,99,114,110,93,99,108,111, 109,103,113,103,97,84,101,103, + 91,100,101,94,110,85,98,97, 98,88,86,93,108,101,99,107, 111,91,107,105,91,95,97,104, 105,118,111,98,97,92,87,101, + 101,106,99,111,87,110,107,116, 114,105,99,102,87,99,93,98, 100,103,88,98,89,111,105,101, 111,92,89,98,104,108,110,105, + 102,102,83,99,77,115,78,86, 85,100,104,107,98,100,92,97, 86,77,86,117,94,64,98,84, 97,89,103,109,121,97,98,126, + }, + {236,123,100,94,96,100,91,97, 108,196,193,90,112,182,101,92, 101,105,95,98,102,96,89,96, 98,112,104,103,108,101,95,106, + 216,149,203,169,119,166,174,176, 165,165,142,152,168,181,187,198, 189,182,180,175,173,177,172,171, 173,176,177,184,198,197,198,156, + 139,172,168,169,171,168,166,159, 159,167,150,145,165,165,166,163, 165,145,164,168,170,153,155,156, 147,150,149,144,147,141,118,176, + 125,206,186,196,197,208,187,190, 192,205,164,175,200,191,201,201, 195,151,202,202,207,188,182,182, 175,179,161,149,134,149,121,100, + 115,103,100,89,101,94,90,87, 101,114,108,116,108,98,92,113, 113,107,90,81,101,110,105,94, 107,95,107,74,84,72,92,81, + 118,95,89,86,95,86,81,84, 92,99,79,88,102,91,89,97, 104,100,92,91,99,99,79,96, 89,102,98,99,90,95,85,101, + 101,103,87,94,104,94,85,94, 97,94,83,90,106,96,82,86, 105,103,85,93,102,108,92,91, 91,103,79,87,101,91,92,87, + 112,124,97,99,119,112,90,105, 108,128,107,81,91,121,89,85, 88,97,79,113,98,90,111,79, 102,83,100,94,112,102,86,130, + }, + {128,124,128,126,126,126,126,126, 204,202,224,222,224,224,220,218, 120,164,116,98,140,156,124,122, 220,224,168,162,168,220,206,238, + 82,158,96,72,110,162,88,92, 170,160,158,158,158,176,158,164, 54,158,66,68,104,108,56,66, 158,158,158,158,158,148,158,158, + 48,158,58,62,88,96,50,60, 158,158,158,158,158,148,158,158, 50,158,60,64,90,98,52,62, 158,158,158,158,158,148,158,158, + 62,158,74,80,110,116,66,76, 158,158,158,158,158,148,158,158, 112,192,96,138,138,132,104,106, 206,210,184,198,188,196,186,186, + 106,174,86,120,124,134,92,112, 96,94,82,82,82,78,66,76, 122,214,110,132,136,160,112,112, 228,230,210,212,214,210,216,212, + 90,200,118,146,140,162,114,120, 234,222,202,200,206,188,196,196, 96,206,128,142,144,156,116,126, 238,216,210,206,214,206,218,208, + 94,216,130,142,136,160,108,126, 238,236,218,214,222,212,214,212, 94,214,134,138,140,158,114,124, 238,238,212,208,212,204,214,208, + 62,162,54,148,148,164,116,124, 232,226,164,164,162,150,164,174, 94,210,110,146,134,162,112,118, 232,228,192,198,194,188,198,208, + }, +}, + +{ // HZ-GB-2312 (87.400M chars) [40] + {NULL, NULL, NULL, NULL}, + 92, 0, 37, 0, 255, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {126,0,164,0,0,0,126,0, 178,139,148,0,0,132,154,146, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 161,195,176,211,162,158,148,144, 213,209,179,164,154,148,168,174, 182,184,172,182,184,188,187,175, 180,183,176,176,182,177,179,172, + 170,193,196,199,167,165,195,168, 183,178,178,180,168,178,186,182, 183,158,180,182,181,183,186,180, 155,132,136,132,146,136,132,132, + 132,132,136,139,173,183,178,171, 162,161,132,142,144,132,139,139, 132,136,139,144,132,132,149,139, 132,132,136,152,139,132,245,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, +}, + +{ // CSN_369103 (8.850M chars) [41] + {NULL, NULL, NULL, NULL}, + 90, 204, 46, 27, 127, + {0,0,0,0,0,0,0,0, 0,90,90,0,0,90,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 176,178,96,184,92,102,188,127, 120,153,117,98,133,96,143,153, 122,178,93,182,115,102,188,96, 119,152,117,98,133,101,141,152, + 98,169,119,130,151,111,96,137, 171,147,170,103,153,155,105,120, 96,98,118,171,112,104,128,105, 180,129,158,96,133,127,119,102, + 99,169,99,125,153,107,102,128, 169,142,170,99,155,155,103,119, 95,99,118,171,112,105,148,95, 180,130,154,95,137,127,119,96, + 0,0,0,0,0,0,0,0, 0,55,55,0,0,55,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 185,202,93,207,98,140,210,145, 119,178,153,123,170,124,172,196, 158,217,94,211,139,141,210,121, 116,176,151,152,187,124,173,200, + 103,198,155,156,200,128,165,183, 202,208,195,143,194,194,151,144, 149,174,157,197,159,157,199,120, 192,171,178,137,201,170,155,174, + 106,203,144,173,201,105,197,170, 203,203,208,143,202,204,139,150, 148,188,166,199,147,166,197,121, 192,191,178,144,188,182,155,122, + }, + {62,0,0,0,0,0,0,0, 0,129,153,0,0,162,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 228,154,181,95,91,108,164,158, 144,155,114,105,191,153,189,148, 132,145,139,130,128,126,119,117, 115,116,177,135,201,95,124,155, + 93,200,180,210,197,203,168,188, 175,191,170,190,200,190,208,194, 182,141,204,199,200,181,182,186, 146,188,181,105,114,126,105,120, + 112,201,181,209,196,205,167,186, 172,191,169,190,200,189,207,194, 180,135,203,198,199,182,181,191, 143,189,181,100,125,92,99,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 176,176,95,167,93,99,163,117, 120,144,106,125,140,115,142,179, 121,178,93,168,111,97,163,92, 119,144,107,125,141,107,143,179, + 99,160,117,127,149,96,190,132, 166,138,143,97,95,185,108,127, 94,120,128,168,99,91,130,104, 171,126,127,95,123,101,122,153, + 100,161,110,128,150,96,190,125, 167,128,145,96,95,185,105,130, 94,120,128,170,114,91,134,95, 172,126,113,95,119,100,122,97, + }, + {182,0,124,152,122,132,122,132, 0,0,162,164,156,176,156,176, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 12,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 14,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 24,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 26,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 24,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 26,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 132,0,96,130,142,136,100,114, 0,0,172,130,168,162,110,142, 130,0,136,132,52,54,136,130, 0,0,108,174,92,106,170,166, + 98,0,90,100,140,142,100,90, 0,0,164,122,170,178,132,132, 100,0,92,102,138,142,108,110, 0,0,166,106,174,156,130,144, + 134,0,136,134,38,54,134,134, 0,0,118,168,102,146,168,180, 132,0,130,134,44,58,136,140, 0,0,108,170,98,158,172,156, + }, +}, + +{ // ISO-2022-KR (85.145M chars) [42] + {NULL, NULL, NULL, NULL}, + 44, 144, 15, 3, 129, + {0,0,130,0,0,0,0,0, 0,66,66,0,0,66,213,252, 0,0,0,0,0,0,0,0, 0,0,0,224,0,0,91,91, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {80,0,0,0,0,0,0,0, 0,155,178,0,0,191,94,16, 0,0,0,0,0,0,0,0, 0,0,0,159,0,0,115,80, + 237,178,211,150,215,142,197,197, 215,186,147,141,202,191,204,184, 182,193,189,179,176,177,168,168, 173,174,186,191,233,164,175,184, + 177,172,153,166,162,158,159,169, 164,164,152,159,147,160,152,147, 160,143,152,154,156,148,153,153, 128,113,118,160,143,179,134,168, + 120,133,133,128,134,139,123,121, 142,133,113,107,120,125,168,114, 123,102,122,140,136,109,112,132, 116,115,107,101,157,124,155,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {130,130,126,130,130,130,118,128, 0,0,0,0,0,0,0,0, 42,2,134,2,62,40,70,60, 0,0,0,0,0,0,0,0, + 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, +}, + +{ // Latin6 (0.061M chars) [43] + {NULL, NULL, ced_hires_19, ced_hires_19, }, + 93, 214, 54, 26, 129, + {0,0,0,0,0,0,0,0, 0,156,156,0,0,156,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 175,158,158,158,158,158,158,159, 158,158,161,158,159,158,158,158, 158,158,158,158,159,158,158,159, 158,158,161,158,159,158,158,158, + 159,164,158,159,162,158,158,158, 171,161,158,158,159,162,158,158, 158,160,158,158,158,158,159,158, 158,158,162,158,158,158,158,158, + 159,164,158,158,163,158,158,158, 171,160,158,158,159,162,158,158, 158,160,158,158,158,158,162,158, 158,159,162,158,159,158,158,158, + 0,0,0,0,0,0,0,0, 0,130,130,0,0,130,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 180,198,158,158,160,158,158,160, 158,163,190,158,168,158,159,158, 163,212,158,158,162,158,158,166, 159,158,180,158,168,158,158,158, + 206,194,163,172,195,183,171,185, 198,203,191,160,209,190,162,159, 161,179,158,193,165,163,194,158, 179,176,175,160,196,171,160,172, + 211,198,160,173,196,193,171,194, 199,198,204,160,214,199,160,158, 167,178,159,195,161,163,193,158, 178,219,176,159,185,179,160,158, + }, + {0,0,0,0,0,0,0,0, 0,160,164,0,0,168,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 227,163,177,159,159,159,210,162, 160,170,159,159,189,161,185,159, 162,161,160,159,159,159,159,159, 159,159,178,159,200,159,159,164, + 159,184,177,200,197,187,171,187, 174,180,189,189,194,188,202,180, 180,160,204,208,200,171,181,173, 162,166,178,159,159,159,159,159, + 159,184,179,199,197,189,170,185, 172,181,189,189,194,186,201,179, 179,159,203,208,200,171,185,173, 162,169,178,159,159,159,159,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 176,159,159,159,159,159,159,159, 159,159,163,159,161,159,159,159, 159,159,159,159,159,160,159,159, 159,159,163,159,161,159,159,159, + 161,164,159,159,163,159,159,159, 168,160,159,159,159,168,159,159, 160,159,159,159,159,159,159,159, 159,159,159,159,159,159,159,164, + 161,164,159,159,163,159,159,159, 169,159,159,159,159,169,159,159, 160,159,159,159,159,159,159,159, 159,159,159,159,159,159,159,159, + }, + {152,0,122,146,128,132,128,130, 0,0,154,156,154,156,154,158, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 4,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 4,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, 4,0,2,2,2,2,2,2, 0,0,2,2,2,2,2,2, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 144,0,114,140,138,132,120,128, 0,0,162,154,152,154,152,154, 142,0,138,134,108,112,134,126, 0,0,154,158,154,156,154,156, + 118,0,98,118,143,145,106,106, 0,0,154,154,162,156,154,154, 132,0,108,126,143,143,118,118, 0,0,154,156,158,158,154,156, + 126,0,132,132,90,92,139,139, 0,0,152,156,152,156,162,156, 126,0,140,126,98,102,131,131, 0,0,154,156,154,158,156,158, + }, +}, + +{ // UTF7 (0.037M chars) [44] + {NULL, NULL, NULL, NULL}, + 77, 207, 29, 27, 255, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,184, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,189,189,0,0,189,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,189,189,189,189,189,189,189, 189,189,189,0,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, + 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, +}, + +{ // ISO_2022_CN (63.392M chars) [45] + {NULL, NULL, NULL, NULL}, + 43, 144, 14, 3, 129, + {0,0,0,0,0,0,0,0, 0,70,70,0,0,70,213,252, 0,0,0,0,0,0,0,0, 0,0,0,222,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {79,0,0,0,0,0,0,0, 0,155,177,0,0,190,19,19, 0,0,0,0,0,0,0,0, 0,0,0,158,0,0,114,79, + 240,177,210,148,212,141,197,195, 214,185,147,140,202,190,203,183, 182,192,188,179,175,177,167,168, 173,174,186,190,231,164,175,183, + 177,172,152,166,161,157,158,168, 164,163,151,158,146,160,151,146, 159,143,151,153,155,147,152,152, 127,112,117,160,142,178,133,168, + 119,132,130,126,124,138,122,120, 141,131,112,106,119,124,122,112, 122,101,108,135,135,101,111,130, 112,115,106,96,156,123,154,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {130,130,126,128,130,128,128,130, 0,0,0,0,0,0,0,0, 44,2,134,2,62,26,62,10, 0,0,0,0,0,0,0,0, + 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, +}, + +{ // BIG5-CP950 (0.029M chars) [46] + {NULL, NULL, NULL, NULL}, + 158, 182, 61, 26, 128, + {0,166,166,166,166,166,166,166, 166,177,177,166,166,177,166,166, 158,158,158,158,158,158,158,158, 158,158,158,158,158,158,158,158, + 166,179,169,151,208,201,198,190, 197,193,202,187,190,196,191,184, 197,185,191,191,184,189,185,179, 190,185,188,182,184,184,187,182, + 181,178,182,183,178,186,166,166, 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,166,166, + 166,166,166,166,166,167,168,167, 166,167,166,166,168,166,166,166, 166,166,166,166,166,166,166,166, 166,168,166,166,166,166,166,101, + 0,161,161,161,161,161,161,161, 161,161,161,161,161,161,161,161, 149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149, + 161,211,166,161,206,199,200,187, 180,182,185,186,188,181,182,176, 183,186,179,188,175,185,185,193, 178,185,170,180,179,177,170,167, + 175,174,171,172,168,174,169,161, 161,161,161,161,161,161,161,161, 161,161,161,161,161,161,161,161, 161,161,161,161,161,161,161,161, + 161,161,161,161,161,161,161,161, 161,161,161,161,161,161,161,161, 161,161,161,161,161,161,161,161, 161,161,161,161,161,161,161,167, + }, + {0,0,0,0,0,0,0,0, 0,113,113,0,0,113,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113, 113,113,113,113,113,113,113,113, + 197,198,187,191,188,176,184,188, 190,180,179,179,184,184,183,189, 185,182,178,177,182,184,174,187, 183,177,175,178,176,185,181,180, + 178,183,181,174,182,182,176,180, 180,186,185,181,180,177,186,185, 184,187,175,191,180,185,185,183, 181,180,181,179,185,179,190,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 150,188,176,189,185,179,174,184, 181,179,178,184,179,179,175,174, 182,179,180,187,176,180,183,176, 183,185,197,182,175,183,176,175, + 184,181,177,176,183,178,186,182, 182,184,183,179,184,180,187,185, 186,186,182,191,174,179,179,182, 182,177,184,182,180,179,178,181, + 179,179,180,177,180,182,186,176, 180,190,188,180,185,181,175,179, 174,176,178,183,188,178,182,182, 186,183,185,180,183,180,180,121, + }, + {170,0,170,170,104,110,110,108, 128,128,2,2,2,2,2,78, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 14,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, 20,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, + 34,0,10,10,2,2,2,2, 128,128,2,2,2,2,2,2, 42,0,18,18,2,2,2,2, 128,128,2,2,2,2,2,2, + 40,0,18,16,2,2,2,2, 128,128,2,2,2,2,2,2, 42,0,18,18,2,2,2,2, 128,128,2,2,2,2,2,2, + 0,0,0,0,134,142,140,138, 0,0,132,132,132,132,132,132, 0,0,0,0,134,142,140,138, 0,0,136,134,134,136,136,136, + 0,0,0,0,142,136,138,134, 0,0,134,138,132,134,134,134, 0,0,0,0,134,136,140,144, 0,0,134,130,138,136,134,136, + 0,0,0,0,136,142,138,140, 0,0,130,134,134,132,140,138, 0,0,0,0,134,142,140,138, 0,0,136,134,134,136,136,136, + 0,0,0,0,134,142,140,138, 0,0,138,134,134,134,134,134, 160,128,160,160,134,140,140,138, 128,128,136,134,134,134,136,136, + }, +}, + +{ // JAGRAN (0.046M chars) [47] + {NULL, NULL, NULL, NULL}, + 142, 199, 66, 34, 133, + {174,174,174,174,174,174,174,174, 174,182,182,174,174,182,174,174, 174,174,174,174,174,174,174,174, 174,174,174,0,0,0,174,174, + 0,182,182,182,182,182,182,182, 182,182,182,182,182,0,182,182, 182,182,0,182,182,182,182,182, 182,182,182,182,182,182,182,182, + 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,0,182, + 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,0,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, + 166,166,166,166,166,166,166,166, 166,178,178,166,166,178,166,166, 166,166,166,166,166,166,166,166, 166,166,166,0,0,0,166,166, + 0,178,178,178,178,178,178,178, 178,178,178,178,178,0,178,178, 166,166,0,166,166,166,166,166, 166,166,166,166,166,166,166,166, + 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,0,166, + 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,0,166, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + }, + {0,0,0,0,0,0,0,0, 0,180,180,0,0,180,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,180,127,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,127,180, 180,180,180,180,180,180,180,180, 180,180,127,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,127,180,180,0, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,0,0,0,176,176, + 0,176,176,176,176,176,176,176, 176,176,176,176,176,0,176,176, 176,176,0,176,176,176,176,176, 176,176,176,176,176,176,176,176, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,0,176, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,0,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 132,0,132,132,132,132,132,132, 130,130,130,130,130,130,130,130, 136,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, + 136,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, 136,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, + 136,0,134,136,134,134,136,134, 130,130,130,130,130,130,130,130, 136,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, + 136,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, 136,0,134,136,134,134,136,134, 130,130,130,130,130,130,130,130, + }, +}, + +{ // BHASKAR (0.047M chars) [48] + {NULL, NULL, NULL, NULL}, + 141, 199, 66, 34, 132, + {174,174,174,174,174,174,174,174, 174,182,182,174,174,182,174,174, 174,174,174,174,174,174,174,174, 174,174,174,0,0,0,174,174, + 0,182,182,182,181,182,182,182, 182,182,182,182,182,0,182,182, 182,182,0,182,182,182,182,182, 182,182,182,182,182,182,182,182, + 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,0,182, + 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,0,181, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, + 166,166,166,166,166,166,166,166, 166,178,178,166,166,178,166,166, 166,166,166,166,166,166,166,166, 166,166,166,0,0,0,166,166, + 0,178,178,178,178,178,178,178, 178,178,178,178,178,0,178,178, 166,166,0,166,166,166,166,166, 166,166,166,166,166,166,166,166, + 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,0,166, + 166,166,166,166,166,166,166,166, 166,166,166,166,166,166,0,166, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + }, + {0,0,0,0,0,0,0,0, 0,180,180,0,0,180,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,126,180, 180,180,180,180,180,180,180,180, 180,180,126,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,0, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,0,0,0,176,176, + 0,176,176,176,176,176,176,176, 176,176,176,176,176,0,176,176, 176,176,0,176,176,176,176,176, 176,176,176,176,176,176,176,176, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,0,176, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,0,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 132,0,132,132,132,132,132,132, 130,130,130,130,130,130,130,130, 134,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, + 136,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, 136,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, + 134,0,134,136,134,134,136,134, 130,130,130,130,130,130,130,130, 136,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, + 136,0,134,134,134,134,134,134, 130,130,130,130,130,130,130,130, 134,0,134,136,134,134,136,134, 130,130,130,130,130,130,130,130, + }, +}, + +{ // HTCHANAKYA (0.041M chars) [49] + {NULL, NULL, NULL, NULL}, + 142, 202, 68, 32, 133, + {173,0,0,0,173,173,173,173, 173,182,171,173,105,171,0,0, 0,173,173,0,173,173,173,173, 0,0,173,0,0,0,0,0, + 181,182,182,182,181,182,182,182, 182,182,182,182,182,0,182,182, 182,182,182,182,182,182,182,0, 182,182,182,182,182,182,182,182, + 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, + 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,0,181, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, + 169,0,0,0,169,169,169,169, 169,180,170,169,0,170,0,0, 0,169,169,0,169,169,169,169, 0,0,169,0,0,0,0,0, + 0,180,180,180,179,180,180,180, 180,180,180,180,180,0,180,180, 169,169,169,169,169,169,169,0, 169,169,169,169,169,169,169,169, + 169,169,169,169,169,169,169,169, 169,169,169,169,169,169,169,169, 169,169,169,169,169,169,169,169, 169,169,169,169,169,169,169,169, + 169,169,169,169,169,169,169,169, 169,169,169,169,169,169,0,168, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + }, + {0,0,0,0,0,0,0,0, 0,181,181,0,0,181,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,181,129,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, + 181,181,181,181,181,181,181,181, 181,181,181,129,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, + 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,0, + 176,0,0,0,176,176,176,176, 176,176,0,176,0,0,0,0, 0,176,176,0,176,176,176,176, 0,0,176,0,0,0,0,0, + 175,176,176,176,176,176,176,176, 176,176,176,176,176,0,176,176, 176,176,176,176,176,176,176,0, 176,176,176,176,176,176,176,176, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,0,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 130,0,128,130,128,130,130,128, 128,128,128,128,128,128,128,128, 134,0,134,134,134,134,134,134, 132,132,132,132,132,132,132,132, + 134,0,134,134,134,134,134,134, 132,132,132,132,132,132,132,132, 134,0,134,134,134,134,134,134, 132,132,132,132,132,132,132,132, + 134,0,134,134,134,134,134,134, 132,132,132,132,132,132,132,132, 134,0,134,134,134,134,134,134, 132,132,132,132,132,132,132,132, + 134,0,134,134,134,134,134,134, 132,132,132,132,132,132,132,132, 134,0,134,134,134,134,134,134, 132,132,132,132,132,132,132,132, + }, +}, + +{ // TSCII (0.047M chars) [50] + {NULL, NULL, NULL, NULL}, + 141, 199, 66, 33, 134, + {173,173,173,173,173,173,173,173, 173,182,182,173,173,182,173,173, 173,173,173,173,173,173,173,173, 173,173,173,173,173,173,0,173, + 0,181,181,181,181,181,157,157, 157,181,0,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, + 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, + 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,0, + 167,167,167,167,167,167,167,167, 167,179,179,167,167,167,167,167, 167,167,175,168,170,167,167,167, 167,167,167,167,167,167,0,167, + 0,178,178,178,178,178,0,0, 0,183,0,178,178,178,178,178, 167,167,167,167,167,167,167,167, 167,167,167,167,167,167,167,167, + 167,167,167,167,167,167,167,167, 167,167,167,167,167,167,167,167, 167,167,167,167,167,167,167,167, 167,167,167,167,167,167,167,167, + 167,167,167,167,167,167,167,167, 167,167,167,167,167,167,167,167, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,0, + }, + {0,0,0,0,0,0,0,0, 0,179,179,0,0,125,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 170,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,180,179,179,179,180,179,179, 179,180,179,179,179,179,179,179, 179,179,179,182,179,179,179,179, 179,179,179,179,179,179,179,0, + 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,0,175, + 0,175,175,175,175,175,0,0, 0,175,0,175,175,175,175,175, 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,175,175, + 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,175,175, + 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,175,175, 175,175,175,175,175,175,175,0, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 132,0,132,132,132,132,132,132, 128,128,130,128,128,128,128,128, 132,0,134,132,132,132,134,136, 130,130,132,130,130,130,130,130, + 134,0,136,134,134,134,134,134, 132,130,130,132,132,130,130,130, 134,0,134,134,134,134,134,134, 130,130,132,130,130,130,130,130, + 134,0,134,134,134,134,134,134, 130,130,132,130,130,130,130,130, 134,0,134,134,134,134,134,134, 130,130,132,130,130,130,130,130, + 134,0,134,134,134,134,134,134, 130,130,132,130,130,130,130,130, 134,0,134,134,134,134,134,134, 130,130,132,130,130,130,130,130, + }, +}, + +{ // TAM (0.036M chars) [51] + {NULL, NULL, NULL, NULL}, + 140, 203, 70, 33, 133, + {0,0,174,174,174,174,174,174, 174,184,184,174,174,174,0,0, 0,0,0,0,0,0,0,0, 174,174,174,174,174,0,0,174, + 0,183,183,183,183,0,183,183, 183,0,161,161,161,0,183,183, 183,183,183,183,183,183,183,0, 183,183,183,183,183,183,183,183, + 183,183,183,183,183,183,183,183, 183,183,0,183,183,183,183,183, 0,0,0,0,0,0,183,183, 183,183,183,183,183,183,183,183, + 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, + 0,0,170,170,170,170,170,170, 170,181,181,170,170,0,0,0, 0,0,0,0,0,0,0,0, 170,170,170,170,170,0,0,170, + 0,181,181,181,181,0,181,181, 181,0,0,0,0,0,181,181, 170,170,170,170,170,170,170,0, 170,170,170,170,170,170,170,170, + 170,170,170,170,170,170,170,170, 170,170,0,170,170,170,170,170, 0,0,0,0,0,0,170,170, 170,170,170,170,170,170,170,170, + 170,170,170,170,170,170,170,170, 170,170,170,170,170,170,170,170, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, + }, + {0,0,0,0,0,0,0,0, 0,182,182,0,0,132,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, + 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,132,132,132,132,132, + 132,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182, 182,182,182,132,132,132,132,0, + 0,0,177,177,177,177,177,177, 177,177,177,177,177,0,0,0, 0,0,0,0,0,0,0,0, 177,177,177,177,177,0,0,177, + 0,177,177,177,177,0,177,177, 177,0,0,0,0,0,177,177, 177,177,177,177,177,177,177,0, 177,177,177,177,177,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,0,177,177,177,177,177, 0,0,0,0,0,0,177,177, 177,177,177,177,177,177,177,177, + 177,177,177,177,177,177,177,177, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,177,177, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 132,0,132,132,132,132,132,132, 130,130,130,128,128,128,128,128, 134,0,136,136,136,134,136,134, 132,132,132,134,134,132,132,132, + 134,0,134,134,134,134,134,134, 132,132,132,132,132,132,134,134, 134,0,134,134,134,134,134,134, 132,134,132,132,132,132,132,132, + 134,0,134,134,134,134,134,134, 132,134,132,132,132,132,132,132, 134,0,134,134,134,134,134,134, 132,132,134,132,132,132,132,132, + 134,0,134,134,134,134,134,134, 132,134,132,132,132,132,132,132, 134,0,134,134,134,134,134,134, 132,134,132,132,132,132,132,132, + }, +}, + +{ // TAB (0.030M chars) [52] + {NULL, NULL, NULL, NULL}, + 137, 210, 72, 28, 132, + {0,0,0,0,0,0,0,0, 0,174,174,0,0,174,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,183,183,183,0,183,183, 183,0,165,165,165,0,183,183, 183,183,183,183,183,183,183,0, 183,183,183,183,183,183,183,183, + 183,183,183,183,183,183,183,183, 183,183,0,183,183,183,183,183, 0,0,0,0,0,0,183,0, 0,0,0,183,183,183,183,183, + 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, + 0,0,0,0,0,0,0,0, 0,174,174,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,186,186,186,0,186,186, 186,0,0,0,0,0,186,186, 177,177,177,177,177,177,177,0, 177,177,177,177,177,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,0,177,177,177,177,177, 0,0,0,0,0,0,177,0, 0,0,0,177,177,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 186,186,186,186,186,186,186,186, 186,186,186,186,186,186,186,186, + }, + {0,0,0,0,0,0,0,0, 0,183,183,0,0,136,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, + 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, + 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,183, 183,183,183,183,183,183,183,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,176,176,176,0,176,176, 176,0,0,0,0,0,176,176, 176,176,176,176,176,176,176,0, 176,176,176,176,176,176,176,176, + 176,176,176,176,176,176,176,176, 176,176,0,176,176,176,176,176, 0,0,0,0,0,0,176,0, 0,0,0,176,176,176,176,176, + 176,176,176,176,176,176,176,176, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,176,176, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,0,0,0,0, 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, 128,0,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 132,0,132,134,134,134,134,132, 128,128,134,134,134,134,138,138, 132,0,132,132,132,132,132,132, 128,128,136,136,136,136,136,136, + 132,0,132,132,132,132,132,132, 128,128,136,136,136,136,136,136, 132,0,134,134,134,134,134,134, 128,128,136,136,136,136,136,136, + 132,0,132,134,134,134,134,132, 128,128,136,136,136,136,136,136, 132,0,132,134,134,134,134,132, 128,128,136,136,136,136,136,136, + }, +}, + +{ // EUC-CN (0.035M chars) [53] + {NULL, NULL, NULL, NULL}, + 197, 192, 37, 32, 128, + {0,0,0,0,0,0,0,0, 0,169,169,0,0,169,119,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,240,216,176,191,186,168,185, 184,166,0,0,118,0,0,0, 0,103,0,0,0,0,29,0, 0,0,0,0,0,0,0,0, + 0,0,169,0,197,197,190,192, 190,212,188,187,188,186,190,188, 187,186,186,185,184,186,187,187, 185,185,186,185,193,186,186,190, + 185,185,185,187,189,185,186,191, 185,185,185,184,186,185,184,184, 185,184,184,184,184,184,184,184, 186,184,184,184,184,173,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,147,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,134,134,0,0,134,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,134,134,134,134,134,134,134, 134,134,134,134,134,134,134,134, 134,134,134,134,134,134,134,134, 134,134,134,134,134,134,134,134, + 134,134,134,134,138,134,138,134, 134,138,134,134,138,134,134,134, 134,134,134,134,138,138,134,134, 134,134,134,134,134,134,134,134, + 134,134,134,134,134,134,134,134, 134,134,134,134,138,134,134,134, 134,134,134,134,134,134,134,134, 134,134,134,134,134,134,134,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 170,230,193,197,184,184,184,184, 210,184,185,182,188,181,181,185, 183,207,189,182,181,182,181,180, 181,181,182,185,181,179,187,187, + 183,180,180,181,182,180,186,180, 180,185,195,191,183,180,182,180, 179,182,189,183,182,180,192,195, 179,179,181,182,181,179,183,183, + 180,180,178,184,182,198,195,192, 180,183,186,180,180,183,181,181, 183,179,180,189,179,179,178,178, 182,179,212,180,186,180,211,0, + }, + {182,0,182,182,180,182,182,182, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 128,128,2,10,14,14,12,8, 76,0,52,52,50,52,52,52, 128,128,128,128,128,128,128,128, + 4,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, 8,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, + 8,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, 12,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, + 0,0,0,0,0,0,0,0, 0,0,76,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,134,124,114,118,122,124, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,116,126,130,128,126,136, 0,0,0,0,0,0,0,0, 0,0,116,128,136,132,134,124, + 0,0,0,0,0,0,0,0, 0,0,118,130,132,134,130,124, 0,0,0,0,0,0,0,0, 0,0,118,130,132,134,130,126, + }, +}, + +{ // EUC (15478 chars) [54] + {NULL, NULL, NULL, NULL}, + 197, 200, 38, 33, 129, + {0,0,0,0,0,0,0,0, 0,173,173,0,0,173,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,234,211,180,190,188,173,189, 189,170,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,174,0,193,195,190,191, 191,208,190,189,190,189,191,190, 190,189,190,189,189,190,189,190, 189,189,190,189,193,189,190,191, + 189,189,189,190,191,190,190,193, 189,190,189,189,190,189,189,189, 189,189,189,189,189,189,189,189, 190,189,189,189,189,178,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,140,140,0,0,140,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, + 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, + 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 162,226,192,195,186,186,185,186, 205,186,187,185,188,185,185,186, 184,202,187,184,184,184,183,183, 184,184,184,185,183,183,187,187, + 183,183,183,183,184,183,186,183, 183,185,192,189,184,183,184,183, 182,184,187,184,183,182,190,192, 182,182,182,183,184,182,184,184, + 182,182,182,185,184,194,191,190, 183,184,185,183,183,184,183,183, 184,182,182,188,182,182,182,182, 184,182,206,183,185,182,206,0, + }, + {176,0,176,176,176,176,176,176, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, 128,0,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, + 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, + 0,0,0,0,0,0,0,0, 0,0,2,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,136,124,116,118,122,124, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,118,126,128,128,128,136, 0,0,0,0,0,0,0,0, 0,0,118,128,132,130,130,126, + 0,0,0,0,0,0,0,0, 0,0,120,128,130,132,130,126, 0,0,0,0,0,0,0,0, 0,0,120,130,130,130,130,126, + }, +}, + +{ // CNS (15478 chars) [55] + {NULL, NULL, NULL, NULL}, + 197, 200, 38, 33, 129, + {0,0,0,0,0,0,0,0, 0,173,173,0,0,173,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,234,211,180,190,188,173,189, 189,170,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,174,0,193,195,190,191, 191,208,190,189,190,189,191,190, 190,189,190,189,189,190,189,190, 189,189,190,189,193,189,190,191, + 189,189,189,190,191,190,190,193, 189,190,189,189,190,189,189,189, 189,189,189,189,189,189,189,189, 190,189,189,189,189,178,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,140,140,0,0,140,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, + 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, + 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 162,226,192,195,186,186,185,186, 205,186,187,185,188,185,185,186, 184,202,187,184,184,184,183,183, 184,184,184,185,183,183,187,187, + 183,183,183,183,184,183,186,183, 183,185,192,189,184,183,184,183, 182,184,187,184,183,182,190,192, 182,182,182,183,184,182,184,184, + 182,182,182,185,184,194,191,190, 183,184,185,183,183,184,183,183, 184,182,182,188,182,182,182,182, 184,182,206,183,185,182,206,0, + }, + {176,0,176,176,176,176,176,176, 128,128,128,128,128,128,128,128, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, 128,0,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, + 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, 2,0,2,2,2,2,2,2, 128,128,128,128,128,128,128,128, + 0,0,0,0,0,0,0,0, 0,0,2,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,136,124,116,118,122,124, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,118,126,128,128,128,136, 0,0,0,0,0,0,0,0, 0,0,118,128,132,130,130,126, + 0,0,0,0,0,0,0,0, 0,0,120,128,130,132,130,126, 0,0,0,0,0,0,0,0, 0,0,120,130,130,130,130,126, + }, +}, + +{ // UTF-32BE (1032.458M chars) [56] + {NULL, NULL, NULL, NULL}, + 77, 151, 56, 41, 127, + {250,137,119,116,158,116,151,92, 103,89,82,111,111,75,204,151, 102,106,71,86,94,92,104,91, 88,92,106,215,97,93,99,106, + 79,97,116,106,115,126,78,66, 89,96,94,80,79,92,90,90, 93,101,90,90,72,96,79,91, 82,89,78,88,80,99,84,86, + 86,92,83,59,101,100,101,79, 89,93,71,46,102,89,64,68, 78,74,72,65,71,56,71,64, 76,84,65,68,92,98,94,106, + 182,177,181,215,194,207,203,198, 193,188,166,179,184,171,90,183, 67,2,0,27,20,10,16,20, 7,0,3,46,24,71,43,104, + 160,104,104,120,120,123,106,99, 106,101,107,114,119,100,91,96, 110,88,107,102,79,91,100,101, 99,92,100,94,88,67,104,92, + 68,80,83,73,92,62,75,75, 79,64,69,73,88,82,78,88, 92,73,82,84,71,76,74,82, 84,98,91,76,78,66,71,80, + 78,89,78,91,66,88,86,94, 97,83,76,79,62,78,71,75, 80,86,62,78,68,93,85,80, 83,80,76,75,69,83,90,83, + 82,82,61,78,58,98,56,64, 68,80,85,85,74,85,73,74, 60,46,58,83,68,31,72,64, 71,62,78,78,88,72,62,103, + }, + {231,96,83,86,82,95,79,87, 91,190,189,71,101,175,87,75, 88,93,82,83,89,84,75,84, 89,98,94,150,95,84,82,97, + 211,164,198,158,206,163,163,167, 204,160,139,149,163,176,181,194, 186,180,173,172,169,172,164,166, 171,171,175,177,193,193,193,164, + 169,173,164,169,169,167,165,166, 164,164,153,153,160,162,163,160, 163,145,162,165,167,153,156,157, 144,147,146,140,138,138,110,171, + 103,201,181,192,192,203,181,185, 187,200,161,171,196,187,196,196, 190,145,197,197,203,183,178,178, 170,174,157,147,130,147,113,85, + 194,202,196,197,161,172,160,164, 174,168,169,165,163,162,161,172, 167,152,151,154,172,173,173,172, 170,167,172,172,181,172,158,158, + 158,165,152,155,174,160,165,166, 161,156,155,157,154,167,173,166, 170,159,161,164,160,162,155,162, 190,174,180,181,186,173,165,168, + 96,98,83,90,99,87,83,90, 91,88,75,80,102,90,78,81, 99,97,81,86,97,102,86,85, 95,107,84,92,106,96,96,92, + 105,120,91,98,114,104,86,102, 104,125,102,72,80,118,81,79, 79,91,70,110,91,83,108,69, 93,74,94,86,107,97,65,124, + }, + {132,132,126,132,132,132,132,132, 122,128,140,130,230,224,222,224, 60,24,152,14,68,74,40,40, 104,122,122,98,204,218,206,224, + 8,96,12,22,38,48,10,20, 44,64,80,56,128,128,128,128, 20,128,26,34,56,70,22,32, 40,58,72,50,128,128,128,128, + 20,128,24,34,54,66,22,32, 38,56,70,50,128,128,128,128, 26,128,30,40,62,74,28,38, 40,60,76,52,128,128,128,128, + 2,2,2,2,2,2,2,2, 42,62,78,54,128,128,128,128, 134,180,74,128,144,158,114,92, 116,128,122,78,150,192,132,164, + 118,142,64,114,106,120,82,106, 14,12,26,10,92,80,68,72, 138,192,94,128,132,154,112,108, 34,52,40,14,124,118,102,106, + 142,188,72,144,148,176,108,110, 156,152,90,112,202,162,200,174, 142,200,86,138,146,162,110,118, 156,146,132,106,208,200,212,192, + 142,208,88,138,138,162,96,118, 154,152,138,122,208,212,182,178, 138,180,68,144,148,178,114,122, 154,162,112,112,184,192,158,168, + 140,128,102,142,150,172,108,116, 148,148,148,148,20,14,4,12, 136,196,112,138,136,176,110,118, 132,148,136,112,148,160,162,150, + }, +}, + +{ // UTF-32LE (1032.461M chars) [57] + {NULL, NULL, NULL, NULL}, + 77, 152, 56, 41, 127, + {250,137,119,116,158,116,151,92, 103,89,82,111,111,75,204,150, 102,106,71,86,94,92,104,91, 88,92,106,215,97,93,99,106, + 79,97,116,106,114,126,78,66, 89,96,94,144,79,92,90,90, 93,101,90,90,72,96,79,91, 80,89,78,88,80,99,84,86, + 86,92,83,58,101,100,101,79, 89,93,71,46,102,89,64,68, 78,74,72,65,71,54,71,64, 76,84,65,68,92,98,94,106, + 182,177,181,215,193,207,203,198, 193,188,166,178,184,171,90,183, 67,3,0,27,20,11,17,20, 8,0,4,46,24,71,162,104, + 160,104,104,120,120,123,106,99, 106,101,107,114,118,100,91,94, 110,88,107,102,79,91,100,101, 99,92,100,94,88,67,104,92, + 68,80,83,73,92,62,75,75, 79,64,71,124,88,82,78,88, 92,73,82,84,71,76,74,82, 84,98,91,76,78,66,71,80, + 78,89,78,91,66,88,86,94, 97,83,76,79,62,78,71,75, 80,86,62,78,68,93,85,80, 83,80,76,75,69,83,90,83, + 82,82,61,78,57,98,57,64, 68,80,85,85,74,85,73,74, 60,46,57,83,68,31,72,64, 71,62,78,78,88,72,122,103, + }, + {231,96,83,86,82,95,79,87, 91,190,189,71,101,175,87,75, 88,93,82,83,89,84,75,84, 88,98,94,158,95,84,82,97, + 211,164,198,159,206,163,163,167, 204,160,139,149,163,176,181,194, 186,180,174,172,169,172,165,166, 171,171,175,177,193,193,193,164, + 169,173,164,169,169,167,165,166, 164,164,155,154,161,163,165,160, 163,145,162,165,167,154,157,157, 144,147,146,140,138,138,110,171, + 103,201,181,192,192,203,181,185, 187,200,161,171,196,187,196,196, 190,145,197,197,203,183,178,177, 170,174,157,147,130,147,131,85, + 193,202,196,197,161,172,160,164, 174,168,169,165,163,162,161,172, 167,152,151,154,172,173,173,172, 170,167,172,172,181,172,158,158, + 158,165,152,155,174,160,165,166, 161,155,155,157,154,167,173,166, 170,159,161,164,160,162,155,162, 190,174,180,181,186,173,165,168, + 99,99,87,92,100,90,85,93, 93,89,79,83,102,91,81,82, 101,97,82,87,97,102,87,86, 95,107,84,92,106,96,96,92, + 105,120,93,102,115,107,92,103, 105,125,103,77,82,118,81,84, 79,91,70,110,91,83,107,69, 93,74,94,86,107,97,65,124, + }, + {132,124,126,132,132,132,132,132, 122,128,140,130,228,224,222,224, 60,14,152,16,66,74,40,40, 104,122,122,98,204,218,206,224, + 44,212,2,12,34,104,44,134, 116,112,144,150,220,208,220,130, 20,116,26,34,56,70,22,32, 40,58,72,50,128,128,128,128, + 20,104,24,34,54,66,22,32, 38,56,70,50,128,128,128,128, 26,114,30,40,60,74,28,38, 42,60,76,52,128,128,128,128, + 2,2,2,2,2,2,2,2, 44,62,78,54,128,128,128,128, 84,190,114,148,160,156,70,62, 116,118,160,144,212,200,222,166, + 118,134,64,114,106,120,82,106, 14,12,26,8,90,80,66,72, 138,168,94,128,130,154,112,108, 34,52,40,14,122,116,100,106, + 130,162,60,130,122,146,98,100, 146,140,78,102,202,162,172,162, 142,200,86,138,144,162,110,118, 158,146,132,106,208,200,212,192, + 142,208,88,138,136,162,96,118, 154,152,138,122,208,212,182,176, 138,180,68,144,148,178,114,122, 156,162,112,112,182,192,156,168, + 140,128,102,142,150,172,108,116, 148,148,148,148,18,14,4,12, 124,168,100,124,114,154,98,106, 76,90,78,54,122,120,108,108, + }, +}, + +{ // X-BINARYENC (0 chars) [58] + {NULL, NULL, NULL, NULL}, + 0, 0, 0, 0, 255, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + }, +}, + +{ // X-UTF8UTF8 (43.271M chars) [59] + {NULL, NULL, NULL, NULL}, + 150, 194, 32, 13, 129, + {191,104,167,173,203,123,113,0, 0,69,69,80,0,107,0,105, 95,0,125,146,116,0,0,0, 104,129,184,0,125,122,159,0, + 139,144,162,111,112,105,148,117, 115,101,122,104,217,112,130,114, 151,116,107,120,116,116,98,89, 124,119,136,113,115,116,126,105, + 0,0,239,243,62,181,145,62, 62,62,62,147,62,62,62,62, 62,62,62,62,62,62,62,62, 62,62,62,62,62,62,62,62, + 0,0,220,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,58,0,0,0,0,5,0, 0,0,36,0,102,23,86,28, 9,0,75,142,74,0,0,0, 89,85,64,0,119,139,99,0, + 121,119,159,71,88,75,139,88, 67,69,78,82,156,71,75,61, 134,70,55,54,61,63,56,60, 80,102,119,63,76,71,134,73, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,24,140,0,0,147,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 195,107,138,80,100,83,158,123, 107,139,106,91,157,127,159,122, 111,135,127,120,115,117,108,109, 106,109,120,113,182,78,121,111, + 84,149,138,143,143,145,133,136, 138,145,127,129,143,142,149,143, 141,113,143,148,151,137,137,140, 124,119,115,112,96,117,97,106, + 108,137,132,140,136,131,138,130, 131,133,119,128,140,133,137,128, 135,113,137,152,143,136,130,123, 116,108,106,112,84,77,91,0, + 196,150,226,235,119,165,141,52, 52,52,52,115,52,142,52,124, 121,52,147,165,107,52,52,52, 97,124,126,52,187,166,117,52, + 216,191,222,181,200,177,168,187, 191,218,177,170,169,189,169,153, 169,175,160,194,171,165,189,171, 182,163,176,175,198,160,155,150, + 0,0,205,182,0,189,133,0, 0,0,0,163,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,209,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 12,0,2,2,2,2,2,2, 0,0,0,0,2,128,2,128, 66,0,20,36,40,48,50,54, 0,0,0,0,2,128,2,128, + 2,0,2,2,2,2,2,2, 0,0,0,0,128,128,128,128, 128,0,84,128,128,128,128,128, 0,0,0,0,128,128,128,128, + 10,0,2,2,2,2,2,2, 0,0,0,0,128,128,128,128, 128,0,128,128,128,128,128,128, 0,0,0,0,128,128,128,128, + 120,0,130,112,192,198,136,140, 2,168,134,98,134,128,124,128, 160,0,168,162,178,176,178,178, 2,2,2,2,170,128,2,128, + 178,0,174,178,150,154,158,156, 2,2,2,2,158,128,164,128, 156,0,162,152,182,182,182,184, 2,26,2,2,170,128,10,128, + 0,0,128,128,128,128,128,128, 128,108,130,130,2,128,2,128, 0,0,128,128,128,128,128,128, 120,210,124,154,74,128,70,128, + 0,0,128,128,128,128,128,128, 140,2,2,2,2,128,2,128, 0,0,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + }, +}, + +{ // X-TAM-ELANGO (0.036M chars) [60] + {NULL, NULL, NULL, NULL}, + 126, 180, 58, 30, 129, + {0,180,180,180,180,180,180,180, 180,191,191,180,180,191,0,180, 170,170,170,170,170,170,170,170, 170,170,170,170,170,170,0,170, + 0,180,180,180,180,180,180,180, 180,180,180,180,0,0,180,0, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,0,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,0,0,180,180, + 180,0,180,180,0,0,0,0, 0,0,0,0,180,0,180,180, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,181,181,181,181,181,181,181, 181,191,191,181,181,191,0,181, 171,171,171,171,171,171,171,171, 171,171,171,171,171,171,0,171, + 0,181,181,181,181,181,181,181, 181,181,181,181,0,0,181,0, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, + 181,181,181,181,181,181,0,181, 181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181, 181,181,181,181,0,0,181,181, + 181,0,181,181,0,0,0,0, 0,0,0,0,181,0,181,181, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {0,0,0,0,0,0,0,0, 0,180,180,0,0,180,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,0, + 0,180,180,180,180,180,180,180, 180,180,180,180,180,180,0,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,0,180, + 0,180,180,180,180,180,180,180, 180,180,180,180,0,0,180,0, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,0,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,0,0,180,180, + 180,0,180,180,0,0,0,0, 0,0,0,0,180,0,180,180, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + }, + {110,0,110,110,110,110,110,110, 110,110,110,110,110,110,110,128, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,128, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,128, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,128, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,128, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,128, 128,0,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 132,0,132,132,132,132,132,132, 132,132,132,132,132,132,132,128, 136,0,134,134,134,134,134,134, 136,136,136,136,136,136,136,128, + 136,0,136,136,136,136,136,136, 136,136,136,136,136,136,136,128, 136,0,134,134,134,134,134,134, 136,136,136,136,136,136,136,128, + 136,0,134,134,134,134,134,134, 136,136,136,136,136,136,136,128, 136,0,134,134,134,134,134,134, 136,136,136,136,136,136,136,128, + 136,0,136,136,136,136,136,136, 136,136,136,136,136,136,136,128, 128,0,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + }, +}, + +{ // X-TAM-LTTMBARANI (0.043M chars) [61] + {NULL, NULL, NULL, NULL}, + 141, 199, 69, 34, 128, + {0,178,178,0,178,0,178,178, 0,187,187,178,178,176,0,0, 0,0,0,0,0,168,0,0, 0,0,168,168,168,0,0,168, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 0,176,176,0,176,0,176,176, 0,187,187,176,176,178,0,0, 0,0,0,0,0,165,0,0, 0,0,165,165,165,0,0,165, + 0,176,176,176,176,176,177,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,182, 176,176,176,176,176,176,176,176, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 176,176,176,176,176,177,176,176, + 176,176,176,176,176,176,176,176, 176,176,176,176,176,176,176,176, 181,176,176,176,176,176,176,176, 176,176,176,176,176,189,176,176, + }, + {0,0,0,0,0,0,0,0, 0,178,177,0,0,177,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 185,177,177,177,177,177,178,177, 177,177,177,177,178,177,178,177, 177,177,177,177,177,177,177,177, 177,177,177,177,180,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,0, + 0,178,178,0,178,0,178,178, 0,178,178,178,178,0,0,0, 0,0,0,0,0,178,0,0, 0,0,178,178,178,0,0,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,179, 179,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + }, + {116,0,114,116,116,116,116,116, 118,118,116,118,118,118,118,118, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 134,0,132,134,134,134,134,134, 132,132,132,132,132,132,132,132, 138,0,136,138,138,138,138,138, 136,136,136,136,136,136,136,136, + 138,0,138,138,138,138,138,138, 136,136,136,136,136,136,136,136, 138,0,138,138,138,138,138,138, 136,136,136,136,136,136,136,136, + 138,0,136,138,138,138,138,138, 136,136,136,136,136,136,136,136, 138,0,138,138,138,138,138,138, 136,136,136,136,136,136,136,136, + 138,0,136,138,138,138,138,138, 136,136,136,136,136,136,136,136, 136,0,142,138,136,136,136,136, 136,136,136,136,136,136,136,136, + }, +}, + +{ // X-TAM-SHREE (0.037M chars) [62] + {NULL, NULL, NULL, NULL}, + 140, 204, 70, 30, 129, + {0,0,0,0,0,0,0,0, 0,188,179,0,0,179,0,0, 0,168,0,0,0,168,0,0, 0,0,0,168,0,0,0,168, + 0,178,178,178,178,178,178,178, 178,178,178,178,0,0,178,178, 178,178,178,178,178,178,0,0, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,0,178, + 0,0,0,0,0,0,0,0, 0,188,178,0,0,178,0,0, 0,169,0,0,0,169,0,0, 0,0,0,169,0,0,0,169, + 0,179,179,179,179,179,179,179, 179,179,179,179,0,0,179,179, 179,179,179,179,179,179,0,0, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,0,179, + }, + {0,0,0,0,0,0,0,0, 0,179,179,0,0,179,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,0, + 0,0,0,0,0,0,0,0, 0,179,0,0,0,0,0,0, 0,179,0,0,0,179,0,0, 0,0,0,179,0,0,0,179, + 0,179,179,179,179,179,179,179, 179,179,179,179,0,0,179,179, 179,179,179,179,179,179,0,0, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,0,179, + }, + {132,0,132,132,132,132,132,132, 134,134,132,132,132,132,132,132, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 118,0,118,118,118,118,118,118, 118,118,118,118,118,118,118,118, 136,0,136,138,138,138,138,136, 138,138,138,138,138,138,138,138, + 136,0,136,136,136,136,136,136, 138,138,138,138,138,138,138,138, 136,0,136,136,136,136,136,136, 138,138,138,138,138,138,138,138, + 136,0,136,136,136,136,136,136, 138,138,138,138,138,138,138,138, 136,0,136,136,136,136,136,136, 138,138,138,138,138,138,138,138, + 136,0,136,136,136,136,136,136, 138,138,138,138,138,138,138,138, 136,0,136,136,136,136,136,136, 138,138,138,138,138,138,138,138, + }, +}, + +{ // X-TAM-TBOOMIS (0.038M chars) [63] + {NULL, NULL, NULL, NULL}, + 139, 205, 71, 31, 129, + {178,0,0,0,0,0,0,0, 0,178,178,0,0,178,0,0, 0,0,0,168,168,0,0,0, 0,0,0,0,0,0,0,0, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,0,0,0,0,0,0,0, 0,178,178,0,0,178,0,0, 0,0,0,168,168,0,0,0, 0,0,0,0,0,0,0,0, + 0,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,200,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 179,178,178,178,181,190,178,188, + }, + {0,0,0,0,0,0,0,0, 0,178,178,0,0,178,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 200,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,180,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,177, + 178,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,178,178,0,0,0, 0,0,0,0,0,0,0,0, + 177,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + }, + {134,0,130,132,132,132,132,132, 132,132,132,132,132,132,132,132, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 94,94,94,94,94,94,94,94, + 118,0,114,116,116,116,116,118, 116,116,118,116,116,116,116,116, 138,0,134,136,136,136,136,138, 136,136,138,136,136,136,136,136, + 138,0,134,136,136,136,136,136, 136,136,138,136,136,136,136,136, 138,0,134,136,136,136,136,138, 136,136,138,136,136,136,136,136, + 138,0,134,136,136,136,136,138, 136,136,138,136,136,136,136,136, 138,0,134,136,136,136,136,138, 136,136,138,136,136,136,136,136, + 134,0,144,134,134,134,134,134, 136,136,138,136,136,136,136,136, 134,0,138,136,134,134,134,134, 136,136,138,136,136,136,136,136, + }, +}, + +{ // X-TAM-TMNEWS (0.037M chars) [64] + {NULL, NULL, NULL, NULL}, + 141, 205, 71, 29, 128, + {0,0,0,0,0,0,0,0, 0,179,179,0,0,179,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 0,0,0,0,0,0,0,0, 0,179,179,0,0,179,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,190,179,180,181,179, 180,179,179,179,179,179,179,179, + }, + {0,0,0,0,0,0,0,0, 0,179,179,0,0,179,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 180,179,180,179,179,179,179,179, 179,179,179,179,180,179,180,179, 179,179,179,179,179,179,179,179, 179,179,180,179,181,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, + 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,179, 179,179,179,179,179,179,179,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 179,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180, + }, + {138,0,136,136,138,138,138,138, 128,128,136,136,136,136,136,136, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 128,128,2,2,2,2,2,2, 128,0,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 138,0,136,136,136,136,136,136, 128,128,136,136,136,136,136,136, 138,0,136,136,138,138,138,136, 128,128,136,136,136,136,136,136, + 138,0,136,136,138,138,138,136, 128,128,136,136,136,136,136,136, 138,0,136,136,138,138,138,136, 128,128,136,136,136,136,136,136, + 138,0,136,136,138,138,138,136, 128,128,136,136,136,136,136,136, 136,0,140,136,136,136,136,136, 128,128,136,136,136,136,136,136, + }, +}, + +{ // X-TAM-WEBTAMIL (0.050M chars) [65] + {NULL, NULL, NULL, NULL}, + 142, 193, 66, 37, 129, + {178,178,178,178,178,178,178,178, 178,186,186,178,178,186,178,178, 169,169,169,169,169,169,0,169, 169,169,169,169,169,169,169,169, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,179, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, 178,178,178,178,178,178,178,178, + 174,174,174,174,174,174,174,174, 174,186,186,174,174,186,174,174, 162,162,162,162,162,162,0,162, 162,162,162,162,162,162,162,162, + 0,174,174,174,174,174,174,174, 174,174,174,174,174,174,174,174, 174,174,174,174,174,174,174,181, 174,174,174,174,174,174,174,174, + 174,174,174,174,174,174,174,174, 174,174,174,174,174,174,174,174, 174,174,174,174,174,174,174,174, 174,174,174,174,174,174,174,174, + 174,174,174,174,174,174,174,174, 174,174,174,174,174,174,174,174, 174,174,174,174,174,174,174,174, 174,174,174,174,174,174,174,174, + }, + {0,0,0,0,0,0,0,0, 0,178,177,0,0,177,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 158,177,177,177,177,177,178,177, 177,177,177,177,177,177,178,177, 177,177,177,177,177,177,177,177, 177,177,177,177,179,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,177,177,178,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,0, + 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,133,177, 177,177,177,177,177,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,178, 177,177,177,177,177,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, + 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, 177,177,177,177,177,177,177,177, + }, + {108,0,108,108,108,108,108,108, 110,110,110,110,110,110,110,110, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,0,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 134,0,134,134,134,134,134,134, 132,132,132,132,132,132,132,132, 138,0,138,138,138,138,138,138, 134,134,134,134,134,134,134,134, + 138,0,138,138,138,138,138,138, 134,134,134,134,134,134,134,134, 138,0,138,138,138,138,138,138, 134,134,134,134,134,134,134,134, + 138,0,138,138,138,138,138,138, 134,134,134,134,134,134,134,134, 138,0,138,138,138,138,138,138, 134,134,134,134,134,134,134,134, + 138,0,138,138,138,138,138,138, 134,134,134,134,134,134,134,134, 138,0,138,138,138,138,138,138, 134,134,134,134,134,134,134,134, + }, +}, + +{ // UTF8CP1252 (178.156M chars) [66] + {NULL, NULL, NULL, NULL}, + 127, 200, 59, 31, 133, + {181,189,183,184,176,167,163,162, 171,165,167,170,170,164,161,165, 163,161,165,161,164,166,165,166, 163,164,168,163,171,163,158,162, + 206,174,166,168,175,173,174,175, 177,166,173,171,187,176,178,175, 178,168,166,174,175,166,165,168, 186,173,179,177,184,174,171,171, + 119,121,206,216,183,183,147,141, 116,157,118,125,127,125,181,171, 210,198,125,120,113,136,145,187, 200,196,150,157,110,121,122,116, + 177,173,191,209,190,201,198,198, 188,185,166,178,183,167,123,183, 120,134,134,122,116,132,155,115, 122,120,125,97,146,127,124,122, + 186,143,146,128,162,163,140,136, 145,136,144,136,144,130,143,126, 134,159,199,183,181,182,183,161, 136,161,149,139,147,147,140,133, + 194,145,152,160,146,142,140,152, 139,166,140,162,150,144,159,142, 165,141,142,133,158,130,129,165, 138,130,156,172,141,139,132,152, + 146,177,150,157,188,159,153,165, 178,205,165,144,125,177,148,136, 125,164,126,181,156,148,180,118, 161,109,162,137,189,137,127,170, + 196,183,151,159,189,172,153,166, 185,210,166,152,154,180,147,138, 133,164,153,186,156,147,178,152, 160,162,164,140,188,144,126,109, + }, + {148,50,56,78,0,0,0,0, 0,146,153,0,0,166,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 225,137,174,103,110,121,177,155, 149,159,126,115,183,160,179,142, 162,172,165,154,151,151,144,143, 141,143,157,138,205,108,138,142, + 124,187,176,189,179,184,170,182, 175,169,154,158,186,182,198,181, 175,156,199,194,193,169,173,155, 158,150,147,134,124,138,112,134, + 122,193,181,189,179,191,172,183, 177,178,152,159,187,182,199,184, 175,153,200,203,195,176,174,143, 147,148,143,122,135,97,118,45, + 189,193,197,200,179,177,173,171, 177,169,174,172,176,171,162,170, 167,165,159,165,169,171,167,170, 167,172,168,170,176,168,162,169, + 201,180,183,168,179,169,167,182, 176,187,173,166,167,178,173,174, 182,177,171,180,173,177,171,169, 186,175,179,179,186,179,179,171, + 129,129,169,152,124,152,130,133, 107,158,114,130,116,114,119,120, 120,118,126,120,107,124,147,116, 137,132,118,122,118,119,119,156, + 174,145,176,207,186,198,193,190, 186,184,161,173,176,161,128,175, 133,123,125,123,107,155,137,103, 119,110,131,110,136,122,127,123, + }, + {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 2,0,2,2,2,2,2,2, 0,0,0,0,2,4,2,6, 2,0,2,2,2,2,2,2, 0,0,0,0,4,14,2,16, + 2,0,2,2,2,2,2,2, 0,0,0,0,2,2,2,2, 2,0,2,2,2,2,2,2, 0,0,0,0,2,2,2,2, + 2,0,2,2,2,2,2,2, 0,0,0,0,2,2,2,2, 32,0,2,4,2,2,2,2, 0,0,0,0,2,2,2,2, + 156,0,136,152,124,138,112,108, 126,134,130,124,120,126,140,96, 138,0,138,136,122,116,134,138, 124,130,118,122,140,122,146,112, + 150,0,140,156,114,112,112,112, 108,122,140,112,150,128,142,122, 144,0,142,152,118,120,114,114, 124,134,120,126,132,136,144,128, + 0,0,90,80,150,152,98,98, 134,120,142,130,128,128,70,112, 0,0,102,98,150,148,124,110, 134,128,128,144,104,128,66,114, + 0,0,138,118,64,72,142,142, 138,138,122,134,110,120,110,140, 0,0,126,122,70,82,148,144, 88,108,108,110,162,194,128,196, + }, +}, + +}; // End unigram_table + +static const uint8 kMostLikelyEncoding[] = { +// 00xx + 37,39,39,39,39,39,39,39, 39,37,37,39,39,39,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 37,37,37,39,39,37,39,39, 39,39,37,39,37,37,39,37, 39,39,39,39,39,39,39,39, 39,39,37,39,37,39,37,39, + 37,39,39,39,39,37,39,39, 37,37,39,37,39,39,39,39, 37,39,37,37,37,37,37,37, 39,39,39,37,39,37,56,39, + 39,37,37,37,37,37,39,37, 37,37,37,37,37,37,37,37, 37,39,37,37,37,37,37,37, 39,37,37,37,39,37,39,56, + 56,39,56,56,39,39,39,39, 56,56,56,56,56,56,39,56, 56,56,39,39,57,56,56,39, 56,56,56,57,39,39,56,39, + 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,57, 39,56,39,39,39,56,39,39, 39,39,39,39,39,57,39,39, + 39,39,57,39,39,39,39,39, 39,39,39,39,56,39,39,39, 39,39,39,39,39,57,39,39, 57,57,57,57,56,57,56,57, + 39,37,39,39,37,39,39,39, 39,37,39,39,39,37,39,39, 39,37,39,37,39,39,39,39, 39,39,39,39,37,39,39,57, + // 01xx + 56,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,39,37,37,37, + 39,39,39,37,37,37,39,39, 39,39,37,37,39,39,39,37, 39,37,39,37,37,37,37,37, 37,37,39,39,39,37,37,39, + 39,37,37,37,37,39,37,39, 37,39,39,39,39,39,37,39, 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,39,39,39,39,37,37, 37,39,39,37,39,39,39,39, 39,37,39,39,39,39,39,39, 39,39,37,37,37,37,37,37, + 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, + 39,37,37,39,39,39,39,39, 37,39,37,39,39,39,37,37, 37,39,37,39,39,37,39,39, 37,39,37,37,37,37,37,39, + 37,39,39,39,37,39,39,39, 39,39,39,39,39,37,37,37, 37,37,37,39,37,39,37,39, 37,56,56,56,37,56,39,56, + 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,37, 39,39,39,39,39,37,39,37, 39,39,39,37,39,39,37,39, + // 02xx + 37,37,37,39,37,37,37,39, 39,39,39,37,37,39,37,37, 37,8,37,37,37,37,37,37, 37,37,37,37,39,39,37,39, + 37,37,39,40,37,39,37,37, 39,39,39,39,39,39,39,39, 39,37,37,37,37,37,40,37, 40,40,39,39,39,39,37,37, + 6,39,39,40,39,37,39,39, 39,39,37,37,39,39,37,37, 37,37,37,37,37,37,37,37, 39,37,37,37,37,37,39,37, + 37,37,37,37,39,37,37,37, 37,37,39,37,37,37,37,39, 37,37,39,37,39,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,39,37,37,37,39, 37,37,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, + 37,37,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, 37,37,37,39,39,37,37,39, 39,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,39,37,37,37,37,37,39, 37,39,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,39,37,37,37,37, + // 03xx + 56,37,37,37,56,37,37,37, 37,37,39,56,37,39,39,37, 39,37,37,39,37,39,37,37, 37,39,56,39,37,37,39,39, + 39,39,39,37,37,37,39,39, 39,39,39,39,39,39,39,39, 37,39,39,39,39,39,39,39, 39,56,39,39,39,39,39,56, + 39,39,39,56,56,39,39,39, 39,39,39,39,39,39,37,37, 37,37,37,37,37,37,37,37, 37,37,39,37,37,37,39,37, + 37,37,37,39,37,37,37,39, 37,39,37,37,37,39,39,39, 39,37,37,37,39,37,37,37, 37,37,37,37,37,37,40,37, + 39,37,37,39,39,37,37,37, 37,37,37,37,39,37,37,39, 37,37,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, + 37,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 39,37,37,37,37,37,37,39, 37,37,37,37,37,37,37,37, + 37,37,37,39,37,39,37,37, 37,39,39,37,39,37,37,37, 39,37,39,37,39,37,37,37, 39,39,39,39,39,39,37,37, + // 04xx + 56,39,37,39,37,39,37,37, 37,39,39,37,39,39,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,37,39,37,37,37,39,39, 37,39,39,37,39,39,39,37, 39,39,37,39,39,39,39,37, 39,39,39,39,39,39,39,37, + 39,39,39,39,39,37,39,39, 39,39,39,39,39,37,39,39, 37,39,37,37,39,37,37,37, 37,39,37,37,39,39,37,39, + 37,39,37,39,39,37,37,37, 39,39,37,39,37,37,39,39, 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,39,37, + 37,37,37,39,37,37,37,37, 37,37,37,39,37,37,37,37, 37,37,37,39,37,37,37,39, 37,37,37,37,39,37,37,39, + 39,37,39,39,37,37,39,39, 37,39,37,37,39,39,37,37, 37,39,37,37,39,39,37,39, 37,39,37,39,39,39,39,37, + 37,37,37,39,37,37,39,37, 39,37,39,37,37,39,39,37, 39,39,37,37,37,39,39,39, 37,37,37,37,37,37,37,37, + 39,37,39,39,39,39,39,39, 37,37,39,37,39,37,37,37, 37,37,37,37,39,39,39,37, 39,39,39,39,37,39,37,37, + // 05xx + 56,37,37,37,37,37,37,37, 37,37,39,37,37,39,37,37, 37,37,37,39,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,39,39,37,37,37,39,39, 39,39,39,39,39,39,39,39, 37,39,39,39,37,37,40,37, 37,39,39,39,39,39,39,39, + 37,39,40,39,37,37,37,39, 37,37,37,37,40,37,37,37, 37,37,37,39,37,37,39,37, 37,37,37,37,37,37,39,39, + 39,37,37,37,39,37,37,37, 37,37,37,37,37,37,39,37, 37,37,37,37,37,37,37,37, 37,37,39,37,37,39,37,37, + 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,39,37, 39,39,37,37,37,37,37,37, + 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,39,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,37, 37,37,37,37,39,37,37,37, + // 06xx + 56,37,37,37,37,37,37,37, 37,37,39,37,39,39,39,39, 37,37,37,39,37,37,37,37, 39,39,37,37,37,37,37,37, + 39,39,39,37,37,37,39,37, 37,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,39,39,39,39,39,39, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,39,37,37,37,37,37, 37,37,37,37,39,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, 37,37,39,37,39,37,37,37, 37,37,37,37,37,37,37,39, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 39,37,39,37,37,37,37,37, 37,37,37,39,37,37,37,37, + 39,37,37,39,37,37,37,39, 37,37,37,39,39,39,39,37, 37,37,37,37,37,37,37,39, 37,37,37,39,37,37,37,39, + 37,37,37,37,37,37,37,37, 37,37,39,37,37,37,37,39, 37,37,37,39,37,37,37,39, 37,37,37,37,37,37,37,37, + 39,39,39,39,39,37,39,37, 39,37,39,37,39,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 07xx + 56,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,39,37,37,37, + 39,37,39,40,37,37,37,37, 37,39,37,37,39,37,39,37, 37,39,37,40,37,40,37,37, 37,37,40,37,39,37,37,37, + 37,37,39,37,37,37,40,40, 37,37,37,40,37,37,39,37, 37,37,39,37,37,39,37,37, 37,39,39,37,39,39,37,37, + 37,37,37,39,37,37,37,37, 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,39,37,37,37,39,37, 37,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 08xx + 37,37,37,37,37,37,37,37, 3,39,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,39,40,40,37,37,37, 40,40,37,37,37,37,37,37, 37,39,40,40,40,40,40,40, 40,40,40,40,40,40,40,37, + 40,40,40,40,37,37,37,37, 40,40,37,37,40,37,37,37, 37,37,37,37,39,37,37,37, 37,37,37,37,39,37,39,37, + 37,39,37,37,37,37,37,39, 37,37,37,37,37,37,39,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,40,37, + 37,37,39,37,37,37,37,37, 37,37,39,37,39,37,37,37, 37,37,37,37,37,37,37,37, 39,37,37,37,37,39,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,39,37, 37,39,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, + 37,37,37,39,37,37,39,37, 39,37,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,39,37,37,37,37,39, + // 09xx + 37,37,37,37,37,37,37,37, 37,0,0,37,37,0,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 0,10,0,0,0,0,0,0, 0,0,0,0,0,10,0,10, 10,0,0,0,0,0,0,0, 0,0,0,0,0,10,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + // 0Axx + 37,37,37,37,37,37,37,37, 37,0,0,37,37,0,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 0,10,0,0,0,0,0,0, 0,0,0,0,0,10,0,10, 10,0,0,0,0,0,0,0, 0,0,0,0,0,10,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + // 0Bxx + 56,37,37,37,37,37,37,37, 37,37,39,37,37,37,37,40, 37,37,37,37,37,37,37,37, 37,39,37,37,37,37,37,37, + 39,40,39,40,37,37,37,37, 37,39,37,37,39,39,39,40, 37,39,39,39,39,39,39,40, 39,39,39,37,39,37,37,37, + 37,37,40,40,37,37,40,37, 39,37,37,37,39,37,39,37, 39,37,37,37,37,37,37,39, 37,37,37,37,39,37,37,37, + 37,37,37,37,37,37,37,39, 37,37,37,37,37,39,37,37, 37,37,37,37,37,37,37,39, 37,37,39,37,37,37,40,37, + 37,37,37,37,37,37,39,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 0Cxx + 57,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,37,39,37,37,37,37,37, 37,39,37,37,39,37,37,37, 37,39,37,37,37,37,37,37, 37,37,39,37,39,37,37,39, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,39,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, 37,37,37,37,37,37,37,37, + 39,37,37,37,39,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,39,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,37, 37,37,37,39,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 0Dxx + 37,37,37,37,37,37,37,37, 37,0,0,37,37,0,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 0,10,0,0,0,0,0,0, 0,0,0,0,0,10,0,10, 10,0,0,0,0,0,0,0, 0,0,0,0,0,10,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + // 0Exx + 56,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,57,56,57,56,37,56,37, 56,56,37,56,56,37,39,39, 57,57,57,57,57,57,57,57, 57,57,57,57,57,57,57,57, + 57,57,56,57,57,57,57,57, 57,57,56,57,57,57,56,56, 57,56,57,56,56,57,56,57, 56,56,56,56,57,56,56,56, + 56,56,56,56,56,56,39,56, 56,56,56,56,56,56,56,56, 56,56,56,56,56,37,56,56, 37,56,39,56,56,37,37,37, + 37,37,37,39,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,39,39,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 6,37,37,37,37,37,37,37, 37,37,37,37,37,37,39,37, + 37,37,37,37,37,37,37,37, 37,39,37,39,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 0Fxx + 37,37,40,37,37,37,37,37, 40,42,42,37,37,42,40,37, 37,37,37,37,37,37,37,37, 37,40,37,57,37,37,37,37, + 42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42, + 42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42, + 42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,42, 42,42,42,42,42,42,42,37, + 37,39,42,37,37,37,37,37, 37,37,37,37,37,37,39,37, 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 10xx + 56,39,37,37,39,37,39,37, 37,37,39,37,37,37,37,37, 37,37,37,39,37,37,37,37, 37,37,37,37,39,39,37,39, + 39,40,39,37,37,37,37,37, 40,39,40,37,39,39,39,39, 37,39,37,39,40,40,37,37, 40,40,39,39,39,37,37,39, + 37,40,40,40,37,40,37,37, 37,40,40,37,40,37,37,37, 37,37,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, + 37,37,39,37,37,37,37,37, 37,37,37,37,37,37,39,37, 37,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,37,37,37,37,37,37,37, 37,37,37,37,39,37,39,37, 39,37,37,39,37,37,37,37, 39,39,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 3,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,39,37,37,37,37,37, + // 11xx + 56,39,37,37,39,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,40,39,40,37,37,37,37, 37,37,37,37,37,37,39,37, 37,40,40,40,40,40,40,37, 40,40,40,40,40,40,40,40, + 37,40,40,40,40,37,40,40, 40,40,40,40,37,40,37,39, 39,37,37,37,39,37,37,37, 37,37,37,37,39,37,37,37, + 37,37,39,39,37,37,37,37, 39,37,37,37,39,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,39,37,37,40,37, + 37,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,3,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,39,37,37,37,37,37,37, 37,37,37,37,37,37,39,37, 37,37,37,37,37,37,37,37, + 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,39,37,37,37,37,37, + // 12xx + 37,37,37,37,39,39,37,37, 37,37,37,39,37,39,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,40,39,39,37,37,37,37, 37,39,37,39,37,37,39,39, 37,39,37,40,37,37,37,37, 39,40,37,39,39,37,37,37, + 40,37,37,37,37,39,37,37, 37,37,39,37,37,37,37,37, 39,37,39,37,37,37,37,39, 37,37,37,37,37,37,37,37, + 39,37,39,37,37,37,37,37, 37,39,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,40,37, + 37,37,39,37,37,37,37,39, 37,37,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, 37,37,39,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 13xx + 37,39,37,37,37,37,37,37, 37,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,37, + 39,37,37,40,37,37,37,37, 37,37,39,37,39,39,37,37, 37,39,40,37,40,37,37,37, 37,37,40,37,39,37,37,37, + 37,37,37,40,37,37,37,37, 37,37,37,37,40,37,39,37, 37,37,37,37,37,37,37,39, 37,37,37,37,37,37,37,37, + 37,37,37,37,39,37,39,37, 39,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,40,39, + 37,37,37,37,37,39,37,37, 37,37,39,37,39,37,37,37, 37,37,37,37,37,37,37,39, 37,39,39,37,39,37,37,39, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,39,37,37,37,6,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 39,37,37,39,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,37, 37,37,37,39,37,39,37,37, 37,37,37,37,37,37,37,39, + // 14xx + 37,37,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, 37,39,39,39,39,37,37,37, 37,37,37,37,37,37,37,37, + 39,37,37,40,37,39,37,37, 39,37,37,39,39,39,39,37, 37,37,37,39,40,40,40,40, 40,37,40,40,39,37,40,40, + 40,40,40,40,40,37,39,39, 40,40,40,40,37,40,39,37, 37,37,37,37,37,37,37,37, 37,37,37,37,39,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,39,37,37,39, 37,37,37,37,37,37,37,37, 39,37,37,39,37,39,40,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,37, 37,37,37,37,39,37,39,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 15xx + 56,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,40,39,40,39,37,39,37, 37,37,37,37,39,37,37,37, 37,37,39,37,40,40,37,37, 37,40,37,37,39,37,40,40, + 37,40,40,37,37,37,37,37, 37,37,40,37,40,37,37,37, 37,37,37,37,37,37,39,37, 39,39,37,37,37,37,37,39, + 39,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, 37,37,37,37,37,37,37,37, 39,37,37,37,37,37,40,37, + 39,37,37,37,37,37,37,39, 39,37,37,37,37,37,37,39, 37,39,39,37,37,37,37,37, 37,37,37,37,37,39,37,37, + 37,39,37,37,37,39,37,39, 37,37,37,39,39,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,39,37,37,37, + 37,37,39,37,37,37,37,37, 39,37,37,37,37,37,37,37, 39,37,37,37,37,37,39,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,39,37,37,37,37,37, 37,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 16xx + 56,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,39,37,37,37,37,37,37, 37,40,37,37,37,37,37,40, 37,39,37,40,37,37,40,37, 40,40,37,40,37,37,40,37, + 37,40,37,37,40,37,40,37, 40,37,37,40,37,37,39,37, 37,37,37,39,37,37,37,39, 37,39,37,37,37,37,37,37, + 39,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + 37,37,37,37,37,37,39,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,39, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 17xx + 56,37,37,37,37,37,37,37, 37,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,39,37,37, 40,37,37,37,37,37,40,37, 37,39,40,37,37,37,37,37, 37,37,37,37,37,40,40,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, 37,37,39,39,39,37,39,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 39,37,37,37,39,37,39,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,40,37, + 39,37,39,37,37,39,37,39, 37,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 18xx + 37,37,37,37,39,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,39,37,40,37,37,37,37, 37,37,37,37,40,37,37,40, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, 39,37,37,37,37,37,37,39, 37,37,39,37,39,37,37,37, + 37,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + 37,37,37,37,37,37,37,39, 37,37,39,37,37,37,37,37, 37,37,37,37,39,37,37,37, 39,39,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,39,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 19xx + 37,37,37,37,37,37,37,37, 37,39,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,39,37,40,37,37,37, 37,37,37,37,37,37,40,37, 37,37,37,37,37,37,37,37, 37,37,40,37,37,40,37,37, + 37,37,37,40,37,37,37,37, 37,37,37,37,37,37,37,37, 39,37,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,39,37,37,37,37, 37,37,39,37,37,37,37,37, 37,39,37,37,37,37,37,37, 37,39,37,37,37,39,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 39,37,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 1Axx + 37,37,37,37,37,37,37,37, 37,37,4,37,37,37,37,40, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,40,39,40,37,37,37,37, 37,37,37,37,37,37,37,37, 37,39,37,37,40,40,37,37, 37,37,37,37,37,37,40,6, + 40,37,37,37,37,37,37,37, 37,37,37,37,37,37,39,39, 37,37,37,37,37,37,37,37, 37,39,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,37, + 37,37,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 1Bxx + 56,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,57,37,37,37, 57,37,37,37,37,37,37,37, 37,39,37,37,40,40,37,37, 40,37,37,37,37,40,37,37, + 37,37,37,37,37,40,37,37, 37,37,37,37,37,37,56,37, 37,37,39,37,39,37,37,37, 37,37,39,37,37,39,37,37, + 37,39,37,37,37,37,37,39, 37,37,37,37,39,39,39,37, 37,37,39,39,37,37,37,37, 37,37,37,37,37,37,40,37, + 37,37,37,37,37,37,37,37, 37,37,37,39,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 1Cxx + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,37,37,40,37,39,37,37, 37,37,40,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,40,37,37,37,37, 37,40,40,37,37,37,39,37, 37,37,37,37,37,37,37,37, 37,39,39,37,37,37,37,37, + 37,37,37,37,39,37,37,37, 37,39,37,37,37,37,37,37, 37,37,37,39,37,39,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,39, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,39,39, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,39,37,37,37, 37,37,37,37,39,37,37,37, + 37,39,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 1Dxx + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 39,37,40,40,37,39,37,37, 37,37,37,37,37,37,37,37, 37,39,37,37,37,37,37,37, 40,37,37,37,37,40,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, 37,37,39,37,37,37,37,37, 37,37,37,37,37,37,39,37, + 39,37,37,37,37,37,37,39, 37,37,37,37,37,37,39,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,39,37,37,37, 37,37,37,39,37,39,39,37, 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 1Exx + 57,37,37,37,37,37,37,37, 37,39,39,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,37, + 39,40,39,40,37,37,39,39, 37,39,37,37,39,39,39,39, 37,40,42,40,40,40,40,37, 40,40,39,39,39,40,37,39, + 37,39,42,37,37,37,42,37, 42,39,40,40,40,39,39,39, 39,37,37,37,39,39,37,37, 37,37,42,37,37,37,37,37, + 37,39,37,39,39,39,37,37, 39,39,42,39,37,37,39,39, 39,37,37,37,39,39,37,39, 37,39,37,37,37,37,40,37, + 37,37,39,37,37,37,37,37, 37,37,37,37,37,39,37,37, 39,37,39,37,37,37,37,39, 37,37,37,37,37,37,39,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 1Fxx + 37,37,37,37,39,37,39,37, 37,39,37,37,37,39,40,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,40,42,40,37,37,37,37, 42,37,37,42,39,37,37,42, 37,39,40,40,40,40,40,40, 40,40,40,40,40,40,42,40, + 40,40,42,40,40,40,40,42, 40,40,40,40,42,42,37,37, 39,37,37,37,37,37,37,39, 37,37,39,37,37,37,37,37, + 37,39,37,37,37,37,39,39, 37,37,37,37,37,37,37,37, 37,37,37,37,37,39,37,39, 37,37,37,37,37,37,40,37, + 37,37,39,37,37,37,37,37, 37,37,37,37,37,39,37,37, 39,37,37,37,37,37,39,37, 37,37,37,37,37,37,39,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,39,37,37,37,37, 37,37,37,39,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,39, + // 20xx + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + // 21xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 22xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 23xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 24xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 25xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 26xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 27xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 28xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 29xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 2Axx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 2Bxx + 2,39,1,37,37,37,37,5, 3,2,2,37,3,2,42,42, 37,40,37,37,37,40,37,37, 40,37,40,57,37,37,37,21, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,3,3,3,11,11,11,11, 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 3,11,12,11,12,36,12,4, + 11,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, + 2,2,2,2,2,2,2,11, 2,1,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,11,2,1,11,13,6, + 14,10,2,2,2,2,2,2, 2,2,2,2,2,10,17,2, 10,10,10,10,10,10,1,17, 17,17,17,2,11,10,13,37, + // 2Cxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 2Dxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 2Exx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 2Fxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 30xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 31xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 32xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 33xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 34xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 35xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 36xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 37xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 38xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 39xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 3Axx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 3Bxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 3Cxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 3Dxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 3Exx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 3Fxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 40xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 41xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 42xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 43xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 44xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 45xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 46xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 47xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 48xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 49xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 4Axx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 4Bxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 4Cxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 4Dxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 4Exx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 4Fxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 50xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 51xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 52xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 53xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 54xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 55xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 56xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 57xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 58xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 59xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 5Axx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 5Bxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 5Cxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 5Dxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 5Exx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 5Fxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 60xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 61xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 62xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 63xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 64xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 65xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 66xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 67xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 68xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 69xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 6Axx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 6Bxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 6Cxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 6Dxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 6Exx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 6Fxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 70xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 71xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 72xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 73xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,31, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,33,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 74xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 75xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 76xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 77xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 78xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 79xx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 7Axx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 7Bxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 7Cxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 7Dxx + 37,37,37,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,37, + 3,10,11,11,11,11,11,11, 11,11,0,11,11,10,0,10, 10,11,11,11,11,11,11,11, 0,11,0,11,11,10,0,0, + 11,1,11,11,11,11,11,11, 11,11,1,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,1,11,11,11,11,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,11, 1,1,1,1,1,1,1,1, + 11,1,11,1,1,1,1,11, 11,11,11,11,1,1,11,11, 1,1,1,1,11,1,1,11, 1,11,1,11,11,1,1,1, + // 7Exx + 2,39,39,39,39,39,39,39, 39,2,2,39,39,2,42,42, 39,39,39,39,39,39,39,39, 39,39,39,56,39,39,39,39, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,3, + 3,3,3,3,39,39,11,11, 11,3,3,3,3,3,3,3, 3,3,3,3,3,11,3,3, 39,11,39,3,39,39,39,37, + 11,3,3,3,11,3,3,3, 3,3,3,3,3,3,11,3, 11,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, + 2,2,2,2,2,2,2,11, 2,2,2,2,11,11,2,2, 2,11,2,11,11,2,2,2, 2,37,11,11,11,11,11,11, + 17,11,2,2,2,2,2,2, 2,2,2,2,2,2,17,2, 14,17,17,11,37,1,11,17, 16,17,11,39,37,11,39,37, + // 7Fxx + 56,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, 39,39,39,37,39,37,37,39, 37,39,39,39,39,37,39,39, + 39,39,39,39,39,39,39,39, 39,37,39,39,39,39,39,39, 37,39,39,39,39,39,37,39, 39,39,37,39,39,39,39,39, + 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,37,39, 37,37,37,37,37,39,37,37, 39,37,39,37,37,37,39,37, + 37,39,39,37,37,37,37,39, 39,37,37,37,37,37,37,39, 37,37,37,39,37,37,37,39, 39,37,39,37,39,37,37,39, + 37,39,37,37,39,37,39,39, 37,39,37,37,39,37,37,37, 39,39,39,39,37,39,37,39, 39,37,37,39,39,39,39,39, + 39,39,39,39,37,39,39,39, 37,37,39,39,39,39,39,39, 39,39,39,39,37,39,39,39, 39,39,39,39,39,37,39,39, + 39,37,39,39,39,37,39,39, 39,39,39,39,37,39,39,39, 39,39,37,39,37,39,39,39, 56,56,39,56,56,56,56,56, + 37,39,39,39,39,39,39,39, 39,37,39,39,39,39,39,39, 37,37,39,39,39,39,39,39, 39,39,39,37,37,39,39,37, + // 80xx + 11,37,39,37,39,37,39,39, 39,2,2,39,37,2,39,39, 37,39,39,39,39,37,39,37, 39,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,11, 2,11,11,2,11,11,11,11, 11,11,11,2,11,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,11,2,2, 2,2,2,2,2,2,2,39, + 2,2,2,2,36,2,2,36, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 59,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 10,39,2,2,2,10,37,2, 10,2,39,2,37,39,2,2, 2,2,2,10,39,2,33,11, 2,2,2,2,37,5,37,5, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 36,31,39,39,39,31,37,39, 37,39,37,39,11,37,4,37, + // 81xx + 56,39,37,39,39,37,39,37, 37,2,2,39,39,2,39,39, 37,37,39,39,39,39,39,39, 39,37,37,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,6,6,6,6,6,6,6, 6,6,2,6,6,6,2,6, 6,6,6,2,2,6,6,2, 6,2,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,37, + 36,6,2,6,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,6,2, 2,2,6,2,6,2,2,2, + 2,6,6,2,2,6,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 10,39,2,2,2,10,4,11, 6,6,6,6,6,6,2,2, 2,11,11,11,11,39,12,19, 2,2,6,2,6,6,6,6, + 2,6,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 6,6,6,6,6,6,6,6, 4,4,37,39,6,19,39,37, + // 82xx + 56,39,39,39,39,39,39,37, 37,2,2,39,39,2,42,39, 39,39,37,39,39,39,39,39, 39,39,39,39,39,39,37,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,6, 6,6,6,6,6,6,6,6, 6,2,2,2,2,2,2,2, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,2,2,2,2,2,37, + 2,2,2,2,2,6,2,2, 2,2,2,2,2,2,6,2, 6,36,2,2,6,6,6,6, 2,2,2,36,2,2,2,6, + 6,2,6,2,6,2,6,2, 6,6,6,6,2,6,6,2, 2,6,6,6,2,6,6,6, 2,2,2,6,6,6,6,6, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 6,6,6,2,2,2,6,6, 6,6,6,6,6,6,6,2, 6,6,31,12,11,31,39,19, 5,19,39,19,11,33,39,37, + // 83xx + 56,39,37,37,37,37,39,39, 39,2,2,39,39,2,37,39, 39,39,39,39,39,39,39,37, 39,39,39,39,37,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,37, + 6,6,6,2,6,6,2,6, 2,6,6,6,6,6,2,6, 2,2,2,6,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,6, + 6,6,59,6,6,59,59,6, 19,6,6,6,6,6,2,2, 2,2,6,6,19,6,6,11, 2,2,2,2,37,6,4,4, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,5,2, 31,4,11,10,39,19,19,11, 37,39,39,39,39,39,39,37, + // 84xx + 57,39,39,39,39,39,39,39, 39,2,2,39,39,2,39,39, 39,39,39,39,39,39,39,39, 37,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,11,2,2,2, 2,2,2,11,2,2,2,2, 2,2,2,11,2,2,11,11, 2,2,11,2,2,2,2,2, + 37,11,2,2,11,2,2,11, 2,2,2,11,2,2,11,2, 2,6,2,2,6,6,39,2, 6,6,11,6,2,6,2,37, + 36,2,2,2,2,36,2,2, 2,2,2,36,2,36,36,2, 2,2,2,36,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,2,59,6,2,6,2,2, 36,6,6,6,6,2,36,6, 2,2,2,2,2,6,2,2, 2,2,6,5,2,5,2,2, + 10,10,2,2,2,10,10,10, 12,12,10,2,10,10,2,2, 2,2,10,19,10,19,12,2, 2,2,2,2,12,19,16,10, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,5,2, 36,10,10,10,11,12,12,10, 12,12,12,39,11,39,16,37, + // 85xx + 56,11,39,37,39,39,39,39, 39,2,2,39,39,2,39,11, 39,39,39,37,37,39,39,37, 37,37,37,39,39,39,39,39, + 2,2,2,2,11,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,39,2,2,2,2,11,11, 2,2,2,2,2,2,19,2, + 2,11,11,2,11,2,2,2, 2,11,33,2,2,2,2,11, 11,11,2,11,11,2,33,11, 11,11,33,2,2,2,2,39, + 2,2,36,2,2,2,2,2, 2,2,36,2,2,2,2,36, 2,36,2,2,2,2,36,36, 2,2,2,5,2,2,2,36, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 39,5,2,2,19,11,5,11, 11,12,5,2,2,37,2,2, 2,2,6,11,11,19,12,39, 2,2,2,2,11,11,11,11, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,5,2, 36,36,4,23,23,4,19,11, 19,11,12,37,11,33,11,37, + // 86xx + 56,39,39,11,39,39,39,37, 39,2,2,39,39,2,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,37, + 2,6,2,2,36,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,19,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,36,2, 2,2,2,2,2,5,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 39,19,2,2,2,2,2,2, 11,2,19,2,19,37,2,2, 2,2,4,12,12,19,12,11, 2,2,2,2,11,12,4,6, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 36,36,39,31,39,4,39,11, 4,39,39,39,11,12,19,37, + // 87xx + 56,39,37,39,39,39,39,39, 39,2,2,39,39,2,39,37, 39,37,37,37,39,37,39,37, 37,39,39,39,37,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,6,6,6,6,6,6,6, 6,2,6,6,2,2,2,2, 2,11,2,2,6,6,6,6, 6,6,6,2,2,2,2,2, + 6,2,2,2,6,39,2,31, 2,11,11,2,2,2,2,6, 2,6,31,31,2,2,31,2, 11,2,37,2,2,2,2,37, + 36,6,2,2,2,36,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,5,2, 2,2,2,36,2,2,5,2, + 2,2,36,2,2,2,2,2, 2,5,2,36,2,2,11,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 19,12,2,2,2,2,4,11, 4,12,4,2,19,39,2,2, 2,2,4,12,12,4,19,11, 2,2,2,2,11,11,31,19, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,5,2, 36,4,37,11,11,11,4,11, 19,37,19,11,19,4,4,37, + // 88xx + 57,39,39,39,39,39,39,39, 39,2,2,39,39,2,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,39, + 2,36,36,36,2,36,2,2, 2,2,2,36,36,36,2,2, 2,2,2,36,2,2,2,2, 2,2,2,2,2,2,2,36, + 2,2,6,6,6,2,2,36, 2,2,2,2,2,2,6,2, 2,2,2,6,2,6,2,2, 2,2,2,2,6,2,2,2, + 6,6,2,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 2,6,6,6,6,6,6,6, + 2,6,6,2,2,2,2,2, 2,2,6,2,2,2,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,37,39,37, + // 89xx + 56,39,39,39,39,39,39,37, 39,2,2,39,39,2,39,39, 37,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,6,6,2,2,6,6,6, 6,2,6,6,6,2,6,2, 6,6,6,6,2,2,6,2, 6,6,6,2,6,2,6,6, + 6,6,6,6,2,6,6,6, 6,6,6,6,6,2,2,2, 6,6,6,6,6,6,6,6, 6,37,6,6,6,6,6,37, + 2,2,2,6,6,6,2,2, 2,6,2,2,2,2,2,6, 6,6,36,2,6,2,6,6, 6,2,6,6,6,6,6,6, + 6,6,6,2,6,2,2,2, 6,2,6,6,2,6,6,2, 2,2,2,6,2,2,2,6, 6,6,6,6,6,6,2,6, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,2, 2,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 2,6,2,2,2,2,6,2, 2,2,6,2,2,2,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,39,39,37, + // 8Axx + 56,39,37,39,39,39,39,39, 37,2,2,39,39,2,37,39, 39,39,39,37,39,39,39,39, 37,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,12,6,6,6,6,6,6, 2,12,6,6,12,2,12,6, 12,6,2,2,6,6,12,6, 6,6,6,6,2,2,6,6, + 6,12,2,2,6,6,37,6, 2,6,6,12,6,6,6,6, 6,37,6,6,6,6,6,6, 6,6,6,6,6,6,6,39, + 2,6,2,6,6,36,36,6, 6,2,2,6,6,12,36,6, 2,2,36,2,2,2,2,2, 2,6,6,2,2,2,2,2, + 2,2,2,6,2,2,6,6, 2,2,6,2,2,2,6,6, 6,2,6,6,6,2,2,6, 2,2,6,6,2,6,6,2, + 10,12,6,6,6,6,12,6, 6,6,6,6,6,12,6,6, 2,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 2,6,6,2,2,2,2,2, 2,2,2,6,2,6,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,39,4,37, + // 8Bxx + 56,39,37,39,39,39,39,39, 39,2,2,39,39,2,39,39, 39,39,39,39,39,39,39,39, 39,37,39,37,39,37,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,6,6,6,2,6,6,6, 6,6,2,6,6,6,6,6, 6,6,6,6,6,6,6,2, 6,6,6,2,6,2,6,6, + 6,2,2,6,2,6,2,6, 2,6,6,6,6,2,2,31, 6,6,6,6,6,6,6,2, 6,6,6,6,6,6,6,37, + 2,6,2,6,6,6,6,2, 2,2,36,6,6,2,6,6, 6,2,6,6,2,2,6,2, 2,2,5,6,2,2,6,6, + 2,2,2,6,2,2,6,2, 2,2,2,6,2,6,2,2, 2,2,6,6,6,6,6,6, 6,2,6,6,2,6,6,6, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 6,6,6,2,2,2,2,2, 2,2,6,2,2,2,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,39,37,37, + // 8Cxx + 56,39,39,37,39,39,39,39, 37,2,2,37,39,2,39,39, 37,39,39,37,39,39,39,39, 39,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,2,2,12,2,2,6,2, 2,6,6,6,12,2,6,2, 6,6,6,6,2,11,2,6, 6,6,6,6,6,2,6,6, + 6,6,6,6,2,6,6,6, 6,6,6,6,2,2,6,6, 6,6,2,2,2,6,6,12, 6,6,2,6,6,6,2,37, + 2,2,6,2,2,2,6,2, 6,2,6,6,6,36,6,6, 2,2,6,6,6,6,2,2, 6,6,6,6,6,6,6,6, + 6,2,6,6,6,2,2,6, 2,6,2,2,6,6,2,6, 6,6,2,6,6,6,2,6, 6,6,2,6,6,2,6,2, + 6,6,6,6,6,6,12,6, 6,6,6,6,6,6,6,6, 2,6,6,6,6,6,6,6, 2,2,2,2,6,6,6,6, + 2,6,2,2,2,2,2,2, 2,2,6,2,2,2,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,4,4,37, + // 8Dxx + 57,39,39,39,39,39,39,39, 39,2,2,39,39,2,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,37,37, + 2,2,2,37,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,12,2,6,6,6,6,6, 6,6,6,6,6,2,6,6, 6,6,6,6,6,6,2,6, 6,6,6,6,6,6,6,6, + 6,6,6,2,6,6,6,6, 6,6,6,6,6,6,2,6, 2,6,6,6,2,6,6,6, 6,6,6,2,6,6,6,39, + 6,2,6,2,6,36,6,6, 2,2,2,6,6,36,2,6, 6,6,2,2,2,2,2,2, 2,36,2,36,6,6,6,2, + 6,6,6,2,2,6,2,2, 2,6,6,2,6,6,2,2, 2,2,6,2,2,2,6,2, 6,6,2,6,2,6,2,2, + 6,12,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,11,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 2,2,6,2,2,2,2,2, 2,2,2,2,6,6,6,2, 6,6,6,6,6,6,6,6, 6,6,4,6,6,39,39,37, + // 8Exx + 56,39,39,39,39,39,39,39, 39,2,2,39,39,2,39,37, 39,39,39,37,37,37,39,39, 37,39,39,39,39,37,37,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,12,6,2,6,12,6,6, 2,12,2,12,2,6,12,6, 2,6,6,12,2,6,2,2, 6,6,6,2,6,6,6,6, + 6,12,6,6,6,12,6,6, 6,6,6,6,6,6,6,6, 6,6,31,6,6,6,6,6, 6,2,2,6,6,6,6,39, + 6,6,2,6,6,2,6,2, 2,2,6,2,6,6,6,6, 36,6,2,2,6,6,6,6, 2,6,6,6,6,6,6,6, + 6,6,2,7,7,2,6,2, 2,6,2,6,7,6,6,6, 2,7,2,7,7,6,7,2, 6,7,6,2,7,7,6,6, + 6,12,6,7,7,6,7,11, 7,6,6,6,7,12,6,6, 6,7,6,6,6,6,6,7, 6,7,7,7,7,7,7,7, + 2,6,2,2,2,2,2,2, 6,2,6,6,2,6,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,37,8,37, + // 8Fxx + 57,39,39,37,39,39,39,39, 39,2,2,39,39,2,39,39, 39,39,39,39,37,37,39,39, 39,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,6,6,6,2,6,6,6, 6,6,6,6,6,6,12,6, 6,6,6,2,6,2,6,6, 6,6,6,6,6,6,2,6, + 6,6,6,6,6,6,6,2, 6,2,6,6,2,6,6,6, 6,6,6,2,6,6,6,2, 6,6,6,6,2,6,6,39, + 6,6,2,6,2,2,6,6, 6,6,6,2,2,2,36,6, 2,6,2,2,6,6,2,6, 2,2,2,2,6,6,6,6, + 2,2,6,2,6,2,2,6, 36,2,2,6,6,6,36,2, 2,2,2,6,2,6,2,2, 2,6,6,6,6,2,2,5, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,2,6,6,6,6,6,6, + 2,6,2,2,2,2,2,2, 2,2,6,6,6,6,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,37,8,37, + // 90xx + 57,37,37,37,39,39,37,39, 39,2,2,39,39,2,39,37, 39,39,37,39,37,39,39,39, 39,37,37,39,39,39,39,37, + 2,2,2,37,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,6,6,2,6,6,6,6, 6,2,6,6,6,6,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,2,6,6, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,37, + 36,6,6,2,2,6,2,6, 2,2,2,6,2,2,2,6, 2,2,36,36,6,2,2,2, 2,6,6,2,2,6,2,6, + 36,6,6,6,6,2,2,6, 6,6,6,6,6,6,6,6, 6,2,6,6,6,2,6,6, 6,6,6,6,6,2,2,6, + 6,6,6,6,6,6,6,11, 6,6,6,6,6,6,6,6, 6,6,11,6,6,6,6,2, 6,6,6,6,6,6,6,6, + 6,2,6,2,2,2,2,2, 2,2,6,2,2,6,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,37,39,37, + // 91xx + 57,39,39,39,39,39,39,39, 39,2,2,39,39,2,39,39, 39,39,39,39,39,37,39,39, 39,39,39,39,39,39,37,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,2,6,2,6,6,6,2, 6,6,6,6,2,2,6,6, 6,6,6,6,6,6,6,11, 6,6,11,6,6,6,6,6, + 6,6,6,2,6,6,6,6, 6,2,6,6,2,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,2,39, + 6,6,2,6,2,36,2,6, 6,2,2,6,36,6,36,36, 6,6,36,36,6,6,6,6, 2,2,2,6,6,6,2,6, + 6,6,6,6,6,6,6,6, 2,2,6,6,6,6,6,36, 6,6,6,2,6,6,6,6, 6,6,6,2,6,6,6,6, + 10,6,2,6,6,6,2,6, 6,6,6,6,6,6,6,6, 2,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 6,2,2,2,2,6,2,2, 2,2,2,2,2,2,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,22,22,37, + // 92xx + 56,39,39,37,39,39,37,39, 39,2,2,39,39,2,39,39, 37,39,37,39,37,37,39,37, 37,39,39,39,37,39,37,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,11,2,2,2, 39,2,2,2,2,2,2,2, 2,2,2,11,2,2,2,2, + 6,11,6,6,6,6,2,2, 11,6,6,6,2,6,6,6, 6,6,2,6,6,6,2,6, 2,6,6,6,2,6,6,6, + 6,11,6,6,11,11,6,6, 11,6,6,6,6,6,6,11, 6,6,6,11,11,6,6,6, 6,11,6,6,6,6,6,37, + 36,6,36,6,2,6,6,6, 2,6,6,6,2,6,36,2, 36,6,2,6,2,2,2,2, 6,2,6,36,36,6,2,2, + 6,6,2,6,6,6,6,6, 2,6,6,2,6,2,6,2, 2,2,6,2,6,6,6,6, 6,6,6,2,6,2,6,6, + 6,6,6,6,6,6,2,6, 6,6,6,6,6,6,6,6, 6,2,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 6,6,6,2,2,2,2,2, 6,2,6,6,2,6,11,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,22,10,10, + // 93xx + 56,39,39,39,37,39,39,39, 39,2,2,39,39,2,39,39, 39,39,39,39,39,39,39,37, 37,39,39,39,39,39,37,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,11,11,11,11,6,11,6, 11,6,6,6,11,11,6,6, 11,11,11,6,6,11,6,6, 6,6,6,2,6,6,6,6, + 6,6,2,6,6,11,6,11, 6,2,11,6,6,2,2,6, 11,6,6,6,11,2,11,6, 6,6,6,6,6,6,6,37, + 6,2,6,6,2,2,36,6, 2,2,6,6,6,2,2,6, 6,36,6,2,6,6,6,36, 36,6,6,6,2,6,6,6, + 2,2,6,2,2,2,2,6, 2,6,6,6,6,6,6,6, 6,6,2,5,6,6,6,2, 2,6,2,6,2,6,6,6, + 10,6,6,59,6,6,6,6, 6,12,6,6,10,6,2,6, 6,2,6,10,6,6,6,2, 6,2,6,6,6,6,6,6, + 6,2,2,2,2,2,2,2, 2,2,2,2,6,6,6,2, 6,6,6,6,19,6,6,6, 6,6,6,6,6,10,19,37, + // 94xx + 56,39,39,39,39,39,39,39, 39,2,2,11,39,2,39,39, 39,39,39,39,39,39,39,37, 37,39,39,39,37,39,39,39, + 2,2,2,11,2,2,2,2, 2,2,2,2,11,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,11,2, + 6,6,2,6,6,6,6,6, 2,2,6,6,6,6,6,6, 2,2,6,6,6,2,6,2, 6,6,6,6,6,6,2,6, + 6,2,2,6,6,6,2,6, 6,2,6,2,2,2,6,6, 6,6,6,6,6,2,6,6, 6,6,6,6,6,6,6,39, + 2,2,2,6,6,2,2,2, 2,2,2,2,2,6,6,6, 2,6,6,6,2,6,6,6, 2,2,6,6,2,2,6,2, + 6,2,2,2,2,36,6,6, 2,2,6,6,2,6,2,2, 2,2,6,2,2,2,2,2, 2,2,2,2,6,6,2,2, + 6,6,6,2,6,6,6,6, 6,6,6,6,6,6,2,6, 2,6,6,6,6,6,6,2, 6,2,6,6,6,6,6,6, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,22,37,37, + // 95xx + 56,39,39,39,39,37,39,39, 37,11,2,39,39,11,39,39, 37,39,39,39,39,39,39,39, 39,37,39,39,39,39,39,39, + 11,2,2,39,11,2,11,2, 2,2,2,2,2,2,11,2, 2,2,2,2,2,2,2,2, 2,2,11,2,2,2,2,2, + 6,2,2,6,6,6,6,6, 6,6,2,6,11,6,11,6, 6,6,6,6,11,6,11,6, 6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,37, + 2,6,6,6,2,2,2,2, 2,6,2,6,2,6,6,2, 6,6,6,2,6,6,2,6, 2,2,6,6,2,6,6,6, + 6,6,2,2,2,6,2,6, 6,2,6,2,2,2,2,2, 2,6,6,6,2,6,6,6, 2,6,6,6,2,6,6,2, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,39,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 2,2,6,2,2,2,2,2, 2,2,6,2,2,2,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,37,19,37, + // 96xx + 57,39,39,39,39,37,39,39, 39,2,2,39,39,11,39,39, 37,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 11,2,2,2,11,11,2,2, 2,2,2,2,2,2,2,2, 11,11,11,2,11,2,11,11, 11,11,2,2,2,2,11,2, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,2,6, 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,11,6,6, 6,6,6,11,11,6,6,6, 6,6,6,6,6,6,6,39, + 2,6,6,6,2,6,2,2, 6,2,2,2,6,6,2,2, 2,2,2,2,6,6,6,2, 6,2,2,6,6,6,6,6, + 2,6,6,6,2,2,2,6, 6,2,2,2,2,2,2,6, 2,6,2,6,2,2,2,2, 2,2,6,2,6,2,6,6, + 6,6,6,6,6,6,6,11, 6,6,6,6,6,6,6,6, 2,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 2,2,6,2,2,2,2,2, 2,2,2,6,6,6,6,2, 6,6,6,6,6,6,6,6, 6,6,17,6,6,39,37,37, + // 97xx + 56,39,39,39,39,39,39,37, 39,2,2,39,39,2,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,37,39,37,39, + 2,2,2,11,11,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,11,2, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 6,2,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 6,6,11,6,6,6,6,6, 6,2,6,6,6,6,6,11, 6,6,6,11,6,6,6,6, 6,6,6,6,2,6,6,39, + 36,6,6,6,2,2,2,2, 6,2,6,2,2,6,6,2, 2,6,6,6,2,2,6,6, 6,6,6,2,2,6,6,6, + 2,2,6,6,6,2,6,6, 2,2,6,6,6,2,2,6, 2,6,6,6,2,6,2,6, 2,6,2,2,6,2,6,6, + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, 2,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, + 2,6,6,2,2,2,2,2, 2,2,6,6,6,6,6,2, 6,6,6,6,6,6,6,6, 6,6,6,6,6,39,39,37, + // 98xx + 57,37,37,37,39,37,37,39, 37,2,2,39,39,2,39,39, 37,37,37,37,39,39,39,39, 37,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,6,6,6,2,2,6,2, 6,6,6,2,6,2,6,6, 2,6,6,2,2,6,6,2, 6,6,6,6,6,2,6,6, + 6,6,6,2,2,6,6,6, 6,2,6,2,6,2,2,2, 6,6,6,2,2,2,2,2, 2,2,2,2,2,2,2,39, + 2,2,2,2,2,2,2,2, 2,2,36,2,2,2,2,2, 2,2,36,2,2,2,2,2, 2,5,2,2,2,11,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,5,2,2, + 11,39,2,2,2,6,39,11, 6,11,11,19,6,39,2,11, 2,11,6,11,11,39,6,2, 2,2,2,2,11,11,5,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,5,2, 6,6,37,6,6,4,39,6, 6,5,6,39,6,37,37,37, + // 99xx + 56,39,39,37,39,37,39,39, 39,2,2,39,39,2,39,39, 37,39,39,37,39,39,39,39, 37,37,39,39,39,39,37,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,6,2,2,2,11,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,6,6,2,2,2,37, + 2,2,2,2,2,2,2,2, 2,2,6,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,37,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,5,2,2,2,2,2, 2,2,2,2,2,2,2,5, + 6,6,2,2,2,2,2,11, 6,6,6,2,6,6,2,2, 2,2,6,6,6,6,6,2, 2,2,19,2,11,6,11,6, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,5,2, 6,36,6,6,6,6,6,6, 6,6,6,6,6,39,4,37, + // 9Axx + 56,39,39,39,39,39,39,39, 39,2,2,39,39,2,37,39, 39,39,37,37,39,39,39,39, 39,37,39,37,39,39,37,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,12,2,2,2,12,2,2, 2,12,2,12,12,2,12,12, 12,6,2,2,12,12,12,2, 2,2,2,2,2,2,2,37, + 2,2,2,5,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,6,2,2,2,2,2, 2,2,12,2,2,12,6,36, + 6,6,2,2,2,5,2,2, 2,2,2,2,6,6,2,5, 2,2,5,5,2,2,2,2, 2,2,2,2,2,2,2,2, + 5,6,59,2,2,2,6,12, 6,2,6,2,4,6,2,2, 2,2,6,6,37,39,6,2, 37,2,6,6,6,19,6,6, + 2,2,2,2,2,2,2,2, 2,2,2,5,2,12,6,2, 36,6,12,10,12,6,6,6, 6,12,6,6,12,12,39,37, + // 9Bxx + 56,39,39,39,39,39,37,39, 39,2,2,39,39,2,39,39, 39,39,39,37,39,39,39,39, 39,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,6,2,2,2,2,2,2, 2,2,39,2,2,2,2,2, 5,2,6,2,2,2,2,2, + 2,2,2,2,2,2,2,6, 2,2,6,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,6,6,2,2,2,37, + 2,2,36,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,6,2,36,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,5,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,6,2,2,6,2,6,2, 4,6,6,2,2,12,2,2, 2,2,6,6,6,39,2,2, 2,2,6,6,6,6,6,6, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,6,2, 6,6,6,6,6,6,6,11, 4,6,6,6,11,11,22,37, + // 9Cxx + 56,39,39,11,37,37,39,39, 39,2,2,39,39,2,39,39, 37,37,39,37,39,37,39,39, 39,39,39,39,39,39,39,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,6,2,2,2, + 2,2,2,12,2,2,2,2, 2,2,2,2,12,2,2,2, 2,2,12,2,2,11,2,12, 2,2,2,2,2,2,2,37, + 2,2,2,2,2,36,2,2, 2,2,2,2,2,2,2,2, 2,36,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,4,2,2,2,2,6,2, 6,6,19,2,6,4,2,2, 2,2,2,2,6,2,2,2, 2,2,2,6,6,6,6,6, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 6,12,6,10,37,4,6,6, 6,6,6,6,11,4,19,37, + // 9Dxx + 56,39,12,4,37,39,37,39, 37,2,2,39,39,2,39,39, 37,39,37,39,37,37,39,37, 37,37,37,39,37,37,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,6, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 6,2,2,2,2,2,2,2, + 2,12,2,2,2,2,6,2, 2,2,2,2,2,2,2,12, 2,2,2,2,12,12,2,2, 2,2,2,2,6,2,2,37, + 2,2,2,2,2,5,2,2, 2,2,2,36,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,5, 2,2,2,36,2,2,2,2, 2,2,5,2,2,2,2,2, 2,2,6,2,2,2,2,2, + 5,6,2,2,2,2,11,11, 11,6,11,2,11,11,11,11, 2,11,11,11,11,11,4,6, 2,2,11,6,6,11,11,11, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,19,2, 6,19,6,6,6,6,6,19, 6,6,12,10,4,19,11,37, + // 9Exx + 56,39,39,39,37,39,39,39, 39,2,2,39,39,2,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,37,37, + 12,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,12,12,2,12,12,2,2, 2,12,2,12,2,2,12,12, 2,2,2,12,2,12,2,2, 2,2,2,2,2,2,2,37, + 2,2,2,2,2,2,6,2, 2,2,6,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,11,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,5,6,2,2,2,2,2, 2,6,2,2,2,6,2,2, + 6,12,59,2,6,2,2,2, 6,6,6,6,2,5,2,6, 2,2,6,11,6,6,6,2, 11,6,6,2,6,19,37,6, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,12,5,2, 12,4,12,10,6,19,39,6, 6,12,12,6,6,12,11,37, + // 9Fxx + 56,39,39,39,4,39,39,39, 39,2,2,39,39,2,37,39, 39,39,39,37,39,37,39,39, 37,39,39,39,39,39,39,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,6,6, 2,2,2,2,6,2,2,2, 2,2,2,2,2,2,2,2, + 2,33,2,31,12,33,2,31, 31,2,2,33,33,2,2,2, 33,6,31,2,33,33,2,12, 2,2,2,6,2,2,2,37, + 2,2,36,2,2,36,6,36, 2,2,36,2,36,36,2,2, 2,2,2,2,2,6,36,2, 2,36,2,2,2,2,36,2, + 2,33,2,2,2,2,2,2, 6,2,36,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 6,4,2,2,6,2,6,6, 6,6,6,2,6,6,2,2, 2,2,1,6,6,6,4,2, 2,2,6,6,4,6,6,6, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 6,12,6,6,19,6,6,6, 6,6,6,6,6,19,4,37, + // A0xx + 7,11,37,11,37,1,37,1, 1,11,11,37,1,11,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 11,2,2,11,11,11,2,2, 11,2,2,11,2,11,2,2, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,2, + 2,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,2,2,2, + 2,11,11,11,11,11,11,11, 11,11,11,11,33,11,33,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,2,2,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,11,2,2,12,2, + 11,2,36,36,2,2,36,36, 2,36,2,36,36,2,36,2, 2,2,2,5,2,2,2,2, 2,2,2,2,2,2,2,12, + 10,10,2,2,10,11,10,11, 11,1,10,14,10,10,10,10, 2,11,11,11,11,11,1,2, 2,2,11,11,1,10,11,11, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,36,2, 10,10,10,10,10,10,10,10, 12,17,1,10,11,33,1,10, + // A1xx + 7,37,37,1,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,3,37,37,37,37, + 11,2,2,2,2,2,11,2, 2,2,2,2,2,2,14,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,14,2, + 8,8,8,8,9,8,8,8, 8,8,8,8,8,8,8,8, 8,8,8,9,9,8,8,8, 8,1,9,2,8,8,8,2, + 8,8,33,2,33,8,8,1, 33,8,8,33,33,8,8,2, 2,8,8,33,2,8,8,8, 8,8,8,39,2,8,2,37, + 2,2,2,2,2,2,2,2, 2,2,2,39,2,2,2,2, 2,2,2,2,2,2,6,2, 2,2,2,2,2,2,2,33, + 2,3,3,3,3,7,7,7, 2,7,7,3,2,3,3,3, 3,3,7,8,8,2,3,3, 8,7,3,3,7,7,3,3, + 3,7,7,7,7,14,9,14, 7,7,7,7,7,14,7,7, 8,14,14,14,14,14,7,7, 7,7,7,7,7,7,5,7, + 2,5,5,2,2,2,2,2, 2,2,2,7,2,2,3,3, 3,3,3,7,3,7,7,7, 3,7,7,7,7,7,7,37, + // A2xx + 7,37,37,1,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,8,2,2,8,2,2,8, 8,8,8,2,2,2,2,2, 2,2,2,2,2,2,2,2, 8,2,2,2,2,2,2,2, + 2,2,8,8,33,8,8,2, 8,8,2,8,2,2,2,2, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + 2,2,6,2,2,2,2,2, 2,6,2,2,2,2,2,6, 6,2,2,2,6,6,2,2, 2,2,2,2,2,2,2,2, + 36,7,7,7,7,7,7,7, 7,7,7,2,7,7,36,8, 2,8,8,8,8,8,8,14, 5,5,5,14,2,5,5,5, + 5,5,5,5,5,14,5,14, 5,5,14,23,5,14,5,5, 8,5,14,8,8,14,14,8, 14,3,3,3,3,5,8,5, + 2,2,2,2,2,2,2,2, 2,2,8,36,8,8,8,2, 8,3,3,3,8,8,7,8, 8,3,8,8,8,8,8,37, + // A3xx + 7,37,37,39,37,37,37,37, 37,2,2,37,4,2,9,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 2,2,2,2,11,11,2,2, 2,2,2,2,2,2,2,2, 11,11,11,11,11,11,11,11, 11,11,2,2,2,2,2,2, + 36,12,12,12,12,12,2,12, 2,2,2,12,2,12,12,12, 12,2,2,12,12,12,11,12, 8,12,12,2,8,2,11,2, + 8,12,2,2,33,12,2,8, 11,2,8,12,2,2,2,2, 2,11,2,8,2,12,8,2, 8,2,8,8,8,8,8,37, + 2,2,2,6,2,2,2,2, 3,2,2,2,2,2,2,2, 2,2,2,2,3,2,5,2, 2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3, 3,3,3,2,3,3,3,3, 3,3,3,3,3,3,3,3, 3,3,3,3,2,2,2,3, + 10,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 3,3,3,3,5,3,3,3, + 2,2,2,2,2,2,2,2, 2,2,2,3,3,3,3,2, 3,3,3,12,3,3,3,3, 3,3,3,3,3,3,3,37, + // A4xx + 7,37,37,11,1,37,11,39, 11,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,7,37,37,37,37,37, + 2,2,2,11,2,11,2,2, 2,2,11,2,2,2,2,2, 37,2,11,2,2,2,2,17, 2,17,2,2,2,2,2,2, + 8,8,8,8,8,8,8,8, 8,2,8,8,8,8,2,8, 2,8,8,8,8,8,8,8, 8,8,8,8,8,8,2,8, + 8,8,8,11,8,11,8,8, 8,8,8,8,8,2,2,8, 8,8,8,8,8,8,8,8, 8,8,8,2,2,8,8,39, + 2,2,2,2,2,2,2,2, 2,2,2,6,2,2,2,2, 2,2,2,6,6,2,2,2, 2,2,2,2,2,2,2,2, + 36,3,3,8,3,36,3,2, 3,2,3,3,3,3,3,3, 3,3,3,3,3,3,8,3, 3,3,8,3,3,3,2,3, + 3,3,14,3,3,14,3,3, 3,3,3,3,3,3,3,3, 3,8,3,3,14,3,8,3, 3,3,8,3,3,3,3,3, + 3,3,3,2,3,8,2,2, 3,3,3,3,3,3,8,3, 8,8,3,3,8,8,8,8, 11,8,8,8,8,5,8,1, + // A5xx + 7,6,37,39,37,37,6,37, 1,2,2,37,1,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 2,2,2,2,2,2,2,11, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,9,8,12,8,2,8,8, 8,8,8,8,8,2,8,8, 8,2,8,8,12,8,8,2, 8,8,8,8,8,8,8,8, + 8,8,8,2,8,8,8,2, 8,8,8,8,8,2,2,2, 2,8,2,8,2,8,8,2, 8,2,8,8,8,8,8,37, + 2,2,2,6,2,2,2,2, 2,2,2,2,2,2,6,2, 2,2,6,6,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,3,3,3,3,6,3,3, 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 3,3,3,8,2,2,3,3, + 3,3,2,3,3,8,3,3, 3,3,3,3,3,8,8,3, 3,3,3,3,3,3,3,3, 8,3,3,3,3,3,3,3, + 3,3,3,2,2,2,2,2, 2,3,3,3,3,3,8,3, 8,8,8,3,8,8,3,8, 8,8,8,8,8,8,8,37, + // A6xx + 7,37,37,39,37,37,37,1, 12,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,6,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,8,8,9,8,33,2,2, 8,33,8,9,9,9,9,8, 8,8,9,8,8,8,8,8, 8,8,8,2,2,8,8,8, + 8,8,8,9,2,2,2,2, 8,8,8,8,9,9,8,8, 8,2,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 36,8,5,8,2,36,5,2, 8,8,2,8,2,8,2,2, 2,8,2,8,2,8,8,8, 8,8,8,2,2,2,2,8, + 8,3,3,8,8,3,9,8, 8,14,8,8,8,3,2,8, 8,8,8,8,3,8,33,8, 3,8,8,8,8,8,8,8, + 2,2,8,2,2,2,8,2, 2,2,8,8,8,8,8,2, 3,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + // A7xx + 7,1,1,37,37,37,37,37, 37,14,2,14,37,14,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 2,2,2,2,11,2,2,14, 2,2,11,2,2,2,2,2, 11,11,11,11,11,11,11,11, 11,11,2,2,2,2,11,2, + 8,8,8,8,8,8,2,8, 8,8,8,8,8,8,8,8, 8,8,8,2,8,8,8,2, 8,8,8,11,2,11,8,8, + 8,2,8,8,8,8,8,8, 8,8,8,8,8,2,2,8, 8,8,8,8,8,2,8,8, 8,2,2,8,8,8,2,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,5, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 36,14,14,2,14,3,2,11, 8,8,14,2,2,36,8,2, 2,2,8,5,14,14,14,14, 2,8,8,2,14,8,14,2, + 8,14,14,14,14,14,8,8, 14,8,14,14,8,14,8,8, 8,8,14,8,14,3,8,14, 2,2,8,2,8,8,8,8, + 2,14,8,2,2,2,2,2, 2,2,2,8,8,8,3,2, 8,3,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + // A8xx + 7,11,1,39,1,37,37,37, 4,2,2,14,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 2,2,2,2,2,2,2,2, 2,2,11,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,2,8,8,8,2,8,2, 8,8,2,8,8,8,8,3, 2,2,8,8,8,8,2,2, 2,2,8,2,2,2,8,2, + 11,8,8,8,8,8,8,8, 2,2,8,8,8,8,8,8, 8,8,3,8,8,8,8,3, 8,8,8,8,8,8,8,37, + 2,2,2,2,2,2,2,2, 2,5,2,2,2,2,2,3, 3,3,3,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,7,8,8,8,7,7, 14,8,2,8,7,8,8,8, 11,2,7,2,2,8,2,14, 2,2,8,2,2,8,8,2, + 8,14,2,8,8,8,8,8, 8,8,8,14,8,14,8,8, 14,8,14,8,14,5,8,8, 14,2,8,5,5,6,5,8, + 2,2,8,2,2,2,2,2, 2,2,2,2,8,2,8,2, 5,5,8,8,8,8,5,8, 8,5,8,8,8,8,8,37, + // A9xx + 7,1,37,39,37,37,39,37, 37,2,2,37,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 11,2,2,2,11,2,11,2, 2,2,2,11,2,2,2,2, 37,11,11,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,9,8,8,9,9,11,8, 8,8,8,9,9,8,9,8, 8,8,8,8,8,8,9,8, 2,8,8,8,2,8,8,8, + 8,2,8,2,8,8,8,8, 8,8,8,9,8,8,2,3, 8,2,2,8,2,8,8,8, 8,8,8,8,8,8,8,39, + 2,3,6,3,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,6,2,2,3,2, 2,2,2,2,2,2,2,2, + 2,8,2,8,3,3,3,3, 8,2,3,8,2,3,3,8, 2,8,8,8,2,8,2,2, 3,8,2,2,8,3,8,2, + 3,3,2,2,3,14,8,8, 8,8,8,2,3,9,8,3, 8,14,8,8,8,14,8,2, 2,2,8,8,8,8,8,8, + 2,2,8,2,2,2,2,2, 2,2,2,2,2,2,8,2, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + // AAxx + 7,37,37,37,37,1,37,37, 4,2,2,1,37,2,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,8,8,8,8,8,8,8, 2,12,2,8,8,8,2,8, 8,8,8,2,12,2,2,2, 2,8,8,8,2,2,8,8, + 8,8,2,8,8,8,8,8, 8,8,8,8,8,8,8,8, 8,8,8,2,2,8,8,8, 8,8,8,8,2,2,2,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,5,2,2,2,2,2,2, + 36,14,8,8,2,3,8,8, 2,8,2,8,8,2,36,8, 2,8,2,5,8,5,2,5, 14,14,8,2,8,8,8,2, + 8,14,14,14,10,8,5,14, 8,1,5,5,8,14,8,8, 14,8,14,8,14,14,8,14, 14,2,8,2,8,8,8,5, + 2,8,2,2,2,2,2,2, 2,2,8,5,8,8,8,2, 8,8,8,5,8,10,8,8, 8,8,8,8,8,8,8,37, + // ABxx + 7,1,1,37,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,6,37,37,37, 37,37,37,37,37,37,37,37, + 2,2,2,2,2,2,11,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,11,8,8,8,11,8,8, 8,8,8,8,8,11,8,8, 8,8,2,11,8,8,11,8, 8,8,2,2,8,2,8,8, + 8,8,8,11,8,8,11,8, 8,8,8,8,8,2,8,8, 8,8,8,8,8,2,8,8, 8,8,8,8,8,8,8,37, + 2,2,2,2,2,2,5,2, 2,2,2,2,2,2,39,2, 5,2,2,2,2,11,2,2, 2,2,5,2,2,5,2,2, + 2,8,8,8,5,2,2,8, 36,2,2,8,8,2,36,2, 8,8,3,8,8,8,2,5, 2,2,8,2,8,8,2,2, + 8,8,8,8,8,8,5,8, 8,8,8,8,8,14,8,11, 14,8,8,8,14,14,14,8, 8,14,11,8,8,8,11,8, + 2,8,2,2,2,2,2,2, 2,2,2,2,36,8,36,2, 20,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + // ACxx + 7,37,37,39,37,39,39,37, 37,2,2,37,39,2,37,39, 37,37,37,37,37,39,37,37, 39,37,37,39,37,37,37,37, + 2,2,2,11,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,8,8,9,8,33,8,8, 2,8,8,8,9,8,9,8, 8,8,9,2,2,8,8,9, 8,8,8,8,8,2,2,8, + 8,8,2,8,8,33,8,11, 8,2,2,2,2,8,8,8, 8,8,8,8,8,8,8,8, 8,8,8,2,8,8,8,37, + 2,6,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,6,5,2,2,2,2, 2,2,2,2,2,2,2,2, + 36,8,2,8,2,36,2,2, 36,6,8,36,2,36,36,8, 8,2,2,8,2,8,8,3, 2,8,2,2,2,8,2,3, + 8,8,59,8,8,59,8,3, 8,8,3,59,8,8,3,2, 8,5,8,8,8,8,8,8, 2,8,5,8,8,8,8,8, + 2,2,59,2,2,2,2,2, 2,2,2,2,2,2,8,2, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + // ADxx + 7,39,37,37,39,39,37,39, 39,2,2,37,39,2,37,39, 39,37,39,39,39,39,39,37, 39,39,37,39,39,39,37,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,8,2,8,8,2,8,8, 2,8,8,2,8,8,2,2, 8,2,2,8,8,8,8,8, 8,8,8,8,2,8,8,2, + 8,2,8,2,11,8,8,11, 8,2,11,11,8,8,8,11, 8,8,11,8,2,8,11,8, 8,2,8,8,2,8,2,37, + 2,2,2,2,2,2,2,2, 2,2,39,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,5,2, + 36,2,2,2,2,2,2,8, 36,2,14,8,2,8,36,2, 2,8,8,2,2,8,8,8, 2,8,8,8,8,2,2,8, + 8,14,8,14,8,8,8,8, 8,8,8,8,8,8,2,2, 7,8,14,8,8,14,7,8, 2,8,8,8,8,8,8,8, + 2,8,2,2,2,2,2,2, 2,2,2,2,8,2,36,2, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + // AExx + 7,39,1,39,39,39,37,37, 37,2,2,37,39,2,37,39, 39,39,39,39,39,39,37,37, 39,39,37,39,39,39,37,37, + 2,2,2,2,2,2,2,2, 2,2,2,5,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,9,8,2,2,9,2,2, 8,9,8,9,8,8,9,9, 2,8,2,8,8,2,8,2, 2,2,8,2,2,8,2,8, + 8,8,8,8,8,8,2,8, 8,8,2,8,8,8,2,8, 8,8,8,2,8,8,8,8, 8,8,8,8,8,8,11,37, + 2,2,6,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,36,8,8, 2,2,2,2,36,2,2,2, 2,2,2,2,2,2,2,8, 2,2,2,8,8,2,2,2, + 8,8,8,14,8,6,8,8, 8,8,8,14,8,9,2,2, 8,8,8,8,8,8,8,8, 8,2,8,8,8,6,8,8, + 2,36,36,2,2,2,2,2, 2,2,2,2,2,8,8,2, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + // AFxx + 7,9,1,1,39,39,39,37, 37,2,2,37,39,2,37,37, 37,37,37,37,37,39,37,37, 39,39,37,37,39,37,37,37, + 2,2,2,2,2,2,2,2, 2,11,2,2,2,2,2,2, 39,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,12,8,2,12,12,8,2, 2,8,2,12,12,8,12,12, 8,8,8,8,8,2,2,2, 2,12,8,8,2,8,2,2, + 11,2,8,2,8,8,8,8, 2,2,2,8,8,2,2,12, 2,8,2,2,2,8,8,8, 8,12,8,8,2,8,2,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 36,9,2,6,2,2,2,2, 2,2,8,8,8,2,36,2, 11,2,8,8,2,8,2,2, 8,2,8,2,2,8,2,2, + 8,8,8,8,6,8,8,8, 8,8,8,6,6,10,8,8, 8,8,8,8,14,10,1,8, 2,2,2,2,8,8,8,8, + 8,2,2,2,2,2,2,2, 2,2,2,8,2,2,8,2, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + // B0xx + 7,39,37,37,39,4,37,37, 39,11,2,37,37,2,37,37, 39,39,37,37,39,39,37,37, 39,39,37,39,39,39,37,37, + 2,2,2,2,11,2,2,2, 2,2,11,2,2,2,2,2, 11,11,11,11,11,11,11,11, 11,11,2,2,2,2,2,2, + 8,8,2,11,8,11,11,2, 2,8,8,8,2,2,2,8, 2,8,2,2,8,8,8,2, 2,2,8,2,8,8,8,8, + 11,8,2,2,8,8,8,8, 8,2,8,8,8,11,2,11, 8,8,2,8,8,8,8,8, 8,8,2,8,8,8,11,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 11,5,5,5,2,5,7,2, 5,5,8,8,3,5,3,2, 5,2,3,5,3,8,5,8, 3,5,3,8,8,2,2,2, + 6,3,7,2,3,5,7,5, 8,3,8,5,7,5,3,8, 2,3,14,8,5,7,3,3, 3,3,5,7,5,5,7,5, + 2,5,8,2,2,2,5,2, 5,2,8,2,3,5,5,3, 5,5,8,8,3,8,8,5, 5,3,5,7,5,5,3,37, + // B1xx + 7,11,11,39,39,37,39,37, 37,2,2,37,37,9,39,39, 37,39,37,37,39,39,37,37, 37,39,37,37,39,39,37,37, + 9,9,2,2,37,2,2,2, 2,2,2,5,9,2,9,2, 2,2,2,2,2,2,2,2, 2,2,9,9,2,2,2,9, + 8,2,8,8,2,8,8,8, 8,8,8,8,8,8,8,8, 2,2,11,2,8,8,8,8, 8,8,8,8,2,2,8,8, + 8,8,8,9,9,8,8,9, 8,8,8,9,8,8,2,8, 9,8,8,9,9,2,8,8, 8,8,8,8,2,8,2,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,5,2, 2,2,2,2,2,2,2,2, + 2,8,7,3,5,3,3,3, 3,3,2,7,3,3,3,3, 2,3,3,5,3,8,3,8, 5,5,5,3,5,2,3,7, + 8,5,8,5,7,5,8,5, 3,7,3,3,3,5,3,3, 8,7,3,8,5,3,5,5, 3,5,8,5,3,5,5,7, + 3,8,5,2,3,2,2,2, 5,2,3,2,2,3,5,2, 3,8,5,7,5,3,3,7, 8,3,5,7,7,8,7,37, + // B2xx + 7,39,37,39,37,37,39,1, 37,2,2,39,37,2,39,39, 39,39,37,37,39,39,37,39, 39,39,37,37,39,39,37,39, + 2,2,2,2,2,39,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,2,8,2,8,8,2,8, 8,2,8,8,8,8,8,8, 8,8,8,2,2,8,8,8, 8,8,8,8,8,8,8,8, + 8,8,8,2,8,2,2,8, 2,8,8,8,8,8,8,8, 8,8,8,2,3,2,8,8, 8,8,8,8,2,39,8,37, + 2,2,2,2,2,2,5,5, 2,2,5,2,2,2,5,5, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,3,3,8,8,3,7,8, 3,3,3,7,7,7,3,7, 7,8,5,8,2,3,3,2, 2,3,3,3,3,3,2,3, + 5,7,3,7,8,3,3,7, 7,3,3,3,7,3,3,7, 7,10,3,8,7,8,7,8, 3,3,7,7,3,3,5,3, + 2,3,3,2,2,2,2,2, 7,3,7,5,3,10,3,2, 7,7,7,7,5,7,5,7, 8,7,3,5,8,3,7,37, + // B3xx + 7,39,1,39,39,37,37,37, 39,12,2,37,39,2,37,39, 39,39,37,37,39,39,39,37, 39,39,37,39,39,39,37,37, + 12,12,2,2,11,39,2,2, 2,2,2,2,12,2,12,12, 37,2,2,2,2,2,2,2, 2,2,12,12,2,2,2,12, + 8,2,8,8,8,2,2,2, 2,2,8,2,2,2,8,12, 2,8,2,8,8,8,8,8, 8,8,8,2,8,8,8,2, + 2,12,12,12,8,12,8,8, 8,2,8,12,2,12,8,8, 8,8,8,8,8,12,8,8, 8,12,8,8,2,8,8,37, + 2,2,6,2,2,2,2,2, 2,2,2,2,2,2,2,6, 2,2,2,2,2,2,2,2, 5,2,2,2,2,2,2,2, + 2,3,2,3,3,3,7,3, 2,3,5,7,3,5,8,5, 7,9,5,5,2,3,2,3, 2,8,8,5,2,8,3,3, + 7,3,3,5,5,3,3,3, 7,3,5,3,3,7,7,3, 3,5,8,7,3,8,3,5, 7,3,7,7,8,5,3,8, + 5,8,5,2,2,2,2,2, 2,2,3,5,5,5,5,2, 5,10,8,5,7,8,3,3, 8,8,5,3,8,3,3,10, + // B4xx + 7,39,1,39,39,37,37,4, 39,14,2,14,39,2,37,39, 37,39,37,37,39,39,37,37, 37,39,37,39,37,39,39,37, + 2,2,2,11,11,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,11,8,8,8,11,2,2, 8,8,8,8,8,8,8,8, 8,8,11,11,8,8,8,2, 8,8,8,8,2,2,8,8, + 8,11,8,8,8,11,8,8, 11,11,8,8,2,11,11,8, 11,8,8,11,11,11,11,8, 8,8,8,2,2,8,2,37, + 2,2,2,6,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,3,2,8,8,3,3,14, 3,5,2,3,3,2,3,2, 2,7,3,7,3,8,7,14, 2,2,5,2,8,3,2,3, + 5,8,5,5,7,3,7,3, 3,5,3,3,3,14,3,5, 5,7,14,3,5,14,7,5, 7,5,8,7,5,5,5,3, + 2,14,2,2,5,2,2,5, 2,2,2,5,2,2,3,3, 3,5,3,3,7,5,5,3, 3,7,3,3,7,3,8,37, + // B5xx + 7,39,37,39,39,37,37,37, 39,2,2,37,39,2,37,37, 37,39,39,37,37,37,37,37, 37,39,37,37,37,37,37,37, + 2,2,2,2,39,2,2,2, 2,2,2,2,2,2,14,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,2,33,33,33,2,11,8, 8,8,8,33,8,8,33,8, 8,39,33,8,33,8,33,8, 8,8,33,8,8,2,8,2, + 8,9,8,8,8,8,8,11, 8,8,8,8,8,11,8,8, 8,8,11,8,3,8,8,8, 8,8,8,8,8,8,2,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,5, 2,2,2,2,2,2,2,5, + 2,7,7,3,7,3,8,8, 5,3,8,3,7,7,3,3, 2,3,8,3,8,5,5,2, 5,8,3,7,3,3,3,5, + 3,3,3,3,3,5,3,5, 3,5,5,5,3,3,5,3, 3,14,7,14,14,7,3,3, 3,7,3,8,7,3,7,7, + 2,7,5,3,3,5,2,3, 2,5,3,2,2,2,5,2, 5,5,5,8,3,3,7,3, 8,8,3,8,8,8,7,37, + // B6xx + 7,1,4,39,37,37,37,37, 37,2,2,37,37,2,37,37, 37,37,37,37,39,37,37,37, 37,39,37,37,37,37,37,37, + 9,2,2,2,11,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,9,2,2,2,9, + 8,2,8,2,8,8,8,2, 8,2,8,8,8,2,2,8, 8,8,8,8,8,8,8,8, 8,3,8,2,2,8,8,2, + 8,30,8,9,8,8,2,8, 8,8,2,9,9,8,9,8, 9,8,9,8,8,8,8,9, 8,2,8,8,8,8,8,37, + 2,2,2,5,2,2,5,5, 2,2,2,2,2,5,2,2, 2,11,5,2,2,2,5,5, 2,2,2,2,2,2,2,2, + 2,8,8,2,8,3,7,5, 3,3,3,3,3,3,8,3, 8,5,2,2,3,7,7,3, 7,3,8,5,3,3,3,7, + 3,3,8,8,3,3,3,5, 3,7,7,3,3,3,3,3, 7,7,14,3,3,8,3,8, 7,3,7,7,8,7,6,5, + 3,7,7,2,2,2,2,2, 2,2,8,8,7,3,3,2, 8,7,5,5,5,5,5,5, 3,3,3,3,3,8,3,37, + // B7xx + 7,39,37,14,39,37,39,37, 39,11,11,37,39,2,37,39, 39,39,37,39,39,39,39,37, 39,39,37,39,39,39,37,37, + 11,2,2,11,11,2,11,2, 2,2,11,2,2,2,11,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,11,2, + 8,8,8,33,33,11,8,8, 8,2,8,33,8,8,8,8, 8,8,8,8,33,8,8,8, 8,8,33,2,8,2,2,2, + 11,11,8,2,8,11,8,11, 8,8,8,8,11,8,8,8, 2,8,8,8,2,8,8,8, 8,8,8,2,8,8,8,37, + 2,6,6,2,2,2,2,2, 2,6,2,2,2,2,2,2, 2,2,2,2,2,11,2,2, 2,2,2,5,2,2,2,2, + 2,5,3,5,7,2,5,8, 3,5,7,5,3,3,5,5, 5,5,2,5,3,3,3,11, 2,5,3,5,2,3,3,3, + 3,5,5,5,5,3,3,3, 7,3,7,8,3,14,5,5, 5,3,14,8,5,14,3,7, 14,14,7,3,3,3,7,3, + 2,5,3,2,2,2,2,3, 2,2,7,7,5,8,7,7, 3,3,3,7,3,7,3,7, 3,5,7,3,5,5,3,37, + // B8xx + 7,39,37,39,39,39,37,37, 37,2,2,37,37,2,37,1, 39,39,37,39,39,39,39,37, 39,37,37,37,39,39,39,37, + 2,2,2,2,37,2,2,2, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,8,2,8,2,6,2,8, 8,8,8,8,8,6,8,8, 2,2,8,8,8,8,8,8, 8,8,8,2,37,2,2,8, + 8,8,2,11,8,8,8,8, 8,8,8,8,2,8,8,8, 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,7,2,5,2,5,5,5, 8,7,2,7,2,2,5,2, 2,2,5,5,3,5,5,5, 5,8,2,5,5,3,3,5, + 7,5,5,3,3,5,5,5, 8,3,3,8,8,7,3,3, 3,8,3,5,5,5,3,3, 14,3,3,3,8,7,5,3, + 2,7,3,2,2,2,3,5, 3,5,8,2,2,5,7,3, 5,5,7,5,8,8,3,3, 3,3,3,8,3,7,7,37, + // B9xx + 7,39,4,37,39,39,39,37, 39,14,2,14,39,14,4,37, 39,39,39,39,39,39,37,37, 39,39,37,39,39,39,39,37, + 14,2,2,2,2,2,2,14, 2,2,2,2,2,2,14,2, 37,2,2,2,2,2,2,2, 2,2,2,2,2,2,14,2, + 8,8,8,8,8,8,8,8, 8,2,8,8,8,8,2,8, 2,8,2,8,8,2,8,2, 8,8,2,2,8,8,2,8, + 8,8,12,12,12,9,2,12, 8,9,8,9,9,8,9,9, 8,8,38,8,9,8,8,8, 8,8,12,8,8,8,2,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,14,8,2,3,7,3,14, 14,3,8,3,3,7,5,7, 5,3,3,2,2,14,2,14, 2,3,3,3,2,7,2,2, + 3,7,5,14,3,3,7,3, 3,3,3,3,5,7,5,8, 5,14,14,14,7,14,7,5, 3,5,5,3,3,5,5,5, + 7,7,3,3,2,2,5,7, 5,5,8,2,2,3,8,8, 7,7,3,3,8,7,5,5, 5,3,3,3,5,3,7,37, + // BAxx + 7,39,37,39,39,39,37,37, 39,2,2,37,39,2,37,39, 39,39,37,39,39,39,39,37, 39,39,37,39,39,39,37,37, + 1,2,2,2,2,1,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,14,2,2,2,2,2, + 8,8,2,8,8,2,2,8, 2,8,8,8,8,8,8,8, 8,2,8,2,2,8,8,1, 8,2,8,8,2,8,8,1, + 2,8,8,8,2,12,2,2, 8,12,8,8,2,2,8,12, 8,8,2,2,8,8,8,8, 8,8,8,8,8,8,8,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,8,3,3,2,5,2,2, 14,8,2,2,2,2,5,5, 5,3,2,2,5,3,2,2, 5,5,2,5,3,3,5,2, + 5,3,7,3,3,3,7,7, 3,3,8,3,7,3,5,3, 5,7,5,3,14,3,8,7, 8,7,3,3,3,7,8,7, + 7,3,8,2,2,2,2,2, 2,2,5,8,3,5,7,2, 3,5,3,3,8,3,7,7, 3,5,3,8,5,3,3,37, + // BBxx + 7,39,1,39,39,37,14,39, 39,2,2,1,39,11,37,11, 39,39,37,37,39,39,39,37, 39,39,37,37,39,39,37,37, + 11,2,2,2,2,11,11,11, 2,2,2,2,11,2,11,2, 37,2,2,11,11,2,11,11, 11,11,2,11,11,2,14,2, + 8,8,8,2,8,8,8,8, 2,8,2,11,8,2,2,8, 8,8,8,2,8,2,11,8, 8,8,8,8,8,8,2,8, + 8,8,2,2,11,8,11,2, 8,2,11,8,2,2,8,2, 8,8,8,8,2,8,37,8, 8,8,8,8,8,8,8,37, + 2,2,6,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,8,3,2,3,2,3,3, 3,5,3,8,2,3,3,3, 3,7,7,7,2,3,2,3, 2,3,2,3,3,2,2,2, + 7,14,7,14,7,7,3,5, 7,7,3,7,5,7,7,7, 7,14,7,3,7,3,3,7, 3,7,8,3,7,3,7,7, + 7,3,8,2,2,2,2,5, 2,2,5,7,5,2,3,7, 3,3,3,5,8,5,5,3, 3,3,3,7,3,5,7,37, + // BCxx + 7,39,39,39,39,39,37,37, 39,2,2,37,39,2,37,37, 39,39,39,39,37,37,37,37, 37,39,37,37,37,37,37,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,12,8,8,2,2,8,12, 8,2,8,12,8,12,12,12, 8,8,2,12,2,12,12,8, 8,8,8,8,2,2,8,2, + 2,8,8,9,9,8,8,8, 8,8,2,9,9,9,9,8, 8,8,9,8,8,8,8,8, 8,8,8,8,2,8,8,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,7,2,7,3,5,3,2, 7,2,3,7,2,5,5,3, 3,5,3,2,3,2,3,2, 3,2,5,2,5,8,5,5, + 3,7,7,3,3,5,3,3, 3,8,3,8,7,3,3,8, 8,3,3,3,7,5,8,3, 3,3,8,3,3,3,3,8, + 3,3,5,2,3,2,2,2, 7,2,7,2,3,2,5,7, 7,7,3,7,3,3,5,5, 5,3,5,3,3,7,3,37, + // BDxx + 7,39,37,11,37,37,37,37, 39,2,2,37,39,2,6,37, 37,39,37,37,39,39,37,37, 39,39,37,39,39,39,37,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 8,2,2,2,2,6,8,8, 8,2,2,8,8,8,2,2, 2,8,8,8,8,8,8,8, 8,8,8,2,8,8,2,8, + 8,8,8,8,8,2,8,8, 2,2,2,8,8,8,8,8, 2,8,2,8,8,8,8,8, 2,3,2,8,8,8,8,39, + 2,2,6,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,3,2,3,7,2,2,8, 3,2,7,3,2,3,2,2, 2,2,3,2,5,3,3,3, 7,3,5,3,5,2,7,2, + 5,5,5,5,5,5,8,5, 5,5,5,7,3,5,5,3, 7,7,8,3,3,8,3,8, 3,3,3,3,3,3,8,8, + 3,3,3,2,2,2,2,3, 2,3,7,2,3,2,3,2, 3,7,3,3,3,3,3,7, 3,7,3,3,3,7,3,37, + // BExx + 7,39,37,14,39,1,37,37, 39,2,2,37,37,2,37,39, 37,39,39,37,37,39,37,37, 39,39,37,39,39,37,37,39, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,14,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,14,2, + 8,8,8,2,8,8,8,8, 8,2,8,8,8,2,2,2, 8,8,8,59,8,8,2,8, 8,8,8,2,8,2,8,8, + 8,12,9,8,8,9,2,12, 8,8,8,12,8,12,8,12, 8,8,8,12,12,12,8,8, 8,8,8,8,8,2,8,37, + 2,2,6,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,3,3,3,2,8,7,3, 8,3,3,3,3,3,7,3, 3,3,5,3,5,3,3,2, 5,8,3,3,2,2,5,3, + 3,14,8,3,14,3,5,8, 5,8,5,5,8,3,7,5, 7,14,5,3,8,5,3,5, 5,3,7,3,7,3,3,5, + 5,8,2,2,2,2,2,5, 2,2,2,7,7,3,5,5, 7,3,7,5,8,3,3,5, 5,3,5,5,3,3,7,37, + // BFxx + 7,11,37,37,37,12,37,1, 37,2,2,37,39,2,37,37, 37,37,37,37,39,37,37,37, 37,37,37,37,39,37,37,37, + 12,11,2,2,2,2,2,11, 2,2,2,2,2,2,2,2, 37,2,2,2,2,2,2,2, 2,2,12,2,2,2,2,1, + 8,8,1,1,8,8,1,2, 1,1,2,8,1,1,8,8, 1,1,1,1,1,8,1,8, 8,1,8,2,8,2,8,2, + 8,12,12,8,12,12,8,2, 1,8,8,12,12,2,2,12, 2,8,1,12,2,2,8,12, 2,12,8,2,8,8,2,37, + 2,2,2,2,2,2,2,2, 2,2,2,6,2,2,2,2, 2,2,2,5,2,2,2,2, 2,2,5,2,2,2,2,2, + 2,5,5,5,8,5,7,7, 3,5,3,2,5,5,7,3, 5,5,7,8,3,5,7,7, 3,5,2,2,3,2,5,7, + 5,5,5,5,8,3,3,7, 7,3,7,3,3,7,3,5, 5,14,3,3,5,3,3,3, 3,3,3,3,5,3,7,8, + 2,3,3,2,5,2,2,2, 2,8,3,5,5,3,5,5, 8,3,5,3,7,5,3,3, 5,5,8,8,5,8,5,37, + // C0xx + 7,39,37,1,39,39,37,1, 39,10,18,1,39,10,37,39, 39,39,37,37,39,39,39,37, 39,39,7,37,39,39,37,39, + 10,10,10,10,1,10,10,10, 10,10,10,10,10,10,10,10, 37,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, + 8,8,1,1,1,8,1,1, 8,8,8,30,1,1,1,1, 1,1,8,1,1,3,8,8, 1,8,8,8,8,8,3,3, + 8,3,8,1,8,8,8,8, 39,3,8,3,3,8,8,39, 8,8,1,8,8,8,8,8, 8,8,8,8,8,37,8,37, + 10,6,6,6,6,39,3,3, 39,6,12,6,10,6,6,6, 6,6,6,6,6,6,6,6, 6,3,37,3,3,5,37,1, + 10,3,3,8,7,5,8,5, 3,3,7,3,3,3,7,5, 5,5,5,8,3,7,3,14, 5,7,5,5,3,5,7,3, + 3,10,10,10,10,10,10,5, 3,8,10,10,5,10,5,5, 10,10,10,5,5,10,5,3, 10,8,5,5,7,10,10,7, + 3,5,10,7,3,5,3,5, 7,7,10,3,7,3,3,3, 10,3,8,10,8,7,3,3, 3,8,5,5,5,3,7,10, + // C1xx + 7,39,1,39,39,39,37,37, 39,14,18,37,39,11,37,39, 39,39,37,39,39,39,37,39, 39,39,39,39,37,37,37,37, + 11,18,14,14,37,11,18,14, 14,11,11,14,18,18,14,11, 37,20,11,14,14,14,14,11, 37,14,11,18,11,10,18,18, + 8,8,1,1,1,1,1,1, 1,1,1,1,1,1,1,8, 1,1,1,1,1,1,1,8, 1,8,1,14,8,11,8,8, + 8,8,1,8,16,16,1,1, 1,10,8,1,1,16,8,8, 8,8,1,16,1,8,16,8, 8,8,1,8,8,8,8,37, + 39,6,6,4,39,11,3,6, 3,39,12,39,37,12,12,6, 37,6,6,6,39,3,6,6, 37,3,3,3,4,11,12,1, + 14,5,3,3,5,3,5,3, 5,5,3,3,3,3,5,5, 7,7,10,7,3,3,5,5, 5,5,3,5,3,3,5,3, + 10,5,5,14,3,10,3,7, 10,11,8,3,18,20,10,3, 3,14,14,10,18,14,5,14, 5,3,3,10,3,5,3,5, + 10,7,3,3,8,3,3,8, 14,3,7,10,3,3,5,5, 5,5,5,10,3,5,5,3, 5,3,5,10,7,5,5,10, + // C2xx + 7,39,37,37,39,39,39,37, 39,14,14,1,39,14,37,1, 39,37,39,39,39,39,39,37, 37,37,37,39,37,39,37,39, + 10,14,14,14,39,10,14,14, 14,14,14,10,14,10,10,14, 37,10,10,14,14,10,10,10, 39,14,14,10,14,10,14,14, + 8,8,1,16,16,8,8,1, 8,8,16,16,16,1,1,8, 16,8,16,16,1,1,16,8, 8,1,8,8,8,14,8,8, + 8,8,8,8,8,8,8,1, 1,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,1, 8,8,8,8,14,8,8,37, + 37,59,2,11,3,39,11,11, 2,39,10,2,2,59,11,59, 11,11,12,3,2,3,2,2, 11,11,3,12,4,59,17,11, + 2,2,7,2,2,3,7,2, 59,2,2,2,3,7,2,3, 2,2,8,7,2,2,3,3, 7,14,2,2,3,3,7,2, + 10,3,8,3,3,10,3,3, 10,3,3,10,3,10,10,18, 7,10,14,7,3,18,3,3, 7,14,10,3,8,3,3,7, + 8,11,10,11,3,7,7,7, 7,3,7,3,14,3,10,5, 3,10,3,3,3,10,3,5, 5,5,3,5,5,3,3,10, + // C3xx + 7,1,4,39,39,37,37,1, 37,14,12,3,39,14,1,1, 39,37,39,37,37,39,37,37, 39,39,37,37,39,37,37,37, + 14,14,14,1,1,1,14,14, 14,11,11,5,14,11,14,11, 37,14,10,14,14,10,14,14, 10,10,11,14,14,11,14,1, + 8,10,8,8,8,1,8,12, 8,12,8,8,12,8,12,1, 8,8,12,1,12,12,10,10, 8,8,8,8,8,8,8,39, + 8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8, 1,8,1,8,8,8,8,8, 8,8,8,8,14,8,8,37, + 2,2,59,59,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,5,2,5, 2,2,2,5,2,2,2,3, + 3,14,7,14,10,3,7,3, 11,3,5,3,11,11,10,7, 14,11,14,11,11,11,5,3, 3,14,11,11,3,11,11,5, + 5,11,5,11,11,7,3,3, 3,14,7,5,14,11,10,3, 10,3,5,11,3,11,8,3, 5,3,7,3,3,8,8,10, + // C4xx + 7,6,1,39,37,37,37,37, 39,10,18,1,39,18,1,37, 37,37,37,37,39,37,37,37, 39,37,37,37,39,37,37,37, + 18,18,10,1,1,1,10,1, 6,10,6,3,18,10,18,10, 37,10,10,10,10,5,5,5, 5,5,18,18,10,6,10,1, + 8,8,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,8,1,1,1,1,1,8, 1,8,1,8,8,8,8,8, + 3,8,8,8,8,1,8,1, 1,8,8,1,8,8,1,8, 1,8,1,1,1,1,8,8, 8,8,8,8,8,8,8,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,5,7,3,3,7,3,5, 5,3,3,5,3,5,7,2, 2,2,8,8,7,8,3,3, 3,7,7,3,2,3,3,3, + 10,5,10,3,5,10,10,3, 10,3,10,10,7,10,10,3, 3,3,8,10,3,18,3,18, 3,18,3,10,3,8,5,10, + 10,3,3,3,3,10,8,20, 10,20,3,10,7,5,10,3, 10,3,8,7,3,8,5,5, 7,7,3,5,5,8,3,10, + // C5xx + 7,39,37,14,39,39,37,37, 39,14,18,39,39,18,39,39, 39,39,37,37,39,39,37,39, 39,39,39,39,39,39,37,37, + 18,18,18,14,39,18,18,1, 14,18,14,3,18,18,18,14, 37,10,10,10,10,6,10,10, 39,20,18,18,18,1,18,18, + 8,8,1,3,1,1,8,1, 1,1,8,1,1,1,1,1, 1,8,1,1,1,8,1,8, 8,8,1,8,8,8,8,8, + 39,8,1,3,1,8,8,1, 1,8,12,1,1,1,8,8, 1,8,1,1,1,8,8,8, 8,8,12,3,8,8,8,37, + 2,2,2,2,2,2,2,2, 2,37,5,2,2,2,12,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,3,2,3,14, 3,5,7,2,5,5,3,2, 5,2,5,2,7,3,3,7, 5,7,2,5,2,2,2,5, + 7,5,5,5,10,3,3,10, 11,10,10,10,10,5,18,11, 10,10,10,11,7,10,11,5, 5,7,11,5,8,3,11,7, + 3,11,3,8,5,8,5,7, 14,8,7,5,7,11,3,3, 5,10,7,3,3,5,7,5, 5,7,3,3,7,8,7,37, + // C6xx + 7,37,39,1,39,39,37,37, 37,10,12,37,39,11,37,37, 39,39,37,39,39,39,39,37, 39,39,37,39,39,39,37,39, + 11,12,10,1,37,39,11,1, 37,11,11,10,12,18,10,10, 37,3,11,10,3,3,3,3, 39,3,12,39,11,6,10,12, + 37,12,1,8,1,12,8,1, 1,12,8,1,1,1,1,8, 8,8,1,1,1,8,1,8, 8,8,8,8,8,8,8,8, + 8,8,1,1,1,8,8,8, 8,12,8,8,8,12,1,12, 8,8,8,8,1,12,8,12, 8,1,8,8,8,8,8,37, + 37,6,6,6,4,3,2,4, 6,39,6,39,6,6,6,2, 6,6,2,6,37,6,39,6, 39,2,4,2,39,3,37,4, + 2,2,3,7,3,3,7,7, 7,7,3,3,3,3,5,5, 2,3,5,7,3,3,3,3, 3,3,3,7,5,3,3,3, + 3,3,3,7,5,10,3,5, 10,7,10,5,3,10,10,7, 5,11,5,10,5,3,3,3, 3,3,3,5,11,5,3,3, + 7,11,7,11,3,10,3,3, 10,7,5,3,3,5,7,3, 3,7,5,3,3,3,11,5, 3,5,5,3,7,7,7,37, + // C7xx + 7,39,39,39,37,39,39,39, 39,11,11,14,39,11,37,39, 39,39,37,39,39,39,39,37, 39,39,37,39,39,39,39,39, + 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 37,11,11,11,11,14,11,11, 11,11,11,11,11,11,1,11, + 18,1,1,16,16,1,8,16, 1,1,16,16,1,1,16,1, 16,8,16,16,16,1,16,1, 37,1,16,11,39,11,11,11, + 39,1,1,31,16,1,8,1, 1,1,8,1,1,1,1,1, 8,8,1,1,37,1,1,3, 37,8,8,39,37,11,8,37, + 2,11,6,2,37,37,39,12, 37,6,39,3,39,2,2,39, 11,2,2,2,2,11,2,6, 11,11,2,2,2,2,11,2, + 11,11,3,3,7,5,3,3, 3,3,5,3,3,7,3,7, 5,3,5,5,14,7,3,3, 3,14,7,5,7,7,7,3, + 10,11,10,1,10,3,11,11, 11,11,11,11,11,11,11,5, 5,5,5,11,11,5,11,5, 5,5,11,11,7,11,11,11, + 5,11,5,11,11,11,11,3, 5,3,3,3,3,11,7,3, 11,7,3,3,5,5,5,3, 3,5,3,5,5,5,3,10, + // C8xx + 7,37,37,14,37,37,39,39, 37,11,11,37,39,11,37,39, 37,37,37,37,39,37,37,39, 39,39,37,39,37,37,37,37, + 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 37,11,11,11,11,11,18,11, 18,11,11,18,11,11,10,18, + 11,12,1,1,1,12,1,1, 12,12,12,12,12,1,12,12, 12,1,1,1,1,12,1,12, 1,1,1,11,11,11,11,11, + 11,12,1,1,1,12,3,1, 12,12,12,12,12,1,1,12, 10,37,12,12,12,12,12,11, 39,12,12,11,11,11,3,37, + 39,11,6,6,3,37,2,3, 39,6,12,37,39,11,10,6, 11,6,6,6,11,11,6,6, 11,2,2,2,2,11,11,1, + 11,3,7,5,3,3,3,3, 3,7,3,3,7,5,5,5, 5,3,5,7,3,3,3,3, 5,5,3,3,3,7,3,5, + 10,10,10,3,5,10,5,11, 3,11,10,3,10,11,3,3, 10,11,10,11,11,3,7,10, 11,3,11,11,11,3,11,10, + 7,11,3,11,11,11,11,3, 7,3,5,3,10,11,10,5, 10,5,7,7,3,3,11,5, 3,5,11,5,3,3,7,37, + // C9xx + 7,39,11,39,37,39,37,10, 39,11,18,39,37,11,37,39, 39,37,39,37,39,39,37,37, 39,39,37,39,39,39,37,39, + 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 37,11,11,11,11,11,11,11, 11,11,11,18,11,11,11,18, + 8,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,11,11,11,11,11, + 18,8,1,1,1,8,1,1, 1,1,1,1,1,1,1,8, 1,1,1,1,1,8,1,3, 1,1,1,1,11,11,11,37, + 39,6,6,6,6,11,37,12, 6,6,12,6,6,6,12,6, 2,2,2,6,2,11,6,2, 6,2,2,2,2,11,11,2, + 11,11,3,3,7,3,7,7, 3,7,3,3,7,3,7,3, 3,3,7,3,7,3,3,3, 7,3,3,11,7,3,7,11, + 14,3,7,7,10,18,3,3, 18,18,7,3,3,10,18,3, 3,10,10,18,7,7,18,7, 7,3,18,7,3,7,18,7, + 3,7,7,3,3,7,3,3, 3,7,3,7,3,3,3,20, 7,3,3,3,7,3,3,7, 3,3,3,7,7,3,7,37, + // CAxx + 7,6,39,37,39,37,37,37, 37,11,11,37,37,11,37,37, 37,37,37,37,39,37,37,37, 39,37,37,37,39,37,37,4, + 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 37,11,11,11,11,11,11,11, 14,11,11,18,11,11,10,18, + 11,10,12,12,12,1,1,12, 1,8,1,12,1,1,1,10, 12,1,1,1,1,1,1,12, 1,37,12,11,8,11,8,11, + 37,10,1,8,12,8,37,37, 1,1,12,12,12,12,1,8, 10,1,1,12,1,1,39,1, 1,8,12,1,11,11,11,37, + 2,2,6,2,2,11,2,2, 2,2,2,2,12,2,39,6, 11,39,2,6,2,11,6,6, 11,11,37,2,10,11,2,2, + 11,3,3,7,3,3,3,3, 3,3,7,3,7,3,3,3, 3,3,3,3,14,3,3,3, 7,3,14,3,3,3,3,3, + 10,14,3,11,7,10,3,3, 11,7,3,10,7,11,10,11, 3,11,3,11,3,3,3,3, 11,3,11,3,3,11,11,11, + 10,11,7,11,3,11,11,7, 14,3,3,10,3,11,10,3, 10,7,10,7,3,3,3,3, 3,20,7,3,7,3,7,11, + // CBxx + 7,1,39,37,37,39,37,37, 1,11,18,37,37,11,37,37, 37,37,37,37,37,37,37,37, 37,37,7,37,37,37,37,37, + 11,18,11,10,1,39,18,11, 11,11,11,3,18,18,10,11, 37,10,10,3,10,3,10,10, 3,11,11,18,11,3,11,18, + 8,10,1,1,16,1,1,16, 1,1,16,16,1,16,1,10, 16,1,1,16,16,1,16,1, 1,39,1,37,11,10,11,11, + 37,1,1,1,1,37,1,1, 1,10,1,1,1,8,1,1, 1,1,1,1,1,37,37,37, 8,39,39,3,8,37,3,37, + 2,6,6,4,39,2,2,2, 2,2,2,2,2,2,2,37, 2,2,6,16,6,11,37,6, 2,2,2,2,2,2,2,1, + 11,7,3,3,3,3,7,3, 7,3,3,3,7,3,3,3, 3,7,10,3,7,3,3,7, 3,3,7,7,3,3,3,3, + 10,14,3,14,3,10,3,11, 10,3,10,10,7,3,3,18, 3,3,14,10,18,3,3,3, 3,3,7,10,7,8,10,3, + 3,11,7,3,3,10,3,14, 7,14,3,3,11,11,10,3, 3,3,8,10,7,3,7,3, 3,3,3,3,3,3,7,10, + // CCxx + 7,39,39,37,39,39,39,37, 39,11,18,37,37,11,37,39, 39,39,39,37,39,39,39,37, 39,39,37,37,39,39,37,37, + 11,10,11,11,11,11,11,11, 18,11,11,10,11,10,10,11, 37,11,11,11,11,11,11,11, 11,11,11,6,11,37,6,18, + 8,1,12,12,12,16,1,1, 12,16,12,12,12,12,12,31, 12,1,12,12,12,8,12,6, 8,10,12,1,11,11,1,11, + 10,1,1,1,8,16,1,1, 1,10,1,1,1,3,1,1, 1,8,18,1,1,10,37,11, 8,10,1,8,8,11,3,39, + 2,2,6,2,2,2,2,2, 2,2,12,6,6,12,12,6, 6,6,6,6,6,6,3,6, 6,37,2,3,37,11,2,1, + 11,7,7,7,7,3,3,3, 3,3,7,3,3,3,7,3, 3,7,3,3,7,7,3,3, 3,3,3,3,3,3,7,7, + 10,18,7,3,7,10,3,11, 10,18,11,10,7,10,10,11, 11,11,11,10,3,3,3,3, 3,3,7,10,7,3,11,10, + 10,3,3,11,11,3,11,7, 10,7,3,7,3,11,10,3, 3,7,7,7,3,3,7,7, 3,3,3,3,3,3,7,10, + // CDxx + 7,39,37,14,39,37,37,37, 37,14,18,14,37,11,14,11, 39,39,37,39,39,39,37,37, 39,37,37,37,39,37,37,37, + 11,18,11,11,11,11,14,14, 14,11,11,11,18,18,14,11, 37,14,11,14,14,14,14,14, 14,11,14,18,11,11,10,18, + 18,1,1,1,1,1,1,1, 1,10,1,1,1,1,1,1, 1,1,1,1,1,1,1,8, 1,10,1,37,37,11,37,11, + 6,1,1,1,1,16,37,1, 8,10,8,39,1,1,1,1, 37,8,1,1,1,37,10,8, 1,39,8,37,14,11,11,37, + 37,6,6,6,37,39,37,2, 6,37,12,6,6,12,12,6, 6,39,6,6,37,6,6,6, 11,37,37,3,37,11,11,1, + 1,14,7,3,14,3,3,14, 3,3,3,7,3,7,3,3, 3,3,10,3,3,3,3,3, 3,14,14,3,3,7,3,3, + 10,3,14,14,10,10,3,11, 10,11,11,3,11,10,10,11, 3,7,10,11,14,7,11,7, 3,11,3,10,11,11,11,11, + 10,11,3,11,11,10,11,3, 7,14,3,3,11,11,10,20, 7,7,3,11,3,3,3,7, 3,3,3,3,3,7,3,10, + // CExx + 7,39,37,37,39,39,37,37, 39,11,18,37,39,11,37,37, 39,39,37,37,39,39,37,37, 39,39,3,37,39,39,37,37, + 11,10,11,11,39,10,10,10, 11,10,11,5,11,18,10,11, 37,11,10,10,11,10,10,11, 11,11,11,18,11,11,10,18, + 5,8,16,16,16,10,1,16, 1,1,16,16,1,16,1,37, 16,37,16,16,1,31,16,39, 37,1,16,37,37,8,37,10, + 8,18,37,1,8,37,10,8, 37,18,1,39,1,1,1,1, 16,8,16,16,37,37,16,37, 8,18,1,37,39,8,3,37, + 37,6,6,6,2,2,2,2, 2,2,2,6,2,6,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,3,2,2,3,2,3, 7,7,3,3,3,2,2,3, 3,2,2,2,3,2,3,2, 2,2,2,3,2,2,2,2, + 3,10,10,10,3,3,10,11, 3,10,3,10,10,10,11,7, 10,10,3,7,10,3,10,10, 11,18,3,3,11,3,3,10, + 7,11,3,7,3,3,11,3, 3,3,10,10,10,11,7,3, 10,3,10,3,10,3,3,3, 7,10,3,3,3,3,3,37, + // CFxx + 7,11,37,37,37,39,37,37, 37,11,18,11,39,11,37,37, 39,37,37,37,39,39,37,37, 39,39,37,39,37,39,37,37, + 11,11,11,6,11,11,11,11, 11,11,11,11,11,18,11,11, 37,11,11,11,11,11,11,11, 11,11,11,18,11,11,11,18, + 11,12,1,1,1,1,1,30, 1,16,30,1,1,1,1,16, 10,1,1,1,1,16,1,1, 1,1,1,11,11,11,11,11, + 8,12,37,39,12,39,8,37, 8,8,1,39,1,8,1,10, 10,8,12,8,1,12,8,8, 8,8,37,37,18,11,39,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,37, 11,39,11,6,11,2,2,6, 11,11,37,2,2,11,2,1, + 11,11,3,3,3,3,3,3, 3,7,3,7,3,7,3,3, 3,3,3,7,3,3,3,3, 3,3,7,7,3,3,20,7, + 10,3,3,7,3,10,3,11, 3,11,3,10,18,18,10,11, 10,11,18,10,3,3,3,3, 3,3,11,10,3,11,3,3, + 3,11,3,11,3,11,11,3, 3,3,3,3,3,11,10,3, 10,3,3,3,3,11,11,3, 11,3,3,3,3,3,3,10, + // D0xx + 7,39,1,37,39,1,39,9, 39,14,14,1,39,14,1,39, 39,39,37,37,39,39,37,37, 39,39,37,39,39,37,37,37, + 11,14,14,11,1,10,14,14, 14,14,14,14,10,10,10,11, 37,10,10,10,10,14,10,31, 10,10,11,10,14,10,10,14, + 1,13,1,13,13,13,1,1, 1,13,1,16,13,13,16,16, 16,37,13,1,16,13,16,1, 39,16,13,14,3,14,14,10, + 8,16,1,39,1,16,31,3, 37,16,1,16,16,16,16,16, 18,8,16,8,16,16,16,8, 39,16,8,8,14,8,3,37, + 10,2,6,2,2,2,2,2, 2,2,2,2,2,3,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,3,2,3,2,2,3,3, 2,3,14,2,3,3,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 10,3,3,10,3,3,10,3, 10,11,10,3,10,3,10,18, 3,10,10,10,3,3,3,3, 3,18,10,10,10,3,3,11, + 10,11,3,3,11,10,11,3, 3,3,3,3,3,3,10,20, 3,20,3,10,3,3,11,3, 3,3,11,3,3,3,3,10, + // D1xx + 7,37,37,37,39,39,11,37, 39,11,18,37,39,11,37,39, 39,39,37,37,39,39,37,37, 39,39,37,39,39,37,37,37, + 11,11,11,10,11,11,11,11, 11,11,11,11,11,11,11,11, 37,11,11,11,11,11,11,11, 11,11,11,18,11,11,11,18, + 11,1,12,12,10,1,10,1, 10,1,1,12,8,12,37,1, 10,37,37,12,10,1,10,31, 11,3,1,37,11,11,11,11, + 39,1,3,10,31,1,37,37, 10,10,1,11,11,37,7,1, 31,11,10,37,31,1,37,31, 11,39,37,8,11,11,11,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 11,2,2,2,2,2,2,2, 2,2,2,2,2,11,2,2, + 11,3,3,3,14,3,3,3, 3,3,3,3,3,3,3,3, 3,3,3,14,14,3,3,14, 3,3,14,3,3,3,14,3, + 10,20,10,11,11,10,11,11, 11,11,10,10,11,11,10,11, 3,10,10,11,3,3,11,3, 3,20,11,3,10,11,11,11, + 10,10,10,11,11,11,11,3, 10,3,10,3,11,11,10,10, 10,10,10,3,3,3,11,10, 3,3,11,3,3,3,3,10, + // D2xx + 7,39,39,37,39,39,37,12, 39,14,14,39,39,14,37,37, 39,39,37,39,39,39,39,37, 39,39,37,37,39,37,37,37, + 11,10,14,14,11,11,14,14, 14,14,11,11,11,10,10,14, 37,10,14,14,10,14,11,11, 14,11,14,18,14,14,14,18, + 11,16,1,1,1,16,8,1, 31,16,31,12,1,1,1,12, 1,1,1,12,12,12,1,31, 1,31,1,11,8,14,11,11, + 10,31,31,31,31,12,31,31, 31,12,8,39,31,31,31,1, 31,31,1,31,31,16,10,31, 1,31,8,1,14,39,14,39, + 37,6,6,2,2,39,3,4, 39,39,3,6,6,12,3,6, 11,2,2,2,28,3,2,2, 11,2,2,2,2,2,39,1, + 14,14,14,3,14,3,3,14, 14,3,3,3,3,14,3,2, 3,3,3,3,14,3,3,14, 14,14,3,3,14,3,14,14, + 10,14,10,14,3,10,3,11, 10,3,14,3,11,10,10,18, 10,3,3,10,3,3,3,3, 18,18,3,10,10,3,11,3, + 10,11,3,11,3,3,3,3, 10,3,3,3,3,11,10,3, 10,3,3,10,3,3,3,3, 3,3,10,3,3,3,3,10, + // D3xx + 7,37,37,1,39,37,37,37, 39,11,18,39,37,11,37,18, 37,39,37,39,37,39,37,37, 39,39,37,39,39,37,37,37, + 11,11,11,11,11,11,11,11, 11,11,11,11,11,18,18,11, 11,11,11,11,11,11,11,11, 11,11,11,18,11,11,31,18, + 11,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,3,8,11,3,11, + 37,1,1,1,1,1,1,37, 1,8,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,8,1,11,11,8,39,37, + 10,11,6,6,2,11,3,12, 39,6,6,3,6,3,6,12, 11,2,11,3,11,6,6,2, 2,2,3,3,37,11,3,2, + 11,3,3,12,3,3,3,14, 3,2,3,3,9,3,3,3, 3,3,3,3,3,3,3,14, 20,14,14,14,14,3,3,3, + 3,10,3,3,10,3,10,11, 11,3,3,18,11,3,3,10, 3,3,3,11,18,3,3,10, 11,10,3,18,11,11,10,11, + 3,11,10,11,11,11,11,10, 3,3,3,3,11,11,3,3, 10,3,3,11,3,20,3,10, 11,3,3,3,3,3,3,10, + // D4xx + 7,39,37,1,39,39,39,37, 39,14,18,37,39,11,37,37, 39,39,39,37,39,39,37,37, 39,39,37,37,39,37,37,37, + 11,18,18,1,11,11,11,1, 18,11,11,3,18,18,18,14, 37,11,11,10,11,11,10,11, 11,11,18,18,11,11,11,18, + 1,1,1,1,1,8,1,8, 1,1,1,1,1,1,1,1, 1,1,1,1,1,8,1,11, 1,39,1,37,37,3,11,18, + 18,33,14,31,39,20,31,1, 11,10,1,39,1,1,1,20, 18,8,8,31,1,3,31,31, 1,18,1,8,11,11,3,39, + 37,6,6,3,3,11,12,3, 37,6,3,6,6,6,12,37, 11,6,3,3,3,6,6,6, 11,3,39,3,3,11,3,4, + 11,14,3,3,3,3,3,14, 14,3,3,3,3,3,3,3, 3,3,3,5,3,3,3,14, 3,14,3,14,3,3,3,3, + 10,18,3,3,3,18,3,11, 11,18,3,3,11,11,11,18, 3,11,18,3,3,18,3,18, 3,3,3,11,11,3,11,11, + 10,11,3,11,11,11,11,3, 10,14,14,3,3,11,10,20, 3,3,3,3,3,3,3,3, 3,3,3,3,3,10,3,37, + // D5xx + 7,39,37,39,37,39,37,37, 39,14,18,14,37,11,37,37, 39,39,37,39,39,39,37,37, 39,39,37,39,39,39,39,39, + 11,14,11,14,39,11,14,14, 14,11,11,14,18,10,18,11, 37,11,11,11,11,11,10,11, 11,11,11,18,11,11,10,18, + 1,31,1,12,12,1,12,1, 1,1,1,12,1,1,1,12, 1,37,1,12,1,1,12,37, 37,37,12,37,37,18,8,11, + 37,31,1,1,31,31,3,37, 1,1,1,1,39,31,1,31, 1,39,31,31,31,8,31,1, 1,31,37,3,14,37,8,37, + 2,2,2,2,2,2,2,2, 2,37,2,39,2,2,2,2, 2,2,2,3,2,2,2,6, 39,11,2,2,2,2,2,4, + 14,2,3,2,14,2,3,2, 3,3,3,2,3,3,3,3, 3,3,2,3,2,2,2,14, 2,3,2,14,3,3,3,3, + 10,14,3,3,3,3,3,11, 11,11,3,3,18,11,10,11, 3,11,3,18,3,3,3,3, 3,3,11,3,11,11,18,3, + 10,11,3,3,11,11,11,3, 14,14,3,3,3,11,10,3, 3,3,3,3,3,3,11,3, 11,3,11,3,3,3,3,37, + // D6xx + 7,39,37,37,37,39,37,37, 37,11,11,37,39,11,39,39, 39,37,37,37,37,37,37,37, 39,39,39,39,39,39,37,37, + 11,11,11,1,39,11,11,1, 11,6,11,3,11,1,11,1, 37,1,11,1,11,11,11,11, 37,1,11,1,11,3,1,1, + 39,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,37,37,11,3,11, + 8,1,1,1,1,37,1,1, 1,1,1,1,1,1,1,1, 1,8,1,1,1,1,1,1, 1,1,1,1,39,8,3,37, + 2,2,2,2,2,2,2,2, 6,2,39,12,6,4,6,37, 6,2,2,6,2,12,2,2, 6,2,2,2,2,2,2,4, + 2,14,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,2,3, 3,3,20,3,3,3,3,3, + 10,3,3,3,18,10,3,11, 10,11,3,18,3,11,3,11, 3,11,3,3,3,3,3,3, 3,3,3,10,3,3,3,8, + 3,11,10,11,11,10,11,3, 10,3,3,3,3,11,3,3, 3,3,3,3,3,3,11,3, 3,3,3,3,3,3,3,10, + // D7xx + 7,39,37,37,39,37,37,6, 39,18,18,37,39,18,37,4, 37,37,37,39,39,39,37,37, 37,39,37,37,39,39,37,37, + 18,18,18,11,11,11,18,10, 11,18,11,3,18,10,18,10, 37,11,11,11,11,11,11,11, 11,11,18,18,18,11,10,11, + 11,10,11,3,11,10,11,11, 8,10,11,11,11,11,11,37, 11,8,3,39,11,8,11,11, 11,10,11,11,11,11,8,39, + 11,11,11,11,11,37,11,3, 11,18,11,11,11,11,11,3, 18,11,11,11,11,3,37,11, 3,18,11,11,11,11,11,37, + 2,2,2,2,2,3,11,6, 2,6,37,6,3,4,6,6, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,3,3,2,3,2,2, 2,2,2,3,3,3,3,3, 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, + 10,18,10,3,7,3,3,3, 10,3,3,3,3,14,18,18, 3,20,10,3,3,18,3,11, 10,18,3,3,3,3,3,3, + 10,20,3,3,3,3,3,3, 14,3,3,10,3,3,3,3, 3,3,3,3,3,3,3,3, 3,3,11,10,7,8,20,37, + // D8xx + 7,39,39,39,39,39,39,39, 39,1,18,39,39,11,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 11,11,11,39,39,39,11,11, 11,11,1,3,11,1,11,1, 7,1,1,1,1,1,1,1, 1,1,11,18,11,1,18,18, + 1,12,1,12,1,12,1,1, 1,12,1,1,1,1,1,12, 1,39,1,1,1,1,1,1, 1,1,1,11,11,11,39,11, + 39,12,1,33,33,12,1,1, 33,1,33,1,33,33,1,1, 8,39,1,1,33,1,1,1, 1,1,33,8,18,11,3,39, + 39,6,6,6,39,39,39,39, 3,39,12,6,2,6,6,39, 3,6,39,3,3,6,6,6, 39,39,39,2,33,11,39,2, + 11,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,14,14,3,14,5, + 10,14,14,14,3,10,11,11, 11,11,10,10,10,12,18,10, 10,11,10,10,3,27,10,27, 11,27,11,11,11,11,11,11, + 10,11,10,11,11,11,11,20, 14,14,10,10,11,11,10,10, 10,11,10,11,3,11,11,3, 11,3,11,10,3,3,3,3, + // D9xx + 7,12,39,1,4,39,4,39, 39,18,18,39,39,11,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 11,18,18,14,1,18,18,11, 6,18,14,5,18,18,18,18, 7,6,6,6,6,6,6,6, 6,6,18,18,18,18,14,18, + 8,1,12,12,12,1,3,1, 12,1,12,12,12,12,12,1, 12,3,12,12,12,1,12,7, 1,3,12,7,7,6,8,39, + 18,8,12,12,12,1,7,8, 12,1,1,12,1,12,1,8, 3,8,12,12,12,3,12,6, 1,8,39,7,3,14,5,3, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,3,6,6, 6,6,3,3,3,3,39,3, + 2,14,2,5,3,5,2,14, 14,3,14,2,2,14,9,3, 6,2,3,3,14,14,3,14, 3,2,14,14,2,5,2,3, + 10,14,7,14,18,10,3,11, 10,11,18,18,18,20,10,6, 20,11,18,20,20,5,20,18, 12,3,11,18,10,11,18,11, + 14,11,3,11,11,11,11,8, 14,14,14,5,11,11,10,7, 3,3,3,11,3,11,11,3, 11,5,11,7,5,5,5,10, + // DAxx + 7,1,39,1,39,39,39,39, 11,11,11,39,39,11,39,11, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 11,11,11,11,11,11,11,11, 11,11,11,5,11,11,11,11, 7,11,11,5,5,3,5,11, 11,11,11,18,11,11,11,18, + 11,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,3, 1,1,1,11,11,11,11,11, + 8,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,8,1,1,1,1,1,3, 1,1,1,8,8,39,11,3, + 2,2,6,6,2,2,2,2, 2,2,12,6,2,12,12,2, 6,2,6,2,11,2,2,6, 2,2,2,3,2,11,12,1, + 11,11,5,3,3,8,5,3, 10,2,5,3,8,2,3,2, 6,5,6,2,3,2,3,5, 5,3,2,8,3,6,2,11, + 18,18,11,3,18,10,10,11, 11,11,11,11,11,18,18,11, 11,11,11,11,11,11,11,18, 11,11,11,3,11,11,11,10, + 27,11,27,11,11,11,11,7, 12,3,3,5,11,11,3,3, 11,11,11,11,3,11,11,3, 12,3,11,3,3,5,3,11, + // DBxx + 7,39,39,39,39,39,39,39, 39,10,10,39,39,10,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 11,10,10,10,39,10,10,1, 3,11,11,5,11,10,10,31, 7,31,31,31,31,31,31,31, 31,31,10,18,10,10,10,10, + 18,12,1,16,16,12,12,16, 12,1,12,16,16,16,16,39, 16,7,16,16,1,1,12,7, 10,1,16,7,7,8,7,8, + 8,1,12,39,16,1,39,16, 31,8,8,16,8,8,1,10, 8,39,1,1,1,8,39,1, 1,8,7,39,3,8,5,39, + 2,2,6,2,39,39,2,2, 2,6,6,2,2,2,2,39, 2,6,2,2,2,2,6,6, 39,3,2,39,2,2,2,1, + 11,3,3,8,3,8,8,3, 10,2,3,3,3,3,5,3, 2,2,2,2,2,2,2,2, 2,2,3,3,3,6,5,3, + 3,18,10,10,10,10,10,11, 11,10,10,10,10,10,18,11, 11,11,10,11,18,10,11,10, 11,7,3,1,11,11,27,10, + 3,11,3,11,11,11,11,3, 3,1,7,3,11,11,27,27, 7,3,11,11,5,11,5,3, 11,7,11,3,3,3,3,3, + // DCxx + 7,39,1,11,4,39,39,39, 39,1,11,39,39,11,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 11,11,11,11,11,11,11,1, 11,1,11,11,11,11,11,11, 7,11,11,11,11,11,11,11, 11,11,11,20,11,11,1,1, + 11,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,11,1,1,1,11,1,1, 1,1,1,11,11,11,11,11, + 8,11,1,1,1,1,1,8, 1,11,11,1,1,1,1,11, 11,11,1,1,1,11,1,11, 1,1,1,11,11,3,11,3, + 39,6,6,39,6,11,11,3, 39,3,3,6,6,6,3,39, 2,11,11,6,3,11,6,6, 2,11,2,3,3,2,3,2, + 2,11,3,3,3,7,11,11, 5,11,2,3,5,3,11,6, 3,5,3,3,7,3,6,3, 3,5,11,5,3,3,3,3, + 3,10,11,11,11,10,18,11, 11,11,11,18,11,10,11,11, 13,11,11,11,18,11,11,11, 11,11,11,11,11,11,13,11, + 3,11,5,11,11,11,11,3, 20,20,20,20,11,11,3,3, 11,20,11,20,20,11,3,20, 11,3,11,3,1,5,3,11, + // DDxx + 7,1,4,39,39,39,39,39, 39,13,11,13,39,11,4,39, 39,3,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 11,13,11,11,11,11,13,13, 13,11,13,5,11,13,13,11, 7,11,11,11,11,11,11,13, 11,11,11,13,11,11,13,13, + 11,13,1,1,13,13,13,13, 13,1,1,13,13,13,13,13, 1,39,13,13,13,1,1,13, 13,13,13,7,13,11,3,11, + 13,13,13,13,13,13,13,13, 13,13,13,13,13,13,13,13, 13,13,13,13,13,7,13,7, 13,13,13,11,13,11,5,3, + 56,6,6,6,3,3,3,6, 39,6,12,6,6,12,12,6, 6,6,6,6,6,6,6,6, 11,6,6,3,3,11,3,3, + 11,11,8,5,5,3,7,8, 7,9,3,3,3,3,3,8, 3,3,6,1,3,7,3,3, 3,3,3,5,3,6,5,11, + 6,5,10,11,11,11,11,11, 11,11,11,10,11,11,11,11, 11,11,10,11,11,11,11,5, 11,11,11,11,11,11,11,11, + 3,11,10,11,11,11,11,13, 20,10,10,10,11,11,20,10, 10,20,10,11,20,11,11,20, 11,20,11,8,3,10,13,3, + // DExx + 7,1,39,39,4,39,4,39, 39,11,11,39,6,11,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, + 11,11,11,11,11,11,11,11, 6,11,11,11,11,11,13,11, 7,11,11,11,11,11,11,6, 11,11,11,6,11,11,13,18, + 11,13,13,13,16,13,13,13, 13,13,1,13,13,13,16,16, 16,8,1,16,13,13,13,13, 1,13,33,11,11,11,11,1, + 13,13,13,1,1,13,13,1, 13,13,1,3,13,16,13,13, 1,3,1,8,13,13,16,1, 7,16,39,7,6,11,11,3, + 2,6,2,2,2,2,2,2, 2,2,2,2,2,2,2,6, 2,2,31,2,2,2,2,2, 6,2,2,4,2,2,2,4, + 11,11,3,3,3,3,2,2, 2,2,2,2,2,2,2,7, 2,3,6,8,5,6,6,3, 6,3,3,3,7,6,6,11, + 5,18,10,10,10,18,10,11, 11,11,11,18,10,11,18,11, 10,11,10,11,18,11,11,10, 11,10,11,18,11,11,11,11, + 27,11,10,11,11,11,11,10, 20,5,20,10,11,11,13,10, 10,20,20,11,20,11,11,7, 11,10,11,7,13,13,11,11, + // DFxx + 7,1,39,39,7,10,39,39, 39,11,11,7,39,11,39,11, 39,39,39,39,39,39,39,39, 39,39,37,37,39,39,39,39, + 11,11,11,11,11,11,11,11, 11,11,11,6,11,1,11,11, 7,11,11,11,11,14,14,11, 14,14,11,6,11,11,11,1, + 3,11,1,1,1,1,1,1, 1,1,1,8,1,3,8,1, 1,1,1,1,1,1,1,39, 11,8,1,3,3,11,3,11, + 3,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,39,1,1,1,1,1,1, 3,1,1,7,11,11,39,3, + 3,6,6,6,6,3,12,6, 6,6,6,6,6,6,6,6, 6,6,6,12,6,6,6,3, 39,6,6,6,6,11,3,4, + 11,11,3,5,5,6,3,5, 11,5,10,5,3,6,3,6, 6,3,5,3,3,3,3,7, 3,3,3,3,6,3,5,11, + 7,10,10,11,10,10,10,11, 11,11,11,11,10,10,11,11, 11,11,10,11,11,10,10,10, 10,10,11,11,11,11,10,11, + 27,11,10,11,11,11,11,10, 20,3,10,20,11,11,20,20, 10,10,3,11,20,11,11,3, 11,20,11,3,1,7,11,11, + // E0xx + 7,37,37,14,1,37,37,37, 37,10,10,37,37,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 11,10,10,10,11,11,10,10, 10,10,10,10,10,10,10,10, 37,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, + 10,3,11,11,33,11,6,33, 8,11,11,6,33,11,33,3, 11,39,33,8,8,11,6,33, 11,6,8,10,10,10,10,6, + 17,11,11,11,11,39,11,11, 6,11,16,30,11,11,11,11, 11,11,11,11,11,6,11,11, 11,11,39,6,17,37,3,37, + 6,6,6,6,6,11,6,6, 6,6,6,6,6,6,6,6, 6,6,6,6,10,6,6,6, 37,6,12,3,10,6,10,10, + 36,14,14,36,2,2,2,2, 14,14,14,14,36,36,2,2, 2,2,2,2,2,14,2,14, 2,2,14,14,14,2,14,14, + 14,14,14,14,17,14,17,14, 14,1,14,14,18,14,14,8, 27,3,18,27,5,27,3,3, 27,3,3,6,27,7,3,6, + 3,10,10,10,10,17,10,10, 17,17,10,10,10,10,17,10, 10,10,10,10,10,10,10,10, 17,17,17,18,5,10,10,10, + // E1xx + 7,1,1,37,37,39,4,37, 12,1,11,20,37,11,3,11, 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 11,11,11,11,11,11,11,11, 11,11,11,11,11,1,10,11, 37,11,11,11,17,11,11,11, 11,11,11,1,11,11,11,1, + 11,11,1,1,1,17,1,17, 17,8,1,1,1,8,1,39, 6,39,1,6,39,1,8,11, 6,8,1,11,17,11,11,11, + 37,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,6, 1,6,1,6,11,11,11,37, + 2,2,2,2,2,2,2,6, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,6, 11,2,12,6,12,12,12,2, + 36,14,14,3,14,36,5,14, 14,6,36,36,36,36,36,36, 3,7,3,10,14,14,14,14, 2,14,2,2,2,2,14,14, + 3,14,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,18, 11,11,11,11,11,11,11,11, + 10,11,36,11,11,11,11,17, 10,17,20,10,11,11,10,17, 10,18,17,10,18,11,11,18, 17,17,17,10,10,18,18,10, + // E2xx + 7,7,37,37,37,39,37,37, 37,10,10,37,4,10,1,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,10,11,10,10,17, 10,10,10,3,10,10,10,10, 37,10,17,10,10,10,10,10, 10,10,10,10,10,10,10,10, + 10,8,8,11,3,6,11,6, 6,6,6,6,6,6,11,6, 6,6,11,6,11,6,6,6, 6,37,6,10,17,10,37,10, + 17,10,11,16,16,10,16,11, 11,10,16,16,16,11,11,10, 16,8,16,16,11,11,16,6, 8,11,16,3,6,6,3,37, + 2,2,2,6,2,2,2,2, 2,2,2,6,2,6,2,6, 6,2,2,2,2,2,2,2, 2,2,10,6,2,2,6,6, + 36,14,36,3,14,36,14,3, 36,5,14,14,3,36,36,3, 3,3,3,10,14,14,3,14, 10,14,14,14,14,3,14,3, + 14,18,14,14,6,18,3,14, 3,18,14,14,18,14,14,18, 27,3,18,3,7,18,3,3, 27,18,27,7,20,20,27,3, + 10,18,10,17,10,10,17,10, 10,17,10,10,17,10,10,18, 10,10,10,10,17,18,10,10, 17,18,10,10,10,3,16,10, + // E3xx + 7,37,37,37,37,37,37,1, 3,11,11,37,37,11,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,39,37, + 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,10,11, 37,11,11,11,11,11,11,11, 11,11,11,10,11,11,11,17, + 10,12,1,6,6,12,6,1, 31,18,6,6,1,31,39,6, 6,37,6,39,12,1,6,6, 1,6,8,11,11,10,11,11, + 6,10,12,12,12,1,37,12, 11,12,6,6,12,12,8,1, 12,8,12,1,12,12,10,37, 37,3,12,11,17,11,11,37, + 2,2,2,2,2,2,2,6, 2,2,2,2,2,2,2,2, 11,11,6,6,6,6,6,6, 11,11,6,4,6,11,6,4, + 36,11,36,36,14,36,36,36, 14,6,14,36,36,36,7,36, 3,3,3,10,14,14,3,7, 8,14,14,11,5,3,3,11, + 5,5,11,11,11,18,11,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,18, 11,11,11,11,11,11,11,11, + 10,11,17,11,11,11,11,36, 10,17,10,10,11,11,10,20, 10,20,17,11,17,11,11,17, 17,17,11,3,3,5,3,1, + // E4xx + 7,11,1,11,37,37,37,37, 1,11,11,4,4,11,3,11, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 11,17,11,11,11,11,11,17, 11,11,11,17,11,17,11,11, 11,11,11,11,11,11,11,11, 11,11,11,17,11,11,11,17, + 11,1,6,6,6,1,6,1, 1,17,1,1,1,1,6,11, 6,37,1,6,1,1,1,8, 6,1,1,11,11,11,11,11, + 17,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,17,11,11,1, + 2,11,6,6,12,11,2,6, 6,6,6,6,6,6,11,6, 11,6,31,3,11,6,6,6, 11,11,6,3,12,12,2,6, + 36,11,14,7,14,36,8,14, 36,14,14,14,5,3,36,3, 3,3,5,10,14,14,6,14, 2,2,2,2,2,2,2,2, + 3,14,3,14,11,18,11,11, 11,11,11,14,11,11,11,11, 11,11,11,11,11,11,11,18, 11,11,11,11,11,11,11,11, + 10,17,10,11,1,10,11,17, 10,17,10,10,11,11,10,18, 10,17,17,10,17,18,17,17, 17,17,17,10,10,20,11,10, + // E5xx + 7,10,37,37,37,39,37,4, 39,10,10,1,37,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,11,11,10,10,10, 11,11,11,10,10,10,10,10, 37,11,11,11,36,11,10,11, 11,11,10,10,11,11,10,10, + 11,6,31,31,6,31,8,1, 6,6,6,6,1,6,6,37, 8,6,1,37,31,6,1,37, 3,6,6,11,10,11,11,11, + 17,1,1,10,1,1,1,1, 1,1,6,1,1,1,1,33, 1,39,1,1,1,33,1,39, 8,6,1,11,11,11,11,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 17,7,11,11,11,18,18,11, 11,11,11,3,11,18,11,11, 11,11,11,18,11,5,11,18, 11,11,11,3,11,11,11,20, + 17,11,10,11,10,11,11,10, 17,10,10,10,10,10,18,17, 10,10,10,18,17,11,10,17, 17,17,17,18,5,20,10,10, + // E6xx + 7,11,1,9,1,39,1,12, 1,12,12,11,37,11,37,11, 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 11,12,11,11,11,11,11,11, 11,11,11,5,12,11,12,11, 37,11,11,11,11,11,11,11, 11,11,11,12,11,11,11,12, + 6,33,11,8,11,33,6,11, 11,33,11,33,33,31,33,33, 33,6,1,6,33,33,6,11, 8,37,11,39,17,6,11,11, + 17,12,1,1,1,12,1,1, 1,12,1,1,1,1,1,12, 1,1,1,1,1,12,1,12, 6,8,1,11,6,11,6,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 5,11,11,11,3,11,7,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,3, 11,11,11,11,11,11,11,11, + 10,11,10,11,11,11,11,20, 10,17,10,17,11,11,17,18, 1,10,11,11,18,11,11,17, 11,20,11,10,10,3,11,10, + // E7xx + 7,10,37,37,4,39,37,37, 37,11,10,20,4,10,10,37, 37,37,37,37,37,37,37,37, 37,37,37,3,37,37,37,37, + 10,10,10,11,11,10,11,11, 10,10,10,11,10,10,10,17, 37,10,10,11,11,11,10,17, 11,10,11,20,10,11,11,10, + 11,11,11,11,31,8,31,31, 6,11,11,11,31,8,31,6, 31,3,31,31,31,11,31,6, 11,11,31,11,17,11,6,11, + 11,11,11,16,16,11,11,16, 11,11,16,16,11,11,16,11, 16,6,16,16,16,11,16,11, 8,11,16,11,17,11,8,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,14,2,2,2,2,2,2, + 1,14,14,14,18,18,1,14, 5,18,14,14,18,3,6,18, 27,3,18,7,3,18,6,3, 27,18,27,3,8,5,3,3, + 10,17,10,1,10,17,17,17, 10,17,10,10,10,10,10,18, 10,17,18,10,17,1,1,17, 17,17,17,10,11,13,10,10, + // E8xx + 7,1,37,1,12,39,1,37, 37,10,10,10,37,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,17,11,10,10,10, 10,10,10,10,10,10,10,10, 37,14,14,14,14,14,14,14, 14,14,10,10,10,10,10,10, + 10,6,6,11,6,12,3,11, 14,6,6,12,31,6,12,6, 18,37,11,11,11,12,6,6, 8,37,6,10,10,10,10,10, + 10,12,11,11,11,12,11,11, 12,12,12,12,12,11,12,12, 12,11,11,11,12,12,11,6, 11,11,11,6,10,39,10,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 10,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,14,2,2,2,2,2,2, + 14,14,14,14,7,14,3,14, 14,3,14,14,18,14,14,18, 14,3,14,14,6,18,3,3, 5,3,27,3,20,20,20,7, + 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,18, 10,10,10,10,10,10,10,10, 17,10,17,8,20,20,10,10, + // E9xx + 7,1,11,4,1,37,39,37, 37,11,11,11,37,11,37,1, 37,37,37,37,37,37,37,37, 37,37,37,3,37,37,39,37, + 11,10,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 37,17,11,17,11,11,11,11, 11,11,10,10,11,10,11,11, + 11,11,11,11,11,11,3,8, 33,11,6,33,6,31,11,11, 33,6,31,31,3,11,11,11, 11,11,33,6,6,11,11,11, + 6,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,8, 11,11,11,6,17,6,17,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,14, 2,2,2,2,2,2,2,2, 2,2,2,2,14,14,2,14, 2,14,2,2,2,2,2,3, + 18,14,14,14,3,14,3,14, 18,3,14,14,18,14,18,3, 14,3,14,14,18,27,18,18, 3,3,18,18,20,20,20,3, + 14,17,17,17,17,17,17,17, 17,17,20,17,17,17,18,17, 17,10,10,18,18,17,17,17, 17,17,17,18,20,18,18,10, + // EAxx + 7,37,9,37,37,39,37,9, 37,10,10,37,37,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,12,10,12,11,10,10,10, 10,10,10,10,10,10,10,10, 37,10,6,10,10,10,10,10, 10,10,10,10,10,10,10,12, + 10,31,31,31,31,31,6,12, 31,6,6,31,31,8,31,31, 3,31,37,31,31,37,31,8, 11,11,31,10,12,10,12,10, + 10,10,12,12,12,11,37,12, 11,10,11,12,11,11,11,10, 12,11,11,11,11,11,11,12, 11,6,12,8,17,6,3,37, + 6,39,6,6,2,3,2,3, 6,6,6,2,39,6,6,6, 6,3,6,6,6,6,6,6, 6,11,6,11,12,6,6,6, + 10,14,6,5,14,36,8,14, 3,3,5,5,5,5,5,3, 2,2,2,2,2,2,9,2, 2,2,2,2,2,2,2,12, + 3,3,14,3,10,5,3,3, 3,3,3,3,3,3,5,3, 14,3,14,3,3,3,5,3, 3,34,3,7,20,20,20,20, + 10,20,10,10,18,10,10,20, 10,20,10,10,10,10,10,20, 10,10,10,10,18,20,10,10, 10,20,10,18,20,20,18,10, + // EBxx + 7,10,37,37,4,37,37,37, 37,10,10,10,37,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,10,11,10,16,10, 10,11,10,5,10,10,10,11, 37,10,17,17,17,10,10,17, 17,10,10,10,10,36,10,10, + 10,3,8,8,8,3,11,11, 3,18,14,11,8,3,31,18, 18,37,8,3,31,3,8,37, 39,18,37,3,10,10,37,39, + 17,10,11,11,16,11,11,16, 11,11,16,16,11,16,11,10, 16,11,11,16,16,11,16,11, 3,3,11,37,8,37,5,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,36,2,5,2,2,2, 2,2,2,36,2,2,2,2, 2,2,2,2,2,5,2,2, 2,2,5,2,5,2,7,2, + 5,18,14,5,3,18,3,14, 3,18,3,3,18,14,18,18, 3,3,18,18,18,18,3,3, 3,3,3,8,20,20,20,20, + 10,18,10,10,10,10,10,20, 10,18,10,10,17,10,10,18, 17,10,18,10,18,18,18,10, 17,17,17,10,10,20,10,10, + // ECxx + 7,11,37,1,37,37,37,37, 37,14,10,14,37,11,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 11,10,11,11,11,10,10,17, 14,10,11,11,10,10,10,10, 37,11,10,10,17,11,17,11, 17,17,11,10,11,10,14,10, + 11,1,17,8,8,18,8,8, 8,8,1,8,31,17,39,11, 17,31,17,17,1,1,17,17, 17,18,3,14,17,11,11,11, + 3,1,12,12,12,16,1,1, 12,16,12,12,12,12,12,1, 12,1,12,12,12,16,12,1, 11,10,12,11,17,11,11,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,10,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2, 14,2,2,3,36,36,3,2, 2,2,2,10,2,2,2,14, 2,2,2,2,2,2,14,11, + 18,14,14,14,17,3,17,14, 14,18,14,14,3,14,14,18, 3,5,3,11,7,18,3,5, 18,3,12,5,20,20,20,20, + 10,18,17,17,17,10,17,17, 10,17,10,17,10,10,10,10, 17,17,17,10,17,18,17,17, 18,17,17,10,10,10,11,10, + // EDxx + 7,11,37,37,37,37,37,37, 4,1,1,1,37,1,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 11,1,11,17,11,11,1,1, 11,11,11,17,1,10,1,1, 37,11,11,11,11,11,11,11, 11,11,10,1,11,11,10,1, + 11,1,33,33,33,18,1,1, 33,18,1,33,8,33,1,1, 33,39,33,33,33,33,33,37, 11,37,33,11,10,11,11,11, + 17,1,1,1,1,1,1,1, 1,10,1,1,1,1,1,1, 1,1,1,1,1,1,1,8, 1,10,1,11,17,10,11,37, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 11,2,2,3,2,2,2,2, 2,2,2,2,2,2,2,10, + 1,11,36,3,11,3,3,3, 11,7,36,36,3,5,5,7, 7,5,3,10,7,3,3,3, 10,9,5,5,3,3,9,11, + 5,18,11,11,11,18,11,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, + 10,11,36,11,11,10,11,10, 10,18,10,10,11,10,10,18, 18,10,10,10,10,11,10,10, 11,18,11,10,10,20,10,10, + // EExx + 7,10,37,37,37,37,4,37, 37,10,10,1,37,10,10,37, 39,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,10,11,10,10,10, 10,10,10,10,10,10,10,10, 37,17,17,17,10,17,10,10, 10,17,10,10,10,10,10,10, + 10,3,3,31,31,18,31,31, 3,3,31,8,31,31,31,39, 8,37,31,31,31,37,31,31, 31,18,8,10,10,10,3,10, + 17,11,16,16,16,37,11,16, 8,11,16,16,11,16,11,11, 16,11,16,16,11,8,16,3, 11,11,16,37,10,3,3,37, + 2,2,6,2,2,10,3,2, 2,2,3,2,6,2,6,2, 3,6,11,2,10,6,2,2, 37,2,2,2,2,3,2,2, + 10,3,5,3,5,3,8,3, 3,3,3,3,36,10,3,5, 5,7,3,5,3,7,3,3, 10,2,10,5,10,3,3,10, + 17,18,3,10,17,18,3,8, 3,18,5,3,17,5,3,18, 3,3,3,3,3,18,3,27, 18,3,3,3,5,20,20,20, + 17,10,10,10,10,10,10,17, 10,10,10,10,10,10,18,10, 10,10,10,18,10,10,10,10, 17,17,17,18,18,10,10,10, + // EFxx + 7,37,37,37,37,37,37,10, 37,17,20,17,37,17,37,37, 37,37,37,37,37,37,37,37, 37,37,37,3,37,37,37,37, + 17,17,17,17,17,10,18,17, 17,17,17,17,17,10,10,17, 37,10,10,17,10,10,10,17, 17,10,17,17,17,17,17,17, + 3,11,11,11,11,11,3,3, 8,18,3,11,3,31,37,37, 18,37,37,39,31,11,37,8, 8,37,11,37,17,17,37,17, + 17,12,11,11,11,11,11,30, 3,16,30,11,11,11,11,16, 10,11,11,11,11,16,11,11, 11,39,39,8,17,37,3,37, + 2,2,2,2,2,2,2,2, 2,37,2,2,2,39,2,2, 2,2,2,2,2,2,2,3, 39,3,2,2,2,2,12,2, + 17,36,36,3,2,5,5,5, 2,36,7,7,36,2,3,2, 5,3,3,10,2,3,3,5, 2,2,2,2,2,2,2,2, + 3,5,18,18,18,7,18,18, 18,3,18,18,18,18,18,3, 18,3,18,18,18,7,18,5, 3,5,3,3,20,20,18,20, + 10,5,18,20,18,10,18,18, 10,20,18,10,18,18,10,10, 10,20,18,10,18,20,18,18, 10,20,18,10,10,20,18,10, + // F0xx + 3,37,1,37,10,37,39,39, 37,10,10,37,37,11,4,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,10,11,10,10,10, 10,10,11,10,10,10,10,10, 37,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,1, + 10,12,3,14,1,1,1,13, 1,13,8,8,13,13,37,18, 18,37,13,39,37,13,39,11, 39,37,1,11,10,10,3,10, + 17,13,1,13,13,13,1,1, 1,13,1,16,13,13,16,16, 16,37,13,1,16,13,16,1, 1,16,13,11,10,11,14,39, + 39,6,6,6,36,11,4,36, 6,6,6,6,6,6,6,6, 2,6,6,6,6,6,6,6, 6,4,3,3,10,2,10,10, + 2,11,3,3,3,3,2,3, 5,3,3,5,5,5,3,5, 3,3,5,10,5,3,5,5, 7,5,11,11,5,3,5,11, + 3,18,5,8,3,18,3,11, 5,18,3,3,18,3,18,18, 3,18,18,18,18,18,3,7, 3,18,5,3,20,20,20,20, + 10,10,10,10,17,10,10,10, 10,17,10,17,10,10,10,18, 10,10,10,10,10,10,10,17, 10,17,17,10,10,13,10,10, + // F1xx + 3,9,37,9,1,10,39,37, 1,12,10,37,37,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,10,10,10,10,10, 10,10,17,10,10,10,10,10, 37,10,10,10,10,10,10,10, 10,10,10,12,10,10,10,10, + 1,1,1,12,8,1,8,1, 1,1,1,8,1,1,37,1, 3,8,3,12,8,1,37,12, 8,37,8,10,1,12,8,10, + 17,1,12,12,10,1,10,1, 10,1,8,12,10,12,1,1, 10,1,10,12,10,1,37,1, 10,10,1,3,17,11,5,37, + 39,6,6,6,4,10,4,4, 6,6,37,6,6,6,6,6, 6,6,6,6,10,6,6,6, 6,37,10,3,4,3,4,4, + 10,11,36,3,3,7,5,5, 3,8,5,3,5,7,3,8, 3,3,3,10,3,3,5,3, 10,5,3,3,3,7,3,3, + 17,5,11,3,3,3,3,3, 11,3,3,18,3,18,18,11, 18,3,18,5,3,5,3,18, 3,7,18,18,20,20,20,20, + 10,20,10,17,10,10,10,20, 10,17,10,10,10,10,10,10, 10,10,10,10,17,10,10,10, 10,20,10,10,10,18,10,10, + // F2xx + 3,1,37,1,37,37,39,37, 37,10,10,10,37,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,10,1,10,10,10, 10,10,10,10,10,10,10,10, 37,10,10,10,10,10,10,10, 10,10,10,10,10,20,10,10, + 10,31,31,17,31,12,10,1, 1,18,31,1,31,31,31,1, 31,37,8,31,31,8,39,37, 39,3,31,10,10,10,8,10, + 17,16,1,1,1,16,39,1, 12,16,1,12,1,1,1,12, 1,1,1,12,12,12,1,1, 1,10,1,1,17,11,37,37, + 37,6,6,39,4,10,3,4, 37,6,6,6,6,6,6,37, 6,6,6,6,10,6,39,6, 39,4,12,11,3,12,3,4, + 10,11,5,3,5,5,3,3, 5,5,5,3,5,8,1,3, 3,5,7,10,7,5,26,5, 10,3,3,20,3,3,3,7, + 3,18,11,3,5,18,3,11, 11,18,11,3,3,11,3,18, 3,3,1,11,3,18,11,3, 5,18,3,3,11,11,11,3, + 10,18,10,17,17,10,17,18, 10,17,10,10,17,10,10,18, 10,10,10,10,18,18,17,10, 17,18,17,10,10,10,10,10, + // F3xx + 3,1,1,37,4,4,39,37, 1,10,10,9,37,10,37,1, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,10,17,10,10,10, 10,10,11,17,10,10,10,1, 37,18,1,10,10,18,10,18, 10,18,1,10,10,10,1,10, + 3,11,1,1,1,1,1,1, 18,18,31,31,31,1,1,8, 1,11,1,39,31,37,39,1, 37,37,31,37,1,10,37,1, + 39,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,11,17,11,24,37, + 37,39,6,6,37,10,3,12, 37,37,6,6,6,6,6,6, 6,11,23,6,12,6,6,39, 37,24,10,3,12,3,10,12, + 10,11,5,3,8,8,3,3, 5,3,8,3,3,5,5,3, 3,3,3,12,3,3,9,5, 3,3,10,3,9,2,3,12, + 5,18,18,11,18,18,3,11, 11,11,11,18,18,11,11,18, 18,11,18,11,18,18,11,18, 11,11,11,11,11,11,11,11, + 10,10,10,10,10,18,10,10, 10,18,10,18,18,10,18,10, 10,10,10,18,18,10,10,10, 10,10,18,18,20,20,10,10, + // F4xx + 3,4,37,37,37,37,39,37, 37,11,10,37,37,11,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,11,17,11,11,10,20,11, 11,10,11,3,10,10,18,20, 37,10,25,17,10,10,10,11, 10,10,10,11,11,17,10,10, + 17,18,11,8,11,18,11,11, 11,18,24,11,11,11,37,18, 18,37,11,37,11,11,39,11, 11,37,11,11,17,11,37,11, + 17,11,11,11,11,37,39,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,39,3,37, + 2,39,6,6,3,24,3,3, 11,37,37,39,11,6,6,6, 37,6,23,6,3,39,6,37, 37,11,12,3,39,12,12,4, + 25,5,3,7,11,3,11,11, 8,3,8,3,3,8,3,8, 8,8,3,10,3,3,5,3, 5,5,3,5,3,3,9,8, + 18,18,3,3,3,18,3,3, 5,3,3,3,3,3,8,18, 3,5,18,3,3,18,3,18, 3,18,1,3,20,20,20,3, + 10,18,17,17,17,17,3,20, 10,17,10,10,17,10,10,18, 10,17,18,10,10,18,17,18, 17,17,17,10,20,20,20,37, + // F5xx + 3,37,1,4,37,39,39,37, 37,10,10,37,37,10,37,39, 37,39,37,37,37,37,37,37, 39,37,37,37,37,37,37,37, + 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,20,10,10, + 10,10,11,1,3,8,8,1, 10,1,1,1,1,1,37,8, 1,1,1,1,1,1,1,8, 8,1,1,1,17,10,37,39, + 17,12,1,12,12,1,12,1, 1,1,1,12,1,1,1,12, 1,3,1,12,1,1,12,1, 1,1,12,1,8,11,3,37, + 37,6,6,6,4,10,4,4, 6,6,6,6,6,39,6,6, 6,11,6,6,10,6,6,6, 4,4,4,4,3,3,3,4, + 10,11,5,3,3,3,8,8, 5,1,3,3,8,8,5,1, 8,5,3,10,3,3,5,3, 3,3,10,3,3,5,3,3, + 3,5,18,5,18,5,18,1, 11,18,11,18,3,11,3,11, 18,11,18,18,11,11,11,18, 11,11,11,11,11,11,18,11, + 10,11,18,11,18,11,11,18, 10,25,20,18,18,10,10,10, 10,1,18,18,18,10,18,18, 20,3,18,18,3,18,18,33, + // F6xx + 3,1,37,37,37,37,39,37, 37,1,1,1,37,1,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 11,10,1,1,1,10,1,17, 3,10,11,5,10,10,10,1, 37,5,1,1,5,10,10,3, 1,1,10,10,1,11,1,1, + 5,11,1,1,1,1,1,1, 1,24,1,1,1,1,39,37, 11,37,1,1,1,37,1,37, 1,1,1,37,17,1,39,1, + 17,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,8,1,11,5,37, + 39,6,6,4,24,24,3,3, 37,6,6,6,37,37,6,37, 6,17,17,6,39,37,39,6, 37,37,3,11,4,3,3,4, + 11,11,5,3,3,8,3,3, 3,3,3,3,3,3,3,8, 3,3,3,10,3,3,3,5, 3,5,3,3,3,5,5,5, + 3,3,3,3,3,18,11,11, 11,18,11,11,11,11,3,11, 11,11,11,11,11,18,11,3, 11,11,11,11,11,20,11,1, + 10,17,10,11,17,10,11,17, 10,17,10,18,17,11,10,20, 13,20,17,10,17,18,1,17, 17,20,17,10,10,20,13,10, + // F7xx + 3,1,37,37,37,37,39,37, 37,10,18,6,37,10,37,37, 37,37,37,37,37,37,37,37, 37,37,7,37,37,37,37,39, + 17,17,17,17,11,10,18,17, 11,10,17,3,17,10,18,10, 11,11,11,11,11,11,11,11, 11,11,17,17,10,17,10,17, + 8,18,11,8,3,18,8,8, 3,18,11,3,11,11,39,18, 11,37,11,39,37,3,11,39, 11,37,3,11,11,8,17,17, + 17,10,37,11,11,10,11,11, 37,8,11,11,11,39,11,20, 11,11,11,11,11,11,11,11, 39,10,11,37,17,17,8,37, + 3,6,6,3,3,3,3,3, 37,6,6,39,6,37,6,39, 6,37,11,6,10,6,6,6, 4,37,3,3,10,4,12,4, + 17,3,3,3,11,3,26,3, 3,3,8,8,3,3,3,3, 3,3,3,10,8,3,26,3, 10,5,3,3,3,5,3,3, + 3,18,3,3,3,18,3,5, 3,18,3,18,18,18,18,18, 18,3,18,18,18,18,3,18, 18,18,18,3,20,20,20,20, + 10,18,10,17,17,10,17,17, 10,17,10,10,17,10,18,18, 17,17,10,18,17,18,17,18, 17,18,17,18,10,20,20,10, + // F8xx + 3,1,37,37,37,37,39,37, 1,17,17,37,37,17,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 17,17,17,17,1,17,16,17, 17,16,17,5,17,17,17,17, 37,5,1,17,1,1,1,1, 1,10,17,17,17,17,17,17, + 10,8,3,1,1,1,12,1, 1,1,8,1,1,1,37,37, 1,37,1,39,37,8,1,8, 8,37,1,37,17,17,37,1, + 17,12,1,12,1,12,1,1, 1,12,1,1,1,1,1,12, 1,8,1,1,1,1,1,1, 1,1,1,3,37,37,5,37, + 39,6,6,39,4,16,3,17, 39,6,37,39,6,37,6,37, 37,11,6,16,16,37,16,6, 37,37,12,3,10,3,12,24, + 17,11,5,3,11,8,8,8, 5,1,8,5,8,8,1,8, 8,5,3,10,3,5,3,3, 10,5,5,3,5,5,3,5, + 5,5,3,11,24,17,17,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,3, 11,3,11,11,11,11,11,11, + 17,17,17,17,17,17,17,17, 10,17,10,17,17,12,18,17, 17,17,10,11,17,17,11,17, 17,17,17,18,10,18,10,37, + // F9xx + 3,1,37,37,37,37,39,39, 37,12,12,1,37,12,37,39, 37,37,37,37,39,37,37,37, 37,37,37,37,37,37,37,37, + 12,17,12,17,11,11,30,12, 12,12,17,5,12,12,12,17, 37,17,17,17,17,17,10,17, 3,17,12,12,12,17,12,12, + 8,8,11,8,12,11,24,24, 24,24,11,17,11,11,11,8, 39,37,11,8,11,11,11,39, 11,11,3,39,17,12,24,11, + 17,11,12,12,12,11,12,11, 12,11,12,12,12,12,12,11, 12,37,12,12,12,11,12,24, 11,11,12,37,17,24,24,37, + 37,24,6,11,11,12,37,24, 24,24,24,37,37,24,24,24, 24,24,24,12,24,24,37,24, 24,24,12,24,24,24,12,24, + 12,5,24,3,8,5,5,24, 5,24,1,5,5,5,8,8, 5,5,3,8,3,3,5,8, 10,5,8,5,24,3,9,24, + 1,5,24,5,8,5,3,5, 3,1,5,24,17,5,5,5, 8,17,17,5,3,8,8,8, 8,8,8,5,8,8,8,8, + 10,17,17,17,17,10,17,17, 10,17,18,17,17,17,17,17, 17,20,17,20,17,7,17,17, 17,17,17,18,10,8,8,10, + // FAxx + 3,10,1,37,37,37,37,37, 37,1,17,1,37,17,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 17,17,17,17,1,17,17,17, 17,17,17,17,17,17,17,17, 37,17,17,17,17,17,17,17, 1,17,17,17,17,17,1,17, + 8,8,1,8,8,1,1,8, 8,1,1,24,1,1,37,37, 8,39,1,37,1,1,39,39, 11,1,1,37,17,11,39,17, + 17,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,37, 1,37,1,1,17,11,11,37, + 39,6,6,6,12,17,37,12, 37,6,37,37,6,6,6,6, 6,6,6,6,12,6,6,24, 6,37,12,12,24,12,12,4, + 17,5,3,5,5,6,8,8, 8,5,5,11,8,5,1,5, 5,3,3,3,5,3,3,5, 10,5,3,9,5,3,5,11, + 5,18,11,11,18,18,3,11, 11,18,11,11,11,11,11,11, 11,11,11,11,11,11,11,18, 11,11,11,11,11,11,11,11, + 17,18,17,11,17,17,11,17, 12,17,17,17,17,18,17,18, 17,18,17,17,17,18,17,17, 17,17,17,1,5,5,5,10, + // FBxx + 3,37,37,37,37,37,37,14, 37,10,10,10,39,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,3,37,37,37,37, + 10,10,10,10,11,10,10,10, 10,10,10,10,10,10,10,10, 39,10,10,10,10,10,10,11, 10,10,10,10,10,10,10,10, + 10,8,11,11,8,18,8,3, 11,18,8,11,11,10,39,37, 11,39,37,37,37,37,37,37, 11,37,11,37,10,10,3,10, + 10,12,11,16,16,12,12,16, 12,8,12,16,16,16,16,11, 16,3,16,16,11,37,12,37, 10,39,16,37,39,37,37,37, + 37,6,6,6,37,10,11,39, 37,6,37,39,6,6,6,6, 3,37,37,6,6,39,6,6, 6,37,37,11,3,10,37,3, + 10,5,10,3,8,8,5,8, 8,3,5,5,5,16,11,8, 3,8,8,5,5,3,3,3, 5,3,5,3,5,3,5,5, + 5,18,5,3,3,18,3,5, 3,18,3,18,18,18,18,18, 18,3,18,3,18,18,3,18, 3,18,7,5,5,5,5,5, + 5,18,10,10,10,10,10,10, 16,10,10,10,10,10,18,18, 10,10,10,5,18,10,10,10, 10,5,5,11,11,5,5,10, + // FCxx + 3,10,37,37,37,37,37,37, 1,11,10,37,4,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,11,11,10,10,11, 10,10,10,10,10,10,10,10, 37,10,10,10,10,10,10,10, 10,10,10,10,10,11,10,10, + 10,33,11,11,11,33,11,11, 11,33,11,11,11,11,11,33, 11,37,11,11,11,33,11,11, 11,11,11,39,10,10,37,11, + 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11, 11,11,11,37,11,37,39,39, + 37,6,6,6,37,11,11,11, 6,6,6,6,39,6,6,6, 6,6,11,6,10,6,6,6, 39,11,3,11,11,4,39,4, + 10,5,5,5,5,5,8,5, 8,8,8,8,5,11,8,5, 5,5,3,5,5,33,3,5, 5,5,5,5,3,5,5,5, + 5,5,18,5,18,3,18,18, 18,3,18,18,18,18,18,5, 18,3,18,18,18,5,33,18, 5,3,18,18,5,1,5,1, + 10,10,20,10,10,10,18,11, 10,18,10,18,20,10,10,10, 13,10,10,20,18,10,10,20, 10,10,18,18,11,1,13,10, + // FDxx + 3,37,1,37,37,37,37,37, 37,13,13,37,37,13,4,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 13,13,13,13,13,13,13,13, 13,13,13,13,13,13,13,13, 11,11,11,11,11,11,11,11, 11,11,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13, 13,13,1,13,13,13,13,37, 13,37,13,13,13,13,39,37, 1,13,13,13,13,13,37,13, + 13,33,1,13,13,33,13,13, 1,33,1,13,13,13,13,13, 13,13,13,13,13,13,1,13, 13,13,13,37,13,13,3,37, + 39,37,37,37,37,22,3,3, 3,37,37,37,39,37,39,39, 39,37,22,12,22,11,37,37, 3,37,12,3,3,12,12,4, + 33,33,8,3,8,8,5,5, 5,8,8,8,8,5,8,1, 3,5,3,5,13,3,3,3, 3,9,5,3,3,3,9,3, + 5,3,3,3,3,18,3,11, 3,18,3,3,5,3,3,3, 13,3,3,3,3,3,3,3, 5,5,11,5,11,1,13,11, + 10,18,10,11,10,18,11,13, 12,18,10,10,10,10,18,10, 13,10,10,20,10,10,1,20, 18,20,5,5,5,13,13,10, + // FExx + 3,39,39,39,37,37,39,39, 37,13,10,37,39,11,39,39, 39,39,39,39,39,37,39,37, 39,39,37,39,37,39,37,39, + 10,10,10,1,1,10,13,13, 11,10,11,13,10,10,10,13, 11,11,11,11,11,11,11,11, 11,11,13,13,13,13,13,10, + 13,13,1,11,13,13,13,13, 11,13,11,13,13,11,37,37, 11,37,37,11,13,13,39,37, 37,13,11,11,13,11,3,13, + 13,13,13,13,16,13,13,13, 13,13,1,13,13,13,16,16, 16,13,1,16,13,13,13,11, 11,13,13,11,13,11,3,37, + 3,11,37,37,4,4,4,4, 37,37,39,39,37,11,37,37, 11,37,22,16,39,11,39,37, 39,4,3,37,4,11,37,3, + 3,11,1,3,8,8,8,8, 8,8,8,11,8,13,1,1, 8,1,3,18,3,3,3,8, 3,3,10,3,3,3,3,11, + 5,18,11,11,3,18,3,11, 11,18,11,11,11,11,11,11, 11,11,11,11,18,18,18,3, 11,11,11,11,11,11,11,11, + 10,18,10,10,10,18,10,10, 10,18,10,18,10,20,18,18, 10,10,10,20,18,18,13,10, 18,10,1,18,13,13,11,37, + // FFxx + 3,37,39,39,39,37,37,39, 37,37,10,37,37,10,37,37, 37,37,37,37,37,37,37,37, 37,37,37,37,37,37,37,37, + 10,10,10,37,37,10,10,10, 10,10,10,10,10,10,10,10, 37,36,36,37,36,36,39,39, 39,39,10,10,10,1,10,10, + 10,39,39,39,39,37,39,39, 1,39,39,36,39,39,37,39, 39,39,37,36,39,39,36,37, 36,39,36,10,10,10,37,10, + 10,2,2,2,36,2,2,2, 2,2,2,36,2,2,36,36, 36,2,2,2,2,2,36,2, 2,2,36,39,10,39,39,39, + 36,36,39,37,39,10,39,39, 4,37,36,39,36,36,36,36, 36,37,39,39,10,11,39,39, 37,39,39,39,39,37,39,33, + 10,39,10,33,39,39,36,33, 36,1,36,39,33,10,36,36, 39,39,39,18,39,39,39,39, 39,39,10,11,39,39,39,1, + 10,1,1,11,39,39,39,39, 39,39,39,39,39,39,39,39, 39,39,39,39,39,39,39,39, 3,3,3,3,11,3,3,1, + 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,39,39,10,37,10,10, + +}; // End kMostLikelyEncoding + +// End of generated tables +#endif // COMPACT_ENC_DET_COMPACT_ENC_DET_GENERATED_TABLES_H_ diff --git a/ced/compact_enc_det/compact_enc_det_generated_tables2.h b/ced/compact_enc_det/compact_enc_det_generated_tables2.h new file mode 100644 index 0000000..4ecf966 --- /dev/null +++ b/ced/compact_enc_det/compact_enc_det_generated_tables2.h @@ -0,0 +1,856 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "util/basictypes.h" + +static const uint8 ced_hires_0[1024] = { + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 0,135,134,135,89,111,136,129, 81,121,130,40,64,74,78,13, 90,87,103,56,51,37,63,44, 0,97,60,55,143,97,70,100, + 29,126,116,149,131,156,108,153, 147,119,135,111,133,135,115,0, 2,13,20,4,12,5,17,5, 4,0,58,50,2,30,80,64, + 35,0,0,0,0,22,0,9, 14,12,4,6,7,8,16,3, 147,160,163,141,144,139,146,127, 131,124,23,17,0,11,16,6, + 0,68,108,52,129,66,109,65, 113,58,116,124,126,117,88,114, 85,122,102,126,116,122,96,131, 102,126,107,117,49,113,80,128, + 0,85,119,107,127,75,102,105, 118,101,108,118,101,117,98,128, 125,114,115,125,115,121,116,121, 125,130,122,119,64,102,78,124, + 93,87,64,93,105,92,76,80, 113,82,75,88,89,68,88,97, 87,102,145,90,90,130,106,116, 129,61,81,75,47,69,74,64, + 92,98,81,95,81,161,75,81, 101,95,93,75,100,87,108,91, 113,110,118,114,105,105,123,94, 89,92,104,90,62,85,81,84, + + 47,141,155,88,85,108,121,141, 94,73,82,81,163,125,111,89, 106,133,156,95,80,96,88,61, 65,47,74,55,33,54,59,19, + 128,129,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,131,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,135,128,128,128, 128,128,161,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 141,115,118,118,118,128,115,127, 136,136,122,124,125,126,128,121, 147,128,128,128,128,128,128,123, 128,121,128,128,107,154,128,124, + 82,141,145,136,128,144,115,123, 124,117,107,104,103,99,107,90, 92,98,102,82,88,134,161,126, 115,104,114,106,73,91,111,84, + 128,93,94,94,94,116,91,103, 108,106,98,100,101,102,110,97, 137,133,120,132,146,114,136,131, 144,145,155,131,107,151,144,133, + 128,103,106,106,106,128,103,115, 120,118,110,112,113,114,122,109, 157,138,128,117,136,123,136,128, 137,123,152,126,104,136,137,134, + + 32,94,46,28,98,102,130,97, 59,91,81,73,26,125,102,48, 100,66,105,57,87,121,71,120, 86,64,64,83,68,105,91,70, + 32,130,98,103,64,30,123,122, 97,123,58,127,70,74,55,59, 53,99,95,99,105,52,48,73, 52,68,138,89,29,104,97,142, + 20,99,54,114,87,86,108,55, 46,27,42,99,130,118,83,95, 138,115,69,67,96,95,125,86, 82,121,92,145,131,142,115,134, + 27,53,57,104,139,102,124,124, 135,81,79,148,118,90,71,25, 151,83,146,71,74,129,109,35, 84,115,121,77,48,24,58,63, + 29,55,85,51,70,123,21,95, 116,128,90,107,124,74,98,80, 132,125,112,114,118,109,167,103, 57,127,95,84,13,65,84,109, + 27,137,123,69,151,81,84,95, 124,80,115,38,140,164,121,122, 86,116,83,102,117,110,111,92, 72,94,114,144,62,90,84,109, + 31,128,63,37,14,138,126,79, 132,63,54,95,60,132,89,132, 25,77,134,94,93,154,147,125, 104,98,113,119,70,130,98,111, + 24,78,61,30,100,41,65,115, 80,28,93,97,86,38,74,112, 85,105,135,113,132,45,65,30, 126,91,113,114,73,89,65,130, + + 21,150,114,47,106,125,121,37, 79,158,90,155,73,92,94,107, 87,137,97,135,91,139,152,102, 98,85,126,121,80,140,42,25, + 23,47,75,42,64,150,67,93, 100,140,70,62,117,140,54,122, 100,98,95,105,88,100,132,41, 81,137,76,144,60,131,128,66, + 23,59,107,144,98,44,20,119, 70,80,58,85,119,93,113,59, 83,28,117,67,135,65,77,60, 130,114,138,111,31,109,92,87, + 18,93,79,109,57,128,94,69, 135,54,72,38,53,55,94,56, 133,98,153,147,82,58,124,55, 48,50,153,128,24,54,80,89, + 29,130,95,117,49,47,46,91, 164,58,99,148,64,113,86,110, 144,134,49,60,102,62,103,107, 69,89,149,71,113,31,107,71, + 25,90,106,113,119,82,75,91, 111,128,139,79,130,101,90,31, 97,103,87,84,53,138,43,87, 155,57,75,150,93,128,120,43, + 24,118,82,52,79,56,143,92, 47,103,22,46,70,106,155,129, 93,104,125,42,96,124,137,93, 73,43,134,98,100,111,139,56, + 22,65,103,76,38,122,121,155, 111,147,47,76,96,103,153,78, 71,103,137,104,150,89,139,159, 77,120,71,98,98,125,78,143, +}; + +static const uint8 ced_hires_1[1024] = { + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 62,124,71,116,117,77,46,71, 78,98,127,132,69,67,72,79, 34,37,88,95,81,88,135,138, 116,123,132,136,97,128,45,101, + 68,71,36,0,24,19,3,1, 0,9,60,40,64,146,70,113, 20,16,20,26,13,20,9,12, 14,21,15,19,55,50,99,61, + 17,127,133,119,128,134,113,109, 106,124,100,107,119,131,111,122, 138,113,136,154,132,125,120,114, 115,119,101,25,19,31,19,19, + 122,112,48,123,115,89,133,132, 124,114,123,130,73,103,139,130, 106,90,103,114,71,97,92,74, 115,112,59,105,83,90,140,121, + 118,113,51,133,112,43,123,112, 133,130,102,109,71,110,89,102, 128,125,104,139,115,139,129,134, 112,120,123,117,111,132,129,118, + 73,151,165,130,127,146,100,107, 108,121,103,114,156,112,107,111, 125,129,150,135,107,155,118,116, 168,85,79,83,77,89,77,77, + 98,101,81,63,71,82,66,64, 60,72,57,62,72,70,60,67, 75,153,138,154,129,161,146,125, 125,139,151,134,139,151,135,146, + + 59,21,36,18,26,37,21,19, 15,27,12,17,27,25,15,22, 30,34,38,44,31,38,27,30, 32,39,33,37,31,43,31,31, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,127,128,124,144,128,127,126, 121,128,118,123,128,128,121,128, 128,128,128,128,128,128,128,128, 128,128,128,128,150,128,128,128, + 90,112,109,86,83,124,57,54, 84,70,53,84,62,78,53,75, 124,134,116,95,118,85,129,65, 67,74,68,72,66,78,66,66, + 141,134,118,107,135,127,130,134, 118,109,94,99,109,107,97,104, 112,116,120,126,113,120,109,112, 114,121,115,119,113,125,113,113, + 161,134,128,112,120,139,115,128, 122,121,106,111,121,119,109,116, 124,128,128,128,125,128,121,124, 126,128,127,128,125,128,125,125, + + 76,29,158,87,47,122,133,89, 63,101,139,116,147,111,79,122, 60,112,93,68,42,145,73,100, 89,123,46,122,124,112,99,90, + 118,56,99,61,145,53,131,144, 66,122,110,97,113,82,19,27, 33,134,120,84,79,124,78,108, 138,87,26,133,114,84,47,165, + 62,148,104,137,139,97,125,86, 134,47,127,93,141,85,119,111, 126,56,42,26,102,89,122,48, 59,116,110,106,46,115,64,113, + 107,81,49,29,28,64,130,22, 111,53,142,89,89,127,131,86, 122,122,37,143,66,96,82,105, 155,96,154,124,63,121,90,60, + 115,107,42,30,134,130,119,108, 66,145,122,85,105,19,88,92, 36,134,34,101,97,112,152,73, 150,89,116,144,71,130,131,103, + 88,123,77,30,132,53,98,51, 116,61,95,57,84,109,31,74, 20,98,135,114,78,114,95,123, 45,136,116,111,130,94,120,99, + 114,121,64,107,94,104,29,77, 152,133,124,119,135,98,0,78, 118,115,88,102,57,61,51,89, 120,51,115,109,64,111,61,66, + 110,135,106,110,98,74,86,137, 124,103,134,80,86,43,76,131, 134,105,91,84,73,34,71,133, 60,111,117,53,90,133,106,61, + + 147,38,145,28,137,149,110,112, 52,83,99,128,56,129,105,74, 93,60,45,62,73,86,30,82, 80,44,19,97,85,87,108,103, + 99,114,94,104,97,104,140,51, 98,62,119,74,85,141,51,23, 71,58,119,110,151,65,116,74, 130,81,86,90,7,99,38,116, + 61,59,140,66,91,133,123,152, 80,82,98,67,112,110,110,89, 121,132,120,62,43,74,45,110, 88,146,113,101,134,135,104,131, + 110,47,96,67,123,147,69,70, 131,106,98,109,71,118,116,128, 92,100,149,53,144,117,99,136, 127,128,3,43,114,100,85,117, + 92,134,156,8,88,62,89,98, 6,19,46,96,145,108,88,69, 78,94,152,96,146,108,133,66, 75,102,101,10,79,44,57,61, + 102,96,123,91,109,149,84,63, 39,134,53,110,111,64,97,103, 155,133,105,105,34,125,93,56, 28,84,65,95,103,58,41,83, + 48,25,116,120,91,104,124,84, 111,119,105,64,63,97,116,114, 128,103,136,74,59,33,47,93, 54,80,130,39,139,130,119,83, + 140,68,94,85,77,79,118,109, 120,106,114,103,115,165,94,79, 60,52,84,77,82,78,49,74, 88,49,48,76,102,99,138,71, +}; + +static const uint8 ced_hires_2[1024] = { + 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 44,106,18,108,117,63,65,73, 40,57,43,81,77,63,68,90, 54,16,20,95,85,131,112,100, 58,144,140,135,114,96,110,128, + 111,93,68,129,135,62,95,32, 82,42,46,10,8,23,10,16, 26,21,70,26,93,84,168,105, 79,71,29,48,15,26,68,128, + 28,126,105,123,109,126,102,109, 105,122,72,104,108,132,113,126, 118,82,122,110,129,125,114,134, 113,133,103,54,21,32,21,128, + 113,122,134,118,123,77,97,101, 121,135,128,138,125,120,35,120, 31,24,148,129,0,0,0,0, 0,0,0,5,0,0,0,128, + 137,137,112,130,105,127,110,121, 86,140,134,139,128,145,17,121, 19,27,60,150,106,62,95,0, 0,0,0,9,0,0,0,128, + 86,81,78,87,82,79,82,75, 75,78,69,74,72,87,74,80, 90,85,84,72,92,96,88,82, 98,102,93,112,79,90,79,128, + 162,135,144,153,151,137,127,118, 113,125,105,106,91,139,129,109, 124,140,83,71,91,95,87,81, 97,101,92,111,78,89,78,128, + + 40,35,34,43,36,33,36,29, 29,32,23,28,26,41,28,34, 44,39,38,26,46,50,42,36, 52,56,47,66,33,44,33,128, + 128,128,128,131,128,128,130,128, 147,152,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,138,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 128,128,128,143,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 166,128,128,130,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,146,128,128, 128,128,128,128,148,128,128,128, + 139,134,133,75,121,105,114,103, 64,68,129,100,62,76,63,69, 79,74,73,114,137,85,77,71, 174,140,82,101,68,79,68,128, + 122,117,114,122,118,115,118,113, 112,117,105,110,108,123,110,116, 126,121,120,108,128,128,124,118, 128,128,128,128,115,126,115,128, + 128,128,126,154,128,127,132,123, 137,126,117,122,120,128,122,128, 128,128,128,120,128,128,128,128, 128,128,128,128,127,128,127,128, + + 67,115,51,135,110,136,135,45, 132,133,58,84,156,90,77,88, 106,108,86,29,51,132,78,133, 122,67,145,151,77,36,57,128, + 142,57,81,110,113,64,18,123, 101,136,98,45,102,79,83,102, 85,86,54,106,94,38,117,74, 115,80,89,151,109,98,137,128, + 57,126,70,74,47,54,112,60, 146,46,72,36,108,101,48,40, 135,151,135,128,78,111,70,101, 107,100,25,118,65,57,106,128, + 67,74,25,123,123,65,42,95, 135,62,82,86,45,70,104,59, 92,30,63,55,143,71,26,83, 97,107,87,111,25,86,45,128, + 65,102,90,116,124,16,45,51, 110,129,118,128,73,120,108,139, 139,102,109,110,120,134,85,66, 104,100,96,129,134,94,84,128, + 68,135,60,114,78,126,135,56, 22,121,35,117,101,118,119,120, 109,82,99,96,29,91,118,96, 63,104,18,139,47,66,138,128, + 78,148,152,94,129,120,107,96, 141,71,52,46,111,50,97,36, 101,133,87,23,91,150,92,38, 110,103,97,84,79,68,85,128, + 118,16,110,124,126,74,99,94, 132,79,88,135,103,84,161,153, 35,41,125,78,122,107,74,90, 93,122,134,117,97,91,38,128, + + 56,121,75,93,68,139,117,78, 23,63,43,75,128,101,116,59, 57,65,121,13,48,108,74,121, 144,120,128,78,95,135,119,128, + 141,128,143,68,91,46,137,151, 29,50,32,92,55,73,81,107, 139,145,72,67,54,129,86,35, 105,40,40,99,98,61,142,128, + 136,98,109,69,113,126,85,56, 56,103,117,104,17,70,148,128, 55,61,117,55,58,53,121,155, 86,126,75,104,27,105,100,128, + 117,110,66,101,135,87,114,88, 69,93,78,106,98,98,117,132, 43,125,54,39,97,119,157,98, 79,131,147,134,59,130,143,128, + 60,89,40,119,87,99,73,123, 138,107,135,72,78,97,83,134, 85,110,119,93,43,141,77,98, 119,124,28,104,55,131,118,128, + 130,92,71,117,97,53,50,134, 114,136,136,98,51,71,62,115, 96,155,36,1,104,124,59,137, 117,93,26,47,129,107,82,128, + 25,44,71,115,56,152,109,40, 117,70,60,119,146,80,83,130, 162,18,126,52,102,137,91,39, 105,113,91,105,37,46,95,128, + 68,104,78,51,112,141,87,82, 79,68,59,77,84,49,21,91, 81,68,66,30,149,62,30,70, 81,114,25,107,6,89,62,128, +}; + +static const uint8 ced_hires_3[1024] = { + 145,108,107,112,108,128,119,120, 123,130,108,110,133,138,120,117, 120,120,128,121,121,116,128,119, 128,119,122,114,121,119,123,124, + 77,160,155,161,143,37,29,56, 47,35,127,103,75,130,115,110, 149,149,88,80,89,85,145,135, 102,93,107,99,91,89,140,135, + 123,90,70,105,58,80,64,65, 54,64,75,114,51,62,65,58, 91,121,130,110,109,105,111,102, 107,100,93,91,94,94,90,92, + 173,130,70,57,104,116,65,65, 135,145,70,76,167,129,117,91, 127,129,135,120,115,112,120,109, 117,108,170,131,84,86,91,132, + 62,79,115,64,137,72,131,76, 108,65,120,128,125,126,92,124, 97,123,106,137,119,127,102,145, 120,143,106,114,81,121,87,140, + 32,95,125,118,134,80,123,115, 112,107,111,122,99,125,101,137, 136,114,118,135,117,125,121,134, 142,145,120,115,95,109,84,135, + 149,90,62,97,105,90,90,83, 100,81,70,84,80,69,84,99, 91,95,141,93,85,127,104,122, 139,91,91,84,114,85,87,82, + 128,108,87,106,88,166,96,91, 95,101,96,78,98,95,111,100, 124,110,121,124,107,109,128,107, 106,107,102,86,93,92,87,95, + + 128,128,121,112,126,121,150,106, 125,124,120,96,136,130,135,110, 131,109,148,108,124,113,113,94, 107,139,145,102,114,94,96,95, + 92,96,25,73,155,144,172,124, 82,104,144,100,98,115,154,121, 106,60,79,85,106,68,75,81, 150,81,74,87,105,46,52,81, + 128,115,75,109,150,190,102,84, 108,126,118,117,98,102,82,70, 101,160,145,120,104,121,112,110, 124,103,124,102,101,99,97,98, + 128,121,92,125,93,113,104,105, 94,104,93,99,93,102,105,98, 129,127,166,129,127,135,139,136, 142,143,142,131,131,127,123,126, + 128,115,81,140,82,102,107,94, 83,93,83,84,80,91,94,87, 131,132,152,131,139,139,150,144, 142,131,134,133,139,135,137,136, + 128,144,99,131,100,120,124,112, 101,111,100,102,98,109,112,105, 126,133,137,137,132,146,148,131, 144,153,139,142,147,123,115,120, + 128,132,96,135,97,117,108,109, 98,108,97,99,95,106,109,108, 133,126,134,126,133,142,142,127, 140,133,144,121,134,129,135,117, + 128,137,98,138,99,119,110,111, 100,110,99,102,97,112,111,111, 133,122,147,135,132,142,126,127, 144,133,138,140,129,124,135,131, + + 66,120,131,103,77,97,82,96, 49,122,50,79,108,111,157,61, 103,104,175,93,150,114,129,97, 163,62,107,74,85,83,86,65, + 60,104,55,155,93,106,145,111, 154,124,81,79,114,119,104,98, 78,156,105,125,122,58,126,51, 158,67,68,140,110,97,170,83, + 57,133,137,102,68,149,108,61, 123,146,85,82,59,65,109,45, 93,71,73,77,93,78,111,93, 84,127,90,164,148,138,91,161, + 61,151,94,146,151,131,111,141, 77,115,111,98,134,96,86,120, 72,120,108,84,108,154,91,107, 59,119,71,81,97,99,110,111, + 61,123,117,54,44,130,154,70, 125,120,23,146,110,91,116,88, 138,83,134,93,150,98,76,53, 90,99,140,60,102,90,84,118, + 48,50,50,114,97,154,78,31, 88,101,72,126,31,104,99,105, 108,142,96,135,96,117,112,62, 90,103,116,59,144,151,100,63, + 60,111,72,74,81,149,104,72, 154,140,90,149,106,117,107,164, 94,68,40,103,113,75,95,119, 78,119,86,84,153,133,135,61, + 57,55,162,113,44,109,106,106, 156,45,51,86,91,122,91,49, 59,115,122,101,140,123,148,88, 128,112,113,99,106,160,94,146, + + 60,103,65,134,55,108,82,107, 109,74,62,66,51,60,154,112, 107,132,118,98,153,90,145,96, 127,103,138,131,32,128,125,71, + 83,37,62,74,156,128,140,85, 67,149,49,158,98,78,96,58, 74,105,154,86,85,104,70,106, 71,139,144,112,70,87,62,57, + 61,52,121,154,38,91,135,69, 50,69,82,123,119,105,113,111, 94,87,99,91,73,100,97,82, 110,100,136,69,126,142,55,51, + 74,69,108,46,132,141,110,157, 133,69,143,44,100,133,144,154, 148,71,78,118,106,110,142,141, 77,145,112,124,118,87,69,36, + 55,94,65,106,116,57,117,82, 111,82,114,127,58,134,115,141, 151,122,124,60,133,57,158,91, 139,85,137,75,157,84,128,56, + 59,132,91,110,40,123,69,72, 156,84,95,148,88,151,121,95, 59,132,143,80,88,128,94,95, 76,120,121,149,98,86,94,91, + 63,124,105,95,61,107,107,129, 65,159,114,147,62,170,118,134, 140,104,135,145,113,123,129,67, 107,117,135,114,64,66,85,147, + 65,101,84,63,70,103,113,106, 138,80,159,36,114,114,86,133, 93,102,95,90,159,137,73,65, 75,126,75,50,154,87,101,119, +}; + +static const uint8 ced_hires_4[1024] = { + 125,128,119,118,134,121,118,117, 121,123,122,116,128,124,115,120, 123,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,133, + 89,125,49,76,12,21,28,18, 21,36,39,85,85,24,34,27, 45,91,39,57,98,41,58,61, 34,65,57,69,88,91,63,51, + 88,107,83,89,76,130,128,123, 123,120,114,104,121,106,102,107, 111,122,121,124,104,124,105,123, 75,193,173,183,166,161,151,140, + 57,123,96,99,90,98,90,87, 92,100,90,86,102,110,91,100, 111,104,117,127,115,104,104,107, 93,107,76,126,75,129,66,99, + 132,140,43,135,109,85,142,143, 142,123,145,142,88,114,151,140, 111,113,116,119,86,108,108,99, 125,132,66,121,102,103,162,139, + 127,140,45,144,105,38,131,121, 150,137,124,119,85,120,100,111, 132,147,116,143,129,149,144,158, 121,139,129,132,129,144,150,135, + 118,171,152,134,113,134,101,109, 118,121,117,117,163,115,111,113, 122,144,155,132,114,158,126,133, 170,108,78,105,109,94,91,87, + 107,128,102,85,100,86,92,85, 99,107,95,79,99,102,94,112, 103,175,150,158,143,171,161,149, 134,158,157,149,157,163,156,163, + + 109,134,92,99,79,88,99,96, 113,116,109,96,117,109,94,107, 109,117,140,123,112,109,118,129, 82,99,110,93,90,120,93,105, + 174,130,49,65,96,52,55,98, 100,54,66,43,94,53,51,88, 117,70,89,96,67,74,69,96, 111,61,42,98,52,58,55,82, + 104,127,95,100,95,101,95,103, 111,102,126,112,114,120,101,120, 111,128,128,120,116,125,119,128, 87,104,85,98,95,101,98,94, + 127,145,120,137,126,116,135,123, 128,134,149,145,134,137,137,135, 138,172,148,150,144,142,146,155, 116,128,113,126,123,128,126,122, + 127,149,116,132,127,126,132,129, 142,132,146,137,136,137,141,133, 138,152,166,158,154,155,150,158, 104,121,102,120,112,119,115,111, + 147,147,113,127,121,115,115,109, 131,129,132,124,135,125,120,129, 126,150,153,163,145,131,145,157, 122,128,120,128,128,128,128,128, + 132,146,128,118,123,118,136,128, 140,142,131,133,128,133,123,134, 135,144,155,144,129,141,146,152, 119,128,117,129,127,128,128,126, + 136,161,124,119,112,127,127,117, 125,135,136,116,159,139,127,131, 135,144,151,151,142,140,146,158, 121,128,119,128,128,128,128,128, + + 56,117,131,52,109,89,49,75, 81,137,58,134,87,143,104,64, 67,158,68,113,116,101,108,155, 107,161,107,92,127,123,72,117, + 86,78,40,98,54,51,93,94, 146,77,132,88,105,47,86,121, 62,41,132,68,70,140,41,104, 135,103,110,99,123,62,88,138, + 101,108,91,108,121,139,137,42, 81,139,135,123,107,124,135,85, 101,65,99,90,94,85,106,115, 139,139,64,101,103,134,95,143, + 70,126,127,75,75,101,140,147, 87,164,107,104,165,99,81,128, 127,71,73,92,129,93,149,99, 116,117,63,116,99,109,92,116, + 76,80,61,56,75,111,73,103, 101,107,139,145,119,80,146,97, 80,85,92,153,99,90,106,97, 63,145,46,83,77,87,100,104, + 146,115,124,137,168,42,104,127, 143,56,58,87,91,127,81,104, 84,80,65,78,61,37,98,132, 153,100,149,107,103,115,86,77, + 130,158,89,75,83,106,85,85, 154,103,67,119,146,96,127,133, 57,111,108,142,164,78,117,83, 96,129,56,73,114,66,45,67, + 144,99,131,129,98,141,102,131, 94,130,123,75,85,40,91,109, 73,161,102,81,53,102,161,124, 69,88,72,127,111,144,48,90, + + 63,71,74,140,135,125,89,112, 80,139,117,97,84,70,104,105, 134,91,113,99,91,128,126,100, 80,119,115,145,82,39,81,166, + 114,92,92,84,94,122,49,104, 105,137,124,110,127,85,72,101, 21,83,117,52,78,79,102,69, 159,137,104,143,160,134,95,104, + 121,128,79,153,100,154,100,103, 107,108,78,130,91,172,136,158, 103,65,53,145,51,100,86,107, 108,103,136,103,149,108,105,77, + 79,64,42,108,78,77,129,65, 55,77,109,88,67,93,68,52, 53,94,114,121,109,121,106,60, 146,113,83,116,96,136,58,100, + 84,132,50,139,86,86,148,141, 107,91,140,68,130,131,107,42, 102,135,166,160,54,62,91,126, 79,136,52,161,124,123,100,71, + 70,99,52,78,44,116,54,121, 67,112,82,59,164,83,92,133, 108,81,120,156,91,84,129,131, 107,110,139,91,122,128,82,92, + 118,77,72,119,66,133,131,40, 125,123,54,65,72,159,54,65, 84,86,68,142,68,101,155,79, 102,155,56,134,117,163,131,155, + 66,82,99,78,48,100,154,96, 81,163,89,132,131,155,126,110, 54,98,82,94,51,152,112,120, 138,77,149,127,74,99,109,80, +}; + +static const uint8 ced_hires_5[1024] = { + 128,127,124,128,128,147,138,139, 162,124,125,126,127,127,152,184, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + 59,56,52,84,74,62,105,50, 75,46,54,59,89,56,113,130, 119,132,110,115,136,127,123,76, 85,121,121,94,112,104,106,128, + 126,117,109,74,77,123,124,119, 122,105,96,86,86,78,87,79, 94,169,180,158,166,149,129,116, 113,117,109,100,100,85,105,128, + 59,98,77,92,84,100,75,88, 93,94,54,78,89,98,98,106, 103,65,103,95,118,105,93,113, 76,102,66,54,135,52,60,128, + 114,126,138,119,130,83,102,112, 141,139,142,144,138,118,52,132, 48,39,161,146,26,1,0,0, 0,6,0,43,34,8,25,128, + 137,140,115,130,111,132,114,131, 105,143,147,144,140,142,33,132, 35,41,72,166,126,73,105,0, 0,0,0,53,3,50,23,128, + 112,128,104,79,120,147,178,100, 105,85,90,74,80,77,120,87, 130,112,180,83,120,100,91,85, 85,95,84,102,99,90,92,128, + 162,138,147,153,157,142,131,128, 132,128,118,111,103,136,145,120, 140,154,95,87,111,106,97,91, 91,101,86,97,105,96,98,128, + + 96,79,91,123,95,99,109,128, 124,80,77,74,81,79,85,86, 101,94,91,83,107,102,93,87, 87,97,91,93,101,92,94,128, + 130,76,66,68,64,65,77,111, 81,61,51,63,45,76,57,136, 63,56,53,46,77,64,62,49, 49,59,123,97,63,54,56,128, + 86,86,81,86,91,131,96,85, 96,81,82,79,84,117,90,91, 106,99,96,88,112,107,98,92, 95,102,87,98,113,97,99,128, + 114,112,109,114,116,119,125,113, 127,111,110,121,112,112,118,119, 128,127,124,116,128,128,126,120, 120,128,115,126,140,125,127,128, + 103,101,98,103,105,118,105,102, 113,98,99,96,101,101,107,108, 147,116,113,105,128,124,115,109, 109,119,104,115,136,114,116,128, + 121,119,116,121,123,142,128,128, 128,116,117,114,119,119,125,126, 128,128,128,123,128,128,128,127, 127,128,122,128,128,128,128,128, + 118,116,113,118,120,127,150,122, 139,118,114,111,116,116,122,123, 128,128,128,120,128,128,128,124, 124,128,119,128,128,128,128,128, + 127,118,115,120,139,136,123,124, 134,127,116,113,118,118,124,125, 128,128,128,122,128,128,128,126, 126,128,121,128,128,128,128,128, + + 144,113,79,134,119,150,168,110, 109,123,87,135,164,70,123,153, 60,128,94,93,119,96,90,82, 80,91,52,120,157,65,95,128, + 152,77,95,138,152,63,122,108, 72,111,161,80,53,163,71,71, 154,47,85,88,86,124,118,33, 115,126,72,98,91,95,82,128, + 128,146,140,137,59,123,98,75, 133,154,41,39,133,67,133,64, 115,98,30,37,84,76,58,26, 78,73,153,84,82,120,63,128, + 106,93,89,71,142,126,122,109, 127,113,101,74,47,71,102,125, 99,87,54,87,115,144,165,81, 99,49,47,81,86,139,114,128, + 95,47,91,59,105,149,149,123, 89,57,69,124,88,133,119,156, 141,64,149,165,107,86,69,108, 135,57,146,122,119,128,82,128, + 44,75,63,157,128,38,92,158, 41,77,129,36,81,96,88,54, 44,93,58,46,115,99,80,131, 96,65,76,87,70,72,83,128, + 165,111,57,90,104,46,83,56, 72,75,68,75,96,118,139,55, 81,118,70,56,99,104,83,106, 143,142,105,139,81,83,155,128, + 86,127,119,93,103,124,116,150, 118,69,88,93,98,72,109,119, 122,130,119,64,126,86,111,57, 87,131,74,125,103,69,156,128, + + 98,68,93,126,62,132,161,123, 149,72,93,84,65,65,112,144, 101,154,60,90,129,83,167,144, 140,140,113,105,164,79,61,128, + 112,113,139,157,96,91,153,68, 106,113,83,60,100,103,74,71, 111,102,68,110,41,73,115,67, 93,107,158,143,83,149,120,128, + 95,117,116,117,99,81,87,114, 115,118,121,91,142,90,110,101, 82,114,128,148,135,125,105,70, 80,91,110,89,129,99,140,128, + 85,169,69,133,73,49,110,60, 96,123,99,77,114,72,157,121, 140,133,145,94,106,142,90,139, 96,154,153,76,95,136,38,128, + 144,125,98,54,162,77,113,95, 108,88,42,67,143,69,97,30, 68,71,136,64,127,135,138,72, 107,115,59,137,148,97,158,128, + 122,156,149,122,108,71,79,147, 128,144,38,68,131,98,99,121, 164,143,123,52,140,126,130,91, 154,67,95,124,146,43,91,128, + 124,62,79,123,127,91,91,135, 121,69,95,76,76,128,74,47, 52,71,100,47,105,141,145,88, 123,140,106,86,152,110,91,128, + 123,121,138,108,94,76,62,115, 57,128,70,49,149,129,153,78, 71,120,117,115,74,80,143,95, 64,35,73,80,92,79,49,128, +}; + +static const uint8 ced_hires_6[1024] = { + 131,89,116,77,83,97,102,136, 133,105,111,105,87,87,87,105, 108,118,117,124,140,105,110,104, 68,96,93,87,81,101,115,102, + 17,136,152,147,132,68,100,48, 56,48,81,53,20,72,87,102, 143,155,79,74,108,84,137,154, 76,94,89,93,83,102,92,87, + 66,79,73,41,49,115,104,62, 46,89,89,70,100,49,89,121, 91,76,85,75,125,76,65,130, 119,156,144,96,123,158,156,118, + 20,106,67,42,24,96,44,57, 144,132,70,77,156,109,89,83, 121,135,126,114,134,111,112,128, 91,109,152,125,78,102,101,136, + 43,96,88,68,104,16,25,125, 72,107,35,59,22,13,0,14, 89,145,128,73,85,131,89,165, 108,108,98,155,106,124,167,120, + 128,81,99,82,73,82,85,63, 69,94,110,62,46,48,43,56, 155,167,150,139,160,127,125,138, 97,126,85,77,73,94,89,89, + 67,136,152,100,83,91,124,114, 106,89,92,124,146,131,103,110, 120,137,118,86,122,92,116,123, 90,103,95,79,104,103,104,97, + 122,74,119,104,124,104,96,98, 90,118,93,81,76,100,118,130, 143,123,120,167,152,126,138,151, 125,120,83,101,102,118,116,108, + + 79,88,103,83,60,34,70,38, 92,77,94,49,116,95,82,88, 43,144,139,131,133,98,98,121, 86,94,95,101,96,80,109,97, + 88,98,105,102,82,110,51,104, 115,100,128,93,119,80,46,69, 110,117,74,90,120,121,93,128, 119,85,83,79,94,103,104,110, + 89,75,115,84,121,92,114,102, 122,90,122,128,106,108,84,118, 107,133,113,126,141,123,115,158, 103,135,99,112,107,138,121,141, + 94,79,115,97,115,104,113,108, 122,102,110,119,95,109,90,121, 119,127,118,122,154,126,117,158, 112,137,104,112,113,135,125,129, + 121,83,109,77,84,83,62,98, 104,84,113,116,93,81,73,85, 118,113,99,96,123,96,108,131, 95,111,79,75,101,113,113,103, + 140,66,86,79,79,90,80,94, 100,88,90,93,77,79,74,87, 118,152,103,106,142,108,110,143, 111,131,122,106,115,147,126,135, + 166,67,85,78,78,89,79,93, 99,87,89,92,76,78,73,86, 130,127,102,124,155,105,121,151, 123,149,123,109,120,162,148,136, + 154,75,95,88,88,99,89,103, 109,97,99,102,86,88,83,96, 149,130,112,108,140,112,120,145, 114,125,119,102,115,145,139,135, + + 31,150,134,141,48,120,36,27, 151,116,122,82,89,136,91,28, 119,68,44,150,145,40,107,55, 36,92,23,66,46,41,24,59, + 41,45,12,0,141,58,83,30, 9,9,61,106,0,45,9,16, 14,23,66,152,39,5,42,56, 144,155,123,64,151,84,75,33, + 107,62,98,81,89,126,87,70, 167,111,120,112,104,100,108,129, 72,124,176,74,96,72,84,77, 115,63,29,72,108,97,111,154, + 85,144,123,65,80,95,99,66, 65,55,176,121,104,135,27,146, 62,44,158,114,101,106,105,126, 60,80,72,160,55,126,113,101, + 36,0,87,20,72,44,8,0, 67,127,87,121,10,84,77,51, 34,21,68,32,57,64,38,24, 9,14,132,0,17,87,36,41, + 67,104,95,43,73,154,82,100, 126,72,76,68,26,71,58,32, 24,45,36,21,55,166,135,135, 134,126,7,36,81,101,84,170, + 75,82,59,49,43,129,38,169, 67,116,63,94,69,64,52,101, 133,117,129,120,66,52,28,69, 66,82,50,119,104,83,74,71, + 47,131,113,126,57,142,116,109, 99,107,76,126,9,6,123,152, 96,136,103,126,142,67,90,109, 102,148,97,101,76,87,83,95, + + 49,8,75,129,53,138,158,150, 98,83,101,27,3,66,159,125, 128,114,158,134,119,126,153,139, 137,128,35,126,84,61,108,84, + 34,0,18,21,24,22,93,33, 38,1,18,168,88,79,156,105, 149,47,24,56,50,69,76,64, 20,102,71,68,46,62,48,58, + 30,53,84,128,83,135,48,120, 32,36,94,29,44,92,100,149, 138,79,46,24,153,61,30,49, 158,143,56,138,115,118,110,93, + 74,93,20,31,73,44,42,111, 52,105,68,74,46,43,29,66, 45,67,37,7,76,88,82,101, 52,70,30,45,51,78,66,100, + 54,32,43,64,72,117,82,71, 69,29,37,29,4,167,126,75, 26,161,51,143,53,30,104,121, 74,79,144,27,157,129,153,117, + 55,53,53,87,24,19,80,75, 68,63,40,42,111,20,59,68, 72,114,50,26,138,29,70,86, 43,51,156,34,99,130,66,103, + 53,0,46,31,71,79,87,57, 59,51,34,39,24,0,25,66, 1,47,140,45,144,92,34,50, 90,75,50,2,24,40,147,114, + 63,150,105,113,95,108,52,72, 62,157,153,73,141,125,32,38, 104,104,25,64,137,147,31,105, 16,139,27,46,1,90,101,23, +}; + +static const uint8 ced_hires_7[1024] = { + 120,127,110,107,125,119,124,105, 127,128,122,128,102,123,102,99, 129,154,113,122,107,119,106,109, 116,98,104,108,120,117,116,111, + 91,83,50,46,97,86,122,78, 99,143,61,80,78,80,62,52, 17,15,56,62,51,91,64,93, 138,118,150,133,136,119,114,121, + 173,162,166,159,148,141,205,123, 204,166,143,146,120,144,133,153, 134,173,138,140,103,106,108,117, 108,108,71,103,148,151,114,164, + 86,147,121,122,141,130,130,109, 132,142,124,133,108,143,112,113, 130,102,125,146,122,120,113,107, 113,92,86,127,123,136,75,107, + 137,141,85,124,139,117,115,121, 96,81,80,124,153,77,61,54, 173,171,86,199,83,61,48,51, 58,40,46,50,62,59,58,53, + 145,149,144,119,151,127,147,125, 167,161,116,130,99,120,128,128, 128,103,131,112,106,147,108,130, 151,83,89,93,105,102,101,96, + 129,134,99,103,101,147,132,118, 111,96,87,94,100,88,67,64, 93,74,78,87,72,84,86,74, 81,63,69,73,85,82,81,76, + 125,123,130,99,124,109,144,109, 111,115,106,113,93,107,93,83, 92,101,134,122,117,122,132,121, 100,122,88,92,104,101,112,95, + + 117,129,112,84,103,101,127,90, 87,91,82,100,75,179,112,185, 110,132,107,115,106,185,103,103, 136,103,135,134,129,86,137,125, + 139,147,101,95,125,132,138,134, 114,118,109,116,89,113,94,123, 98,96,100,109,94,106,93,96, 103,85,91,95,107,104,103,98, + 159,165,129,148,166,141,172,150, 179,163,171,181,122,149,165,145, 138,128,145,149,124,146,132,127, 143,122,121,133,144,135,162,148, + 171,165,133,151,163,146,162,148, 172,168,156,165,126,154,137,132, 143,140,143,155,135,156,140,142, 142,127,130,137,149,145,153,146, + 132,133,96,93,127,105,110,92, 113,117,108,115,88,109,88,85, 94,169,171,176,140,166,165,125, 134,143,158,156,158,166,150,158, + 169,154,126,147,134,128,175,148, 138,128,128,128,118,128,118,115, 124,125,128,128,123,128,122,125, 128,114,120,124,128,128,128,127, + 160,159,125,129,155,136,156,153, 149,128,128,128,117,128,117,114, 123,124,128,128,122,128,121,124, 128,113,119,123,128,128,128,126, + 168,147,128,128,128,139,128,143, 141,128,128,128,127,128,127,124, 128,128,128,128,128,128,128,128, 128,123,128,128,128,128,128,128, + + 26,71,23,0,18,145,93,129, 88,129,0,160,78,145,20,29, 21,64,41,28,155,90,68,73, 46,65,128,9,130,142,83,131, + 59,84,81,102,49,55,8,132, 69,48,0,80,0,123,0,36, 37,33,0,62,129,121,64,162, 123,122,0,154,69,160,143,89, + 155,85,24,119,133,127,86,100, 126,180,98,119,16,37,81,98, 82,71,113,46,31,50,30,33, 70,148,98,135,141,102,162,99, + 94,74,90,98,122,40,42,20, 72,125,152,93,42,97,112,5, 103,130,75,82,21,65,120,149, 107,58,80,48,61,150,41,63, + 118,82,161,115,70,0,55,0, 13,151,100,56,59,0,25,151, 102,102,94,0,133,95,68,98, 35,166,95,80,163,108,138,85, + 47,27,46,3,18,108,113,138, 156,140,109,142,22,49,123,83, 98,107,78,74,32,109,58,60, 83,0,109,0,1,0,105,55, + 71,49,44,31,49,30,38,141, 120,37,96,114,14,14,14,21, 22,111,109,31,70,103,7,100, 17,109,62,65,72,49,18,128, + 40,154,151,137,126,105,104,61, 119,144,127,42,0,0,164,141, 135,126,95,119,107,112,29,0, 0,0,99,11,15,13,9,0, + + 108,133,116,95,53,149,107,100, 56,66,115,79,15,100,65,0, 1,0,7,140,111,132,101,0, 95,4,92,92,46,22,161,72, + 58,38,113,14,88,36,11,97, 67,63,27,39,143,108,133,82, 135,0,52,60,72,93,90,149, 109,147,143,103,45,159,148,153, + 132,115,1,88,45,51,72,56, 44,62,5,83,23,28,153,121, 167,37,147,101,0,82,26,76, 97,99,17,1,1,0,40,86, + 83,46,30,15,41,21,26,83, 78,66,41,84,84,78,0,41, 50,103,63,122,73,69,0,61, 48,0,97,105,70,96,62,90, + 85,84,93,6,54,125,46,123, 102,62,7,71,96,44,54,0, 54,4,166,155,31,144,107,0, 87,55,65,143,79,47,0,5, + 163,95,121,171,161,163,63,142, 100,152,141,64,95,125,105,56, 0,89,99,83,64,43,95,89, 83,50,23,0,68,0,0,76, + 92,65,42,71,88,88,176,120, 171,105,154,154,18,44,54,106, 112,92,134,139,0,134,133,130, 116,101,84,51,64,46,90,155, + 152,122,117,113,19,86,30,51, 85,122,99,90,18,146,45,102, 58,13,43,75,104,119,101,0, 77,0,0,0,146,0,119,0, +}; + +static const uint8 ced_hires_8[1024] = { + 130,127,155,168,146,193,173,178, 138,176,189,169,199,152,146,172, 128,127,128,122,128,128,109,122, 115,128,126,128,120,128,128,128, + 142,160,113,159,112,138,145,87, 133,125,100,110,109,101,70,134, 52,81,111,42,63,48,9,22, 34,44,34,64,45,60,106,128, + 98,91,146,105,104,134,59,53, 74,82,71,49,70,51,52,76, 77,69,81,64,94,79,51,64, 57,75,68,77,62,74,106,128, + 90,132,91,134,101,123,97,99, 109,125,92,97,124,114,109,140, 123,84,137,120,149,126,95,134, 90,124,96,82,140,78,116,128, + 68,69,88,133,99,128,124,111, 101,105,137,125,134,111,84,138, 137,75,81,64,111,89,60,64, 57,75,68,77,62,215,110,128, + 111,181,158,179,148,178,161,155, 155,149,184,172,200,153,139,187, 156,138,159,137,153,154,108,115, 129,118,111,120,105,117,128,128, + 91,101,111,146,104,81,82,70, 84,86,94,72,93,74,75,99, 100,92,104,87,117,102,74,87, 80,98,91,100,85,97,128,128, + 137,111,137,155,136,166,170,156, 138,140,168,155,174,149,139,169, 119,111,123,106,128,121,93,106, 99,117,110,119,104,116,128,128, + + 127,121,128,160,166,147,149,173, 185,181,184,160,174,149,143,166, 164,138,146,126,151,136,178,115, 117,182,167,95,80,92,124,128, + 113,114,134,159,120,170,172,178, 160,151,180,174,185,158,134,167, 122,114,126,109,128,124,181,188, 193,130,119,145,158,155,152,128, + 155,164,146,164,148,177,155,147, 159,166,174,167,174,147,135,174, 105,97,186,168,122,107,79,92, 85,103,96,105,90,102,128,128, + 161,164,146,176,146,180,170,159, 156,165,177,172,179,155,145,171, 111,103,162,180,176,113,104,98, 91,109,102,111,96,108,128,128, + 187,159,158,190,172,180,181,159, 155,156,183,160,177,165,170,171, 148,172,125,108,128,141,95,108, 101,119,112,121,126,118,128,128, + 128,128,120,133,128,128,128,121, 128,128,128,123,128,125,126,128, 128,128,128,128,128,128,125,128, 166,128,128,128,131,128,128,128, + 128,128,119,128,128,128,128,122, 129,131,128,122,128,124,125,128, 128,128,128,128,128,128,124,128, 128,128,128,128,128,128,128,128, + 128,128,128,154,128,128,133,128, 142,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128, + + 20,141,64,92,31,78,151,53, 145,20,53,48,65,154,102,114, 93,115,27,0,49,93,58,115, 144,65,153,88,149,88,17,128, + 84,40,161,60,108,42,125,33, 139,68,83,54,43,81,132,82, 69,84,108,0,122,85,6,2, 53,70,102,0,36,34,41,128, + 100,104,66,145,69,110,103,89, 76,65,98,98,84,63,121,133, 106,95,152,44,168,45,122,127, 129,38,117,149,53,137,128,128, + 134,104,149,56,114,62,74,104, 71,45,50,137,132,122,110,44, 112,56,54,136,150,128,59,0, 0,81,103,3,0,0,33,128, + 81,17,22,151,126,101,49,126, 22,36,76,149,81,76,40,83, 64,111,53,68,65,145,96,0, 110,0,87,0,39,98,99,128, + 104,20,78,59,26,158,114,116, 105,158,62,77,97,99,149,60, 158,104,111,51,111,77,41,70, 35,124,61,140,87,83,139,128, + 89,103,71,128,99,85,122,108, 62,50,67,61,120,64,44,79, 43,9,107,179,176,163,107,154, 141,87,110,163,2,37,115,128, + 0,162,20,49,20,47,97,121, 95,83,96,88,115,58,47,97, 61,11,73,19,29,17,0,0, 0,148,82,94,111,89,40,128, + + 120,92,69,58,56,38,49,120, 38,153,95,56,69,140,92,44, 157,155,88,91,145,0,89,50, 109,97,0,66,0,18,97,128, + 114,13,57,120,93,77,153,77, 152,135,99,80,88,24,69,60, 107,53,43,2,13,0,131,78, 141,49,121,0,119,153,135,128, + 0,4,6,55,124,56,65,29, 21,40,149,41,100,137,17,39, 3,163,111,111,140,0,52,59, 72,113,76,118,116,81,92,128, + 47,32,26,62,0,51,45,166, 142,38,168,49,140,20,96,145, 124,74,90,169,73,151,143,89, 64,116,26,75,20,162,143,128, + 0,0,91,31,9,39,39,26, 90,29,42,35,53,27,112,56, 58,67,4,76,79,51,153,115, 122,50,137,120,19,114,123,128, + 78,120,61,100,65,59,85,52, 72,57,93,54,61,10,72,78, 56,75,77,0,33,34,43,38, 0,0,14,44,0,44,24,128, + 151,95,67,85,59,72,70,135, 53,60,105,54,54,25,160,139, 142,61,116,126,90,1,104,159, 139,115,141,100,41,62,100,128, + 0,0,16,46,152,103,55,43, 56,47,60,148,157,92,133,148, 0,0,158,50,138,103,111,67, 150,157,47,12,78,21,146,128, +}; + +static const uint8 ced_hires_9[1024] = { + 130,71,129,141,137,60,133,127, 113,78,80,127,94,127,117,51, 103,62,119,129,148,68,133,101, 38,42,158,125,112,190,163,124, + 139,45,127,155,132,105,145,125, 136,78,127,128,145,136,141,61, 122,142,128,129,137,97,140,143, 1,3,145,120,131,129,135,62, + 124,125,104,88,80,128,69,72, 68,127,36,103,135,92,101,131, 77,126,132,112,51,143,88,87, 94,151,72,95,120,110,80,161, + 81,123,101,98,60,133,79,54, 52,155,28,125,46,72,67,101, 90,70,86,76,45,128,37,119, 86,129,81,86,102,49,41,88, + 96,132,92,99,114,136,90,108, 121,130,15,114,132,93,122,129, 135,112,129,111,82,133,131,124, 119,129,105,108,112,39,105,147, + 115,68,124,132,149,103,109,139, 127,72,144,126,137,143,146,76, 122,99,138,142,133,69,134,126, 32,11,131,145,107,148,126,61, + 77,126,72,78,49,124,127,85, 75,135,43,82,121,79,83,143, 74,43,129,98,111,130,44,45, 87,106,101,92,138,51,52,89, + 95,126,67,51,135,116,72,112, 51,131,24,106,133,97,111,143, 71,33,136,82,68,135,62,78, 22,49,63,84,114,36,104,82, + + 46,129,63,71,69,93,73,121, 119,140,58,72,114,107,136,142, 96,57,126,112,97,126,48,117, 55,54,76,101,134,53,81,140, + 139,93,114,144,122,123,128,130, 146,120,146,137,129,138,134,101, 109,151,120,136,133,78,129,131, 0,6,154,131,126,122,151,58, + 103,57,111,129,142,74,122,99, 101,56,40,136,131,124,138,107, 93,87,91,150,153,48,74,96, 29,52,125,155,90,119,156,95, + 71,137,72,129,58,106,76,87, 65,135,10,79,127,82,98,139, 95,29,127,121,126,138,126,104, 58,30,84,95,111,27,55,91, + 148,128,84,57,100,136,84,113, 74,138,28,114,116,81,111,129, 86,138,17,107,80,134,130,64, 160,116,80,94,104,93,101,84, + 76,131,112,98,55,135,114,120, 76,132,40,106,110,135,121,131, 146,114,77,99,59,136,66,90, 106,140,89,78,129,75,105,92, + 119,136,75,128,125,129,141,113, 81,139,14,124,57,64,124,132, 74,124,75,119,117,122,73,70, 119,145,101,93,142,120,105,136, + 111,62,156,130,141,107,139,152, 124,103,148,125,129,141,131,71, 138,116,130,137,129,82,139,148, 0,0,125,133,142,126,134,55, + + 72,116,48,77,48,122,93,65, 57,115,22,108,127,51,83,142, 87,100,151,86,87,131,39,43, 86,113,70,90,98,53,85,72, + 149,20,138,146,143,112,62,118, 158,65,125,130,127,150,129,33, 114,116,113,124,140,58,141,141, 24,20,165,129,84,163,122,98, + 106,140,115,104,111,132,132,124, 123,125,23,112,87,134,120,128, 118,121,93,124,114,141,143,116, 117,135,106,137,107,90,103,86, + 104,114,115,105,103,116,131,80, 117,119,30,147,132,120,108,122, 147,136,106,132,147,127,81,123, 134,114,71,127,123,66,120,147, + 106,131,95,77,65,135,100,63, 69,133,8,113,86,81,116,133, 74,114,131,122,67,128,53,135, 151,132,60,61,111,92,110,88, + 161,88,152,116,143,105,115,146, 136,61,114,137,128,126,120,44, 151,90,132,138,125,54,155,126, 8,28,138,144,121,160,160,75, + 87,124,98,82,154,145,88,92, 46,138,32,132,81,107,138,90, 81,34,84,103,27,129,104,81, 109,61,73,49,116,47,121,91, + 72,136,72,95,97,132,49,95, 111,125,35,117,129,103,124,133, 112,95,117,134,95,115,67,97, 102,148,126,135,108,97,99,123, + + 165,12,134,132,98,115,126,113, 92,122,36,138,34,110,157,63, 107,139,40,148,113,22,79,71, 31,22,127,133,78,127,95,90, + 38,12,112,64,133,138,43,108, 175,16,168,125,147,148,91,8, 100,54,87,106,121,17,106,130, 17,47,101,161,65,95,131,83, + 119,144,110,98,143,110,64,120, 43,121,32,102,111,138,133,123, 86,119,120,80,52,126,109,143, 98,130,90,84,85,38,91,148, + 95,124,58,99,38,144,76,50, 77,139,32,143,125,91,120,110, 106,28,108,77,132,126,36,92, 136,57,38,62,101,62,40,90, + 47,23,65,73,87,20,162,94, 103,127,100,162,133,118,116,37, 117,60,94,98,151,51,49,98, 24,20,116,121,117,51,42,90, + 54,123,33,45,31,151,56,33, 42,145,36,29,25,35,119,81, 32,43,48,22,12,118,44,43, 149,32,38,50,76,65,37,95, + 46,130,41,34,22,145,59,49, 59,134,20,125,111,79,130,70, 69,37,81,47,140,127,73,75, 123,43,61,147,80,46,72,78, + 115,32,81,74,58,149,102,67, 71,46,65,60,49,57,61,30, 68,174,54,51,45,52,72,53, 57,53,71,79,105,84,67,123, +}; + +static const uint8 ced_hires_10[1024] = { + 58,122,143,128,136,100,142,138, 75,129,136,141,139,140,49,124, 126,129,133,99,142,134,152,137, 120,138,45,14,25,143,136,140, + 125,108,87,90,85,127,88,79, 128,11,95,136,93,104,132,81, 132,106,62,140,86,72,90,83, 121,114,149,146,89,121,124,118, + 133,75,100,96,92,129,79,127, 127,44,117,130,100,119,132,110, 114,131,93,115,52,110,92,107, 134,108,137,144,103,119,70,100, + 129,70,93,99,140,110,67,56, 133,40,103,132,85,100,142,72, 134,84,77,132,70,53,62,94, 79,31,106,60,43,131,68,32, + 132,100,125,106,118,135,136,106, 130,30,113,134,97,123,128,124, 125,111,84,130,80,106,89,109, 111,56,133,127,111,123,95,111, + 67,126,128,140,149,99,132,133, 69,144,128,139,143,147,68,121, 136,137,133,67,119,131,136,128, 136,149,79,10,23,96,114,96, + 125,102,73,98,152,143,106,80, 137,19,128,84,119,136,89,83, 74,107,89,132,74,58,81,126, 52,49,110,73,108,116,88,42, + 142,113,137,119,142,109,104,86, 122,38,105,107,137,130,124,108, 116,84,69,126,79,79,97,100, 101,51,133,133,97,103,115,109, + + 96,116,125,136,124,122,129,150, 119,148,137,131,138,134,97,111, 120,136,131,74,132,148,147,147, 126,125,57,11,16,101,139,150, + 64,113,99,105,134,74,84,122, 61,63,130,131,122,139,112,93, 90,147,154,53,127,109,126,145, 147,109,83,59,31,99,68,83, + 137,90,110,94,59,103,126,88, 132,21,84,127,93,105,137,97, 124,122,120,138,85,68,128,65, 88,44,132,42,58,106,79,34, + 124,85,81,119,108,133,128,91, 138,36,114,116,86,113,128,87, 26,102,87,132,98,77,76,98, 95,93,108,117,161,118,149,141, + 131,125,92,102,68,135,80,85, 131,41,104,110,136,120,132,145, 74,100,62,135,119,73,95,106, 84,72,119,134,102,130,74,113, + 136,71,72,117,124,128,73,106, 138,23,122,64,52,124,130,76, 75,120,120,120,127,85,126,105, 103,120,93,146,119,110,119,124, + 59,156,145,150,141,110,137,123, 104,147,127,129,138,125,77,138, 130,135,130,87,148,123,129,136, 129,131,48,15,26,124,110,114, + 115,51,73,57,54,120,36,57, 115,11,101,125,70,76,140,93, 150,94,84,126,85,49,83,103, 85,56,128,111,78,103,71,102, + + 137,112,116,124,112,131,132,116, 126,33,113,86,134,122,127,115, 94,124,117,137,127,116,110,91, 128,86,117,135,114,119,99,120, + 116,104,122,83,102,118,81,68, 114,12,145,131,124,108,121,145, 103,127,145,127,115,112,108,119, 140,58,140,108,123,116,98,134, + 131,98,133,63,58,136,35,61, 131,29,113,81,78,117,131,74, 128,121,76,127,101,71,79,105, 70,83,126,131,150,127,103,111, + 95,145,124,149,145,102,158,144, 73,115,137,128,126,118,39,154, 127,136,124,85,112,136,102,157, 149,155,63,39,21,131,157,85, + 121,75,41,91,52,123,59,122, 133,55,87,113,80,75,144,80, 121,95,110,126,123,72,70,79, 101,39,94,99,84,136,68,51, + 127,76,124,126,75,95,60,87, 130,36,76,111,110,138,142,109, 125,113,92,127,77,120,87,88, 92,44,116,59,67,146,52,55, + 124,94,127,65,59,135,31,83, 154,42,119,47,70,56,99,85, 70,79,69,127,80,57,107,42, 77,38,108,135,113,116,94,95, + 134,58,90,56,42,142,76,51, 134,21,125,102,78,135,80,81, 78,60,137,122,61,53,43,84, 147,45,82,70,120,107,56,52, + + 125,58,101,70,50,142,31,51, 142,44,142,128,93,121,116,115, 115,88,119,127,79,67,100,81, 78,68,109,74,131,115,109,34, + 128,20,41,24,44,151,46,58, 143,31,53,37,38,115,104,35, 49,13,50,110,40,29,34,32, 52,77,75,38,140,67,53,62, + 30,102,98,113,102,138,130,139, 39,47,119,112,103,104,37,128, 128,103,110,33,80,102,106,125, 86,137,98,43,38,91,95,175, + 21,105,132,102,123,141,110,109, 31,168,125,139,150,92,18,94, 86,105,122,38,63,172,77,132, 155,93,48,68,35,60,65,79, + 28,139,76,117,98,118,79,120, 117,45,140,50,110,154,88,110, 45,147,116,36,127,99,132,98, 137,124,54,34,56,82,164,143, + 35,74,103,109,98,33,86,125, 55,113,149,141,121,121,50,122, 113,105,152,60,154,113,84,61, 128,49,72,16,20,144,58,61, + 82,126,110,148,135,61,143,155, 65,78,116,108,135,109,46,91, 122,125,145,67,103,116,124,162, 127,185,84,36,46,110,131,52, + 42,137,146,121,136,110,144,167, 67,120,128,125,146,130,34,118, 111,122,138,47,72,152,133,119, 127,160,56,29,36,97,143,120, +}; + +static const uint8 ced_hires_11[1024] = { + 129,46,102,93,87,61,93,55, 96,48,77,76,65,67,91,46, 64,58,113,75,57,62,82,91, 106,70,112,123,68,70,75,108, + 113,55,138,144,134,87,155,40, 138,123,135,133,127,142,137,53, 147,126,126,136,132,133,154,124, 123,43,142,128,28,86,28,104, + 122,134,145,124,106,123,46,119, 48,128,47,146,45,45,47,127, 41,140,89,43,38,100,46,40, 62,104,61,104,126,110,126,124, + 91,125,26,136,96,129,23,115, 19,144,133,118,113,115,63,132, 59,137,94,51,29,117,36,127, 39,136,46,74,118,107,102,110, + 89,128,72,40,74,135,21,135, 34,144,57,55,66,55,51,129, 53,127,93,50,32,126,63,29, 37,128,44,72,113,117,128,118, + 77,69,127,126,130,77,123,31, 130,136,133,130,123,130,153,82, 138,132,127,134,127,137,125,128, 123,115,114,116,75,59,43,117, + 113,116,62,47,39,142,82,137, 41,119,39,88,88,58,47,136, 28,38,72,11,27,108,35,44, 65,155,73,100,130,105,132,111, + 93,34,108,139,100,55,67,50, 146,50,129,131,153,145,111,31, 105,138,137,151,137,51,116,127, 146,30,74,76,15,37,10,59, + + 98,133,33,28,17,143,30,136, 41,115,34,100,131,73,38,123, 12,134,69,24,4,134,39,29, 52,118,53,81,110,140,124,88, + 82,128,133,117,145,106,126,85, 134,68,159,123,131,130,125,127, 111,117,130,146,125,44,111,141, 127,118,87,70,96,9,66,50, + 92,145,86,40,68,123,37,120, 71,114,90,126,74,74,28,128, 73,120,89,54,119,118,68,72, 51,112,35,63,137,116,114,104, + 98,123,104,91,72,135,54,139, 112,130,98,141,114,67,63,136, 86,42,87,61,112,117,101,58, 106,134,41,69,123,123,123,117, + 85,137,150,37,54,142,42,126, 36,124,60,30,130,98,12,132, 135,24,89,53,49,98,125,57, 119,105,38,66,134,116,118,107, + 98,141,79,89,141,133,98,129, 133,130,72,83,48,92,48,131, 38,31,95,107,139,113,59,69, 40,143,37,65,112,132,107,111, + 112,118,69,50,46,149,49,152, 39,130,45,42,40,30,66,118, 54,26,75,14,107,112,49,54, 65,116,73,100,115,143,78,91, + 91,69,145,144,140,88,104,98, 127,131,122,136,136,132,115,76, 134,134,127,139,121,152,149,142, 144,83,166,167,31,77,39,99, + + 82,130,53,59,64,129,54,110, 44,118,48,133,87,91,27,140, 84,148,91,51,122,101,61,86, 50,134,46,84,126,106,112,112, + 84,135,121,143,124,127,87,121, 113,142,112,75,123,109,90,133, 90,98,88,84,123,123,125,129, 92,141,44,70,118,108,114,104, + 134,108,127,101,121,121,98,125, 121,115,125,94,128,88,98,112, 124,82,126,112,130,134,126,138, 101,122,105,119,92,85,86,126, + 77,117,116,48,78,138,27,142, 122,120,126,63,134,48,25,112, 112,39,86,120,154,143,120,143, 28,123,36,63,109,110,108,101, + 71,131,58,45,30,128,122,146, 62,130,49,95,90,25,18,143, 48,127,97,99,74,119,33,43, 22,146,30,57,118,112,106,106, + 95,104,131,129,128,72,131,81, 132,75,120,142,143,138,133,92, 155,132,138,149,139,63,128,144, 160,88,119,81,75,7,47,66, + 102,128,48,47,57,119,70,107, 140,130,80,106,65,90,32,136, 116,123,82,61,117,132,66,43, 55,154,61,89,127,128,105,122, + 110,129,58,13,38,138,30,112, 136,126,30,98,89,135,39,126, 55,147,70,32,117,122,68,87, 58,145,57,84,130,114,103,117, + + 118,115,58,40,45,141,61,156, 51,109,30,30,37,33,59,110, 34,25,81,42,99,147,71,54, 97,128,88,115,120,107,128,103, + 102,62,107,133,115,63,64,42, 135,82,88,103,135,156,108,60, 147,137,139,149,144,30,125,110, 68,80,128,101,53,14,38,71, + 127,100,145,84,145,70,134,37, 72,39,175,114,120,112,75,120, 76,99,111,119,117,48,91,106, 110,125,102,128,84,56,63,90, + 129,77,130,151,138,88,126,88, 117,82,96,136,127,108,124,80, 155,101,115,124,94,99,175,159, 129,107,129,129,106,107,112,114, + 98,9,84,76,73,44,76,33, 73,22,61,73,76,66,62,27, 84,63,137,71,74,28,80,84, 106,47,83,88,29,18,15,66, + 102,23,80,68,70,48,77,40, 82,24,57,72,77,67,80,46, 70,66,135,70,62,10,75,87, 108,64,76,91,16,23,22,74, + 105,19,61,52,70,26,63,47, 80,27,40,55,73,79,73,33, 71,69,127,73,72,12,72,69, 65,55,77,93,18,43,34,72, + 104,44,77,65,69,48,79,52, 74,47,58,58,60,52,78,46, 61,55,123,55,55,61,74,74, 89,67,93,106,71,67,69,73, +}; + +static const uint8 ced_hires_12[1024] = { + 79,129,118,114,118,130,135,136, 122,129,124,105,133,117,122,111, 134,119,65,123,122,86,117,114, 121,123,136,124,126,111,73,121, + 134,116,126,128,129,122,119,131, 131,128,98,130,123,67,131,120, 126,125,137,42,120,129,124,126, 132,124,121,124,126,120,89,121, + 112,133,109,133,111,132,130,71, 99,133,71,58,135,135,120,135, 124,96,123,110,95,72,54,65, 130,119,105,127,127,103,105,127, + 118,122,128,106,129,130,78,100, 80,135,92,115,113,114,117,119, 117,117,148,147,127,77,100,118, 129,121,108,127,127,101,91,127, + 135,132,136,125,118,124,139,134, 122,120,34,135,116,109,141,104, 122,131,129,5,132,82,135,130, 120,130,119,128,123,119,103,118, + 126,133,130,135,119,105,128,126, 122,109,135,125,129,124,128,144, 130,124,127,128,125,138,129,123, 129,123,141,114,116,100,75,111, + 126,110,99,100,152,132,105,74, 73,128,77,140,108,97,135,114, 115,76,102,86,74,55,93,128, 128,65,82,127,127,109,97,127, + 83,137,114,142,118,131,144,118, 104,132,68,106,127,101,119,118, 124,123,62,94,123,122,117,132, 123,130,118,127,145,96,99,127, + + 115,129,121,73,117,134,107,125, 107,139,57,129,133,75,111,122, 115,108,124,112,115,65,89,120, 136,89,100,127,127,107,91,162, + 116,124,116,129,125,122,126,120, 126,115,136,128,123,153,120,132, 126,124,119,124,121,125,124,127, 124,129,124,115,117,98,87,112, + 110,93,120,88,101,100,92,100, 101,103,193,110,109,83,98,97, 81,85,93,129,84,120,83,96, 93,94,86,127,127,127,127,127, + 130,129,102,125,118,128,139,116, 89,126,144,112,143,114,130,139, 137,125,99,129,122,105,77,70, 122,122,127,127,144,123,84,127, + 140,124,123,126,138,124,114,136, 125,129,136,130,115,106,135,110, 119,120,124,115,130,112,127,128, 111,122,116,121,123,113,80,118, + 109,106,107,107,110,111,111,99, 109,127,112,107,106,162,102,138, 105,111,114,99,121,103,86,90, 93,107,100,127,127,170,152,127, + 129,122,126,129,130,127,131,138, 125,126,108,134,116,77,116,126, 127,138,131,43,123,110,137,129, 121,138,123,121,123,110,70,118, + 108,114,111,100,106,124,104,100, 108,110,114,106,106,96,119,162, 90,141,96,108,93,105,112,107, 100,92,93,127,127,144,144,127, + + 119,102,134,125,132,132,111,116, 139,135,118,123,93,104,109,107, 109,137,126,109,126,113,120,127, 111,127,122,127,127,96,84,127, + 108,121,133,121,111,125,73,107, 148,128,119,114,117,108,124,100, 119,106,116,170,155,38,84,144, 123,58,113,127,127,105,99,154, + 57,128,109,135,124,126,134,42, 110,124,72,117,140,133,125,114, 124,133,85,97,99,143,140,113, 129,122,120,127,127,99,87,127, + 93,88,77,107,97,101,91,104, 98,96,155,103,106,69,77,79, 81,137,97,206,81,184,134,112, 92,116,64,127,127,127,127,127, + 118,85,115,94,120,133,99,119, 127,125,107,92,120,53,74,109, 133,143,137,92,89,114,118,130, 145,133,124,127,127,100,88,127, + 93,97,96,121,91,124,100,109, 94,125,112,118,104,82,100,96, 123,97,112,138,108,200,107,142, 135,117,94,127,127,127,127,127, + 130,129,119,115,125,130,53,116, 116,133,51,40,120,97,122,101, 108,62,141,108,137,124,103,105, 138,40,104,127,127,109,97,127, + 111,131,74,122,129,132,85,105, 144,128,63,62,121,83,101,114, 133,139,115,123,125,105,139,99, 136,139,110,127,127,106,92,127, + + 132,119,131,119,128,131,116,120, 132,131,135,136,87,90,112,113, 116,132,115,124,125,154,127,132, 94,130,122,127,127,108,106,127, + 127,129,109,98,125,122,112,115, 115,128,120,126,142,114,126,103, 132,96,127,105,124,69,102,122, 128,103,120,127,127,98,112,127, + 121,120,145,97,119,126,115,132, 89,127,134,127,112,113,133,129, 130,102,128,127,135,64,118,140, 138,124,104,127,127,129,118,127, + 127,127,127,127,127,122,127,127, 127,122,127,127,127,127,127,127, 127,127,127,127,127,127,127,127, 127,127,127,127,127,127,127,127, + 127,127,127,127,127,118,127,127, 127,118,127,127,127,127,127,127, 145,127,127,127,127,127,127,127, 127,127,127,127,127,127,127,127, + 121,124,104,109,109,81,110,97, 104,77,120,119,111,92,119,106, 100,107,107,127,117,127,112,104, 89,124,89,127,127,197,184,127, + 115,99,101,103,110,78,92,110, 84,142,93,113,91,65,122,79, 105,120,109,104,120,113,97,90, 86,115,97,127,127,182,217,127, + 127,127,127,127,127,122,127,127, 127,124,127,127,127,127,127,127, 127,127,127,127,127,127,127,127, 127,127,127,127,127,127,127,127, +}; + +static const uint8 ced_hires_13[1024] = { + 79,36,84,88,70,26,101,101, 57,93,76,44,82,95,88,77, 79,102,93,112,76,86,62,31, 126,102,50,102,97,110,99,131, + 52,43,113,117,112,51,119,123, 107,86,124,118,123,119,119,49, 114,113,112,125,118,105,132,18, 125,60,129,75,77,71,51,90, + 99,65,124,123,98,65,96,121, 107,100,76,93,112,140,131,73, 92,127,90,86,132,109,81,54, 57,124,94,100,98,115,106,112, + 81,31,42,63,61,107,26,43, 32,76,44,28,57,75,56,165, 61,40,75,79,77,82,47,21, 39,68,76,80,81,88,78,107, + 53,55,83,115,118,88,124,129, 135,116,109,113,126,117,121,71, 103,69,120,116,124,140,113,25, 116,121,78,69,55,61,52,95, + 75,63,96,27,126,105,92,121, 78,64,55,123,122,101,117,34, 107,33,121,105,112,47,100,18, 60,36,113,61,64,87,64,99, + 70,75,100,78,116,77,119,135, 81,90,103,129,128,106,113,57, 91,57,132,124,117,87,117,49, 60,46,37,98,75,96,77,107, + 104,148,95,50,41,136,45,51, 72,150,86,83,112,103,30,141, 59,39,43,55,90,129,56,44, 57,84,26,104,80,110,75,126, + + 72,54,96,117,102,69,79,123, 44,79,60,58,105,135,103,47, 69,152,129,129,112,72,124,24, 118,59,89,72,68,75,69,97, + 49,104,110,125,122,126,125,119, 116,94,112,92,115,120,104,110, 129,129,113,124,117,103,117,22, 126,38,90,48,80,82,62,97, + 76,70,64,110,64,64,46,62, 48,63,80,67,84,137,129,30, 93,115,59,121,142,110,109,61, 115,61,70,84,90,95,95,95, + 100,63,73,65,82,99,97,66, 73,125,80,83,138,86,127,52, 78,109,102,98,105,78,103,62, 112,76,108,111,109,108,113,111, + 111,114,86,93,91,76,81,78, 85,82,114,98,92,112,111,94, 98,94,75,90,95,93,90,72, 91,82,103,151,113,118,141,119, + 49,138,104,130,121,72,113,92, 114,38,101,119,105,122,105,109, 107,112,87,116,119,68,115,8, 83,24,113,61,68,71,56,94, + 114,52,76,101,85,55,85,54, 85,94,75,85,117,114,135,41, 81,88,76,85,140,64,70,51, 76,101,82,105,98,101,102,103, + 114,111,126,117,134,117,113,90, 68,92,84,110,117,110,122,91, 91,164,90,122,124,100,108,120, 102,94,88,118,111,108,113,111, + + 101,137,103,32,71,95,111,96, 97,145,123,85,103,96,79,61, 52,54,86,108,68,157,102,41, 69,71,61,101,99,107,96,119, + 73,150,20,28,25,114,26,26, 37,112,46,33,31,22,13,156, 23,49,1,30,13,101,28,20, 32,47,30,71,90,77,68,96, + 105,79,95,84,96,64,96,113, 63,97,73,68,104,114,113,65, 121,104,111,119,80,88,85,63, 121,61,65,125,108,129,103,127, + 42,53,109,91,120,40,90,107, 68,92,130,92,111,108,134,29, 112,80,111,94,96,54,105,150, 132,48,101,55,61,61,49,94, + 106,68,93,88,93,69,69,61, 73,98,117,78,128,133,126,94, 114,78,82,97,141,98,102,65, 75,66,104,102,89,122,99,112, + 107,83,114,50,97,149,84,90, 128,149,119,100,113,91,105,79, 132,52,98,96,108,142,94,37, 91,66,96,111,86,94,85,107, + 46,66,107,104,113,66,126,117, 117,92,123,126,115,109,116,65, 119,42,129,113,104,53,118,79, 78,127,128,50,61,72,51,99, + 121,71,63,62,64,61,69,65, 74,70,74,66,65,54,63,58, 71,84,44,54,50,87,74,66, 113,81,60,152,130,138,134,138, + + 84,83,129,39,123,95,106,128, 82,84,142,138,113,108,107,57, 118,38,127,106,107,90,120,60, 59,142,45,75,98,85,68,107, + 105,90,94,88,71,76,71,67, 72,101,88,64,81,91,95,66, 85,76,67,85,79,82,82,58, 109,96,81,127,113,121,114,123, + 73,100,141,107,128,71,80,84, 100,85,121,103,123,126,115,69, 119,72,94,128,109,59,112,26, 83,59,116,115,83,89,73,94, + 104,73,90,91,87,88,89,78, 90,76,102,101,111,102,89,43, 82,81,118,96,146,75,100,50, 87,96,96,113,113,106,109,114, + 66,58,131,124,106,86,118,114, 132,74,68,119,117,117,117,35, 102,36,125,106,106,24,98,35, 71,128,128,81,81,80,47,96, + 73,41,118,138,109,28,78,48, 115,45,110,113,95,133,88,35, 121,38,106,109,103,103,117,18, 44,86,119,71,77,86,76,105, + 94,137,71,54,52,142,72,61, 72,154,145,98,92,97,38,93, 58,58,95,69,85,132,127,42, 91,123,55,108,102,106,97,140, + 113,65,76,58,62,92,85,62, 80,69,57,64,67,66,51,59, 80,72,50,69,62,68,58,73, 71,60,58,101,115,108,109,118, +}; + +static const uint8 ced_hires_14[1024] = { + 127,73,147,96,119,88,105,109, 120,113,103,118,88,140,101,79, 110,127,68,112,151,94,90,83, 125,83,125,127,127,127,127,127, + 88,49,130,116,118,52,139,140, 125,89,134,128,134,134,134,59, 124,140,131,139,131,105,148,19, 145,52,137,100,89,91,77,99, + 131,71,141,122,104,66,116,138, 125,103,87,103,122,155,146,83, 102,154,109,100,144,109,97,55, 77,116,102,118,110,122,130,121, + 134,25,93,100,106,94,68,101, 54,113,93,18,111,141,103,68, 142,68,136,117,127,146,99,18, 62,18,121,110,88,106,105,109, + 87,60,100,113,123,88,143,145, 153,119,119,122,136,131,136,80, 113,95,138,130,136,140,128,26, 136,113,85,93,67,79,77,103, + 127,99,154,57,97,71,91,93, 125,69,89,116,117,76,110,81, 149,113,85,77,84,90,75,68, 110,72,120,127,127,120,127,123, + 107,127,106,67,34,132,96,32, 46,138,56,96,38,110,100,88, 74,63,26,39,49,130,29,120, 45,34,49,93,90,113,96,118, + 140,153,112,49,46,136,65,67, 90,152,96,92,122,118,45,150, 69,64,61,68,102,129,71,44, 77,75,33,128,92,127,99,134, + + 74,133,89,64,55,143,71,52, 72,150,122,145,125,84,137,124, 106,53,105,97,125,131,90,27, 24,49,71,72,81,88,67,109, + 83,109,127,124,128,126,144,135, 134,97,122,101,125,134,119,119, 139,155,131,138,129,102,132,22, 146,29,97,71,91,102,87,105, + 88,4,133,137,142,3,28,140, 12,31,52,141,80,31,31,20, 149,46,21,114,133,20,2,90, 69,0,136,73,62,95,79,102, + 126,68,90,64,87,99,117,82, 91,127,90,92,147,101,142,60, 88,136,120,111,116,77,118,62, 130,67,116,128,121,114,137,119, + 79,15,89,109,132,0,34,27, 136,25,159,134,135,122,132,40, 105,35,121,133,141,23,146,2, 28,0,125,76,68,108,72,91, + 84,143,121,128,126,72,133,108, 132,41,111,128,115,136,120,118, 117,138,105,130,131,68,130,9, 103,16,120,86,80,91,80,101, + 144,57,93,100,91,55,105,70, 103,96,85,94,127,129,150,50, 91,114,94,98,152,63,85,51, 96,92,89,120,109,108,123,111, + 121,154,45,60,63,64,68,39, 59,85,56,120,31,120,40,125, 43,86,21,83,136,120,56,36, 80,36,43,124,106,113,123,115, + + 121,150,74,14,27,151,56,36, 50,150,69,55,34,102,58,106, 39,82,28,56,34,160,40,31, 75,45,39,131,101,109,119,112, + 104,54,77,132,55,34,31,18, 17,42,46,106,0,82,44,80, 36,49,0,155,40,40,6,33, 43,19,25,91,101,99,89,114, + 112,141,38,57,37,72,43,25, 101,67,64,150,25,96,40,152, 26,69,15,132,116,149,27,18, 62,32,26,112,97,105,106,108, + 78,60,127,91,126,42,111,125, 87,96,141,103,122,124,150,40, 122,106,129,108,108,54,120,151, 152,40,108,78,73,81,74,102, + 140,74,110,87,99,70,89,78, 91,102,128,88,139,149,142,104, 123,104,100,110,153,97,117,66, 94,57,111,124,100,129,123,119, + 112,104,136,78,126,105,142,117, 127,127,143,142,137,115,105,119, 116,69,120,135,123,76,130,29, 62,18,144,114,88,105,106,108, + 82,72,125,103,119,67,146,134, 136,96,134,136,126,124,132,75, 129,68,147,127,116,53,133,80, 97,119,135,74,72,91,76,106, + 131,76,81,61,69,61,88,82, 92,73,84,76,75,69,78,66, 81,110,61,67,61,85,87,66, 132,71,67,154,139,145,139,146, + + 84,133,98,52,42,158,37,23, 89,160,53,107,63,86,87,104, 70,38,30,103,87,98,78,0, 32,26,51,80,58,80,75,91, + 95,14,130,98,109,14,63,29, 116,13,156,109,122,149,89,39, 70,49,106,128,105,19,149,25, 43,4,137,91,82,95,86,110, + 109,107,159,107,134,73,101,102, 119,89,132,114,134,142,131,80, 129,98,112,142,121,59,127,27, 103,51,123,138,94,108,99,102, + 123,108,129,80,86,116,133,102, 135,85,156,146,124,112,121,59, 80,90,122,135,124,64,156,40, 93,40,143,127,110,116,125,119, + 102,64,148,123,112,87,139,131, 152,77,79,129,128,132,133,45, 111,62,143,119,118,22,113,35, 90,119,135,104,92,99,72,104, + 109,48,136,138,115,29,99,66, 134,49,121,124,106,149,104,46, 131,63,124,123,115,103,132,19, 63,78,126,96,88,105,101,112, + 117,136,38,70,20,133,49,30, 43,174,47,36,24,27,9,70, 34,75,10,15,28,140,32,25, 69,25,32,117,95,106,112,109, + 136,54,77,34,51,77,76,61, 86,49,60,57,54,66,64,51, 69,93,44,77,50,54,57,55, 81,42,72,112,121,115,118,126, +}; + +static const uint8 ced_hires_15[1024] = { + 128,67,142,105,122,81,101,108, 115,105,99,113,90,139,98,75, 108,127,69,108,148,90,86,94, 122,79,127,128,128,128,128,128, + 69,43,125,125,121,45,135,139, 120,81,130,123,135,133,130,54, 122,137,129,135,128,100,144,30, 140,48,139,91,84,84,66,98, + 115,65,136,131,106,59,112,137, 120,95,82,98,123,154,142,78, 100,151,107,96,141,104,93,66, 72,112,103,112,105,119,121,120, + 117,20,88,109,109,87,64,100, 48,105,89,13,112,140,99,63, 140,65,134,113,124,141,95,29, 57,14,123,101,83,100,94,108, + 68,54,95,122,126,81,139,144, 148,111,115,117,137,130,132,75, 111,92,136,126,133,135,124,37, 131,109,87,85,62,73,66,102, + 128,93,149,66,99,65,86,92, 121,64,84,111,119,76,106,76, 146,112,85,74,81,85,71,79, 108,70,121,126,126,117,128,122, + 88,121,101,75,36,126,91,31, 42,131,51,91,40,109,96,83, 71,59,25,36,46,125,25,131, 41,30,50,84,85,105,85,117, + 121,147,107,57,49,130,60,66, 85,145,91,87,124,117,41,145, 66,61,60,65,99,124,67,55, 72,71,35,119,87,122,89,133, + + 57,127,84,73,58,136,67,51, 67,142,118,140,126,83,133,119, 104,49,103,93,122,126,86,38, 19,45,73,63,77,81,56,108, + 65,103,122,132,130,120,140,134, 129,89,118,96,126,133,115,114, 137,152,130,134,126,97,128,34, 141,25,99,63,86,95,76,104, + 69,0,128,145,144,0,23,138, 6,23,47,135,81,30,27,14, 146,42,19,110,129,14,0,100, 64,0,137,63,57,87,67,101, + 115,62,85,72,89,93,112,81, 86,120,86,87,149,100,138,56, 85,132,119,108,113,72,114,73, 126,63,117,122,116,111,127,118, + 60,9,84,117,134,0,29,27, 131,18,154,129,137,121,128,35, 102,31,120,130,138,19,142,14, 24,0,126,67,63,101,61,91, + 65,137,116,137,129,65,129,107, 127,33,107,123,116,135,116,113, 115,135,103,126,128,63,126,20, 98,12,122,77,75,84,70,100, + 130,51,88,108,93,49,100,69, 98,89,80,89,129,128,146,44, 88,110,92,95,149,58,81,63, 91,88,91,114,104,105,116,110, + 111,148,40,69,66,57,65,38, 55,77,52,115,34,119,36,120, 41,83,19,79,133,115,53,47, 75,32,45,118,101,111,112,114, + + 109,144,70,22,29,145,51,35, 45,143,64,50,37,101,54,101, 36,78,28,54,31,155,37,42, 71,41,40,124,96,106,108,111, + 84,47,72,141,57,27,25,15, 12,34,40,100,1,81,40,74, 33,45,0,151,36,34,1,42, 38,14,26,81,95,91,77,113, + 96,135,34,65,40,66,38,23, 96,60,59,145,27,95,36,147, 23,65,15,129,113,144,24,29, 58,28,27,104,92,101,95,107, + 59,54,122,100,129,35,107,124, 82,88,137,98,123,123,146,35, 120,103,127,104,105,49,116,162, 147,36,110,70,68,74,63,101, + 123,67,105,95,101,63,84,76, 86,94,123,82,140,147,138,98, 120,100,98,106,149,91,112,76, 89,52,112,117,95,126,112,118, + 96,98,131,86,128,99,137,116, 122,120,138,137,139,114,101,114, 113,65,119,132,120,71,126,41, 58,14,145,105,83,101,95,107, + 63,66,120,112,122,60,142,133, 131,88,130,131,127,123,128,70, 127,65,145,123,113,48,129,91, 92,115,137,65,68,84,65,105, + 132,70,76,69,72,54,84,81, 87,66,80,71,77,68,74,62, 78,106,61,63,58,81,84,77, 127,67,68,155,136,142,140,145, + + 65,127,93,61,45,151,33,22, 84,152,49,102,64,85,83,99, 68,35,28,99,84,93,74,2, 27,22,53,71,53,74,64,90, + 76,8,125,107,112,8,59,28, 111,6,152,104,123,148,85,34, 68,46,104,124,102,13,145,36, 38,2,139,82,77,88,75,110, + 90,101,154,116,137,66,97,101, 114,81,128,109,135,141,127,75, 127,95,110,138,118,54,123,38, 98,47,125,130,89,101,88,102, + 117,102,124,88,89,109,129,101, 130,77,152,141,125,111,117,55, 79,87,120,131,121,58,152,51, 90,36,145,122,105,113,116,118, + 83,58,143,132,115,81,134,130, 147,70,74,124,129,131,129,40, 109,59,141,116,115,18,109,46, 85,115,137,95,87,92,61,103, + 90,42,131,147,118,23,95,65, 129,41,117,119,107,148,100,41, 129,60,122,119,112,98,128,30, 59,74,128,87,83,99,90,112, + 102,130,34,79,23,126,45,29, 38,166,43,32,26,27,5,65, 30,72,8,11,24,135,28,36, 64,21,34,108,90,103,101,108, + 121,48,73,42,53,70,71,61, 81,41,56,52,55,65,60,46, 67,89,42,73,48,49,53,67, 76,38,74,106,116,112,115,125, +}; + +static const uint8 ced_hires_16[1024] = { + 126,77,94,99,85,77,105,111, 93,98,106,78,81,99,92,92, 100,116,99,119,82,86,89,94, 132,90,87,127,125,126,126,131, + 97,47,126,130,125,63,130,137, 117,95,136,122,124,126,123,57, 128,120,120,134,123,99,146,65, 132,56,132,97,96,97,97,110, + 143,93,132,131,106,93,114,132, 110,112,123,95,107,141,130,103, 112,132,92,86,131,103,106,111, 132,107,103,143,142,143,143,130, + 128,105,112,105,109,106,116,109, 113,112,120,113,104,107,99,110, 114,124,100,102,105,111,112,115, 125,111,116,128,128,128,128,128, + 97,58,96,127,131,95,134,142, 146,126,121,116,127,123,126,86, 117,87,128,126,128,135,126,65, 123,114,81,98,96,97,97,110, + 157,107,120,109,115,107,128,115, 124,121,137,109,95,107,86,117, 126,146,89,100,96,117,120,125, 146,116,117,157,156,157,157,139, + 157,107,120,109,115,107,128,115, 124,121,137,109,95,107,86,117, 126,146,89,100,96,117,120,125, 146,116,117,157,156,157,157,139, + 120,155,109,72,78,142,91,78, 87,159,100,85,112,108,49,156, 89,109,52,63,93,123,83,88, 109,79,80,120,119,120,120,118, + + 119,70,107,128,115,75,90,135, 86,88,99,71,105,140,107,80, 93,159,136,138,115,79,136,87, 118,78,88,120,118,119,119,118, + 92,112,123,137,135,133,135,132, 127,104,124,95,116,126,108,126, 143,137,121,134,121,97,130,60, 133,51,92,93,91,92,92,106, + 130,80,93,121,88,80,101,88, 97,94,110,82,83,142,131,90, 104,119,62,128,144,100,121,98, 119,89,90,130,129,130,130,123, + 148,98,111,100,106,98,119,106, 115,127,128,100,131,98,124,108, 117,137,102,96,97,108,111,116, 137,107,108,148,147,148,148,135, + 149,100,112,101,108,100,120,107, 116,113,129,101,88,99,99,110, 118,139,82,93,88,109,112,117, 138,108,110,150,148,149,149,139, + 98,145,117,142,133,78,123,105, 125,62,112,122,105,128,109,124, 120,119,94,125,123,58,128,66, 97,57,115,98,97,98,98,112, + 145,96,108,110,104,96,116,103, 112,109,125,97,110,112,132,106, 114,135,78,89,137,105,108,113, 134,104,106,146,144,145,145,132, + 153,111,124,118,134,108,124,111, 120,117,133,105,101,103,113,113, 122,159,85,115,115,113,116,121, 142,112,113,153,152,153,153,136, + + 128,112,119,112,116,113,123,116, 120,119,127,120,111,114,106,117, 120,128,106,108,111,117,118,121, 128,117,122,128,128,128,128,128, + 120,158,83,72,78,121,91,78, 87,121,100,72,58,70,49,172, 88,108,51,62,58,95,82,87, 108,78,79,119,118,119,119,122, + 146,96,109,98,104,96,117,120, 113,110,126,98,94,116,108,106, 130,134,109,118,84,105,108,113, 134,104,105,145,144,145,145,137, + 98,58,122,104,132,48,101,121, 75,101,142,96,111,115,138,58, 126,86,118,103,100,57,118,161, 139,56,102,97,96,97,97,111, + 139,89,102,96,102,89,110,97, 106,103,124,91,124,135,126,104, 122,127,80,99,141,98,106,106, 127,97,98,138,137,138,138,129, + 155,105,128,107,113,105,126,113, 122,119,135,107,93,105,84,115, 133,143,86,97,93,114,117,122, 143,113,114,154,153,154,154,139, + 99,72,121,117,126,72,137,131, 129,103,136,130,116,116,121,79, 134,87,137,123,109,58,132,89, 87,121,131,98,97,98,98,111, + 154,104,117,106,112,104,125,112, 121,118,134,106,92,104,83,114, 122,142,85,96,92,113,116,121, 142,112,113,153,152,153,153,139, + + 156,106,119,108,114,106,127,114, 123,120,136,108,94,106,85,116, 124,144,87,98,94,115,118,123, 144,114,115,155,154,155,155,140, + 150,101,113,102,109,101,121,108, 117,114,130,102,89,100,80,111, 118,139,82,93,88,109,112,117, 138,108,110,150,148,149,149,140, + 118,107,154,120,140,68,89,96, 111,92,132,106,123,133,119,78, 133,106,101,137,113,77,125,85, 106,76,118,122,116,117,117,121, + 149,99,112,101,107,99,120,107, 116,113,129,101,102,99,83,109, 117,137,115,96,139,108,111,116, 137,107,108,148,147,148,148,135, + 102,62,144,137,119,94,129,128, 144,82,82,123,118,124,122,62, 116,90,133,116,111,61,112,69, 90,121,131,101,100,101,101,110, + 156,106,119,108,114,106,127,114, 123,120,136,108,94,106,85,116, 124,144,87,98,94,115,118,123, 144,114,115,155,154,155,155,140, + 156,106,119,108,114,106,127,114, 123,120,136,108,94,106,85,116, 124,144,87,98,94,115,118,123, 144,114,115,155,154,155,155,140, + 137,88,100,89,96,96,108,95, 104,101,117,89,76,87,67,98, 105,126,69,80,75,96,99,104, 125,95,97,137,135,136,136,123, +}; + +static const uint8 ced_hires_17[1024] = { + 89,91,92,133,130,37,125,74, 42,95,144,140,137,137,121,42, 123,75,132,124,133,87,128,83, 74,53,119,94,87,91,93,108, + 102,61,121,126,115,65,141,137, 130,96,110,126,137,135,142,73, 128,143,129,129,127,116,147,95, 154,82,141,107,100,103,106,114, + 152,89,132,131,102,84,114,134, 128,107,81,104,125,155,153,95, 103,154,108,87,139,120,95,146, 137,146,100,157,150,154,156,136, + 130,66,62,72,62,122,86,62, 83,84,58,60,65,91,78,190, 73,115,92,83,85,91,68,123, 115,94,83,135,128,131,134,127, + 103,75,93,124,121,103,146,143, 159,127,96,121,140,133,145,96, 118,98,137,121,133,153,128,96, 146,146,90,108,101,104,107,114, + 111,83,105,33,129,120,114,135, 102,75,39,131,136,117,141,54, 122,96,138,110,121,62,115,104, 96,75,125,116,109,112,115,120, + 131,94,108,84,119,91,141,148, 104,99,90,137,142,121,136,74, 104,117,149,128,125,99,131,125, 116,95,74,136,129,133,135,128, + 109,71,69,85,106,85,106,131, 62,57,93,110,101,126,73,52, 116,94,127,130,102,60,143,102, 94,73,52,114,107,118,113,119, + + 100,147,79,74,50,157,72,48, 76,157,98,143,128,85,145,139, 110,85,103,87,121,143,89,93, 85,84,74,105,98,101,104,112, + 97,124,119,134,125,141,147,132, 139,104,99,100,129,135,127,134, 143,159,130,128,125,115,131,91, 155,61,101,102,95,99,101,109, + 101,37,124,147,139,33,57,137, 54,39,29,139,83,34,39,44, 153,86,16,104,129,52,39,151, 86,65,140,106,99,102,105,116, + 159,95,91,81,81,113,115,91, 112,133,87,89,150,97,149,102, 102,144,118,100,111,110,113,152, 144,123,117,164,157,160,163,142, + 86,23,75,47,132,18,43,105, 39,54,141,105,128,124,110,29, 89,72,105,147,131,38,115,80, 71,50,78,91,84,88,90,107, + 103,158,113,138,124,86,135,105, 137,41,88,127,119,137,128,133, 120,142,104,120,127,81,129,97, 111,67,124,108,101,105,107,116, + 156,93,94,108,84,88,113,88, 109,99,85,92,130,128,156,99, 99,142,88,85,147,108,94,150, 141,120,99,161,154,158,160,138, + 98,50,162,115,131,30,54,149, 51,46,135,121,106,128,119,41, 135,83,109,116,138,49,147,91, 83,62,136,103,96,99,102,111, + + 160,171,92,82,82,172,116,92, 113,164,88,90,85,109,82,129, 97,139,69,66,71,175,92,147, 139,118,97,159,152,155,158,137, + 129,176,77,84,94,159,85,102, 82,160,57,105,70,85,71,176, 89,108,48,73,73,173,81,116, 108,87,76,128,121,124,127,122, + 180,139,119,109,109,119,143,119, 140,135,125,117,112,120,109,130, 124,166,112,93,98,160,119,174, 166,145,124,180,179,177,180,152, + 156,139,88,78,116,166,138,88, 109,177,94,86,81,89,111,115, 93,135,95,88,77,162,98,171, 135,114,93,155,148,151,154,133, + 156,92,106,103,101,88,112,88, 114,119,110,91,149,156,157,125, 129,135,101,102,152,114,117,143, 135,114,116,155,148,151,154,133, + 152,109,131,74,109,171,109,112, 159,167,115,117,135,115,136,115, 148,132,118,103,119,157,112,140, 131,110,109,151,144,148,150,134, + 112,94,124,121,124,90,156,139, 149,111,118,142,137,133,148,98, 137,91,149,121,116,67,136,145, 107,155,143,111,104,107,110,113, + 180,119,115,104,105,114,139,114, 135,120,111,113,108,115,104,125, 119,162,92,88,93,128,114,170, 161,140,119,178,174,174,178,149, + + 128,111,146,50,134,118,137,150, 112,103,137,155,135,132,138,87, 135,108,147,113,118,105,137,126, 107,169,65,127,120,124,126,122, + 109,46,52,31,32,41,66,41, 62,47,127,60,65,52,41,52, 46,89,19,130,30,55,41,97, 88,67,66,108,101,105,107,132, + 131,129,158,124,139,93,111,106, 131,102,116,120,145,150,146,102, 136,111,114,135,120,77,129,119, 110,89,130,146,123,127,129,123, + 171,107,103,101,93,108,127,103, 124,109,99,114,130,122,116,114, 108,150,135,102,155,116,111,158, 150,129,108,170,163,166,169,141, + 115,87,147,141,117,109,149,136, 164,92,64,135,139,141,148,71, 119,94,145,113,118,60,116,102, 99,155,143,114,107,110,113,112, + 180,125,121,120,111,120,145,120, 141,126,117,119,130,121,126,131, 125,168,98,94,99,134,120,176, 167,146,125,180,179,177,180,152, + 108,45,99,103,139,40,96,117, 61,87,85,145,139,127,138,51, 127,88,152,133,136,64,131,96, 87,66,135,107,100,104,106,112, + 157,94,95,80,80,109,114,90, 119,96,86,88,83,91,80,101, 95,137,67,64,69,103,90,145, 137,116,95,154,150,150,154,125, +}; + +static const uint8 ced_hires_18[1024] = { + 100,47,105,106,88,37,119,122, 76,90,99,47,87,103,100,98, 95,121,106,126,89,84,80,50, 146,101,49,119,100,126,121,130, + 74,55,134,135,131,65,138,145, 126,83,147,122,129,128,131,71, 130,133,126,138,131,103,151,36, 145,59,129,97,84,83,73,90, + 123,78,145,142,117,80,115,143, 127,97,99,98,117,149,143,95, 108,146,104,100,145,107,101,72, 83,123,94,119,107,123,126,111, + 102,42,63,81,78,121,44,64, 50,73,66,32,62,84,68,187, 77,62,89,92,89,80,66,40, 63,66,76,102,89,103,100,106, + 72,67,105,133,136,102,142,150, 155,114,132,117,131,125,133,93, 119,88,133,130,137,139,132,46, 137,120,78,89,64,76,73,94, + 94,75,117,44,144,118,110,142, 98,61,78,127,127,109,129,55, 123,48,134,119,125,45,118,38, 80,35,112,83,72,101,83,96, + 95,87,122,95,134,91,137,156, 101,88,126,133,133,114,125,79, 107,76,145,138,130,85,136,69, 79,46,38,117,85,112,100,104, + 124,160,116,69,60,150,64,73, 92,147,109,87,118,112,42,163, 75,62,57,68,103,128,75,63, 80,83,28,120,89,124,96,125, + + 94,66,118,135,120,83,97,144, 63,76,82,62,110,143,115,69, 85,171,142,143,125,71,143,43, 138,58,89,97,78,95,93,94, + 67,116,131,143,140,140,143,140, 136,91,135,96,120,128,115,131, 145,148,127,138,130,101,135,42, 146,37,89,70,86,94,79,96, + 101,82,86,128,82,78,65,84, 68,60,103,72,89,145,141,49, 109,135,73,134,155,108,128,81, 135,61,70,108,97,107,117,96, + 123,75,94,83,100,113,116,87, 92,122,102,87,143,94,139,71, 93,129,116,111,117,75,121,80, 131,72,108,126,118,118,133,111, + 125,126,107,111,110,90,98,100, 104,78,136,102,98,121,122,116, 113,113,88,103,108,91,109,90, 113,82,103,166,118,129,154,121, + 71,150,125,148,139,85,131,113, 134,35,124,123,110,130,117,130, 123,131,100,130,132,66,133,26, 103,24,112,82,78,81,75,92, + 134,66,98,119,103,70,104,77, 104,91,98,89,123,122,146,64, 97,108,89,98,153,65,88,72, 98,100,82,121,109,113,126,105, + 134,123,148,135,153,131,131,112, 86,89,109,114,122,118,134,113, 106,183,104,135,137,97,127,140, 120,93,88,129,122,120,132,113, + + 95,138,100,94,128,146,84,59, 64,158,26,72,140,108,64,96, 48,37,129,66,66,162,79,20, 36,60,93,75,70,90,70,98, + 95,163,41,47,45,129,41,47, 56,110,67,38,37,31,25,179, 45,69,19,50,32,105,52,43, 62,51,33,101,100,101,98,98, + 122,92,117,103,114,78,115,136, 82,95,96,73,110,123,125,87, 143,128,130,139,99,92,109,87, 147,65,68,148,119,143,129,127, + 68,66,131,110,138,55,109,130, 88,90,153,97,117,117,146,52, 134,105,130,114,115,58,129,176, 158,53,106,82,71,82,78,96, + 129,80,114,106,112,83,88,82, 92,96,140,82,134,142,139,116, 135,103,101,116,160,101,127,91, 102,70,110,124,105,134,125,113, + 123,95,135,69,116,163,102,112, 149,147,143,105,119,100,118,101, 153,80,118,115,127,146,119,62, 116,70,102,133,102,113,117,109, + 70,78,129,122,132,80,145,139, 137,90,147,130,121,118,129,87, 141,67,148,133,123,58,143,105, 104,132,134,80,74,95,79,100, + 136,82,86,79,83,76,90,87, 92,67,102,69,70,65,74,80, 92,115,66,71,68,91,96,94, 140,85,71,156,136,150,142,140, + + 104,96,151,58,141,110,125,150, 102,82,165,143,118,117,119,80, 140,61,146,125,125,94,144,85, 85,147,50,100,110,107,95,109, + 122,103,115,106,89,90,88,87, 92,99,110,70,86,100,108,86, 107,107,86,104,98,85,106,87, 134,101,84,138,122,134,133,128, + 93,113,163,126,146,86,99,107, 120,83,144,108,129,135,127,92, 141,96,113,148,128,63,136,50, 109,64,121,140,95,106,100,97, + 128,86,112,109,106,102,108,101, 111,75,126,105,117,111,101,66, 104,108,137,116,165,81,125,82, 114,102,102,129,126,121,134,116, + 89,71,152,143,125,101,137,136, 153,72,92,124,123,126,129,57, 123,62,145,126,125,29,123,61, 97,133,134,107,94,103,79,98, + 99,71,108,117,119,66,122,99, 108,25,83,132,126,131,130,88, 120,83,124,123,119,71,105,40, 88,140,139,89,119,109,90,120, + 109,146,119,71,82,143,99,110, 107,147,49,135,131,127,53,105, 80,80,69,92,140,135,125,42, 60,114,37,69,92,91,80,109, + 129,78,95,77,81,106,104,83, 99,66,82,66,73,73,63,80, 101,97,69,88,80,74,80,98, 98,65,64,114,130,119,121,120, +}; + +static const uint8 ced_hires_19[1024] = { + 98,93,104,135,134,69,120,71, 84,99,150,144,141,141,121,77, 123,96,135,127,139,85,130,83, 94,88,120,97,97,97,97,113, + 110,85,134,128,119,81,138,142, 127,104,115,130,141,138,142,90, 128,119,133,131,132,117,148,95, 129,101,142,109,109,109,109,119, + 145,120,126,112,107,116,133,123, 131,123,115,115,110,142,136,124, 123,143,99,95,128,132,120,130, 141,135,125,144,144,144,144,134, + 134,109,115,93,96,120,122,107, 120,112,104,104,99,106,91,186, 112,132,88,84,92,121,109,119, 130,124,114,133,133,133,133,130, + 111,86,102,124,125,107,142,148, 156,131,104,126,144,136,144,90, 119,109,140,123,138,153,129,96, 122,136,91,110,110,110,110,118, + 118,93,119,78,133,123,107,139, 104,97,88,134,139,118,140,98, 122,117,141,111,125,105,113,103, 114,109,123,117,117,117,117,124, + 135,110,116,95,117,106,124,148, 121,114,105,136,141,117,132,115, 114,134,148,125,126,122,125,120, 131,126,115,134,134,134,134,130, + 117,92,98,86,109,98,105,136, 103,95,97,112,105,129,74,96, 110,115,130,131,106,104,144,102, 113,107,97,116,116,116,116,123, + + 108,150,89,67,70,160,96,81, 94,161,103,147,132,80,144,139, 109,106,105,88,126,143,83,93, 104,98,88,107,107,107,107,117, + 106,127,132,135,129,144,143,138, 136,107,104,103,133,139,126,134, 143,136,133,131,131,114,133,91, 130,96,102,105,105,105,105,114, + 109,84,137,148,143,80,97,142, 95,87,79,143,84,81,66,88, 152,107,63,106,134,96,84,104, 105,99,141,108,108,108,108,120, + 146,121,127,106,108,117,135,119, 132,125,116,116,133,118,126,126, 125,145,101,96,104,133,121,131, 142,137,126,145,145,145,145,136, + 95,70,86,54,136,66,83,111, 81,73,147,109,132,128,110,74, 88,93,108,151,137,82,117,80, 91,85,75,94,94,94,94,111, + 112,161,124,140,127,83,131,110, 135,90,92,132,123,141,128,133, 120,110,106,123,133,99,130,97, 108,102,125,111,111,111,111,121, + 145,120,126,105,107,116,134,118, 131,124,115,115,115,117,137,125, 124,144,100,95,132,132,120,130, 141,136,125,144,144,144,144,135, + 148,123,129,107,115,119,136,121, 134,126,118,118,113,120,115,127, 126,146,102,103,111,135,123,133, 144,138,128,147,147,147,147,136, + + 147,153,128,106,109,118,135,120, 133,153,117,117,112,119,104,126, 126,146,102,108,106,165,123,133, 144,138,128,147,147,147,147,136, + 132,174,113,92,94,156,121,105, 118,160,102,102,97,104,90,172, 112,132,88,83,91,175,108,118, 129,124,113,132,132,132,132,127, + 152,127,133,112,114,123,141,125, 138,131,122,122,117,124,110,132, 132,152,108,103,111,140,128,138, 149,144,133,152,152,152,152,138, + 117,92,136,107,132,88,105,132, 103,110,127,110,134,133,162,96, 133,116,138,108,116,105,127,176, 144,108,118,117,117,117,117,120, + 148,123,129,107,110,119,136,121, 134,126,118,118,135,141,139,127, 127,147,103,99,147,136,124,134, 145,139,129,148,148,148,148,134, + 148,123,129,107,110,162,136,121, 144,159,118,118,123,120,120,127, 142,147,113,99,117,151,124,134, 145,139,129,148,148,148,148,135, + 117,92,133,120,125,98,149,141, 144,116,122,143,138,132,145,97, 142,117,157,127,125,105,141,103, 114,150,148,117,117,117,117,120, + 153,128,134,112,115,124,141,126, 139,131,123,123,118,125,110,132, 132,152,108,104,112,141,129,139, 150,144,134,153,153,153,153,138, + + 132,107,153,92,134,113,121,151, 118,111,137,154,135,129,133,112, 140,132,153,117,125,120,141,118, 129,163,113,132,132,132,132,127, + 113,88,94,73,75,84,102,86, 99,92,127,83,78,85,71,93, 93,113,69,135,72,101,89,99, 110,105,94,113,113,113,113,129, + 135,125,166,120,137,106,124,108, 121,114,115,115,143,149,142,115, 138,135,119,140,128,123,131,121, 132,127,131,135,135,135,135,129, + 151,126,132,111,113,122,140,124, 137,130,121,121,116,123,109,131, 131,151,114,102,138,139,127,137, 148,143,132,151,151,151,151,137, + 120,95,157,140,118,108,142,138, 158,99,90,136,140,141,145,100, 121,120,153,120,127,108,119,106, 117,149,148,120,120,120,120,119, + 136,111,140,151,118,107,124,109, 137,114,106,126,111,155,113,115, 138,135,129,118,120,124,137,122, 133,127,132,136,136,136,136,131, + 151,146,132,110,113,145,139,124, 137,154,121,121,116,123,108,130, 130,150,106,102,110,139,127,137, 148,142,132,151,151,151,151,137, + 146,121,127,105,108,117,134,119, 132,124,116,116,111,118,103,125, 125,145,101,97,105,134,122,132, 143,137,127,146,146,146,146,131, +}; + +static const uint8 ced_hires_20[1024] = { + 111,51,50,66,67,37,61,60, 62,52,151,76,117,107,89,44, 64,85,123,112,43,48,109,55, 80,47,73,105,103,120,107,126, + 99,78,66,40,113,81,103,136, 51,33,85,110,79,133,68,53, 121,80,125,133,107,49,144,49, 79,46,58,104,94,114,94,119, + 82,89,103,144,141,45,125,85, 60,80,142,139,139,140,118,46, 133,65,134,127,134,77,126,29, 65,28,130,79,73,84,74,99, + 148,112,111,112,105,115,135,114, 133,109,103,112,104,109,99,132, 123,145,97,101,94,117,110,138, 144,123,128,148,147,147,148,137, + 97,70,96,138,128,103,151,149, 163,109,95,119,143,133,146,96, 122,107,138,122,134,143,125,67, 141,129,98,104,95,92,94,114, + 112,73,108,62,136,120,118,141, 105,57,53,129,139,116,142,70, 126,92,139,111,122,64,111,67, 100,63,134,104,102,110,102,119, + 126,53,74,82,77,64,78,76, 74,51,58,72,68,60,68,61, 85,102,50,148,65,58,59,77, 97,64,90,122,116,120,117,129, + 94,50,95,141,134,56,69,127, 60,37,151,133,141,146,122,58, 115,74,138,121,145,52,105,44, 78,35,128,96,85,89,89,105, + + 93,143,83,89,63,158,83,60, 83,139,98,142,132,86,147,141, 115,84,105,89,123,134,85,67, 69,69,82,94,100,99,89,116, + 92,119,122,149,133,142,152,139, 144,87,98,98,132,136,128,136, 148,160,131,130,127,105,129,63, 151,58,111,91,104,103,95,113, + 148,106,116,121,106,102,130,108, 127,89,97,117,103,117,112,113, 133,145,97,94,107,111,109,132, 144,121,140,148,147,147,148,137, + 96,26,70,54,136,23,56,118, 57,39,143,109,136,129,114,24, 102,75,104,149,132,26,115,40, 62,32,99,95,91,85,89,104, + 122,116,63,61,63,156,88,58, 77,162,52,66,68,77,80,112, 84,106,43,53,46,123,55,75, 100,67,77,125,117,120,120,120, + 137,128,86,79,104,158,111,95, 93,154,68,90,84,84,82,113, 113,121,63,81,93,155,94,91, 115,82,99,136,132,131,136,128, + 91,40,166,130,139,40,74,156, 53,33,137,119,108,132,120,47, 139,70,109,117,140,49,148,47, 74,31,142,89,83,85,84,103, + 113,165,84,84,91,133,107,85, 101,142,80,94,94,82,76,158, 92,97,86,89,67,171,112,67, 91,63,89,116,108,115,112,117, + + 84,151,102,50,102,126,72,103, 59,149,74,148,115,116,104,148, 125,78,106,107,133,146,137,43, 60,158,87,85,79,92,80,104, + 115,72,78,158,69,65,71,53, 67,50,47,103,38,82,62,99, 72,98,29,152,56,69,47,84, 93,67,72,118,125,119,113,127, + 116,167,96,89,95,156,80,88, 85,135,64,95,66,79,70,161, 97,98,65,84,85,166,84,67, 92,59,94,117,117,113,112,116, + 95,66,122,116,132,60,119,129, 93,85,117,101,129,126,160,66, 136,118,134,105,111,69,122,180, 161,71,127,101,101,101,96,115, + 148,107,121,119,120,108,132,120, 135,112,126,122,123,123,121,115, 140,147,122,115,120,131,127,129, 146,120,138,149,149,149,149,138, + 145,100,125,89,108,164,120,114, 156,141,106,107,130,110,130,109, 154,126,119,105,123,147,113,96, 136,98,123,146,132,131,136,131, + 96,81,121,129,125,83,154,139, 147,86,111,134,134,126,142,92, 143,98,152,124,120,68,135,108, 111,140,154,101,101,106,99,117, + 148,101,97,103,91,93,119,102, 119,82,86,90,96,95,97,105, 112,145,87,80,83,109,104,119, 153,110,113,160,153,158,154,146, + + 96,28,42,33,46,35,53,45, 49,31,126,40,50,53,52,43, 68,80,39,131,35,47,41,50, 74,51,47,99,104,105,97,134, + 148,137,108,111,112,125,128,118, 139,87,95,116,95,112,110,149, 117,147,86,88,103,140,105,130, 146,146,127,149,149,149,149,138, + 148,129,121,142,101,121,132,114, 128,114,99,114,126,128,120,128, 126,147,104,99,97,132,116,156, 146,121,126,149,149,149,149,138, + 94,39,97,117,138,45,88,117, 67,38,75,139,136,117,133,55, 139,78,153,138,143,54,128,55, 79,53,151,97,89,100,92,107, + 108,73,144,149,117,103,147,136, 162,65,59,127,136,135,143,70, 126,97,148,117,122,55,115,79, 109,140,154,117,114,112,100,115, + 148,128,120,108,115,137,133,110, 129,119,99,112,110,115,116,137, 127,147,98,107,93,131,122,130, 146,149,127,149,149,149,149,138, + 90,141,92,62,123,145,98,94, 71,157,54,115,84,131,112,151, 121,73,99,126,103,146,129,51, 68,144,73,93,87,100,88,107, + 137,80,87,78,75,97,105,85, 110,75,63,75,82,82,81,90, 99,126,66,86,72,87,81,105, 118,85,106,131,142,134,137,133, +}; + +static const uint8 ced_hires_21[1024] = { + 83,35,83,86,68,31,99,99, 55,99,74,45,80,93,87,75, 79,100,91,111,76,86,61,33, 125,101,49,100,98,111,105,129, + 59,43,112,116,111,56,117,121, 105,92,122,118,122,117,117,48, 113,112,111,124,119,105,131,14, 124,58,128,80,75,64,53,89, + 102,65,123,122,96,71,94,119, 105,106,73,93,110,138,129,71, 91,126,89,85,132,109,80,55, 63,122,92,108,98,117,104,108, + 87,29,40,62,58,112,27,40, 29,82,41,27,55,73,54,164, 60,39,74,78,77,82,45,14, 40,65,75,85,83,89,81,104, + 56,54,82,113,116,92,121,126, 133,122,107,112,124,114,119,69, 102,67,118,115,124,140,111,23, 115,119,76,70,57,61,58,92, + 78,62,95,25,124,109,90,119, 76,70,53,123,120,99,116,31, 107,29,119,104,112,46,98,15, 58,34,111,65,65,82,61,97, + 81,74,99,75,114,81,117,133, 79,96,101,129,126,104,112,55, 91,50,130,123,117,86,115,48, 57,41,32,98,76,95,82,105, + 107,147,94,49,39,141,43,49, 70,156,84,83,111,101,28,140, 58,35,42,54,90,129,55,41, 53,82,24,102,79,105,77,124, + + 75,53,95,115,100,73,77,121, 43,85,59,58,103,133,102,46, 69,150,127,128,112,72,122,25, 117,58,87,80,75,79,76,97, + 52,103,109,123,121,131,123,117, 114,100,110,92,113,118,102,108, 129,127,111,123,117,103,115,21, 125,36,88,52,79,81,65,95, + 87,70,63,109,62,69,46,61, 46,69,77,67,83,135,128,27, 93,114,58,120,143,110,108,59, 114,61,69,92,90,96,100,95, + 109,61,71,65,81,104,96,64, 70,131,79,83,136,84,125,49, 77,107,101,97,105,80,101,61, 111,75,106,115,115,112,116,109, + 112,114,84,92,90,82,79,75, 83,89,111,97,91,110,108,93, 97,93,73,90,96,92,89,68, 88,77,101,154,114,122,143,121, + 53,137,103,128,119,76,111,90, 112,44,99,119,103,120,104,107, 107,110,85,115,119,68,113,4, 82,21,111,63,72,62,54,91, + 115,54,75,100,84,61,84,54, 83,100,70,85,116,112,133,43, 80,88,74,84,141,60,68,52, 81,99,81,113,103,108,109,105, + 120,111,126,115,133,122,111,89, 67,99,81,110,116,108,120,90, 90,163,89,121,125,100,107,119, 103,94,88,124,116,114,122,112, + + 102,136,101,31,69,99,109,94, 95,151,120,85,100,94,78,59, 51,53,85,107,69,157,101,38, 64,67,59,99,103,108,95,116, + 79,150,19,27,24,119,22,24, 34,118,44,32,28,19,11,155, 18,43,0,29,14,101,25,9, 34,44,25,79,93,78,75,98, + 109,79,94,83,94,67,94,111, 63,103,71,67,102,112,111,62, 121,102,109,118,80,89,83,60, 119,63,60,126,109,130,110,127, + 52,53,108,90,118,45,88,105, 66,98,128,92,109,106,132,29, 112,78,109,93,96,54,103,149, 131,47,99,57,55,61,53,92, + 113,67,91,86,91,74,66,59, 71,104,115,78,126,131,125,92, 113,78,81,96,142,98,101,64, 76,66,103,108,98,123,99,112, + 107,81,112,47,95,153,81,88, 126,155,117,100,111,89,104,77, 131,53,97,95,109,142,93,38, 90,63,95,109,89,98,95,108, + 53,65,106,102,111,70,124,115, 115,98,121,126,113,107,115,63, 119,40,128,113,105,54,117,78, 77,126,127,58,62,74,59,98, + 130,70,67,61,62,63,68,65, 77,75,76,63,59,56,60,58, 74,89,44,52,52,89,72,70, 112,74,65,152,122,141,139,137, + + 87,83,128,38,121,100,104,126, 80,90,140,138,111,106,105,56, 118,38,125,105,107,90,118,59, 57,141,42,74,97,86,75,106, + 113,89,93,86,69,80,73,66, 73,107,89,65,79,88,93,67, 86,81,65,83,79,83,81,62, 108,93,80,129,114,126,119,125, + 72,100,140,106,126,76,78,82, 98,91,119,103,121,124,113,68, 119,69,92,127,109,58,110,23, 82,57,114,116,85,81,78,92, + 114,71,89,89,85,92,85,77, 88,84,100,100,109,99,87,42, 81,78,116,95,146,76,98,54, 89,93,94,119,114,113,115,110, + 73,57,129,122,104,91,116,112, 130,80,66,119,115,115,115,33, 101,33,124,105,107,25,97,34, 70,127,127,84,81,81,57,94, + 74,41,117,137,107,32,76,46, 113,50,108,113,93,131,86,33, 121,33,104,108,103,103,115,9, 34,85,117,79,74,86,80,101, + 105,136,69,50,52,146,69,59, 68,160,143,98,90,95,36,91, 54,64,94,68,86,132,126,39, 89,121,50,110,105,109,106,138, + 119,64,72,56,60,96,83,58, 74,75,59,61,65,63,48,59, 78,73,49,68,62,65,54,71, 69,57,57,111,119,111,115,117, +}; + + + diff --git a/ced/compact_enc_det/compact_enc_det_hint_code.cc b/ced/compact_enc_det/compact_enc_det_hint_code.cc new file mode 100644 index 0000000..6736e7f --- /dev/null +++ b/ced/compact_enc_det/compact_enc_det_hint_code.cc @@ -0,0 +1,179 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "compact_enc_det/compact_enc_det_hint_code.h" + +#include // for isalpha +#include // for NULL, memchr, strlen, etc + +#include "util/basictypes.h" // for uint8, uint32 +#include "util/string_util.h" + +// Upper to lower, keep digits, everything else to minus '-' (2d) +static const char kCharsetToLowerTbl[256] = { + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, 0x38,0x39,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + + 0x2d,0x61,0x62,0x63,0x64,0x65,0x66,0x67, 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, 0x78,0x79,0x7a,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x61,0x62,0x63,0x64,0x65,0x66,0x67, 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, 0x78,0x79,0x7a,0x2d,0x2d,0x2d,0x2d,0x2d, + + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, + 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, 0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d, +}; + + +static const char kIsAlpha[256] = { + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,0,0,0,0,0, + 0,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +}; + +static const char kIsDigit[256] = { + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1, 1,1,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +}; + +static const char* kFakeEncodingName[] = { + "FakeEnc100", "FakeEnc101", "FakeEnc102", "FakeEnc103", "FakeEnc104", + "FakeEnc105", "FakeEnc106", "FakeEnc107", "FakeEnc108", "FakeEnc109", + "FakeEnc110", "FakeEnc111", "FakeEnc112", "FakeEnc113", "FakeEnc114", + "FakeEnc115", "FakeEnc116", "FakeEnc117", "FakeEnc118", "FakeEnc119", +}; +static const char* kFakeEncodingName2[] = { + "FakeEnc_0", "FakeEnc_1", "FakeEnc_2", "FakeEnc_3", "FakeEnc_4", +}; + +// Return name for extended encoding +const char* MyEncodingName(Encoding enc) { + if (enc < 0) { + return "~"; + } + if (enc == ISO_8859_1) { + return "Latin1"; // I can't stand "ASCII" for this + } + if (enc < NUM_ENCODINGS) { + return EncodingName(enc); + } + // allow fake names, for exploration + if ((NUM_ENCODINGS <= enc) && (enc < (NUM_ENCODINGS + 4))) { + return kFakeEncodingName2[enc - NUM_ENCODINGS]; + } + if ((100 <= enc) && (enc < 120)) { + return kFakeEncodingName[enc - 100]; + } + return "~"; +} + + +// http://www.iana.org/assignments/character-sets says charset name is up to +// 40 bytes of any printable ASCII, but that can't be right +// when parsing HTML; at least quote is not allowed. The list +// here includes all punctuation in all registered names as of April 2006 +static const char* kWordLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "-_.:()"; + + +// Normalize ASCII string to first 4 alphabetic chars and last 4 digit chars +// Letters are forced to lowercase ASCII +// Used to normalize charset= values +string MakeChar44(const string& str) { + string res("________"); // eight underscores + int l_ptr = 0; + int d_ptr = 0; + for (int i = 0; i < str.size(); ++i) { + uint8 uc = static_cast(str[i]); + if (kIsAlpha[uc]) { + if (l_ptr < 4) { // Else ignore + res[l_ptr] = kCharsetToLowerTbl[uc]; + l_ptr++; + } + } else if (kIsDigit[uc]) { + if (d_ptr < 4) { + res[4 + d_ptr] = kCharsetToLowerTbl[uc]; + } else { + // Keep last 4 digits by shifting left + res[4] = res[5]; + res[5] = res[6]; + res[6] = res[7]; + res[7] = kCharsetToLowerTbl[uc]; + } + d_ptr++; + } // If neither letter nor digit, drop entirely + } + return res; +} + +// Normalize ASCII string to first 8 alphabetic/digit chars +// Letters are forced to lowercase ASCII +// Used to normalize TLD values +string MakeChar4(const string& str) { + string res("____"); // four underscores + int l_ptr = 0; + for (int i = 0; i < str.size(); ++i) { + uint8 uc = static_cast(str[i]); + if (kIsAlpha[uc] | kIsDigit[uc]) { + if (l_ptr < 4) { // Else ignore + res[l_ptr] = kCharsetToLowerTbl[uc]; + l_ptr++; + } + } + } + return res; +} + +// Normalize ASCII string to first 8 alphabetic/digit chars +// Letters are forced to lowercase ASCII +// Used to normalize TLD values +string MakeChar8(const string& str) { + string res("________"); // eight dots + int l_ptr = 0; + for (int i = 0; i < str.size(); ++i) { + uint8 uc = static_cast(str[i]); + if (kIsAlpha[uc] | kIsDigit[uc]) { + if (l_ptr < 8) { // Else ignore + res[l_ptr] = kCharsetToLowerTbl[uc]; + l_ptr++; + } + } + } + return res; +} diff --git a/ced/compact_enc_det/compact_enc_det_hint_code.h b/ced/compact_enc_det/compact_enc_det_hint_code.h new file mode 100644 index 0000000..53fe67a --- /dev/null +++ b/ced/compact_enc_det/compact_enc_det_hint_code.h @@ -0,0 +1,45 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef COMPACT_ENC_DET_COMPACT_ENC_DET_HINT_CODE_H_ +#define COMPACT_ENC_DET_COMPACT_ENC_DET_HINT_CODE_H_ + +#include // for string + +#include "util/basictypes.h" // for uint32 +#include "util/encodings/encodings.h" // for Encoding + +using std::string; + +// Return name for extended encoding +const char* MyEncodingName(Encoding enc); + +// Normalize ASCII string to first 4 alphabetic chars and last 4 digit chars +// Letters are forced to lowercase ASCII +// Used to normalize charset= values +string MakeChar44(const string& str); + +// Normalize ASCII string to first 4 alphabetic/digit chars +// Letters are forced to lowercase ASCII +// Used to normalize TLD values +string MakeChar4(const string& str); + +// Normalize ASCII string to first 8 alphabetic/digit chars +// Letters are forced to lowercase ASCII +// Used to normalize other values +string MakeChar8(const string& str); + +#endif // COMPACT_ENC_DET_COMPACT_ENC_DET_HINT_CODE_H_ diff --git a/ced/compact_enc_det/detail_head_string.inc b/ced/compact_enc_det/detail_head_string.inc new file mode 100644 index 0000000..e70e5ff --- /dev/null +++ b/ced/compact_enc_det/detail_head_string.inc @@ -0,0 +1,152 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +// Produced by stringify.cc on 2007-09-28 09:13 from file i18n/encodings/compact_enc_det/tools/detail_head.ps + "%!PS-Adobe-2.0\n\n/inch {72 mul} def\n/cshow {dup stringwidth pop -2 div" + " 0 rmoveto show} def\n\n/lmargin 0.5 inch def\n/rmargin 8.5 inch def\n/t" + "margin 10.5 inch def\n/bmargin 0.5 inch def\n\n\n% set to N>=0 to track " + "ranked encoding N\n/track-me -1 def\n/track-me2 -1 def\n\n/columns 2 def" + "\n\n/lpi 18 def % lines per inch\n/lpc lpi 10 mul def " + " % lines per column\n/lpp lpc columns mul def % lines per page\n" + "/probw 3.0 inch def % probability width\n/probr 50 def " + " % probability range\n/widowlines lpi 2 idiv def % 1/2 inch widow a" + "t bottom\n/widowlines lpi def % 1 inch widow at bottom\n\n/lpg l" + "pi 2 idiv def % 1/2 inch spacing between groups\n\n/delc 4 inch " + "def\n/dell -1 inch lpi div def\n\n/next-line 0 def % 24 lines per i" + "nch, 240 per column\n\n/Cfont /Courier findfont 6 scalefont def\n/Hfont " + "/Helvetica findfont 6 scalefont def\nHfont setfont\n\n\n% simple string " + "hash -- sum the characters\n/strhash {\n /hstr exch def\n /h 0 def\n " + "0 1 hstr length 1 sub {/i exch def /h h hstr i get add def} for\n h\n}" + " def\n\n% convert pro at 30 per 2x to 0-2.5 inches spanning -50 to 0\n/p" + "rob2x {\n 30 idiv probr div probw mul neg probw add\n}def\n\n\n/cliptoc" + "olumn {\n % ====== MUST MATCH ME ======\n gsave\n lmargin tmargin mov" + "eto\n next-line lpc idiv delc mul 0 rmoveto\n -1 18 rmoveto 0 -10.5 in" + "ch rlineto delc 2 add 0 rlineto 0 10.5 inch rlineto closepath\n clip\n" + " newpath\n} def\n\n/endcliptocolumn {\n grestore\n % ====== MUST MATC" + "H ME ======\n} def\n\n\n\n/column-box {\n lmargin tmargin moveto\n nex" + "t-line 1 sub lpc idiv delc mul next-line 1 sub lpc mod 1 add dell mul r" + "moveto\n % box\n gsave -1.5 0 rmoveto 0 detail-count dell mul neg rmov" + "eto probw 3 add 0 rlineto 0.25 setlinewidth stroke grestore\n gsave -1" + ".5 0 rmoveto 0 detail-count dell mul neg rlineto 0.25 setlinewidth strok" + "e grestore\n gsave probw .8 mul 0 rmoveto 0 detail-count dell mul neg r" + "lineto 0.25 setlinewidth 0.8 setgray stroke grestore\n gsave probw .6 m" + "ul 0 rmoveto 0 detail-count dell mul neg rlineto 0.25 setlinewidth 0.8 s" + "etgray stroke grestore\n gsave probw .4 mul 0 rmoveto 0 detail-count de" + "ll mul neg rlineto 0.25 setlinewidth 0.8 setgray stroke grestore\n gsav" + "e probw .2 mul 0 rmoveto 0 detail-count dell mul neg rlineto 0.25 setlin" + "ewidth 0.8 setgray stroke grestore\n gsave probw 1.5 add 0 rmoveto 0 de" + "tail-count dell mul neg rlineto 0.25 setlinewidth stroke grestore\n} def" + "\n\n\n/IncrementLine {\n /incr exch def\n /next-line next-line incr ad" + "d def\n next-line lpc ge next-line incr sub lpc lt and {\n % We " + "just went to the top of column 2; redo clip\n endcliptocolumn % M" + "UST match\n column-box\n /next-line lpc def\n cliptocolumn " + " % MUST match\n } if\n next-line lpp ge {\n % We just went to the" + " top of column 3; start new page column 1\n endcliptocolumn % MUS" + "T match\n column-box\n showpage\n Hfont setfont\n /next-line" + " 0 def\n show-pageno\n cliptocolumn % MUST match\n } if\n}" + " def\n\n/IncrementLineOutside {\n /incr exch def\n /next-line next-lin" + "e incr add def\n next-line lpc ge next-line incr sub lpc lt and {\n" + " % We just went to the top of column 2\n /next-line lpc def\n } i" + "f\n next-line lpp ge {\n % We just went to the top of column 3; star" + "t new page column 1\n showpage\n Hfont setfont\n /next-line 0 d" + "ef\n show-pageno\n } if\n} def\n\n/NextColumn {\n lpc 1 sub Increme" + "ntLine\n} def\n\n/NextPage {\n lpp 1 sub IncrementLine\n} def\n\n% Up" + "on entry, we are OUTSIDE the clip\n/start-detail {\n /d-title exch def\n" + "\n % align >= 1 inch at bottom of column, and/or start new column\n lp" + "c next-line lpc mod sub widowlines lt {\n % Start at top of a column\n" + " next-line lpc ge {\n % Start new page\n showpage\n Hf" + "ont setfont\n /next-line 0 def\n show-pageno\n } {\n %" + " Start new column\n /next-line lpc def\n } ifelse\n } if\n\n l" + "margin tmargin moveto\n next-line lpc idiv delc mul next-line lpc mod " + "dell mul rmoveto\n gsave d-title show grestore\n 0 dell rmoveto\n 1 1" + " 4 {/j exch def gsave probw j mul 5 div -2 rmoveto 50 j 10 mul sub 20 st" + "ring cvs cshow grestore} for\n 2 IncrementLineOutside\n /detail-count " + "1 def\n cliptocolumn % MUST match\n /d-array [] def\n} def\n" + "\n/size-detail {\n /d-names exch def\n /d-size exch def\n % zero sums" + "\n /sums d-size array def\n 0 1 d-size 1 sub {/i exch def sums i 0 pu" + "t} for\n /old-d-max 0 def\n /colors d-size array def\n 0 1 d-size 1 s" + "ub {/i exch def colors i i 3 mul 17 mod 17 div put} for\n %0 1 d-size " + "1 sub {/i exch def colors i d-names i get strhash 3 mul 17 mod 17 div p" + "ut} for\n %0 1 d-size 1 sub {/i exch def ( ) show colors i get 20 stri" + "ng cvs show} for\n} def\n\n/count-detail {\n /detail-total-count exch d" + "ef\n % if total-count >= one column, start at top of a column\n detail" + "-total-count lpp ge {\n % Start new page\n NextPage\n } {\n de" + "tail-total-count lpc ge {\n % Start new column\n NextColumn\n " + " } if\n } ifelse\n} def\n\n% highlight next entry with underbar\n/do-" + "flag {\ngsave\n setrgbcolor\n lmargin tmargin moveto\n next-line lpc " + "idiv delc mul next-line lpc mod dell mul rmoveto\n 0 -2 rmoveto\n pro" + "bw 0 rlineto\n 0 dell neg rlineto\n probw neg 0 rlineto\n closepath\n" + " fill\ngrestore\n} def\n\n/do-detail-e {\n /d-array exch def\n /d-enc" + " exch def\n /d-label exch def\n /d-max -999999 def\n\n lmargin tmargi" + "n moveto\n next-line lpc idiv delc mul next-line lpc mod dell mul rmov" + "eto\n 0.25 setlinewidth\n\n % show label, using encoding color\n gsav" + "e\n probw 2 add -2 rmoveto\n detail-count 1 sub 2 mod 0.25 inch mu" + "l 0 rmoveto\n % ([) show detail-count 20 string cvs show (] ) show\n " + " d-enc 0 lt {\n 0 setgray\n }{\n colors d-enc get 1 .8 se" + "thsbcolor\n } ifelse\n d-label show\n grestore\n % For -prune- d" + "raw horizontal line\n d-label length 8 gt {d-label 4 get (p) 0 get eq d" + "-label 5 get (r) 0 get eq and {\n /prune-val d-label cvi def\n /ne" + "wx prune-val 30 mul prob2x def\n gsave newx 6 rmoveto 0 -12 rlineto 1" + ".5 setlinewidth 0.8 setgray stroke grestore\n gsave probw 0 add 0 rli" + "neto 0.25 setlinewidth 0.8 setgray stroke grestore\n } if } if\n\n % t" + "rack max per new row\n 0 1 d-array length 1 sub {\n /i exch def\n " + " /sum sums i get d-array i get add def\n d-max sum lt {/d-max sum def" + "} if\n } for\n\n % draw line increments\n 0 1 d-array length 1 sub {\n" + " /i exch def\n detail-count 1 gt {\n /oldx old-d-max sums i g" + "et sub prob2x def\n } {\n /oldx 600 prob2x def\n } ifelse\n " + " /oldy dell neg def\n /newx d-max sums i get d-array i get add sub" + " prob2x def\n /newy 0 def\n gsave\n oldx oldy rmoveto\n newx" + " oldx sub newy oldy sub rlineto\n % if encoding is being tracked, ma" + "ke bold line\n i track-me eq\n {2 setlinewidth}\n {i track-" + "me2 eq {1.25 setlinewidth} {0.25 setlinewidth} ifelse}\n ifelse\n " + " colors i get 1 .8 sethsbcolor stroke\n grestore\n } for\n /detail" + "-count detail-count 1 add def\n\n % increment running total in sums, tr" + "ack max per row\n 0 1 d-array length 1 sub {\n /i exch def\n sums" + " i sums i get d-array i get add put\n } for\n /old-d-max d-max def\n" + "\n 1 IncrementLine\n} def\n\n\n/do-detail {\n /d-array exch def\n /d-" + "label exch def\n d-label -1 d-array do-detail-e\n} def\n\n% Upon exit, " + "we are outside the clip\n/end-detail {\n pop\n endcliptocolumn " + " % MUST match\n column-box\n\n % text labels\n 0 1 d-array length 1 s" + "ub {\n /i exch def\n gsave\n /newx old-d-max sums i get sub pro" + "b2x def\n newx 0 ge {\n newx 0 rmoveto\n currentpoint trans" + "late\n colors i get 1 .8 sethsbcolor\n gsave 0 dell neg rline" + "to 0.25 setlinewidth stroke grestore\n -60 rotate\n 0 -2 movet" + "o d-names i get show\n } if\n grestore\n } for\n d-array length " + "0 gt {\n lpg IncrementLineOutside\n } {\n lpg 4 idiv IncrementLin" + "eOutside\n } ifelse\n} def\n\n/do-src {\n/src exch def\n lmargin tmarg" + "in moveto\n next-line lpc idiv delc mul next-line lpc mod dell mul rmo" + "veto\n Cfont setfont\n src show\n Hfont setfont\n 1 IncrementLine\n}" + " def\n\n% Underline trigram in source text\n/do-highlight1 {\n /hl-colo" + "r exch def\n /hl-offset exch def\n /hl-line exch 1 sub 2 mul def\n gs" + "ave\n lmargin tmargin moveto\n next-line hl-line sub lpc idiv delc mul" + "\n next-line hl-line sub lpc mod dell mul rmoveto\n % Assume text is 6" + " chars in and 3.6 pts per char, but 2 chars per offset\n hl-offset 2 mu" + "l 6 add 3.6 mul 4 rmoveto\n\n 0 setgray 0.5 setlinewidth\n hl-color 1" + " eq {0 0 1 setrgbcolor} if % Latin1 blue\n hl-color 2 eq {1 0 1 setrgb" + "color} if % Latin2 magenta\n hl-color 3 eq {1 0.67 0 setrgbcolor} if " + "% Latin7 orange\n 18 -2 rlineto stroke\n grestore\n} def\n\n% Box trig" + "ram in source text\n/do-highlight2 {\n /hl-color exch def\n /hl-offset" + " exch def\n /hl-line exch 1 sub 2 mul def\n gsave\n lmargin tmargin m" + "oveto\n next-line hl-line sub lpc idiv delc mul\n next-line hl-line su" + "b lpc mod dell mul rmoveto\n % Assume text is 6 chars in and 3.6 pts pe" + "r char, but 2 chars per offset\n hl-offset 2 mul 6 add 3.6 mul 4 rmove" + "to\n\n 0 setgray 0.25 setlinewidth\n hl-color 1 eq {0 0 1 setrgbcolor}" + " if % Latin1 blue\n hl-color 2 eq {1 0 1 setrgbcolor} if % Latin2 mag" + "enta\n hl-color 3 eq {1 0.67 0 setrgbcolor} if % Latin7 orange\n -0.5" + " -0.5 rmoveto\n 22 0 rlineto\n 0 4 rlineto\n -11 2 rlineto\n -11 -2 " + "rlineto\n closepath\n stroke\n grestore\n} def\n\n/show-pageno {\ngsa" + "ve\nlmargin bmargin moveto 0 -12 rmoveto\n(Page ) show pageno 20 string " + "cvs show\ngrestore\n/pageno pageno 1 add def\n} def\n\n/pageno 1 def\nsh" + "ow-pageno\n%=============================\n\n\n" diff --git a/ced/util/basictypes.h b/ced/util/basictypes.h new file mode 100644 index 0000000..af391c7 --- /dev/null +++ b/ced/util/basictypes.h @@ -0,0 +1,331 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_BASICTYPES_H_ +#define UTIL_BASICTYPES_H_ + +#include // So we can set the bounds of our types +#include // For size_t +#include // for memcpy + +#include "util/port.h" // Types that only need exist on certain systems + +#ifndef COMPILER_MSVC +// stdint.h is part of C99 but MSVC doesn't have it. +#include // For intptr_t. +#endif + +typedef signed char schar; +typedef signed char int8; +typedef short int16; +// TODO(mbelshe) Remove these type guards. These are +// temporary to avoid conflicts with npapi.h. +#ifndef _INT32 +#define _INT32 +typedef int int32; +#endif + +// The NSPR system headers define 64-bit as |long| when possible. In order to +// not have typedef mismatches, we do the same on LP64. +#if __LP64__ +typedef long int64; +#else +typedef long long int64; +#endif + +// NOTE: unsigned types are DANGEROUS in loops and other arithmetical +// places. Use the signed types unless your variable represents a bit +// pattern (eg a hash value) or you really need the extra bit. Do NOT +// use 'unsigned' to express "this value should always be positive"; +// use assertions for this. + +typedef unsigned char uint8; +typedef unsigned short uint16; +// TODO(mbelshe) Remove these type guards. These are +// temporary to avoid conflicts with npapi.h. +#ifndef _UINT32 +#define _UINT32 +typedef unsigned int uint32; +#endif + +// See the comment above about NSPR and 64-bit. +#if __LP64__ +typedef unsigned long uint64; +#else +typedef unsigned long long uint64; +#endif + +// A type to represent a Unicode code-point value. As of Unicode 4.0, +// such values require up to 21 bits. +// (For type-checking on pointers, make this explicitly signed, +// and it should always be the signed version of whatever int32 is.) +typedef signed int char32; + +const uint8 kuint8max = (( uint8) 0xFF); +const uint16 kuint16max = ((uint16) 0xFFFF); +const uint32 kuint32max = ((uint32) 0xFFFFFFFF); +const uint64 kuint64max = ((uint64) GG_LONGLONG(0xFFFFFFFFFFFFFFFF)); +const int8 kint8min = (( int8) 0x80); +const int8 kint8max = (( int8) 0x7F); +const int16 kint16min = (( int16) 0x8000); +const int16 kint16max = (( int16) 0x7FFF); +const int32 kint32min = (( int32) 0x80000000); +const int32 kint32max = (( int32) 0x7FFFFFFF); +const int64 kint64min = (( int64) GG_LONGLONG(0x8000000000000000)); +const int64 kint64max = (( int64) GG_LONGLONG(0x7FFFFFFFFFFFFFFF)); + +// A macro to disallow the copy constructor and operator= functions +// This should be used in the private: declarations for a class +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +// An older, deprecated, politically incorrect name for the above. +#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName) + +// A macro to disallow all the implicit constructors, namely the +// default constructor, copy constructor and operator= functions. +// +// This should be used in the private: declarations for a class +// that wants to prevent anyone from instantiating it. This is +// especially useful for classes containing only static methods. +#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName(); \ + DISALLOW_COPY_AND_ASSIGN(TypeName) + +// The arraysize(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. If you use arraysize on +// a pointer by mistake, you will get a compile-time error. + +// This template function declaration is used in defining arraysize. +// Note that the function doesn't need an implementation, as we only +// use its type. +template +char (&ArraySizeHelper(T (&array)[N]))[N]; + +// That gcc wants both of these prototypes seems mysterious. VC, for +// its part, can't decide which to use (another mystery). Matching of +// template overloads: the final frontier. +#ifndef _MSC_VER +template +char (&ArraySizeHelper(const T (&array)[N]))[N]; +#endif + +#define arraysize(array) (sizeof(ArraySizeHelper(array))) + + +// Use implicit_cast as a safe version of static_cast or const_cast +// for upcasting in the type hierarchy (i.e. casting a pointer to Foo +// to a pointer to SuperclassOfFoo or casting a pointer to Foo to +// a const pointer to Foo). +// When you use implicit_cast, the compiler checks that the cast is safe. +// Such explicit implicit_casts are necessary in surprisingly many +// situations where C++ demands an exact type match instead of an +// argument type convertable to a target type. +// +// The From type can be inferred, so the preferred syntax for using +// implicit_cast is the same as for static_cast etc.: +// +// implicit_cast(expr) +// +// implicit_cast would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +template +inline To implicit_cast(From const &f) { + return f; +} + +// The COMPILE_ASSERT macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// COMPILE_ASSERT(arraysize(content_type_names) == CONTENT_NUM_TYPES, +// content_type_names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +template +struct CompileAssert { +}; + +#undef COMPILE_ASSERT +#define COMPILE_ASSERT(expr, msg) \ + typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] + +// Implementation details of COMPILE_ASSERT: +// +// - COMPILE_ASSERT works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert +// +// instead, these compilers will refuse to compile +// +// COMPILE_ASSERT(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. + + +// MetatagId refers to metatag-id that we assign to +// each metatag pair.. +typedef uint32 MetatagId; + +// Argument type used in interfaces that can optionally take ownership +// of a passed in argument. If TAKE_OWNERSHIP is passed, the called +// object takes ownership of the argument. Otherwise it does not. +enum Ownership { + DO_NOT_TAKE_OWNERSHIP, + TAKE_OWNERSHIP +}; + +// bit_cast is a template function that implements the +// equivalent of "*reinterpret_cast(&source)". We need this in +// very low-level functions like the protobuf library and fast math +// support. +// +// float f = 3.14159265358979; +// int i = bit_cast(f); +// // i = 0x40490fdb +// +// The classical address-casting method is: +// +// // WRONG +// float f = 3.14159265358979; // WRONG +// int i = * reinterpret_cast(&f); // WRONG +// +// The address-casting method actually produces undefined behavior +// according to ISO C++ specification section 3.10 -15 -. Roughly, this +// section says: if an object in memory has one type, and a program +// accesses it with a different type, then the result is undefined +// behavior for most values of "different type". +// +// This is true for any cast syntax, either *(int*)&f or +// *reinterpret_cast(&f). And it is particularly true for +// conversions betweeen integral lvalues and floating-point lvalues. +// +// The purpose of 3.10 -15- is to allow optimizing compilers to assume +// that expressions with different types refer to different memory. gcc +// 4.0.1 has an optimizer that takes advantage of this. So a +// non-conforming program quietly produces wildly incorrect output. +// +// The problem is not the use of reinterpret_cast. The problem is type +// punning: holding an object in memory of one type and reading its bits +// back using a different type. +// +// The C++ standard is more subtle and complex than this, but that +// is the basic idea. +// +// Anyways ... +// +// bit_cast<> calls memcpy() which is blessed by the standard, +// especially by the example in section 3.9 . Also, of course, +// bit_cast<> wraps up the nasty logic in one place. +// +// Fortunately memcpy() is very fast. In optimized mode, with a +// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline +// code with the minimal amount of data movement. On a 32-bit system, +// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8) +// compiles to two loads and two stores. +// +// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1. +// +// WARNING: if Dest or Source is a non-POD type, the result of the memcpy +// is likely to surprise you. + +template +inline Dest bit_cast(const Source& source) { + // Compile time assertion: sizeof(Dest) == sizeof(Source) + // A compile error here means your Dest and Source have different sizes. + // typedef char VerifySizesAreEqual [sizeof(Dest) == sizeof(Source) ? 1 : -1]; + + Dest dest; + memcpy(&dest, &source, sizeof(dest)); + return dest; +} + +// The following enum should be used only as a constructor argument to indicate +// that the variable has static storage class, and that the constructor should +// do nothing to its state. It indicates to the reader that it is legal to +// declare a static instance of the class, provided the constructor is given +// the base::LINKER_INITIALIZED argument. Normally, it is unsafe to declare a +// static variable that has a constructor or a destructor because invocation +// order is undefined. However, IF the type can be initialized by filling with +// zeroes (which the loader does for static variables), AND the destructor also +// does nothing to the storage, AND there are no virtual methods, then a +// constructor declared as +// explicit MyClass(base::LinkerInitialized x) {} +// and invoked as +// static MyClass my_variable_name(base::LINKER_INITIALIZED); +namespace base { +enum LinkerInitialized { LINKER_INITIALIZED }; +} // base + +// UnaligndLoad32 is put here instead of util/port.h to +// avoid the circular dependency between port.h and basictypes.h +// ARM does not support unaligned memory access. +#if defined(ARCH_CPU_X86_FAMILY) +// x86 and x86-64 can perform unaligned loads/stores directly; +inline uint32 UnalignedLoad32(const void* p) { + return *reinterpret_cast(p); +} +#else +#define NEED_ALIGNED_LOADS +// If target architecture does not support unaligned loads and stores, +// use memcpy version of UNALIGNED_LOAD32. +inline uint32 UnalignedLoad32(const void* p) { + uint32 t; + memcpy(&t, reinterpret_cast(p), sizeof(t)); + return t; +} + +#endif +#endif // UTIL_BASICTYPES_H_ diff --git a/ced/util/case_insensitive_hash.h b/ced/util/case_insensitive_hash.h new file mode 100644 index 0000000..7b0c9db --- /dev/null +++ b/ced/util/case_insensitive_hash.h @@ -0,0 +1,88 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_CASE_INSENSITIVE_HASH_H_ +#define UTIL_CASE_INSENSITIVE_HASH_H_ + +#include +#include +#ifndef _MSC_VER +#include +#endif + +#include + +#include "util/basictypes.h" +#include "util/string_util.h" + +// Functors for hashing c-strings with case-insensitive semantics. +struct CStringCaseHash { + size_t operator()(const char *str) const { + unsigned long hash_val = 0; + while (*str) { + hash_val = 5*hash_val + tolower(*str); + str++; + } + return (size_t)hash_val; + } +}; + +struct CStringCaseEqual { + bool operator()(const char *str1, const char *str2) const { + return !base::strcasecmp(str1, str2); + } +}; + +// These functors, in addition to being case-insensitive, ignore all +// non-alphanumeric characters. This is useful when we want all variants of +// a string -- where variants can differ in puncutation and whitespace -- to +// map to the same value. +struct CStringAlnumCaseHash { + size_t operator()(const char *str) const { + unsigned long hash_val = 0; + while (*str) { + if (isalnum(*str)) { + hash_val = 5*hash_val + tolower(*str); + } + str++; + } + return (size_t)hash_val; + } +}; + +struct CStringAlnumCaseEqual { + bool operator()(const char *str1, const char *str2) const { + while (true) { + // Skip until each pointer is pointing to an alphanumeric char or '\0' + while (!isalnum(*str1) && (*str1 != '\0')) { + str1++; + } + while (!isalnum(*str2) && (*str2 != '\0')) { + str2++; + } + if (tolower(*str1) != tolower(*str2)) { + return false; // mismatch on alphanumeric char or '\0' + } + if (*str1 == '\0') { // in which case *str2 must be '\0' as well + return true; // reached '\0' in both strings without mismatch + } + str1++; + str2++; + } + } +}; + +#endif // UTIL_CASE_INSENSITIVE_HASH_H_ diff --git a/ced/util/commandlineflags.h b/ced/util/commandlineflags.h new file mode 100644 index 0000000..302d449 --- /dev/null +++ b/ced/util/commandlineflags.h @@ -0,0 +1,39 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_COMMANDLINEFLAGS_H_ +#define UTIL_COMMANDLINEFLAGS_H_ + + +#undef DEFINE_bool +#define DEFINE_bool(name, default_value, comment) \ + bool FLAGS_##name = default_value; +#undef DEFINE_int32 +#define DEFINE_int32(name, default_value, comment) \ + int32 FLAGS_##name = default_value; +#undef DEFINE_string +#define DEFINE_string(name, default_value, comment) \ + string FLAGS_##name = default_value; + +#undef DECLARE_bool +#define DECLARE_bool(name) extern bool FLAGS_##name; +#undef DECLARE_int32 +#define DECLARE_int32(name) extern int32 FLAGS_##name; +#undef DECLARE_string +#define DECLARE_string(name) extern string FLAGS_##name; + + +#endif // UTIL_COMMANDLINEFLAGS_H_ diff --git a/ced/util/encodings/encodings.cc b/ced/util/encodings/encodings.cc new file mode 100644 index 0000000..b5f8dc5 --- /dev/null +++ b/ced/util/encodings/encodings.cc @@ -0,0 +1,891 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "util/encodings/encodings.h" + +#include // for strcasecmp +#include +#include // for pair + +#include "util/basictypes.h" +#include "util/string_util.h" +#include "util/case_insensitive_hash.h" + +struct EncodingInfo { + // The standard name for this encoding. + // + const char* encoding_name_; + + // The "preferred MIME name" of an encoding as specified by the IANA at: + // http://www.iana.org/assignments/character-sets + // + // Note that the preferred MIME name may differ slightly from the + // official IANA name: i.e. ISO-8859-1 vs. ISO_8859-1:1987 + // + const char* mime_encoding_name_; + + // It is an internal policy that if an encoding has an IANA name, + // then encoding_name_ and mime_encoding_name_ must be the same string. + // + // However, there can be exceptions if there are compelling reasons. + // For example, Japanese mobile handsets require the name + // "Shift_JIS" in charset=... parameter in Content-Type headers to + // process emoji (emoticons) in their private encodings. In that + // case, mime_encoding_name_ should be "Shift_JIS", despite + // encoding_name_ actually is "X-KDDI-Shift_JIS". + + // Some multi-byte encodings use byte values that coincide with the + // ASCII codes for HTML syntax characters <>"&' and browsers like MSIE + // can misinterpret these, as indicated in an external XSS report from + // 2007-02-15. Here, we map these dangerous encodings to safer ones. We + // also use UTF8 instead of encodings that we don't support in our + // output, and we generally try to be conservative in what we send out. + // Where the client asks for single- or double-byte encodings that are + // not as common, we substitute a more common single- or double-byte + // encoding, if there is one, thereby preserving the client's intent + // to use less space than UTF-8. This also means that characters + // outside the destination set will be converted to HTML NCRs (&#NNN;) + // if requested. + + Encoding preferred_web_output_encoding_; +}; + +static const EncodingInfo kEncodingInfoTable[] = { + { "ASCII", "ISO-8859-1", ISO_8859_1}, + { "Latin2", "ISO-8859-2", ISO_8859_2}, + { "Latin3", "ISO-8859-3", UTF8}, + // MSIE 6 does not support ISO-8859-3 (XSS issue) + { "Latin4", "ISO-8859-4", ISO_8859_4}, + { "ISO-8859-5", "ISO-8859-5", ISO_8859_5}, + { "Arabic", "ISO-8859-6", ISO_8859_6}, + { "Greek", "ISO-8859-7", ISO_8859_7}, + { "Hebrew", "ISO-8859-8", MSFT_CP1255}, + // we do not endorse the visual order + { "Latin5", "ISO-8859-9", ISO_8859_9}, + { "Latin6", "ISO-8859-10", UTF8}, + // MSIE does not support ISO-8859-10 (XSS issue) + { "EUC-JP", "EUC-JP", JAPANESE_EUC_JP}, + { "SJS", "Shift_JIS", JAPANESE_SHIFT_JIS}, + { "JIS", "ISO-2022-JP", JAPANESE_SHIFT_JIS}, + // due to potential confusion with HTML syntax chars + { "BIG5", "Big5", CHINESE_BIG5}, + { "GB", "GB2312", CHINESE_GB}, + { "EUC-CN", + "EUC-CN", + // Misnamed. Should be EUC-TW. + CHINESE_BIG5}, + // MSIE treats "EUC-CN" like GB2312, which is not EUC-TW, + // and EUC-TW is rare, so we prefer Big5 for output. + { "KSC", "EUC-KR", KOREAN_EUC_KR}, + { "Unicode", + "UTF-16LE", + // Internet Explorer doesn't recognize "ISO-10646-UCS-2" + UTF8 + // due to potential confusion with HTML syntax chars + }, + { "EUC", + "EUC", // Misnamed. Should be EUC-TW. + CHINESE_BIG5 + // MSIE does not recognize "EUC" (XSS issue), + // and EUC-TW is rare, so we prefer Big5 for output. + }, + { "CNS", + "CNS", // Misnamed. Should be EUC-TW. + CHINESE_BIG5}, + // MSIE does not recognize "CNS" (XSS issue), + // and EUC-TW is rare, so we prefer Big5 for output. + { "BIG5-CP950", + "BIG5-CP950", // Not an IANA name + CHINESE_BIG5 + // MSIE does not recognize "BIG5-CP950" (XSS issue) + }, + { "CP932", "CP932", // Not an IANA name + JAPANESE_SHIFT_JIS}, // MSIE does not recognize "CP932" (XSS issue) + { "UTF8", "UTF-8", UTF8}, + { "Unknown", + "x-unknown", // Not an IANA name + UTF8}, // UTF-8 is our default output encoding + { "ASCII-7-bit", "US-ASCII", ASCII_7BIT}, + { "KOI8R", "KOI8-R", RUSSIAN_KOI8_R}, + { "CP1251", "windows-1251", RUSSIAN_CP1251}, + { "CP1252", "windows-1252", MSFT_CP1252}, + { "KOI8U", + "KOI8-U", + ISO_8859_5}, // because koi8-u is not as common + { "CP1250", "windows-1250", MSFT_CP1250}, + { "ISO-8859-15", "ISO-8859-15", ISO_8859_15}, + { "CP1254", "windows-1254", MSFT_CP1254}, + { "CP1257", "windows-1257", MSFT_CP1257}, + { "ISO-8859-11", "ISO-8859-11", ISO_8859_11}, + { "CP874", "windows-874", MSFT_CP874}, + { "CP1256", "windows-1256", MSFT_CP1256}, + { "CP1255", "windows-1255", MSFT_CP1255}, + { "ISO-8859-8-I", "ISO-8859-8-I", MSFT_CP1255}, + // Java does not support iso-8859-8-i + { "VISUAL", "ISO-8859-8", MSFT_CP1255}, + // we do not endorse the visual order + { "CP852", "cp852", MSFT_CP1250}, + // because cp852 is not as common + { "CSN_369103", "csn_369103", MSFT_CP1250}, + // MSIE does not recognize "csn_369103" (XSS issue) + { "CP1253", "windows-1253", MSFT_CP1253}, + { "CP866", "IBM866", RUSSIAN_CP1251}, + // because cp866 is not as common + { "ISO-8859-13", "ISO-8859-13", UTF8}, + // because iso-8859-13 is not widely supported + { "ISO-2022-KR", "ISO-2022-KR", KOREAN_EUC_KR}, + // due to potential confusion with HTML syntax chars + { "GBK", "GBK", GBK}, + { "GB18030", "GB18030", GBK}, + // because gb18030 is not widely supported + { "BIG5_HKSCS", "BIG5-HKSCS", CHINESE_BIG5}, + // because Big5-HKSCS is not widely supported + { "ISO_2022_CN", "ISO-2022-CN", CHINESE_GB}, + // due to potential confusion with HTML syntax chars + { "TSCII", "tscii", UTF8}, + // we do not have an output converter for this font encoding + { "TAM", "tam", UTF8}, + // we do not have an output converter for this font encoding + { "TAB", "tab", UTF8}, + // we do not have an output converter for this font encoding + { "JAGRAN", "jagran", UTF8}, + // we do not have an output converter for this font encoding + { "MACINTOSH", "MACINTOSH", ISO_8859_1}, + // because macintosh is relatively uncommon + { "UTF7", "UTF-7", + UTF8}, // UTF-7 has been the subject of XSS attacks and is deprecated + { "BHASKAR", "bhaskar", + UTF8}, // we do not have an output converter for this font encoding + { "HTCHANAKYA", "htchanakya", // not an IANA charset name. + UTF8}, // we do not have an output converter for this font encoding + { "UTF-16BE", "UTF-16BE", + UTF8}, // due to potential confusion with HTML syntax chars + { "UTF-16LE", "UTF-16LE", + UTF8}, // due to potential confusion with HTML syntax chars + { "UTF-32BE", "UTF-32BE", + UTF8}, // unlikely to cause XSS bugs, but very uncommon on Web + { "UTF-32LE", "UTF-32LE", + UTF8}, // unlikely to cause XSS bugs, but very uncommon on Web + { "X-BINARYENC", "x-binaryenc", // Not an IANA name + UTF8}, // because this one is not intended for output (just input) + { "HZ-GB-2312", "HZ-GB-2312", + CHINESE_GB}, // due to potential confusion with HTML syntax chars + { "X-UTF8UTF8", "x-utf8utf8", // Not an IANA name + UTF8}, // because this one is not intended for output (just input) + { "X-TAM-ELANGO", "x-tam-elango", + UTF8}, // we do not have an output converter for this font encoding + { "X-TAM-LTTMBARANI", "x-tam-lttmbarani", + UTF8}, // we do not have an output converter for this font encoding + { "X-TAM-SHREE", "x-tam-shree", + UTF8}, // we do not have an output converter for this font encoding + { "X-TAM-TBOOMIS", "x-tam-tboomis", + UTF8}, // we do not have an output converter for this font encoding + { "X-TAM-TMNEWS", "x-tam-tmnews", + UTF8}, // we do not have an output converter for this font encoding + { "X-TAM-WEBTAMIL", "x-tam-webtamil", + UTF8}, // we do not have an output converter for this font encoding + + { "X-KDDI-Shift_JIS", "Shift_JIS", JAPANESE_SHIFT_JIS}, + // KDDI version of Shift_JIS with Google Emoji PUA mappings. + // Note that MimeEncodingName() returns "Shift_JIS", since KDDI uses + // "Shift_JIS" in HTTP headers and email messages. + + { "X-DoCoMo-Shift_JIS", "Shift_JIS", JAPANESE_SHIFT_JIS}, + // DoCoMo version of Shift_JIS with Google Emoji PUA mappings. + // See the comment at KDDI_SHIFT_JIS for other issues. + + { "X-SoftBank-Shift_JIS", "Shift_JIS", JAPANESE_SHIFT_JIS}, + // SoftBank version of Shift_JIS with Google Emoji PUA mappings. + // See the comment at KDDI_SHIFT_JIS for other issues. + + { "X-KDDI-ISO-2022-JP", "ISO-2022-JP", JAPANESE_SHIFT_JIS}, + // KDDI version of ISO-2022-JP with Google Emoji PUA mappings. + // See the comment at KDDI_SHIFT_JIS for other issues. + // The preferred Web encoding is due to potential confusion with + // HTML syntax chars. + + { "X-SoftBank-ISO-2022-JP", "ISO-2022-JP", JAPANESE_SHIFT_JIS}, + // SoftBank version of ISO-2022-JP with Google Emoji PUA mappings. + // See the comment at KDDI_SHIFT_JIS for other issues. + // The preferred Web encoding is due to potential confusion with + // HTML syntax chars. + + // Please refer to NOTE: section in the comments in the definition + // of "struct I18NInfoByEncoding", before adding new encodings. + +}; + + + +COMPILE_ASSERT(arraysize(kEncodingInfoTable) == NUM_ENCODINGS, + kEncodingInfoTable_has_incorrect_size); + +Encoding default_encoding() {return LATIN1;} + +// ************************************************************* +// Encoding predicates +// IsValidEncoding() +// IsEncEncCompatible +// IsEncodingWithSupportedLanguage +// IsSupersetOfAscii7Bit +// Is8BitEncoding +// IsCJKEncoding +// IsHebrewEncoding +// IsRightToLeftEncoding +// IsLogicalRightToLeftEncoding +// IsVisualRightToLeftEncoding +// IsIso2022Encoding +// IsIso2022JpOrVariant +// IsShiftJisOrVariant +// IsJapaneseCellPhoneCarrierSpecificEncoding +// ************************************************************* + +bool IsValidEncoding(Encoding enc) { + return ((enc >= 0) && (enc < kNumEncodings)); +} + +bool IsEncEncCompatible(const Encoding from, const Encoding to) { + // Tests compatibility between the "from" and "to" encodings; in + // the typical case -- when both are valid known encodings -- this + // returns true iff converting from first to second is a no-op. + if (!IsValidEncoding(from) || !IsValidEncoding(to)) { + return false; // we only work with valid encodings... + } else if (to == from) { + return true; // the trivial common case + } + + if (to == UNKNOWN_ENCODING) { + return true; // all valid encodings are compatible with the unknown + } + + if (from == UNKNOWN_ENCODING) { + return false; // no unknown encoding is compatible with one that is + } + + if (from == ASCII_7BIT) { + return IsSupersetOfAscii7Bit(to); + } + + return (from == ISO_8859_1 && to == MSFT_CP1252) || + (from == ISO_8859_8 && to == HEBREW_VISUAL) || + (from == HEBREW_VISUAL && to == ISO_8859_8) || + (from == ISO_8859_9 && to == MSFT_CP1254) || + (from == ISO_8859_11 && to == MSFT_CP874) || + (from == JAPANESE_SHIFT_JIS && to == JAPANESE_CP932) || + (from == CHINESE_BIG5 && to == CHINESE_BIG5_CP950) || + (from == CHINESE_GB && to == GBK) || + (from == CHINESE_GB && to == GB18030) || + (from == CHINESE_EUC_CN && to == CHINESE_EUC_DEC) || + (from == CHINESE_EUC_CN && to == CHINESE_CNS) || + (from == CHINESE_EUC_DEC && to == CHINESE_EUC_CN) || + (from == CHINESE_EUC_DEC && to == CHINESE_CNS) || + (from == CHINESE_CNS && to == CHINESE_EUC_CN) || + (from == CHINESE_CNS && to == CHINESE_EUC_DEC); +} + +// To be a superset of 7-bit Ascii means that bytes 0...127 in the given +// encoding represent the same characters as they do in ISO_8859_1. + +// TODO: This list could be expanded. Many other encodings are supersets +// of 7-bit Ascii. In fact, Japanese JIS and Unicode are the only two +// encodings that I know for a fact should *not* be in this list. +bool IsSupersetOfAscii7Bit(Encoding e) { + switch (e) { + case ISO_8859_1: + case ISO_8859_2: + case ISO_8859_3: + case ISO_8859_4: + case ISO_8859_5: + case ISO_8859_6: + case ISO_8859_7: + case ISO_8859_8: + case ISO_8859_9: + case ISO_8859_10: + case JAPANESE_EUC_JP: + case JAPANESE_SHIFT_JIS: + case CHINESE_BIG5: + case CHINESE_GB: + case CHINESE_EUC_CN: + case KOREAN_EUC_KR: + case CHINESE_EUC_DEC: + case CHINESE_CNS: + case CHINESE_BIG5_CP950: + case JAPANESE_CP932: + case UTF8: + case UNKNOWN_ENCODING: + case ASCII_7BIT: + case RUSSIAN_KOI8_R: + case RUSSIAN_CP1251: + case MSFT_CP1252: + case RUSSIAN_KOI8_RU: + case MSFT_CP1250: + case ISO_8859_15: + case MSFT_CP1254: + case MSFT_CP1257: + case ISO_8859_11: + case MSFT_CP874: + case MSFT_CP1256: + case MSFT_CP1255: + case ISO_8859_8_I: + case HEBREW_VISUAL: + case CZECH_CP852: + case MSFT_CP1253: + case RUSSIAN_CP866: + case ISO_8859_13: + case GBK: + case GB18030: + case BIG5_HKSCS: + case MACINTOSH_ROMAN: + return true; + default: + return false; + } +} + +// To be an 8-bit encoding means that there are fewer than 256 symbols. +// Each byte determines a new character; there are no multi-byte sequences. + +// TODO: This list could maybe be expanded. Other encodings may be 8-bit. +bool Is8BitEncoding(Encoding e) { + switch (e) { + case ASCII_7BIT: + case ISO_8859_1: + case ISO_8859_2: + case ISO_8859_3: + case ISO_8859_4: + case ISO_8859_5: + case ISO_8859_6: + case ISO_8859_7: + case ISO_8859_8: + case ISO_8859_8_I: + case ISO_8859_9: + case ISO_8859_10: + case ISO_8859_11: + case ISO_8859_13: + case ISO_8859_15: + case MSFT_CP1252: + case MSFT_CP1253: + case MSFT_CP1254: + case MSFT_CP1255: + case MSFT_CP1256: + case MSFT_CP1257: + case RUSSIAN_KOI8_R: + case RUSSIAN_KOI8_RU: + case RUSSIAN_CP866: + return true; + default: + return false; + } +} + +bool IsCJKEncoding(Encoding e) { + switch (e) { + case JAPANESE_EUC_JP: + case JAPANESE_SHIFT_JIS: + case JAPANESE_JIS: + case CHINESE_BIG5: + case CHINESE_GB: + case CHINESE_EUC_CN: + case KOREAN_EUC_KR: + case CHINESE_EUC_DEC: + case CHINESE_CNS: + case CHINESE_BIG5_CP950: + case JAPANESE_CP932: + case ISO_2022_KR: + case GBK: + case GB18030: + case BIG5_HKSCS: + case ISO_2022_CN: + case HZ_GB_2312: + return true; + default: + return false; + } +} + +bool IsHebrewEncoding(Encoding e) { + return (e == ISO_8859_8 || + e == ISO_8859_8_I || + e == MSFT_CP1255 || + e == HEBREW_VISUAL); +} + + + +bool IsRightToLeftEncoding(Encoding enc) { + switch (enc) { + case MSFT_CP1255: + case MSFT_CP1256: + case ARABIC_ENCODING: + case HEBREW_ENCODING: + case ISO_8859_8_I: + case HEBREW_VISUAL: + return true; + default: + return false; + } +} + +bool IsLogicalRightToLeftEncoding(Encoding enc) { + return IsRightToLeftEncoding(enc) && !IsVisualRightToLeftEncoding(enc); +} + +// Note that despite an RFC to the contrary, ARABIC_ENCODING (ISO-8859-6) +// is NOT visual. +bool IsVisualRightToLeftEncoding(Encoding enc) { + switch (enc) { + case HEBREW_ENCODING: + case HEBREW_VISUAL: + return true; + default: + return false; + } +} + + + + + +bool IsIso2022Encoding(Encoding enc) { + return (IsIso2022JpOrVariant(enc) || + enc == ISO_2022_KR || + enc == ISO_2022_CN); +} + +bool IsIso2022JpOrVariant(Encoding enc) { + return (enc == JAPANESE_JIS || + enc == KDDI_ISO_2022_JP || + enc == SOFTBANK_ISO_2022_JP); +} + +bool IsShiftJisOrVariant(Encoding enc) { + return (enc == JAPANESE_SHIFT_JIS || + enc == JAPANESE_CP932 || + enc == KDDI_SHIFT_JIS || + enc == DOCOMO_SHIFT_JIS || + enc == SOFTBANK_SHIFT_JIS); +} + +bool IsJapaneseCellPhoneCarrierSpecificEncoding(Encoding enc) { + return (enc == KDDI_ISO_2022_JP || + enc == KDDI_SHIFT_JIS || + enc == DOCOMO_SHIFT_JIS || + enc == SOFTBANK_SHIFT_JIS || + enc == SOFTBANK_ISO_2022_JP); +} + + +// ************************************************************* +// ENCODING NAMES +// EncodingName() [Encoding to name] +// MimeEncodingName() [Encoding to name] +// EncodingFromName() [name to Encoding] +// EncodingNameAliasToEncoding() [name to Encoding] +// default_encoding_name() +// invalid_encoding_name() +// ************************************************************* + +const char * EncodingName(const Encoding enc) { + if ( (enc < 0) || (enc >= kNumEncodings) ) + return invalid_encoding_name(); + return kEncodingInfoTable[enc].encoding_name_; +} + +// TODO: Unify MimeEncodingName and EncodingName, or determine why +// such a unification is not possible. + +const char * MimeEncodingName(Encoding enc) { + if ( (enc < 0) || (enc >= kNumEncodings) ) + return ""; // TODO: Should this be invalid_encoding_name()? + return kEncodingInfoTable[enc].mime_encoding_name_; +} + +bool EncodingFromName(const char* enc_name, Encoding *encoding) { + *encoding = UNKNOWN_ENCODING; + if ( enc_name == NULL ) return false; + + for ( int i = 0; i < kNumEncodings; i++ ) { + if (!base::strcasecmp(enc_name, kEncodingInfoTable[i].encoding_name_) ) { + *encoding = static_cast(i); + return true; + } + } + return false; +} + +// The encoding_map maps standard and non-standard encoding-names +// (strings) to Encoding enums. It is used only by +// EncodingNameAliasToEncoding. Note that the map uses +// case-insensitive hash and comparison functions. + +typedef std::unordered_map EncodingMap; + +static const EncodingMap& GetEncodingMap() { + static EncodingMap encoding_map; + if (!encoding_map.empty()) { + // Already initialized + return encoding_map; + } + + // Initialize the map with all the "standard" encoding names, + // i.e., the ones returned by EncodingName and MimeEncodingName. + // + // First, add internal encoding names returned by EncodingName(). + for (int i = 0; i < NUM_ENCODINGS; ++i) { + Encoding e = static_cast(i); + // Internal encoding names must be unique. + // The internal names are guaranteed to be unique by the CHECK_EQ. + const char *encoding_name = EncodingName(e); + // CHECK_EQ(0, encoding_map.count(encoding_name)) + // << "Duplicate found for " << encoding_name; + encoding_map[encoding_name] = e; + } + // Then, add mime encoding names returned by MimeEncodingName(). + // We don't override existing entries, to give precedence to entries + // added earlier. + for (int i = 0; i < NUM_ENCODINGS; ++i) { + Encoding e = static_cast(i); + // Note that MimeEncodingName() can return the same mime encoding + // name for different encoding enums like JAPANESE_SHIFT_JIS and + // KDDI_SHIFT_JIS. In that case, the encoding enum first seen + // will be the value for the encoding name in the map. + const char *mime_encoding_name = MimeEncodingName(e); + if (encoding_map.count(mime_encoding_name) == 0) { + encoding_map[mime_encoding_name] = e; + } + } + + // Add some non-standard names: alternate spellings, common typos, + // etc. (It does no harm to add names already in the map.) Note + // that although the map is case-insensitive, by convention the + // keys are written here in lower case. For ease of maintenance, + // they are listed in alphabetical order. + encoding_map["5601"] = KOREAN_EUC_KR; + encoding_map["646"] = ASCII_7BIT; + encoding_map["852"] = CZECH_CP852; + encoding_map["866"] = RUSSIAN_CP866; + encoding_map["8859-1"] = ISO_8859_1; + encoding_map["ansi-1251"] = RUSSIAN_CP1251; + encoding_map["ansi_x3.4-1968"] = ASCII_7BIT; + encoding_map["arabic"] = ISO_8859_6; + encoding_map["ascii"] = ISO_8859_1; + encoding_map["ascii-7-bit"] = ASCII_7BIT; // not iana standard + encoding_map["asmo-708"] = ISO_8859_6; + encoding_map["bhaskar"] = BHASKAR; + encoding_map["big5"] = CHINESE_BIG5; + encoding_map["big5-cp950"] = CHINESE_BIG5_CP950; // not iana standard + encoding_map["big5-hkscs"] = BIG5_HKSCS; + encoding_map["chinese"] = CHINESE_GB; + encoding_map["cns"] = CHINESE_CNS; // not iana standard + encoding_map["cns11643"] = CHINESE_CNS; + encoding_map["cp1250"] = MSFT_CP1250; // not iana standard + encoding_map["cp1251"] = RUSSIAN_CP1251; // not iana standard + encoding_map["cp1252"] = MSFT_CP1252; // not iana standard + encoding_map["cp1253"] = MSFT_CP1253; // not iana standard + encoding_map["cp1254"] = MSFT_CP1254; // not iana standard + encoding_map["cp1255"] = MSFT_CP1255; + encoding_map["cp1256"] = MSFT_CP1256; + encoding_map["cp1257"] = MSFT_CP1257; // not iana standard + encoding_map["cp819"] = ISO_8859_1; + encoding_map["cp852"] = CZECH_CP852; + encoding_map["cp866"] = RUSSIAN_CP866; + encoding_map["cp-866"] = RUSSIAN_CP866; + encoding_map["cp874"] = MSFT_CP874; + encoding_map["cp932"] = JAPANESE_CP932; // not iana standard + encoding_map["cp950"] = CHINESE_BIG5_CP950; // not iana standard + encoding_map["csbig5"] = CHINESE_BIG5; + encoding_map["cseucjpkdfmtjapanese"] = JAPANESE_EUC_JP; + encoding_map["cseuckr"] = KOREAN_EUC_KR; + encoding_map["csgb2312"] = CHINESE_GB; + encoding_map["csibm852"] = CZECH_CP852; + encoding_map["csibm866"] = RUSSIAN_CP866; + encoding_map["csiso2022jp"] = JAPANESE_JIS; + encoding_map["csiso2022kr"] = ISO_2022_KR; + encoding_map["csiso58gb231280"] = CHINESE_GB; + encoding_map["csiso88598i"] = ISO_8859_8_I; + encoding_map["csisolatin1"] = ISO_8859_1; + encoding_map["csisolatin2"] = ISO_8859_2; + encoding_map["csisolatin3"] = ISO_8859_3; + encoding_map["csisolatin4"] = ISO_8859_4; + encoding_map["csisolatin5"] = ISO_8859_9; + encoding_map["csisolatin6"] = ISO_8859_10; + encoding_map["csisolatinarabic"] = ISO_8859_6; + encoding_map["csisolatincyrillic"] = ISO_8859_5; + encoding_map["csisolatingreek"] = ISO_8859_7; + encoding_map["csisolatinhebrew"] = ISO_8859_8; + encoding_map["csksc56011987"] = KOREAN_EUC_KR; + encoding_map["csmacintosh"] = MACINTOSH_ROMAN; + encoding_map["csn-369103"] = CZECH_CSN_369103; + encoding_map["csshiftjis"] = JAPANESE_SHIFT_JIS; + encoding_map["csunicode"] = UTF16BE; + encoding_map["csunicode11"] = UTF16BE; + encoding_map["csunicode11utf7"] = UTF7; + encoding_map["csunicodeascii"] = UTF16BE; + encoding_map["csunicodelatin1"] = UTF16BE; + encoding_map["cyrillic"] = ISO_8859_5; + encoding_map["ecma-114"] = ISO_8859_6; + encoding_map["ecma-118"] = ISO_8859_7; + encoding_map["elot_928"] = ISO_8859_7; + encoding_map["euc"] = CHINESE_EUC_DEC; // not iana standard + encoding_map["euc-cn"] = CHINESE_EUC_CN; // not iana standard + encoding_map["euc-dec"] = CHINESE_EUC_DEC; // not iana standard + encoding_map["euc-jp"] = JAPANESE_EUC_JP; + encoding_map["euc-kr"] = KOREAN_EUC_KR; + encoding_map["eucgb2312_cn"] = CHINESE_GB; + encoding_map["gb"] = CHINESE_GB; // not iana standard + encoding_map["gb18030"] = GB18030; + encoding_map["gb2132"] = CHINESE_GB; // common typo + encoding_map["gb2312"] = CHINESE_GB; + encoding_map["gb_2312-80"] = CHINESE_GB; + encoding_map["gbk"] = GBK; + encoding_map["greek"] = ISO_8859_7; + encoding_map["greek8"] = ISO_8859_7; + encoding_map["hebrew"] = ISO_8859_8; + encoding_map["htchanakya"] = HTCHANAKYA; + encoding_map["hz-gb-2312"] = HZ_GB_2312; + encoding_map["ibm819"] = ISO_8859_1; + encoding_map["ibm852"] = CZECH_CP852; + encoding_map["ibm874"] = MSFT_CP874; + encoding_map["iso-10646"] = UTF16BE; + encoding_map["iso-10646-j-1"] = UTF16BE; + encoding_map["iso-10646-ucs-2"] = UNICODE; + encoding_map["iso-10646-ucs-4"] = UTF32BE; + encoding_map["iso-10646-ucs-basic"] = UTF16BE; + encoding_map["iso-10646-unicode-latin1"] = UTF16BE; + encoding_map["iso-2022-cn"] = ISO_2022_CN; + encoding_map["iso-2022-jp"] = JAPANESE_JIS; + encoding_map["iso-2022-kr"] = ISO_2022_KR; + encoding_map["iso-8559-1"] = ISO_8859_1; // common typo + encoding_map["iso-874"] = MSFT_CP874; + encoding_map["iso-8858-1"] = ISO_8859_1; // common typo + // iso-8859-0 was a temporary name, eventually renamed iso-8859-15 + encoding_map["iso-8859-0"] = ISO_8859_15; + encoding_map["iso-8859-1"] = ISO_8859_1; + encoding_map["iso-8859-10"] = ISO_8859_10; + encoding_map["iso-8859-11"] = ISO_8859_11; + encoding_map["iso-8859-13"] = ISO_8859_13; + encoding_map["iso-8859-15"] = ISO_8859_15; + encoding_map["iso-8859-2"] = ISO_8859_2; + encoding_map["iso-8859-3"] = ISO_8859_3; + encoding_map["iso-8859-4"] = ISO_8859_4; + encoding_map["iso-8859-5"] = ISO_8859_5; + encoding_map["iso-8859-6"] = ISO_8859_6; + encoding_map["iso-8859-7"] = ISO_8859_7; + encoding_map["iso-8859-8"] = ISO_8859_8; + encoding_map["iso-8859-8-i"] = ISO_8859_8_I; + encoding_map["iso-8859-9"] = ISO_8859_9; + encoding_map["iso-9959-1"] = ISO_8859_1; // common typo + encoding_map["iso-ir-100"] = ISO_8859_1; + encoding_map["iso-ir-101"] = ISO_8859_2; + encoding_map["iso-ir-109"] = ISO_8859_3; + encoding_map["iso-ir-110"] = ISO_8859_4; + encoding_map["iso-ir-126"] = ISO_8859_7; + encoding_map["iso-ir-127"] = ISO_8859_6; + encoding_map["iso-ir-138"] = ISO_8859_8; + encoding_map["iso-ir-144"] = ISO_8859_5; + encoding_map["iso-ir-148"] = ISO_8859_9; + encoding_map["iso-ir-149"] = KOREAN_EUC_KR; + encoding_map["iso-ir-157"] = ISO_8859_10; + encoding_map["iso-ir-58"] = CHINESE_GB; + encoding_map["iso-latin-1"] = ISO_8859_1; + encoding_map["iso_2022-cn"] = ISO_2022_CN; + encoding_map["iso_2022-kr"] = ISO_2022_KR; + encoding_map["iso_8859-1"] = ISO_8859_1; + encoding_map["iso_8859-10:1992"] = ISO_8859_10; + encoding_map["iso_8859-11"] = ISO_8859_11; + encoding_map["iso_8859-13"] = ISO_8859_13; + encoding_map["iso_8859-15"] = ISO_8859_15; + encoding_map["iso_8859-1:1987"] = ISO_8859_1; + encoding_map["iso_8859-2"] = ISO_8859_2; + encoding_map["iso_8859-2:1987"] = ISO_8859_2; + encoding_map["iso_8859-3"] = ISO_8859_3; + encoding_map["iso_8859-3:1988"] = ISO_8859_3; + encoding_map["iso_8859-4"] = ISO_8859_4; + encoding_map["iso_8859-4:1988"] = ISO_8859_4; + encoding_map["iso_8859-5"] = ISO_8859_5; + encoding_map["iso_8859-5:1988"] = ISO_8859_5; + encoding_map["iso_8859-6"] = ISO_8859_6; + encoding_map["iso_8859-6:1987"] = ISO_8859_6; + encoding_map["iso_8859-7"] = ISO_8859_7; + encoding_map["iso_8859-7:1987"] = ISO_8859_7; + encoding_map["iso_8859-8"] = ISO_8859_8; + encoding_map["iso_8859-8:1988:"] = ISO_8859_8; + encoding_map["iso_8859-9"] = ISO_8859_9; + encoding_map["iso_8859-9:1989"] = ISO_8859_9; + encoding_map["jagran"] = JAGRAN; + encoding_map["jis"] = JAPANESE_JIS; // not iana standard + encoding_map["koi8-cs"] = CZECH_CSN_369103; + encoding_map["koi8-r"] = RUSSIAN_KOI8_R; + encoding_map["koi8-ru"] = RUSSIAN_KOI8_RU; // not iana standard + encoding_map["koi8-u"] = RUSSIAN_KOI8_RU; + encoding_map["koi8r"] = RUSSIAN_KOI8_R; // not iana standard + encoding_map["koi8u"] = RUSSIAN_KOI8_RU; // not iana standard + encoding_map["korean"] = KOREAN_EUC_KR; // i assume this is what is meant + encoding_map["ks-c-5601"] = KOREAN_EUC_KR; // not iana standard + encoding_map["ks-c-5601-1987"] = KOREAN_EUC_KR; // not iana standard + encoding_map["ks_c_5601-1989"] = KOREAN_EUC_KR; + encoding_map["ksc"] = KOREAN_EUC_KR; // not iana standard + encoding_map["l1"] = ISO_8859_1; + encoding_map["l2"] = ISO_8859_2; + encoding_map["l3"] = ISO_8859_3; + encoding_map["l4"] = ISO_8859_4; + encoding_map["l5"] = ISO_8859_9; + encoding_map["l6"] = ISO_8859_10; + encoding_map["latin-1"] = ISO_8859_1; // not iana standard + encoding_map["latin1"] = ISO_8859_1; + encoding_map["latin2"] = ISO_8859_2; + encoding_map["latin3"] = ISO_8859_3; + encoding_map["latin4"] = ISO_8859_4; + encoding_map["latin5"] = ISO_8859_9; + encoding_map["latin6"] = ISO_8859_10; + encoding_map["mac"] = MACINTOSH_ROMAN; + encoding_map["macintosh"] = MACINTOSH_ROMAN; + encoding_map["macintosh-roman"] = MACINTOSH_ROMAN; + encoding_map["ms932"] = JAPANESE_CP932; // not iana standard + encoding_map["ms_kanji"] = JAPANESE_CP932; + encoding_map["shift-jis"] = JAPANESE_SHIFT_JIS; + encoding_map["shift_jis"] = JAPANESE_SHIFT_JIS; + encoding_map["sjis"] = JAPANESE_SHIFT_JIS; // not iana standard + encoding_map["sjs"] = JAPANESE_SHIFT_JIS; // not iana standard + encoding_map["sun_eu_greek"] = ISO_8859_7; + encoding_map["tab"] = TAMIL_BI; + encoding_map["tam"] = TAMIL_MONO; + encoding_map["tis-620"] = ISO_8859_11; + encoding_map["tscii"] = TSCII; + encoding_map["un"] = UNKNOWN_ENCODING; // not iana standard + encoding_map["unicode"] = UNICODE; // not iana standard + encoding_map["unicode-1-1-utf-7"] = UTF7; + encoding_map["unicode-1-1-utf-8"] = UTF8; + encoding_map["unicode-2-0-utf-7"] = UTF7; + encoding_map["unknown"] = UNKNOWN_ENCODING; // not iana standard + encoding_map["us"] = ISO_8859_1; + encoding_map["us-ascii"] = ISO_8859_1; + encoding_map["utf-16be"] = UTF16BE; + encoding_map["utf-16le"] = UTF16LE; + encoding_map["utf-32be"] = UTF32BE; + encoding_map["utf-32le"] = UTF32LE; + encoding_map["utf-7"] = UTF7; + encoding_map["utf-8"] = UTF8; + encoding_map["utf7"] = UTF7; + encoding_map["utf8"] = UTF8; // not iana standard + encoding_map["visual"] = HEBREW_VISUAL; + encoding_map["win-1250"] = MSFT_CP1250; // not iana standard + encoding_map["win-1251"] = RUSSIAN_CP1251; // not iana standard + encoding_map["window-874"] = MSFT_CP874; + encoding_map["windows-1250"] = MSFT_CP1250; + encoding_map["windows-1251"] = RUSSIAN_CP1251; + encoding_map["windows-1252"] = MSFT_CP1252; + encoding_map["windows-1253"] = MSFT_CP1253; + encoding_map["windows-1254"] = MSFT_CP1254; + encoding_map["windows-1255"] = MSFT_CP1255; + encoding_map["windows-1256"] = MSFT_CP1256; + encoding_map["windows-1257"] = MSFT_CP1257; + encoding_map["windows-31j"] = JAPANESE_CP932; + encoding_map["windows-874"] = MSFT_CP874; + encoding_map["windows-936"] = GBK; + encoding_map["x-big5"] = CHINESE_BIG5; + encoding_map["x-binaryenc"] = BINARYENC; // not iana standard + encoding_map["x-cp1250"] = MSFT_CP1250; + encoding_map["x-cp1251"] = RUSSIAN_CP1251; + encoding_map["x-cp1252"] = MSFT_CP1252; + encoding_map["x-cp1253"] = MSFT_CP1253; + encoding_map["x-cp1254"] = MSFT_CP1254; + encoding_map["x-cp1255"] = MSFT_CP1255; + encoding_map["x-cp1256"] = MSFT_CP1256; + encoding_map["x-cp1257"] = MSFT_CP1257; + encoding_map["x-euc-jp"] = JAPANESE_EUC_JP; + encoding_map["x-euc-tw"] = CHINESE_CNS; + encoding_map["x-gbk"] = GBK; + encoding_map["x-iso-10646-ucs-2-be"] = UTF16BE; + encoding_map["x-iso-10646-ucs-2-le"] = UTF16LE; + encoding_map["x-iso-10646-ucs-4-be"] = UTF32BE; + encoding_map["x-iso-10646-ucs-4-le"] = UTF32LE; + encoding_map["x-jis"] = JAPANESE_JIS; // not iana standard + encoding_map["x-mac-roman"] = MACINTOSH_ROMAN; + encoding_map["x-shift_jis"] = JAPANESE_SHIFT_JIS; // not iana standard + encoding_map["x-sjis"] = JAPANESE_SHIFT_JIS; + encoding_map["x-unicode-2-0-utf-7"] = UTF7; + encoding_map["x-utf8utf8"] = UTF8UTF8; // not iana standard + encoding_map["x-x-big5"] = CHINESE_BIG5; + encoding_map["zh_cn.euc"] = CHINESE_GB; + encoding_map["zh_tw-big5"] = CHINESE_BIG5; + encoding_map["zh_tw-euc"] = CHINESE_CNS; + + // Remove they entry for the empty string, if any. + encoding_map.erase(""); + + return encoding_map; +} + +// ---------------------------------------------------------------------- +// EncodingNameAliasToEncoding() +// +// This function takes an encoding name/alias and returns the Encoding +// enum. The input is case insensitive. It is the union of the common +// IANA standard names, the charset names used in Netscape Navigator, +// and some common names we have been using. +// See: http://www.iana.org/assignments/character-sets +// http://physics.hallym.ac.kr/resource/relnotes/windows-2.0.html +// +// UNKNOWN_ENCODING is returned if none matches. +// +// TODO: Check if it is possible to remove the non-standard, +// non-netscape-use names. It is because this routine is used for +// encoding detections from html meta info. Non-standard names may +// introduce noise on encoding detection. +// +// TODO: Unify EncodingNameAliasToEncoding and EncodingFromName, +// or determine why such a unification is not possible. +// ---------------------------------------------------------------------- +Encoding EncodingNameAliasToEncoding(const char *encoding_name) { + if (!encoding_name) { + return UNKNOWN_ENCODING; + } + + const EncodingMap& encoding_map = GetEncodingMap(); + + EncodingMap::const_iterator emi = encoding_map.find(encoding_name); + if (emi != encoding_map.end()) { + return emi->second; + } else { + return UNKNOWN_ENCODING; + } +} + +const char* default_encoding_name() { + return kEncodingInfoTable[LATIN1].encoding_name_; +} + +static const char* const kInvalidEncodingName = "invalid_encoding"; + +const char *invalid_encoding_name() { + return kInvalidEncodingName; +} + + + +// ************************************************************* +// Miscellany +// ************************************************************* + + +Encoding PreferredWebOutputEncoding(Encoding enc) { + return IsValidEncoding(enc) + ? kEncodingInfoTable[enc].preferred_web_output_encoding_ + : UTF8; +} diff --git a/ced/util/encodings/encodings.h b/ced/util/encodings/encodings.h new file mode 100644 index 0000000..6477974 --- /dev/null +++ b/ced/util/encodings/encodings.h @@ -0,0 +1,299 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_ENCODINGS_ENCODINGS_H_ +#define UTIL_ENCODINGS_ENCODINGS_H_ + +// This interface defines the Encoding enum and various functions that +// depend only on Encoding values. + +// A hash-function for Encoding, hash, is defined in +// i18n/encodings/public/encodings-hash.h + +// On some Windows projects, UNICODE may be defined, which would prevent the +// Encoding enum below from compiling. Note that this is a quick fix that does +// not break any existing projects. The UNICODE enum may someday be changed +// to something more specific and non-colliding, but this involves careful +// testing of changes in many other projects. +#undef UNICODE + +// NOTE: The Encoding enum must always start at 0. This assumption has +// been made and used. + +#ifndef SWIG + +#include "util/encodings/encodings.pb.h" + +#else + +// TODO: Include a SWIG workaround header file. + +#endif + +const int kNumEncodings = NUM_ENCODINGS; + +// some of the popular encoding aliases +// TODO: Make these static const Encoding values instead of macros. +#define LATIN1 ISO_8859_1 +#define LATIN2 ISO_8859_2 +#define LATIN3 ISO_8859_3 +#define LATIN4 ISO_8859_4 +#define CYRILLIC ISO_8859_5 +#define ARABIC_ENCODING ISO_8859_6 // avoiding the same name as language +#define GREEK_ENCODING ISO_8859_7 // avoiding the same name as language +#define HEBREW_ENCODING ISO_8859_8 // avoiding the same name as language +#define LATIN5 ISO_8859_9 +#define LATIN6 ISO_8859_10 +#define KOREAN_HANGUL KOREAN_EUC_KR + +// The default Encoding (LATIN1). +Encoding default_encoding(); + + + +// ************************************************************* +// Encoding predicates +// IsValidEncoding() +// IsEncEncCompatible +// IsSupersetOfAscii7Bit +// Is8BitEncoding +// IsCJKEncoding +// IsHebrewEncoding +// IsRightToLeftEncoding +// IsLogicalRightToLeftEncoding +// IsVisualRightToLeftEncoding +// IsIso2022Encoding +// IsIso2022JpOrVariant +// IsShiftJisOrVariant +// IsJapaneseCellPhoneCarrierSpecificEncoding +// ************************************************************* + +// IsValidEncoding +// =================================== +// +// Function to check if the input language enum is within range. +// + +bool IsValidEncoding(Encoding enc); + +// +// IsEncEncCompatible +// ------------------ +// +// This function is to determine whether or not converting from the +// first encoding to the second requires any changes to the underlying +// text (e.g. ASCII_7BIT is a subset of UTF8). +// +// TODO: the current implementation is likely incomplete. It would be +// good to consider the full matrix of all pairs of encodings and to fish out +// all compatible pairs. +// +bool IsEncEncCompatible(const Encoding from, const Encoding to); + +// To be a superset of 7-bit Ascii means that bytes 0...127 in the given +// encoding represent the same characters as they do in ISO_8859_1. + +// WARNING: This function does not currently return true for all encodings that +// are supersets of Ascii 7-bit. +bool IsSupersetOfAscii7Bit(Encoding e); + +// To be an 8-bit encoding means that there are fewer than 256 symbols. +// Each byte determines a new character; there are no multi-byte sequences. + +// WARNING: This function does not currently return true for all encodings that +// are 8-bit encodings. +bool Is8BitEncoding(Encoding e); + +// IsCJKEncoding +// ------------- +// +// This function returns true if the encoding is either Chinese +// (simplified or traditional), Japanese, or Korean. Note: UTF8 is not +// considered a CJK encoding. +bool IsCJKEncoding(Encoding e); + +// IsHebrewEncoding +// ------------- +// +// This function returns true if the encoding is a Hebrew specific +// encoding (not UTF8, etc). +bool IsHebrewEncoding(Encoding e); + +// IsRightToLeftEncoding +// --------------------- +// +// Returns true if the encoding is a right-to-left encoding. +// +// Note that the name of this function is somewhat misleading. There is nothing +// "right to left" about these encodings. They merely contain code points for +// characters in RTL languages such as Hebrew and Arabic. But this is also +// true for UTF-8. +// +// TODO: Get rid of this function. The only special-case we +// should need to worry about are visual encodings. Anything we +// need to do for all 'RTL' encodings we need to do for UTF-8 as well. +bool IsRightToLeftEncoding(Encoding enc); + +// IsLogicalRightToLeftEncoding +// ---------------------------- +// +// Returns true if the encoding is a logical right-to-left encoding. +// Logical right-to-left encodings are those that the browser renders +// right-to-left and applies the BiDi algorithm to. Therefore the characters +// appear in reading order in the file, and indexing, snippet generation etc. +// should all just work with no special processing. +// +// TODO: Get rid of this function. The only special-case we +// should need to worry about are visual encodings. +bool IsLogicalRightToLeftEncoding(Encoding enc); + +// IsVisualRightToLeftEncoding +// --------------------------- +// +// Returns true if the encoding is a visual right-to-left encoding. +// Visual right-to-left encodings are those that the browser renders +// left-to-right and does not apply the BiDi algorithm to. Therefore each +// line appears in reverse order in the file, lines are manually wrapped +// by abusing
or

tags, etc. Visual RTL encoding is a relic of +// the prehistoric days when browsers couldn't render right-to-left, but +// unfortunately some visual pages persist to this day. These documents require +// special processing so that we don't index or snippet them with each line +// reversed. +bool IsVisualRightToLeftEncoding(Encoding enc); + +// IsIso2022Encoding +// ----------------- +// +// Returns true if the encoding is a kind of ISO 2022 such as +// ISO-2022-JP. +bool IsIso2022Encoding(Encoding enc); + +// IsIso2022JpOrVariant +// -------------------- +// +// Returns true if the encoding is ISO-2022-JP or a variant such as +// KDDI's ISO-2022-JP. +bool IsIso2022JpOrVariant(Encoding enc); + +// IsShiftJisOrVariant +// -------------------- +// +// Returns true if the encoding is Shift_JIS or a variant such as +// KDDI's Shift_JIS. +bool IsShiftJisOrVariant(Encoding enc); + +// IsJapanesCellPhoneCarrierSpecificEncoding +// ----------------------------------------- +// +// Returns true if it's Japanese cell phone carrier specific encoding +// such as KDDI_SHIFT_JIS. +bool IsJapaneseCellPhoneCarrierSpecificEncoding(Encoding enc); + + + +// ************************************************************* +// ENCODING NAMES +// +// This interface defines a standard name for each valid encoding, and +// a standard name for invalid encodings. (Some names use all upper +// case, but others use mixed case.) +// +// EncodingName() [Encoding to name] +// MimeEncodingName() [Encoding to name] +// EncodingFromName() [name to Encoding] +// EncodingNameAliasToEncoding() [name to Encoding] +// default_encoding_name() +// invalid_encoding_name() +// ************************************************************* + +// EncodingName +// ------------ +// +// Given the encoding, returns its standard name. +// Return invalid_encoding_name() if the encoding is invalid. +// +const char* EncodingName(Encoding enc); + +// +// MimeEncodingName +// ---------------- +// +// Return the "preferred MIME name" of an encoding. +// +// This name is suitable for using in HTTP headers, HTML tags, +// and as the "charset" parameter of a MIME Content-Type. +const char* MimeEncodingName(Encoding enc); + + +// The maximum length of an encoding name +const int kMaxEncodingNameSize = 50; + +// The standard name of the default encoding. +const char* default_encoding_name(); + +// The name used for an invalid encoding. +const char* invalid_encoding_name(); + +// EncodingFromName +// ---------------- +// +// If enc_name matches the standard name of an Encoding, using a +// case-insensitive comparison, set *encoding to that Encoding and +// return true. Otherwise set *encoding to UNKNOWN_ENCODING and +// return false. +// +// REQUIRES: encoding must not be NULL. +// +bool EncodingFromName(const char* enc_name, Encoding *encoding); + +// +// EncodingNameAliasToEncoding +// --------------------------- +// +// If enc_name matches the standard name or an alias of an Encoding, +// using a case-insensitive comparison, return that +// Encoding. Otherwise, return UNKNOWN_ENCODING. +// +// Aliases include most mime-encoding names (e.g., "ISO-8859-7" for +// GREEK), alternate names (e.g., "cyrillic" for ISO_8859_5) and +// common variations with hyphens and underscores (e.g., "koi8-u" and +// "koi8u" for RUSSIAN_KOI8_R). + +Encoding EncodingNameAliasToEncoding(const char *enc_name); + +// ************************************************************* +// Miscellany +// ************************************************************* + +// PreferredWebOutputEncoding +// -------------------------- +// +// Some multi-byte encodings use byte values that coincide with the +// ASCII codes for HTML syntax characters <>"&' and browsers like MSIE +// can misinterpret these, as indicated in an external XSS report from +// 2007-02-15. Here, we map these dangerous encodings to safer ones. We +// also use UTF8 instead of encodings that we don't support in our +// output, and we generally try to be conservative in what we send out. +// Where the client asks for single- or double-byte encodings that are +// not as common, we substitute a more common single- or double-byte +// encoding, if there is one, thereby preserving the client's intent +// to use less space than UTF-8. This also means that characters +// outside the destination set will be converted to HTML NCRs (&#NNN;) +// if requested. +Encoding PreferredWebOutputEncoding(Encoding enc); + + +#endif // UTIL_ENCODINGS_ENCODINGS_H_ diff --git a/ced/util/encodings/encodings.pb.h b/ced/util/encodings/encodings.pb.h new file mode 100644 index 0000000..ffbd716 --- /dev/null +++ b/ced/util/encodings/encodings.pb.h @@ -0,0 +1,181 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_ENCODINGS_ENCODINGS_PB_H_ +#define UTIL_ENCODINGS_ENCODINGS_PB_H_ + +enum Encoding { + ISO_8859_1 = 0, // Teragram ASCII + ISO_8859_2 = 1, // Teragram Latin2 + ISO_8859_3 = 2, // in BasisTech but not in Teragram + ISO_8859_4 = 3, // Teragram Latin4 + ISO_8859_5 = 4, // Teragram ISO-8859-5 + ISO_8859_6 = 5, // Teragram Arabic + ISO_8859_7 = 6, // Teragram Greek + ISO_8859_8 = 7, // Teragram Hebrew + ISO_8859_9 = 8, // in BasisTech but not in Teragram + ISO_8859_10 = 9, // in BasisTech but not in Teragram + JAPANESE_EUC_JP = 10, // Teragram EUC_JP + JAPANESE_SHIFT_JIS = 11, // Teragram SJS + JAPANESE_JIS = 12, // Teragram JIS + CHINESE_BIG5 = 13, // Teragram BIG5 + CHINESE_GB = 14, // Teragram GB + CHINESE_EUC_CN = 15, // Misnamed. Should be EUC_TW. Was Basis Tech + // CNS11643EUC, before that Teragram EUC-CN(!) + // See //i18n/basistech/basistech_encodings.h + KOREAN_EUC_KR = 16, // Teragram KSC + UNICODE = 17, // Teragram Unicode + CHINESE_EUC_DEC = 18, // Misnamed. Should be EUC_TW. Was Basis Tech + // CNS11643EUC, before that Teragram EUC. + CHINESE_CNS = 19, // Misnamed. Should be EUC_TW. Was Basis Tech + // CNS11643EUC, before that Teragram CNS. + CHINESE_BIG5_CP950 = 20, // Teragram BIG5_CP950 + JAPANESE_CP932 = 21, // Teragram CP932 + UTF8 = 22, + UNKNOWN_ENCODING = 23, + ASCII_7BIT = 24, // ISO_8859_1 with all characters <= 127. + // Should be present only in the crawler + // and in the repository, + // *never* as a result of Document::encoding(). + RUSSIAN_KOI8_R = 25, // Teragram KOI8R + RUSSIAN_CP1251 = 26, // Teragram CP1251 + + //---------------------------------------------------------- + // These are _not_ output from teragram. Instead, they are as + // detected in the headers of usenet articles. + MSFT_CP1252 = 27, // 27: CP1252 aka MSFT euro ascii + RUSSIAN_KOI8_RU = 28, // CP21866 aka KOI8-U, used for Ukrainian. + // Misnamed, this is _not_ KOI8-RU but KOI8-U. + // KOI8-U is used much more often than KOI8-RU. + MSFT_CP1250 = 29, // CP1250 aka MSFT eastern european + ISO_8859_15 = 30, // aka ISO_8859_0 aka ISO_8859_1 euroized + //---------------------------------------------------------- + + //---------------------------------------------------------- + // These are in BasisTech but not in Teragram. They are + // needed for new interface languages. Now detected by + // research langid + MSFT_CP1254 = 31, // used for Turkish + MSFT_CP1257 = 32, // used in Baltic countries + //---------------------------------------------------------- + + //---------------------------------------------------------- + //---------------------------------------------------------- + // New encodings detected by Teragram + ISO_8859_11 = 33, // aka TIS-620, used for Thai + MSFT_CP874 = 34, // used for Thai + MSFT_CP1256 = 35, // used for Arabic + + //---------------------------------------------------------- + // Detected as ISO_8859_8 by Teragram, but can be found in META tags + MSFT_CP1255 = 36, // Logical Hebrew Microsoft + ISO_8859_8_I = 37, // Iso Hebrew Logical + HEBREW_VISUAL = 38, // Iso Hebrew Visual + //---------------------------------------------------------- + + //---------------------------------------------------------- + // Detected by research langid + CZECH_CP852 = 39, + CZECH_CSN_369103 = 40, // aka ISO_IR_139 aka KOI8_CS + MSFT_CP1253 = 41, // used for Greek + RUSSIAN_CP866 = 42, + //---------------------------------------------------------- + + //---------------------------------------------------------- + // Handled by iconv in glibc + ISO_8859_13 = 43, + ISO_2022_KR = 44, + GBK = 45, + GB18030 = 46, + BIG5_HKSCS = 47, + ISO_2022_CN = 48, + + //----------------------------------------------------------- + // Detected by xin liu's detector + // Handled by transcoder + // (Indic encodings) + + TSCII = 49, + TAMIL_MONO = 50, + TAMIL_BI = 51, + JAGRAN = 52, + + + MACINTOSH_ROMAN = 53, + UTF7 = 54, + BHASKAR = 55, // Indic encoding - Devanagari + HTCHANAKYA = 56, // 56 Indic encoding - Devanagari + + //----------------------------------------------------------- + // These allow a single place (inputconverter and outputconverter) + // to do UTF-16 <==> UTF-8 bulk conversions and UTF-32 <==> UTF-8 + // bulk conversions, with interchange-valid checking on input and + // fallback if needed on ouput. + UTF16BE = 57, // big-endian UTF-16 + UTF16LE = 58, // little-endian UTF-16 + UTF32BE = 59, // big-endian UTF-32 + UTF32LE = 60, // little-endian UTF-32 + //----------------------------------------------------------- + + //----------------------------------------------------------- + // An encoding that means "This is not text, but it may have some + // simple ASCII text embedded". Intended input conversion (not yet + // implemented) is to keep strings of >=4 seven-bit ASCII characters + // (follow each kept string with an ASCII space), delete the rest of + // the bytes. This will pick up and allow indexing of e.g. captions + // in JPEGs. No output conversion needed. + BINARYENC = 61, + //----------------------------------------------------------- + + //----------------------------------------------------------- + // Some Web pages allow a mixture of HZ-GB and GB-2312 by using + // ~{ ... ~} for 2-byte pairs, and the browsers support this. + HZ_GB_2312 = 62, + //----------------------------------------------------------- + + //----------------------------------------------------------- + // Some external vendors make the common input error of + // converting MSFT_CP1252 to UTF8 *twice*. No output conversion needed. + UTF8UTF8 = 63, + //----------------------------------------------------------- + + //----------------------------------------------------------- + // Handled by transcoder for tamil language specific font + // encodings without the support for detection at present. + TAM_ELANGO = 64, // Elango - Tamil + TAM_LTTMBARANI = 65, // Barani - Tamil + TAM_SHREE = 66, // Shree - Tamil + TAM_TBOOMIS = 67, // TBoomis - Tamil + TAM_TMNEWS = 68, // TMNews - Tamil + TAM_WEBTAMIL = 69, // Webtamil - Tamil + //----------------------------------------------------------- + + //----------------------------------------------------------- + // Shift_JIS variants used by Japanese cell phone carriers. + KDDI_SHIFT_JIS = 70, + DOCOMO_SHIFT_JIS = 71, + SOFTBANK_SHIFT_JIS = 72, + // ISO-2022-JP variants used by KDDI and SoftBank. + KDDI_ISO_2022_JP = 73, + SOFTBANK_ISO_2022_JP = 74, + //----------------------------------------------------------- + + NUM_ENCODINGS = 75, // Always keep this at the end. It is not a + // valid Encoding enum, it is only used to + // indicate the total number of Encodings. +}; + +#endif // UTIL_ENCODINGS_ENCODINGS_PB_H_ diff --git a/ced/util/languages/languages.cc b/ced/util/languages/languages.cc new file mode 100644 index 0000000..852351f --- /dev/null +++ b/ced/util/languages/languages.cc @@ -0,0 +1,349 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "util/languages/languages.h" + +#include "util/basictypes.h" +#include "util/string_util.h" + + +Language default_language() {return ENGLISH;} + + +// Language names and codes + +struct LanguageInfo { + const char * language_name_; + const char * language_code_639_1_; // the ISO-639-1 code for the language + const char * language_code_639_2_; // the ISO-639-2 code for the language + const char * language_code_other_; // some nonstandard code for the language +}; + +static const LanguageInfo kLanguageInfoTable[] = { + { "ENGLISH", "en", "eng", NULL}, + { "DANISH", "da", "dan", NULL}, + { "DUTCH", "nl", "dut", NULL}, + { "FINNISH", "fi", "fin", NULL}, + { "FRENCH", "fr", "fre", NULL}, + { "GERMAN", "de", "ger", NULL}, + { "HEBREW", "he", "heb", NULL}, + { "ITALIAN", "it", "ita", NULL}, + { "Japanese", "ja", "jpn", NULL}, + { "Korean", "ko", "kor", NULL}, + { "NORWEGIAN", "nb", "nor", NULL}, + { "POLISH", "pl", "pol", NULL}, + { "PORTUGUESE", "pt", "por", NULL}, + { "RUSSIAN", "ru", "rus", NULL}, + { "SPANISH", "es", "spa", NULL}, + { "SWEDISH", "sv", "swe", NULL}, + { "Chinese", "zh", "chi", "zh-CN"}, + { "CZECH", "cs", "cze", NULL}, + { "GREEK", "el", "gre", NULL}, + { "ICELANDIC", "is", "ice", NULL}, + { "LATVIAN", "lv", "lav", NULL}, + { "LITHUANIAN", "lt", "lit", NULL}, + { "ROMANIAN", "ro", "rum", NULL}, + { "HUNGARIAN", "hu", "hun", NULL}, + { "ESTONIAN", "et", "est", NULL}, + // TODO: Although Teragram has two output names "TG_UNKNOWN_LANGUAGE" + // and "Unknown", they are essentially the same. Need to unify them. + // "un" and "ut" are invented by us, not from ISO-639. + // + { "TG_UNKNOWN_LANGUAGE", NULL, NULL, "ut"}, + { "Unknown", NULL, NULL, "un"}, + { "BULGARIAN", "bg", "bul", NULL}, + { "CROATIAN", "hr", "scr", NULL}, + { "SERBIAN", "sr", "scc", NULL}, + { "IRISH", "ga", "gle", NULL}, + { "GALICIAN", "gl", "glg", NULL}, + // Impossible to tell Tagalog from Filipino at the moment. + // Use ISO 639-2 code for Filipino here. + { "TAGALOG", NULL, "fil", NULL}, + { "TURKISH", "tr", "tur", NULL}, + { "UKRAINIAN", "uk", "ukr", NULL}, + { "HINDI", "hi", "hin", NULL}, + { "MACEDONIAN", "mk", "mac", NULL}, + { "BENGALI", "bn", "ben", NULL}, + { "INDONESIAN", "id", "ind", NULL}, + { "LATIN", "la", "lat", NULL}, + { "MALAY", "ms", "may", NULL}, + { "MALAYALAM", "ml", "mal", NULL}, + { "WELSH", "cy", "wel", NULL}, + { "NEPALI", "ne", "nep", NULL}, + { "TELUGU", "te", "tel", NULL}, + { "ALBANIAN", "sq", "alb", NULL}, + { "TAMIL", "ta", "tam", NULL}, + { "BELARUSIAN", "be", "bel", NULL}, + { "JAVANESE", "jw", "jav", NULL}, + { "OCCITAN", "oc", "oci", NULL}, + { "URDU", "ur", "urd", NULL}, + { "BIHARI", "bh", "bih", NULL}, + { "GUJARATI", "gu", "guj", NULL}, + { "THAI", "th", "tha", NULL}, + { "ARABIC", "ar", "ara", NULL}, + { "CATALAN", "ca", "cat", NULL}, + { "ESPERANTO", "eo", "epo", NULL}, + { "BASQUE", "eu", "baq", NULL}, + { "INTERLINGUA", "ia", "ina", NULL}, + { "KANNADA", "kn", "kan", NULL}, + { "PUNJABI", "pa", "pan", NULL}, + { "SCOTS_GAELIC", "gd", "gla", NULL}, + { "SWAHILI", "sw", "swa", NULL}, + { "SLOVENIAN", "sl", "slv", NULL}, + { "MARATHI", "mr", "mar", NULL}, + { "MALTESE", "mt", "mlt", NULL}, + { "VIETNAMESE", "vi", "vie", NULL}, + { "FRISIAN", "fy", "fry", NULL}, + { "SLOVAK", "sk", "slo", NULL}, + { "ChineseT", + NULL, NULL, // We intentionally set these 2 fields to NULL to avoid + // confusion between CHINESE_T and CHINESE. + "zh-TW"}, + { "FAROESE", "fo", "fao", NULL}, + { "SUNDANESE", "su", "sun", NULL}, + { "UZBEK", "uz", "uzb", NULL}, + { "AMHARIC", "am", "amh", NULL}, + { "AZERBAIJANI", "az", "aze", NULL}, + { "GEORGIAN", "ka", "geo", NULL}, + { "TIGRINYA", "ti", "tir", NULL}, + { "PERSIAN", "fa", "per", NULL}, + { "BOSNIAN", "bs", "bos", NULL}, + { "SINHALESE", "si", "sin", NULL}, + { "NORWEGIAN_N", "nn", "nno", NULL}, + { "PORTUGUESE_P", NULL, NULL, "pt-PT"}, + { "PORTUGUESE_B", NULL, NULL, "pt-BR"}, + { "XHOSA", "xh", "xho", NULL}, + { "ZULU", "zu", "zul", NULL}, + { "GUARANI", "gn", "grn", NULL}, + { "SESOTHO", "st", "sot", NULL}, + { "TURKMEN", "tk", "tuk", NULL}, + { "KYRGYZ", "ky", "kir", NULL}, + { "BRETON", "br", "bre", NULL}, + { "TWI", "tw", "twi", NULL}, + { "YIDDISH", "yi", "yid", NULL}, + { "SERBO_CROATIAN", "sh", NULL, NULL}, + { "SOMALI", "so", "som", NULL}, + { "UIGHUR", "ug", "uig", NULL}, + { "KURDISH", "ku", "kur", NULL}, + { "MONGOLIAN", "mn", "mon", NULL}, + { "ARMENIAN", "hy", "arm", NULL}, + { "LAOTHIAN", "lo", "lao", NULL}, + { "SINDHI", "sd", "snd", NULL}, + { "RHAETO_ROMANCE", "rm", "roh", NULL}, + { "AFRIKAANS", "af", "afr", NULL}, + { "LUXEMBOURGISH", "lb", "ltz", NULL}, + { "BURMESE", "my", "bur", NULL}, + // KHMER is known as Cambodian for Google user interfaces. + { "KHMER", "km", "khm", NULL}, + { "TIBETAN", "bo", "tib", NULL}, + { "DHIVEHI", "dv", "div", NULL}, + { "CHEROKEE", NULL, "chr", NULL}, + { "SYRIAC", NULL, "syr", NULL}, + { "LIMBU", NULL, NULL, "sit-NP"}, + { "ORIYA", "or", "ori", NULL}, + { "ASSAMESE", "as", "asm", NULL}, + { "CORSICAN", "co", "cos", NULL}, + { "INTERLINGUE", "ie", "ine", NULL}, + { "KAZAKH", "kk", "kaz", NULL}, + { "LINGALA", "ln", "lin", NULL}, + { "MOLDAVIAN", "mo", "mol", NULL}, + { "PASHTO", "ps", "pus", NULL}, + { "QUECHUA", "qu", "que", NULL}, + { "SHONA", "sn", "sna", NULL}, + { "TAJIK", "tg", "tgk", NULL}, + { "TATAR", "tt", "tat", NULL}, + { "TONGA", "to", "tog", NULL}, + { "YORUBA", "yo", "yor", NULL}, + { "CREOLES_AND_PIDGINS_ENGLISH_BASED", NULL, "cpe", NULL}, + { "CREOLES_AND_PIDGINS_FRENCH_BASED", NULL, "cpf", NULL}, + { "CREOLES_AND_PIDGINS_PORTUGUESE_BASED", NULL, "cpp", NULL}, + { "CREOLES_AND_PIDGINS_OTHER", NULL, "crp", NULL}, + { "MAORI", "mi", "mao", NULL}, + { "WOLOF", "wo", "wol", NULL}, + { "ABKHAZIAN", "ab", "abk", NULL}, + { "AFAR", "aa", "aar", NULL}, + { "AYMARA", "ay", "aym", NULL}, + { "BASHKIR", "ba", "bak", NULL}, + { "BISLAMA", "bi", "bis", NULL}, + { "DZONGKHA", "dz", "dzo", NULL}, + { "FIJIAN", "fj", "fij", NULL}, + { "GREENLANDIC", "kl", "kal", NULL}, + { "HAUSA", "ha", "hau", NULL}, + { "HAITIAN_CREOLE", "ht", NULL, NULL}, + { "INUPIAK", "ik", "ipk", NULL}, + { "INUKTITUT", "iu", "iku", NULL}, + { "KASHMIRI", "ks", "kas", NULL}, + { "KINYARWANDA", "rw", "kin", NULL}, + { "MALAGASY", "mg", "mlg", NULL}, + { "NAURU", "na", "nau", NULL}, + { "OROMO", "om", "orm", NULL}, + { "RUNDI", "rn", "run", NULL}, + { "SAMOAN", "sm", "smo", NULL}, + { "SANGO", "sg", "sag", NULL}, + { "SANSKRIT", "sa", "san", NULL}, + { "SISWANT", "ss", "ssw", NULL}, + { "TSONGA", "ts", "tso", NULL}, + { "TSWANA", "tn", "tsn", NULL}, + { "VOLAPUK", "vo", "vol", NULL}, + { "ZHUANG", "za", "zha", NULL}, + { "KHASI", NULL, "kha", NULL}, + { "SCOTS", NULL, "sco", NULL}, + { "GANDA", "lg", "lug", NULL}, + { "MANX", "gv", "glv", NULL}, + { "MONTENEGRIN", NULL, NULL, "sr-ME"}, + { "XX", NULL, NULL, "XX"}, +}; + +COMPILE_ASSERT(arraysize(kLanguageInfoTable) == NUM_LANGUAGES + 1, + kLanguageInfoTable_has_incorrect_length); + + +// LANGUAGE NAMES + +const char* default_language_name() { + return kLanguageInfoTable[ENGLISH].language_name_; +} + +static const char* const kInvalidLanguageName = "invalid_language"; + +const char *invalid_language_name() { + return kInvalidLanguageName; +} + +const char* LanguageName(Language lang) { + return IsValidLanguage(lang) + ? kLanguageInfoTable[lang].language_name_ + : kInvalidLanguageName; +} + + + +// LANGUAGE CODES + + +// The space before invalid_language_code is intentional. It is used +// to prevent it matching any two letter language code. +// +static const char* const kInvalidLanguageCode = " invalid_language_code"; + +const char *invalid_language_code() { + return kInvalidLanguageCode; +} + +const char * LanguageCode(Language lang) { + if (! IsValidLanguage(lang)) + return kInvalidLanguageCode; + const LanguageInfo& info = kLanguageInfoTable[lang]; + if (info.language_code_639_1_) { + return info.language_code_639_1_; + } else if (info.language_code_639_2_) { + return info.language_code_639_2_; + } else if (info.language_code_other_) { + return info.language_code_other_; + } else { + return kInvalidLanguageCode; + } +} + +const char* default_language_code() { + return kLanguageInfoTable[ENGLISH].language_code_639_1_; +} + +const char* LanguageCodeISO639_1(Language lang) { + if (! IsValidLanguage(lang)) + return kInvalidLanguageCode; + if (const char* code = kLanguageInfoTable[lang].language_code_639_1_) + return code; + return kInvalidLanguageCode; +} + +const char* LanguageCodeISO639_2(Language lang) { + if (! IsValidLanguage(lang)) + return kInvalidLanguageCode; + if (const char* code = kLanguageInfoTable[lang].language_code_639_2_) + return code; + return kInvalidLanguageCode; +} + +const char* LanguageCodeWithDialects(Language lang) { + if (lang == CHINESE) + return "zh-CN"; + return LanguageCode(lang); +} + + + +bool LanguageFromCode(const char* lang_code, Language *language) { + *language = UNKNOWN_LANGUAGE; + if ( lang_code == NULL ) return false; + + for ( int i = 0 ; i < kNumLanguages ; i++ ) { + const LanguageInfo& info = kLanguageInfoTable[i]; + if ((info.language_code_639_1_ && + !base::strcasecmp(lang_code, info.language_code_639_1_)) || + (info.language_code_639_2_ && + !base::strcasecmp(lang_code, info.language_code_639_2_)) || + (info.language_code_other_ && + !base::strcasecmp(lang_code, info.language_code_other_))) { + *language = static_cast(i); + return true; + } + } + + // For convenience, this function can also parse the non-standard + // five-letter language codes "zh-cn" and "zh-tw" which are used by + // front-ends such as GWS to distinguish Simplified from Traditional + // Chinese. + if (!base::strcasecmp(lang_code, "zh-cn") || + !base::strcasecmp(lang_code, "zh_cn")) { + *language = CHINESE; + return true; + } + if (!base::strcasecmp(lang_code, "zh-tw") || + !base::strcasecmp(lang_code, "zh_tw")) { + *language = CHINESE_T; + return true; + } + if (!base::strcasecmp(lang_code, "sr-me") || + !base::strcasecmp(lang_code, "sr_me")) { + *language = MONTENEGRIN; + return true; + } + + // Process language-code synonyms. + if (!base::strcasecmp(lang_code, "he")) { + *language = HEBREW; // Use "iw". + return true; + } + if (!base::strcasecmp(lang_code, "in")) { + *language = INDONESIAN; // Use "id". + return true; + } + if (!base::strcasecmp(lang_code, "ji")) { + *language = YIDDISH; // Use "yi". + return true; + } + + // Process language-detection synonyms. + // These distinct languages cannot be differentiated by our current + // language-detection algorithms. + if (!base::strcasecmp(lang_code, "fil")) { + *language = TAGALOG; + return true; + } + + return false; +} diff --git a/ced/util/languages/languages.h b/ced/util/languages/languages.h new file mode 100644 index 0000000..4237961 --- /dev/null +++ b/ced/util/languages/languages.h @@ -0,0 +1,381 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_LANGUAGES_LANGUAGES_H_ +#define UTIL_LANGUAGES_LANGUAGES_H_ + +// This interface defines the Language enum and functions that depend +// only on Language values. + +// A hash-function for Language, hash, is defined in +// i18n/languages/public/languages-hash.h + +#ifndef SWIG +// Language enum defined in languages.proto +// Also description on how to add languages. +#include "util/languages/languages.pb.h" + +#else + +// TODO: Include a header containing swig-compatible enum. + +#endif + +const int kNumLanguages = NUM_LANGUAGES; + +// Return the default language (ENGLISH). +Language default_language(); + + +// ******************************************* +// Language predicates +// IsValidLanguage() +// IS_LANGUAGE_UNKNOWN() +// IsCJKLanguage() +// IsChineseLanguage() +// IsNorwegianLanguage() +// IsPortugueseLanguage() +// IsRightToLeftLanguage() +// IsMaybeRightToLeftLanguage() +// IsSameLanguage() +// IsScriptRequiringLongerSnippets() +// ******************************************* + +// IsValidLanguage +// =============== +// +// Function to check if the input is within range of the Language enum. If +// IsValidLanguage(lang) returns true, it is safe to call +// static_cast(lang). +// +inline bool IsValidLanguage(int lang) { + return ((lang >= 0) && (lang < kNumLanguages)); +} + +// Return true if the language is "unknown". (This function was +// previously a macro, hence the spelling in all caps.) +// +inline bool IS_LANGUAGE_UNKNOWN(Language lang) { + return lang == TG_UNKNOWN_LANGUAGE || lang == UNKNOWN_LANGUAGE; +} + +// IsCJKLanguage +// ------------- +// +// This function returns true if the language is either Chinese +// (simplified or traditional), Japanese, or Korean. +bool IsCJKLanguage(Language lang); + +// IsChineseLanguage +// ----------------- +// +// This function returns true if the language is either Chinese +// (simplified or traditional) +bool IsChineseLanguage(Language lang); + +// IsNorwegianLanguage +// -------------------- +// +// This function returns true if the language is any of the Norwegian +// (regular or Nynorsk). +bool IsNorwegianLanguage(Language lang); + +// IsPortugueseLanguage +// -------------------- +// +// This function returns true if the language is any of the Portuguese +// languages (regular, Portugal or Brazil) +bool IsPortugueseLanguage(Language lang); + +// IsSameLanguage +// -------------- +// +// WARNING: This function provides only a simple test on the values of +// the two Language arguments. It returns false if either language is +// invalid. It returns true if the language arguments are equal, or +// if they are both Chinese languages, both Norwegian languages, or +// both Portuguese languages, as defined by IsChineseLanguage, +// IsNorwegianLanguage, and IsPortugueseLanguage. Otherwise it returns +// false. +bool IsSameLanguage(Language lang1, Language lang2); + + +// IsRightToLeftLanguage +// --------------------- +// +// This function returns true if the language is only written right-to-left +// (E.g., Hebrew, Arabic, Persian etc.) +// +// IMPORTANT NOTE: Technically we're talking about scripts, not languages. +// There are languages that can be written in more than one script. +// Examples: +// - Kurdish and Azeri ('AZERBAIJANI') can be written left-to-right in +// Latin or Cyrillic script, and right-to-left in Arabic script. +// - Sindhi and Punjabi are written in different scripts, depending on +// region and dialect. +// - Turkmen used an Arabic script historically, but not any more. +// - Pashto and Uyghur can use Arabic script, but use a Roman script +// on the Internet. +// - Kashmiri and Urdu are written either with Arabic or Devanagari script. +// +// This function only returns true for languages that are always, unequivocally +// written in right-to-left script. +// +// TODO: If we want to do anything special with multi-script languages +// we should create new 'languages' for each language+script, as we do for +// traditional vs. simplified Chinese. However most such languages are rare in +// use and even rarer on the web, so this is unlikely to be something we'll +// be concerned with for a while. +bool IsRightToLeftLanguage(Language lang); + +// IsMaybeRightToLeftLanguage +// -------------------------- +// +// This function returns true if the language may appear on the web in a +// right-to-left script (E.g., Hebrew, Arabic, Persian, Urdu, Kurdish, etc.) +// +// NOTE: See important notes under IsRightToLeftLanguage(...). +// +// This function returns true for languages that *may* appear on the web in a +// right-to-left script, even if they may also appear in a left-to-right +// script. +// +// This function should typically be used in cases where doing some work on +// left-to-right text would be OK (usually a no-op), and this function is used +// just to cut down on unnecessary work on regular, LTR text. +bool IsMaybeRightToLeftLanguage(Language lang); + +// IsScriptRequiringLongerSnippets +// -------------------- +// +// This function returns true if the script chracteristics require longer +// snippet length (Devanagari, Bengali, Gurmukhi, +// Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam). +// COMMENTED OUT TO REDUCE DEPENDENCIES ON GOOGLE3 CODE +// bool IsScriptRequiringLongerSnippets(UnicodeScript script); + + +// ******************************************* +// LANGUAGE NAMES +// +// This interface defines a standard name for each valid Language, +// and a standard name for invalid languages. Some language names use all +// uppercase letters, but others use mixed case. +// LanguageName() [Language to name] +// LanguageEnumName() [language to enum name] +// LanguageFromName() [name to Language] +// default_language_name() +// invalid_language_name() +// ******************************************* + +// Given a Language, returns its standard name. +// Return invalid_language_name() if the language is invalid. +const char* LanguageName(Language lang); + +// Given a Language, return the name of the enum constant for that +// language. In all but a few cases, this is the same as its standard +// name. For example, LanguageName(CHINESE) returns "Chinese", but +// LanguageEnumName(CHINESE) returns "CHINESE". This is intended for +// code that is generating C++ code, where the enum constant is more +// useful than its integer value. Return "NUM_LANGUAGES" if +// the language is invalid. +const char* LanguageEnumName(Language lang); + +// The maximum length of a standard language name. +const int kMaxLanguageNameSize = 50; + +// The standard name for the default language. +const char* default_language_name(); + +// The standard name for all invalid languages. +const char* invalid_language_name(); + +// If lang_name matches the standard name of a Language, using a +// case-insensitive comparison, set *language to that Language and +// return true. +// Otherwise, set *language to UNKNOWN_LANGUAGE and return false. +// +// For backwards compatibility, "HATIAN_CREOLE" is allowed as a name +// for HAITIAN_CREOLE, and "QUECHAU" is allowed as a name for QUECHUA. +// For compatibility with LanguageEnumName, "UNKNOWN_LANGUAGE" is allowed +// as a name for UNKNOWN_LANGUAGE (the return value is true in this case, +// as it is for "Unknown"), and "CHINESE_T" is allowed as a name for +// CHINESE_T (i.e., a synonym for "ChineseT"). +// +// REQUIRES: language must not be NULL. +// +bool LanguageFromName(const char* lang_name, Language *language); + + + +// ******************************************* +// LANGUAGE CODES +// +// This interface defines a standard code for each valid language, and +// a standard code for invalid languages. These are derived from ISO codes, +// with some Google additions. +// LanguageCode() +// default_language_code() +// invalid_language_code() +// LanguageCodeWithDialects() +// LanguageCodeISO639_1() +// LanguageCodeISO639_2() +// ******************************************* + +// Given a Language, return its standard code. There are Google-specific codes: +// For CHINESE_T, return "zh-TW". +// For TG_UNKNOWN_LANGUAGE, return "ut". +// For UNKNOWN_LANGUAGE, return "un". +// For PORTUGUESE_P, return "pt-PT". +// For PORTUGUESE_B, return "pt-BR". +// For LIMBU, return "sit-NP". +// For CHEROKEE, return "chr". +// For SYRIAC, return "syr". +// Otherwise return the ISO 639-1 two-letter language code for lang. +// If lang is invalid, return invalid_language_code(). +// +// NOTE: See the note below about the codes for Chinese languages. +// +const char* LanguageCode(Language lang); + +// The maximum length of a language code. +const int kMaxLanguageCodeSize = 50; + +// The standard code for the default language. +const char* default_language_code(); + +// The standard code for all invalid languages. +const char* invalid_language_code(); + + +// -------------------------------------------- +// NOTE: CHINESE LANGUAGE CODES +// +// There are three functions that return codes for Chinese languages. +// LanguageCode(lang) and LanguageCodeWithDialects(lang) are defined here. +// LanguageCode(lang, encoding) is defined in i18n/encodings.lang_enc.h. +// The following list shows the different results. +// +// LanguageCode(CHINESE) returns "zh" +// LanguageCode(CHINESE_T) returns "zh-TW". +// +// LanguageCodeWithDialects(CHINESE) returns "zh-CN". +// LanguageCodeWithDialects(CHINESE_T) returns "zh-TW". +// +// LanguageCode(CHINESE_T, ) returns "zh-TW". +// LanguageCode(CHINESE, CHINESE_BIG5) returns "zh-TW". +// LanguageCode(CHINESE, ) returns "zh-CN". +// +// -------------------------------------------- + +// LanguageCodeWithDialects +// ------------------------ +// +// If lang is CHINESE, return "zh-CN". Otherwise return LanguageCode(lang). +const char* LanguageCodeWithDialects(Language lang); + +// LanguageCodeISO639_1 +// -------------------- +// +// Return the ISO 639-1 two-letter language code for lang. +// Return invalid_language_code() if lang is invalid or does not have +// an ISO 639-1 two-letter language code. +const char* LanguageCodeISO639_1(Language lang); + +// LanguageCodeISO639_2 +// -------------------- +// +// Return the ISO 639-2 three-letter language for lang. +// Return invalid_language_code() if lang is invalid or does not have +// an ISO 639-2 three-letter language code. +const char* LanguageCodeISO639_2(Language lang); + +// LanguageFromCode +// ---------------- +// +// If lang_code matches the code for a Language, using a case-insensitive +// comparison, set *lang to that Language and return true. +// Otherwise, set *lang to UNKNOWN_LANGUAGE and return false. +// +// lang_code can be an ISO 639-1 (two-letter) code, an ISO 639-2 +// (three-letter) code, or a Google-specific code (see LanguageCode). +// +// Certain language-code aliases are also allowed: +// For "zh-cn" and "zh_cn", set *lang to CHINESE. +// For "zh-tw" and "zh_tw", set *lang to CHINESE_T. +// For "he", set *lang to HEBREW. +// For "in", set *lang to INDONESIAN. +// For "ji", set *lang to YIDDISH. +// For "fil", set *lang to TAGALOG. +// +// REQUIRES: 'lang' must not be NULL. +bool LanguageFromCode(const char* lang_code, Language *language); + + +// LanguageFromCodeOrName +// ---------------------- +// +// If lang_code_or_name is a language code or a language name. +// set *language to the corresponding Language and return true. +// Otherwise set *language to UNKNOWN_LANGUAGE and return false. +// +bool LanguageFromCodeOrName(const char* lang_code_or_name, + Language* language); + +// LanguageNameFromCode +// -------------------- +// +// If language_code is the code for a Language (see LanguageFromCode), +// return the standard name of that language (see LanguageName). +// Otherwise return invalid_language_name(). +// +const char* LanguageNameFromCode(const char* language_code); + + +// Miscellany + +// LanguageCodeToUnderscoreForm +// ---------------------------- +// +// Given a language code, convert the dash "-" to underscore "_". +// +// Specifically, if result_length <= strlen(lang_code), set result[0] +// to '\0' and return false. Otherwise, copy lang_code to result, +// converting every dash to an underscore, converting every character +// before the first dash or underscore to lower case, and converting +// every character after the first dash or underscore to upper +// case. If there is no dash or underscore, convert the entire string +// to lower case. +// +// REQUIRES: 'lang_code' must not be NULL. 'result' must not be NULL. + +bool LanguageCodeToUnderscoreForm(const char* lang_code, + char* result, + int result_length); + +// +// AlwaysPutInExpectedRestrict +// --------------------------- +// +// For Web pages in certain top-level domains, Web Search always +// applies a "country restrict". If 'tld' matches one of those, using +// a case-SENSITIVE comparison, set *expected_language to the Language +// most commonly found in that top-level domain and return true. +// Otherwise, set *expected_language to UNKNOWN_LANGUAGE and return false. +bool AlwaysPutInExpectedRestrict(const char *tld, Language *expected_language); + + +#endif // UTIL_LANGUAGES_LANGUAGES_H_ diff --git a/ced/util/languages/languages.pb.h b/ced/util/languages/languages.pb.h new file mode 100644 index 0000000..84f1d6a --- /dev/null +++ b/ced/util/languages/languages.pb.h @@ -0,0 +1,191 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_LANGUAGES_LANGUAGES_PB_H_ +#define UTIL_LANGUAGES_LANGUAGES_PB_H_ + +enum Language { + ENGLISH = 0, + DANISH = 1, + DUTCH = 2, + FINNISH = 3, + FRENCH = 4, + GERMAN = 5, + HEBREW = 6, + ITALIAN = 7, + JAPANESE = 8, + KOREAN = 9, + NORWEGIAN = 10, + POLISH = 11, + PORTUGUESE = 12, + RUSSIAN = 13, + SPANISH = 14, + SWEDISH = 15, + CHINESE = 16, + CZECH = 17, + GREEK = 18, + ICELANDIC = 19, + LATVIAN = 20, + LITHUANIAN = 21, + ROMANIAN = 22, + HUNGARIAN = 23, + ESTONIAN = 24, + TG_UNKNOWN_LANGUAGE = 25, + UNKNOWN_LANGUAGE = 26, + BULGARIAN = 27, + CROATIAN = 28, + SERBIAN = 29, + IRISH = 30, // UI only. + GALICIAN = 31, + TAGALOG = 32, // Tagalog (tl) + Filipino (fil), + TURKISH = 33, + UKRAINIAN = 34, + HINDI = 35, + MACEDONIAN = 36, + BENGALI = 37, + INDONESIAN = 38, + LATIN = 39, // UI only. + MALAY = 40, + MALAYALAM = 41, + WELSH = 42, // UI only. + NEPALI = 43, + TELUGU = 44, + ALBANIAN = 45, + TAMIL = 46, + BELARUSIAN = 47, + JAVANESE = 48, // UI only. + OCCITAN = 49, // UI only. + URDU = 50, + BIHARI = 51, + GUJARATI = 52, + THAI = 53, + ARABIC = 54, + CATALAN = 55, + ESPERANTO = 56, + BASQUE = 57, + INTERLINGUA = 58, // UI only. + KANNADA = 59, + PUNJABI = 60, + SCOTS_GAELIC = 61, // UI only. + SWAHILI = 62, + SLOVENIAN = 63, + MARATHI = 64, + MALTESE = 65, + VIETNAMESE = 66, + FRISIAN = 67, // UI only. + SLOVAK = 68, + CHINESE_T = 69, // This is added to solve the problem of + // distinguishing Traditional and Simplified + // Chinese when the encoding is UTF8. + FAROESE = 70, // UI only. + SUNDANESE = 71, // UI only. + UZBEK = 72, + AMHARIC = 73, + AZERBAIJANI = 74, + GEORGIAN = 75, + TIGRINYA = 76, // UI only. + PERSIAN = 77, + BOSNIAN = 78, // UI only. LangId language: CROATIAN (28) + SINHALESE = 79, + NORWEGIAN_N = 80, // UI only. LangId language: NORWEGIAN (10) + PORTUGUESE_P = 81, // UI only. LangId language: PORTUGUESE (12) + PORTUGUESE_B = 82, // UI only. LangId language: PORTUGUESE (12) + XHOSA = 83, // UI only. + ZULU = 84, // UI only. + GUARANI = 85, + SESOTHO = 86, // UI only. + TURKMEN = 87, // UI only. + KYRGYZ = 88, + BRETON = 89, // UI only. + TWI = 90, // UI only. + YIDDISH = 91, // UI only. + SERBO_CROATIAN= 92, // UI only. LangId language: SERBIAN (29) + SOMALI = 93, // UI only. + UIGHUR = 94, + KURDISH = 95, + MONGOLIAN = 96, + ARMENIAN = 97, + LAOTHIAN = 98, + SINDHI = 99, + RHAETO_ROMANCE= 100, // UI only. + AFRIKAANS = 101, + LUXEMBOURGISH = 102, // UI only. + BURMESE = 103, + KHMER = 104, + TIBETAN = 105, + DHIVEHI = 106, // sometimes spelled Divehi, lang of Maldives + CHEROKEE = 107, + SYRIAC = 108, // UI only. + LIMBU = 109, // UI only. + ORIYA = 110, + ASSAMESE = 111, // UI only. + CORSICAN = 112, // UI only. + INTERLINGUE = 113, // UI only. + KAZAKH = 114, + LINGALA = 115, // UI only. + MOLDAVIAN = 116, // UI only. LangId language: ROMANIAN (22) + PASHTO = 117, + QUECHUA = 118, // UI only. + SHONA = 119, // UI only. + TAJIK = 120, + TATAR = 121, // UI only. + TONGA = 122, // UI only. + YORUBA = 123, // UI only. + CREOLES_AND_PIDGINS_ENGLISH_BASED = 124, // UI only. + CREOLES_AND_PIDGINS_FRENCH_BASED = 125, // UI only. + CREOLES_AND_PIDGINS_PORTUGUESE_BASED = 126, // UI only. + CREOLES_AND_PIDGINS_OTHER = 127, // UI only. + MAORI = 128, // UI only. + WOLOF = 129, // UI only. + ABKHAZIAN = 130, // UI only. + AFAR = 131, // UI only. + AYMARA = 132, // UI only. + BASHKIR = 133, // UI only. + BISLAMA = 134, // UI only. + DZONGKHA = 135, // UI only. + FIJIAN = 136, // UI only. + GREENLANDIC = 137, // UI only. + HAUSA = 138, // UI only. + HAITIAN_CREOLE= 139, // UI only. + INUPIAK = 140, // UI only. + INUKTITUT = 141, + KASHMIRI = 142, // UI only. + KINYARWANDA = 143, // UI only. + MALAGASY = 144, // UI only. + NAURU = 145, // UI only. + OROMO = 146, // UI only. + RUNDI = 147, // UI only. + SAMOAN = 148, // UI only. + SANGO = 149, // UI only. + SANSKRIT = 150, + SISWANT = 151, // UI only. + TSONGA = 152, // UI only. + TSWANA = 153, // UI only. + VOLAPUK = 154, // UI only. + ZHUANG = 155, // UI only. + KHASI = 156, // UI only. + SCOTS = 157, // UI only. + GANDA = 158, // UI only. + MANX = 159, // UI only. + MONTENEGRIN = 160, // UI only. LangId language: SERBIAN (29) + NUM_LANGUAGES = 161, // Always keep this at the end. It is not a + // valid Language enum. It is only used to + // indicate the total number of Languages. + // NOTE: If you add a language, you will break a unittest. See the note + // at the top of this enum. +}; + +#endif // UTIL_LANGUAGES_LANGUAGES_PB_H_ diff --git a/ced/util/logging.h b/ced/util/logging.h new file mode 100644 index 0000000..16e50f2 --- /dev/null +++ b/ced/util/logging.h @@ -0,0 +1,25 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_LOGGING_H_ +#define UTIL_LOGGING_H_ + +#undef CHECK +#define CHECK(expr) +#undef DCHECK +#define DCHECK(expr) + +#endif // UTIL_LOGGING_H_ diff --git a/ced/util/port.h b/ced/util/port.h new file mode 100644 index 0000000..3799b16 --- /dev/null +++ b/ced/util/port.h @@ -0,0 +1,53 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_PORT_H_ +#define UTIL_PORT_H_ + +#include + +#if defined(_MSC_VER) +#define GG_LONGLONG(x) x##I64 +#define GG_ULONGLONG(x) x##UI64 +#else +#define GG_LONGLONG(x) x##LL +#define GG_ULONGLONG(x) x##ULL +#endif + +// Per C99 7.8.14, define __STDC_CONSTANT_MACROS before including +// to get the INTn_C and UINTn_C macros for integer constants. It's difficult +// to guarantee any specific ordering of header includes, so it's difficult to +// guarantee that the INTn_C macros can be defined by including at +// any specific point. Provide GG_INTn_C macros instead. + +#define GG_INT8_C(x) (x) +#define GG_INT16_C(x) (x) +#define GG_INT32_C(x) (x) +#define GG_INT64_C(x) GG_LONGLONG(x) + +#define GG_UINT8_C(x) (x ## U) +#define GG_UINT16_C(x) (x ## U) +#define GG_UINT32_C(x) (x ## U) +#define GG_UINT64_C(x) GG_ULONGLONG(x) + +// Define an OS-neutral wrapper for shared library entry points +#if defined(_WIN32) +#define API_CALL __stdcall +#else +#define API_CALL +#endif + +#endif // UTIL_PORT_H_ diff --git a/ced/util/string_util.h b/ced/util/string_util.h new file mode 100644 index 0000000..bb612a9 --- /dev/null +++ b/ced/util/string_util.h @@ -0,0 +1,55 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_STRING_UTIL_H_ +#define UTIL_STRING_UTIL_H_ + +#include + +namespace base { + +#if defined(_WIN32) +// Compare the two strings s1 and s2 without regard to case using +// the current locale; returns 0 if they are equal, 1 if s1 > s2, and -1 if +// s2 > s1 according to a lexicographic comparison. +inline int strcasecmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline int strncasecmp(const char* s1, const char* s2, size_t n) { + return _strnicmp(s1, s2, n); +} +#else +inline int strcasecmp(const char* s1, const char* s2) { + return ::strcasecmp(s1, s2); +} +inline int strncasecmp(const char* s1, const char* s2, size_t n) { + return ::strncasecmp(s1, s2, n); +} +#endif +} + +#if !defined(__linux__) +inline void* memrchr(const void* s, int c, size_t n) { + const unsigned char* p = (const unsigned char*) s; + for (p += n; n > 0; n--) { + if (*--p == c) + return (void*) p; + } + return NULL; +} +#endif + +#endif // UTIL_STRING_UTIL_H_ diff --git a/ced/util/varsetter.h b/ced/util/varsetter.h new file mode 100644 index 0000000..8e8cbf2 --- /dev/null +++ b/ced/util/varsetter.h @@ -0,0 +1,66 @@ +// Copyright 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef UTIL_VARSETTER_H_ +#define UTIL_VARSETTER_H_ + +// +// Use a VarSetter object to temporarily set an object of some sort to +// a particular value. When the VarSetter object is destructed, the +// underlying object will revert to its former value. +// +// Sample code: +// +#if 0 +{ + bool b = true; + { + VarSetter bool_setter(&b, false); + // Now b == false. + } + // Now b == true again. +} +#endif + +template +class VarSetter { +public: + + // Constructor that just sets the object to a fixed value + VarSetter(C* object, const C& value) : object_(object), old_value_(*object) { + *object = value; + } + + ~VarSetter() { *object_ = old_value_; } + +private: + + C*const object_; + C old_value_; + + // Disallow + VarSetter(const VarSetter&); + VarSetter& operator=(const VarSetter&); + + // VarSetters always live on the stack + static void* operator new (size_t); + static void* operator new[](size_t); // Redundant, no default ctor + + static void operator delete (void*); + static void operator delete[](void*); +}; + +#endif // UTIL_VARSETTER_H_ diff --git a/cmake/Modules/FindAVCodec.cmake b/cmake/Modules/FindAVCodec.cmake new file mode 100644 index 0000000..fa1ca9f --- /dev/null +++ b/cmake/Modules/FindAVCodec.cmake @@ -0,0 +1,46 @@ +# - Try to find FFMPEG libavcodec +# Once done, this will define +# +# AVCodec_FOUND - the library is available +# AVCodec_INCLUDE_DIRS - the include directories +# AVCodec_LIBRARIES - the libraries +# AVCodec_INCLUDE - the file to #include (may be used in config.h) +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_package(AVCodec AVUtil) + +# TODO: pkg-config extra deps: libraw1394 theora vorbisenc + +libfind_pkg_check_modules(AVCodec_PKGCONF libavcodec) + +find_path(AVCodec_INCLUDE_DIR + NAMES libavcodec/avcodec.h ffmpeg/avcodec.h avcodec.h + HINTS ${AVCodec_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES ffmpeg +) + +if(AVCodec_INCLUDE_DIR) + foreach(suffix libavcodec/ ffmpeg/ "") + if(NOT AVCodec_INCLUDE) + if(EXISTS "${AVCodec_INCLUDE_DIR}/${suffix}avcodec.h") + set(AVCodec_INCLUDE "${suffix}avcodec.h" CACHE INTERNAL "") + endif(EXISTS "${AVCodec_INCLUDE_DIR}/${suffix}avcodec.h") + endif(NOT AVCodec_INCLUDE) + endforeach(suffix) + + if(NOT AVCodec_INCLUDE) + message(FATAL_ERROR "Found avcodec.h include dir, but not the header file. Perhaps you need to clear CMake cache?") + endif(NOT AVCodec_INCLUDE) +endif(AVCodec_INCLUDE_DIR) + +find_library(AVCodec_LIBRARY + NAMES libavcodec.dll.a avcodec + HINTS ${AVCodec_PKGCONF_LIBRARY_DIRS} +) + +libfind_process(AVCodec) + diff --git a/cmake/Modules/FindAVFormat.cmake b/cmake/Modules/FindAVFormat.cmake new file mode 100644 index 0000000..2984a1d --- /dev/null +++ b/cmake/Modules/FindAVFormat.cmake @@ -0,0 +1,44 @@ +# - Try to find FFMPEG libavformat +# Once done, this will define +# +# AVFormat_FOUND - the library is available +# AVFormat_INCLUDE_DIRS - the include directories +# AVFormat_LIBRARIES - the libraries +# AVFormat_INCLUDE - the file to include (may be used in config.h) +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_package(AVFormat AVCodec) + +libfind_pkg_check_modules(AVFormat_PKGCONF libavformat) + +find_path(AVFormat_INCLUDE_DIR + NAMES libavformat/avformat.h ffmpeg/avformat.h avformat.h + HINTS ${AVFormat_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES ffmpeg +) + +if(AVFormat_INCLUDE_DIR) + foreach(suffix libavformat/ ffmpeg/ "") + if(NOT AVFormat_INCLUDE) + if(EXISTS "${AVFormat_INCLUDE_DIR}/${suffix}avformat.h") + set(AVFormat_INCLUDE "${suffix}avformat.h") + endif(EXISTS "${AVFormat_INCLUDE_DIR}/${suffix}avformat.h") + endif(NOT AVFormat_INCLUDE) + endforeach(suffix) + + if(NOT AVFormat_INCLUDE) + message(FATAL_ERROR "Found avformat.h include dir, but not the header file. Perhaps you need to clear CMake cache?") + endif(NOT AVFormat_INCLUDE) +endif(AVFormat_INCLUDE_DIR) + +find_library(AVFormat_LIBRARY + NAMES libavformat.dll.a avformat + HINTS ${AVFormat_PKGCONF_LIBRARY_DIRS} +) + +libfind_process(AVFormat) + diff --git a/cmake/Modules/FindAVUtil.cmake b/cmake/Modules/FindAVUtil.cmake new file mode 100644 index 0000000..f6478a7 --- /dev/null +++ b/cmake/Modules/FindAVUtil.cmake @@ -0,0 +1,42 @@ +# - Try to find FFMPEG libavutil +# Once done, this will define +# +# AVUtil_FOUND - the library is available +# AVUtil_INCLUDE_DIRS - the include directories +# AVUtil_LIBRARIES - the libraries +# AVUtil_INCLUDE - the file to #include (may be used in config.h) +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(AVUtil_PKGCONF libavutil) + +find_path(AVUtil_INCLUDE_DIR + NAMES libavutil/avutil.h ffmpeg/avutil.h avutil.h + HINTS ${AVUtil_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES ffmpeg +) + +if(AVUtil_INCLUDE_DIR) + foreach(suffix libavutil/ ffmpeg/ "") + if(NOT AVUtil_INCLUDE) + if(EXISTS "${AVUtil_INCLUDE_DIR}/${suffix}avutil.h") + set(AVUtil_INCLUDE "${suffix}avutil.h") + endif(EXISTS "${AVUtil_INCLUDE_DIR}/${suffix}avutil.h") + endif(NOT AVUtil_INCLUDE) + endforeach(suffix) + + if(NOT AVUtil_INCLUDE) + message(FATAL_ERROR "Found avutil.h include dir, but not the header file. Perhaps you need to clear CMake cache?") + endif(NOT AVUtil_INCLUDE) +endif(AVUtil_INCLUDE_DIR) + +find_library(AVUtil_LIBRARY + NAMES libavutil.dll.a avutil + HINTS ${AVUtil_PKGCONF_LIBRARY_DIRS} +) + +libfind_process(AVUtil) + diff --git a/cmake/Modules/FindAtk.cmake b/cmake/Modules/FindAtk.cmake new file mode 100644 index 0000000..ffdbe6f --- /dev/null +++ b/cmake/Modules/FindAtk.cmake @@ -0,0 +1,34 @@ +# - Try to find Atk 1.0 +# Once done, this will define +# +# Atk_FOUND - system has Atk +# Atk_INCLUDE_DIRS - the Atk include directories +# Atk_LIBRARIES - link these to use Atk + +include(LibFindMacros) + +# Dependencies +libfind_package(Atk GObject) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Atk_PKGCONF atk) + +# Main include dir +find_path(Atk_INCLUDE_DIR + NAMES atk/atk.h + HINTS ${Atk_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES atk-1.0 +) + +# Find the library +find_library(Atk_LIBRARY + NAMES atk-1.0 + HINTS ${Atk_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(Atk_PROCESS_INCLUDES Atk_INCLUDE_DIR) +set(Atk_PROCESS_LIBS Atk_LIBRARY GObject_LIBRARIES) +libfind_process(Atk) + diff --git a/cmake/Modules/FindAtkmm.cmake b/cmake/Modules/FindAtkmm.cmake new file mode 100644 index 0000000..8dc4d28 --- /dev/null +++ b/cmake/Modules/FindAtkmm.cmake @@ -0,0 +1,35 @@ +# - Try to find Atkmm 1.6 +# Once done, this will define +# +# Atkmm_FOUND - system has Atkmm +# Atkmm_INCLUDE_DIRS - the Atkmm include directories +# Atkmm_LIBRARIES - link these to use Atkmm + +include(LibFindMacros) + +# Dependencies +libfind_package(Atkmm Atk) +libfind_package(Atkmm Glibmm) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Atkmm_PKGCONF atkmm-1.6) + +# Main include dir +find_path(Atkmm_INCLUDE_DIR + NAMES atkmm.h + HINTS ${Atkmm_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES atkmm-1.6 +) + +# Finally the library itself +find_library(Atkmm_LIBRARY + NAMES atkmm-1.6 + HINTS ${Atkmm_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(Atkmm_PROCESS_INCLUDES Atkmm_INCLUDE_DIR Atk_INCLUDE_DIRS Glibmm_INCLUDE_DIRS) +set(Atkmm_PROCESS_LIBS Atkmm_LIBRARY Atk_LIBRARIES Glibmm_LIBRARIES) +libfind_process(Atkmm) + diff --git a/cmake/Modules/FindCairo.cmake b/cmake/Modules/FindCairo.cmake new file mode 100644 index 0000000..923fbc2 --- /dev/null +++ b/cmake/Modules/FindCairo.cmake @@ -0,0 +1,14 @@ +# - Try to find Cairo +# Once done, this will define +# +# Cairo_FOUND - system has Cairo +# Cairo_INCLUDE_DIRS - the Cairo include directories +# Cairo_LIBRARIES - link these to use Cairo + +include(LibFindMacros) +libfind_package(Cairo Freetype) # Cairo depends on Freetype +libfind_pkg_detect(Cairo cairo FIND_PATH cairo.h PATH_SUFFIXES cairo FIND_LIBRARY cairo) +libfind_process(Cairo) + + + diff --git a/cmake/Modules/FindCairomm.cmake b/cmake/Modules/FindCairomm.cmake new file mode 100644 index 0000000..13823d4 --- /dev/null +++ b/cmake/Modules/FindCairomm.cmake @@ -0,0 +1,34 @@ +# - Try to find Cairomm 1.0 +# Once done, this will define +# +# Cairomm_FOUND - system has Cairomm +# Cairomm_INCLUDE_DIRS - the Cairomm include directories +# Cairomm_LIBRARIES - link these to use Cairomm + +include(LibFindMacros) + +# Dependencies +libfind_package(Cairomm Cairo) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Cairomm_PKGCONF cairomm-1.0) + +# Main include dir +find_path(Cairomm_INCLUDE_DIR + NAMES cairomm/cairomm.h + HINTS ${Cairomm_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES cairomm-1.0 +) + +# Finally the library itself +find_library(Cairomm_LIBRARY + NAMES cairomm-1.0 + HINTS ${Cairomm_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(Cairomm_PROCESS_INCLUDES Cairomm_INCLUDE_DIR Cairo_INCLUDE_DIRS) +set(Cairomm_PROCESS_LIBS Cairomm_LIBRARY Cairo_LIBRARIES) +libfind_process(Cairomm) + diff --git a/cmake/Modules/FindClanLib.cmake b/cmake/Modules/FindClanLib.cmake new file mode 100644 index 0000000..cb0f8b4 --- /dev/null +++ b/cmake/Modules/FindClanLib.cmake @@ -0,0 +1,48 @@ +# - Try to find ClanLib +# Example usage: find_package(ClanLib 0.8 REQUIRED COMPONENTS Core App Display GL Sound) +# +# Once done, this will define +# +# ClanLib_FOUND - system has ClanLib (all the components requested) +# ClanLib_INCLUDE_DIRS - the ClanLib include directories +# ClanLib_LIBRARIES - link these to use ClanLib +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +if (ClanLib_FIND_VERSION_MAJOR AND ClanLib_FIND_VERSION_MINOR) + set(ClanLib_VERSION "${ClanLib_FIND_VERSION_MAJOR}.${ClanLib_FIND_VERSION_MINOR}") +else (ClanLib_FIND_VERSION_MAJOR AND ClanLib_FIND_VERSION_MINOR) + set(ClanLib_VERSION "0.8") +endif (ClanLib_FIND_VERSION_MAJOR AND ClanLib_FIND_VERSION_MINOR) + +libfind_pkg_check_modules(ClanLib_PKGCONF clanCore-${ClanLib_VERSION}) + +find_path(ClanLib_INCLUDE_DIR + NAMES ClanLib/core.h + HINTS ${ClanLib_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES ClanLib-${ClanLib_VERSION} +) + +# Extract the actual version number +if (ClanLib_INCLUDE_DIR) + file(READ "${ClanLib_INCLUDE_DIR}/ClanLib/core.h" _ClanLib_CORE_H_CONTENTS) + set(_ClanLib_VERSION_REGEX ".*#define CL_VERSION_STRING \"([^\n]*)\".*") + if ("${_ClanLib_CORE_H_CONTENTS}" MATCHES "${_ClanLib_VERSION_REGEX}") + string(REGEX REPLACE "${_ClanLib_VERSION_REGEX}" "\\1" ClanLib_VERSION "${_ClanLib_CORE_H_CONTENTS}") + endif ("${_ClanLib_CORE_H_CONTENTS}" MATCHES "${_ClanLib_VERSION_REGEX}") +endif (ClanLib_INCLUDE_DIR) + +foreach(COMPONENT ${ClanLib_FIND_COMPONENTS}) + find_library(ClanLib_${COMPONENT}_LIBRARY + NAMES clan${COMPONENT} + HINTS ${ClanLib_PKGCONF_LIBRARY_DIRS} + ) + set(ClanLib_PROCESS_LIBS ${ClanLib_PROCESS_LIBS} ClanLib_${COMPONENT}_LIBRARY) +endforeach(COMPONENT) + +set(ClanLib_PROCESS_INCLUDES ClanLib_INCLUDE_DIR) +libfind_process(ClanLib) + diff --git a/cmake/Modules/FindCppRest.cmake b/cmake/Modules/FindCppRest.cmake new file mode 100644 index 0000000..21d1e97 --- /dev/null +++ b/cmake/Modules/FindCppRest.cmake @@ -0,0 +1,18 @@ +# - Try to find cpprest +# Once done, this will define +# +# CppRest_FOUND - system has CppRest +# CppRest_INCLUDE_DIRS - the CppRest include directories +# CppRest_LIBRARIES - link these to use CppRest +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_package(CppRest Crypto) +libfind_package(CppRest Ssl) + +libfind_pkg_detect(CppRest cpprest FIND_PATH http_client.h PATH_SUFFIXES cpprest FIND_LIBRARY cpprest) +set(CppRest_VERSION ${CppRest_PKGCONF_VERSION}) +libfind_process(CppRest) \ No newline at end of file diff --git a/cmake/Modules/FindCrypto.cmake b/cmake/Modules/FindCrypto.cmake new file mode 100644 index 0000000..809ca9d --- /dev/null +++ b/cmake/Modules/FindCrypto.cmake @@ -0,0 +1,14 @@ +# - Try to find Crypto +# Once done, this will define +# +# Crypto_FOUND - system has Crypto +# Crypto_INCLUDE_DIRS - the Crypto include directories +# Crypto_LIBRARIES - link these to use Crypto +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) +libfind_pkg_detect(Crypto libcrypto FIND_PATH openssl/crypto.h FIND_LIBRARY crypto) +set(Crypto_VERSION ${Crypto_PKGCONF_VERSION}) +libfind_process(Crypto) diff --git a/cmake/Modules/FindDL.cmake b/cmake/Modules/FindDL.cmake new file mode 100644 index 0000000..17352df --- /dev/null +++ b/cmake/Modules/FindDL.cmake @@ -0,0 +1,23 @@ +# - Try to find dynamic linker library. Does nothing on Windows +# Once done, this will define +# +# DL_FOUND - system has dl (always set on Windows) +# DL_INCLUDE_DIRS - dlfcn.h include dir +# DL_LIBRARIES - link these to use dl +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +if(WIN32) + set(DL_FOUND TRUE) +else() + include(LibFindMacros) + + find_path(DL_INCLUDE_DIR NAMES dlfcn.h) + find_library(DL_LIBRARY NAMES dl) + + set(DL_PROCESS_INCLUDES DL_INCLUDE_DIR) + set(DL_PROCESS_LIBS DL_LIBRARY) + libfind_process(DL) +endif() + diff --git a/cmake/Modules/FindFAAC.cmake b/cmake/Modules/FindFAAC.cmake new file mode 100644 index 0000000..84dc13c --- /dev/null +++ b/cmake/Modules/FindFAAC.cmake @@ -0,0 +1,24 @@ +# - Try to find FAAC +# Once done, this will define +# +# FAAC_FOUND - system has FAAC +# FAAC_INCLUDE_DIRS - the FAAC include directories +# FAAC_LIBRARIES - link these to use FAAC +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +find_path(FAAC_INCLUDE_DIR + NAMES faac.h +) + +find_library(FAAC_LIBRARY + NAMES faac +) + +set(FAAC_PROCESS_INCLUDES FAAC_INCLUDE_DIR) +set(FAAC_PROCESS_LIBS FAAC_LIBRARY) +libfind_process(FAAC) + diff --git a/cmake/Modules/FindFontconfig.cmake b/cmake/Modules/FindFontconfig.cmake new file mode 100644 index 0000000..6469621 --- /dev/null +++ b/cmake/Modules/FindFontconfig.cmake @@ -0,0 +1,28 @@ +# - Try to find Fontconfig +# Once done, this will define +# +# Fontconfig_FOUND - system has Fontconfig +# Fontconfig_INCLUDE_DIRS - the Fontconfig include directories +# Fontconfig_LIBRARIES - link these to use Fontconfig +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(Fontconfig_PKGCONF Fontconfig) + +find_path(Fontconfig_INCLUDE_DIR + NAMES fontconfig/fontconfig.h + HINTS ${Fontconfig_PKGCONF_INCLUDE_DIRS} +) + +find_library(Fontconfig_LIBRARY + NAMES fontconfig + HINTS ${Fontconfig_PKGCONF_LIBRARY_DIRS} +) + +set(Fontconfig_PROCESS_INCLUDES Fontconfig_INCLUDE_DIR) +set(Fontconfig_PROCESS_LIBS Fontconfig_LIBRARY) +libfind_process(Fontconfig) + diff --git a/cmake/Modules/FindFreetype.cmake b/cmake/Modules/FindFreetype.cmake new file mode 100644 index 0000000..b26f637 --- /dev/null +++ b/cmake/Modules/FindFreetype.cmake @@ -0,0 +1,31 @@ +# - Try to find Freetype2 +# Once done, this will define +# +# Freetype_FOUND - system has Freetype +# Freetype_INCLUDE_DIRS - the Freetype include directories +# Freetype_LIBRARIES - link these to use Freetype + +include(LibFindMacros) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Freetype_PKGCONF freetype2) + +# Include dir +find_path(Freetype_INCLUDE_DIR + NAMES freetype/freetype.h freetype2/freetype.h + HINTS ${Freetype_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES freetype2 +) + +# Finally the library itself +find_library(Freetype_LIBRARY + NAMES freetype + HINTS ${Freetype_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(Freetype_PROCESS_INCLUDES Freetype_INCLUDE_DIR) +set(Freetype_PROCESS_LIBS Freetype_LIBRARY) +libfind_process(Freetype) + diff --git a/cmake/Modules/FindGDK-PixBuf.cmake b/cmake/Modules/FindGDK-PixBuf.cmake new file mode 100644 index 0000000..e71f619 --- /dev/null +++ b/cmake/Modules/FindGDK-PixBuf.cmake @@ -0,0 +1,32 @@ +# - Try to find gdk-pixbuf 2.0 +# Once done, this will define +# +# GDK-PixBuf_FOUND - system has GDK-PixBuf +# GDK-PixBuf_INCLUDE_DIRS - the GDK-PixBuf include directories +# GDK-PixBuf_LIBRARIES - link these to use GDK-PixBuf + +include(LibFindMacros) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(GDK-PixBuf_PKGCONF gdk-pixbuf-2.0) + +# Main include dir +find_path(GDK-PixBuf_INCLUDE_DIR + NAMES gdk-pixbuf/gdk-pixbuf.h + HINTS ${GDK-PixBuf_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES gtk-2.0 gdk-pixbuf-2.0 +) + +# Finally the library itself +find_library(GDK-PixBuf_LIBRARY + NAMES gdk_pixbuf-2.0 + HINTS ${GDK-PixBuf_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(GDK-PixBuf_PROCESS_INCLUDES GDK-PixBuf_INCLUDE_DIR) +set(GDK-PixBuf_PROCESS_LIBS GDK-PixBuf_LIBRARY) +libfind_process(GDK-PixBuf) + + diff --git a/cmake/Modules/FindGDK.cmake b/cmake/Modules/FindGDK.cmake new file mode 100644 index 0000000..b0f9ac5 --- /dev/null +++ b/cmake/Modules/FindGDK.cmake @@ -0,0 +1,43 @@ +# - Try to find GDK 2.0 +# Once done, this will define +# +# GDK_FOUND - system has GDK +# GDK_INCLUDE_DIRS - the GDK include directories +# GDK_LIBRARIES - link these to use GDK + +include(LibFindMacros) + +# Dependencies +libfind_package(GDK GDK-PixBuf) +libfind_package(GDK Pango) +libfind_package(GDK GIO) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(GDK_PKGCONF gdk-2.0) + +# Main include dir +find_path(GDK_INCLUDE_DIR + NAMES gdk/gdk.h + HINTS ${GDK_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES gtk-2.0 +) + +# Glib-related libraries also use a separate config header, which is in lib dir +find_path(GDKConfig_INCLUDE_DIR + NAMES gdkconfig.h + HINTS ${GDK_PKGCONF_INCLUDE_DIRS} /usr + PATH_SUFFIXES lib/gtk-2.0/include +) + +# Finally the library itself +find_library(GDK_LIBRARY + NAMES gdk-x11-2.0 + HINTS ${GDK_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(GDK_PROCESS_INCLUDES GDK_INCLUDE_DIR GDKConfig_INCLUDE_DIR GDK-PixBuf_INCLUDE_DIRS Pango_INCLUDE_DIRS GIO_INCLUDE_DIRS) +set(GDK_PROCESS_LIBS GDK_LIBRARY GDK-PixBuf_LIBRARIES Pango_LIBRARIES GIO_LIBRARIES) +libfind_process(GDK) + diff --git a/cmake/Modules/FindGDKmm.cmake b/cmake/Modules/FindGDKmm.cmake new file mode 100644 index 0000000..23ccb83 --- /dev/null +++ b/cmake/Modules/FindGDKmm.cmake @@ -0,0 +1,44 @@ +# - Try to find GDKmm 2.4 +# Once done, this will define +# +# GDKmm_FOUND - system has GDKmm +# GDKmm_INCLUDE_DIRS - the GDKmm include directories +# GDKmm_LIBRARIES - link these to use GDKmm + +include(LibFindMacros) + +# Dependencies +libfind_package(GDKmm GDK) +libfind_package(GDKmm Glibmm) +libfind_package(GDKmm Pangomm) +libfind_package(GDKmm Cairomm) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(GDKmm_PKGCONF gdkmm-2.4) + +# Main include dir +find_path(GDKmm_INCLUDE_DIR + NAMES gdkmm.h + HINTS ${GDKmm_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES gdkmm-2.4 +) + +# Glib-related libraries also use a separate config header, which is in lib dir +find_path(GDKmmConfig_INCLUDE_DIR + NAMES gdkmmconfig.h + HINTS ${GDKmm_PKGCONF_INCLUDE_DIRS} /usr + PATH_SUFFIXES lib/gdkmm-2.4/include +) + +# Finally the library itself +find_library(GDKmm_LIBRARY + NAMES gdkmm-2.4 + HINTS ${GDKmm_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(GDKmm_PROCESS_INCLUDES GDKmm_INCLUDE_DIR GDKmmConfig_INCLUDE_DIR GDK_INCLUDE_DIRS Glibmm_INCLUDE_DIRS Pangomm_INCLUDE_DIRS Cairomm_INCLUDE_DIRS) +set(GDKmm_PROCESS_LIBS GDKmm_LIBRARY GDK_LIBRARIES Glibmm_LIBRARIES Pangomm_LIBRARIES Cairomm_LIBRARIES) +libfind_process(GDKmm) + diff --git a/cmake/Modules/FindGIO.cmake b/cmake/Modules/FindGIO.cmake new file mode 100644 index 0000000..c039042 --- /dev/null +++ b/cmake/Modules/FindGIO.cmake @@ -0,0 +1,27 @@ +# - Try to find GIO 2.0 +# Once done, this will define +# +# GIO_FOUND - system has GIO +# GIO_INCLUDE_DIRS - the GIO include directories +# GIO_LIBRARIES - link these to use GIO + +include(LibFindMacros) + +# Dependencies +libfind_package(GIO Glib) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(GIO_PKGCONF gio-2.0) + +# Find the library +find_library(GIO_LIBRARY + NAMES gio-2.0 + HINTS ${GIO_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(GIO_PROCESS_INCLUDES Glib_INCLUDE_DIRS) +set(GIO_PROCESS_LIBS GIO_LIBRARY Glib_LIBRARIES) +libfind_process(GIO) + diff --git a/cmake/Modules/FindGIOmm.cmake b/cmake/Modules/FindGIOmm.cmake new file mode 100644 index 0000000..bed2569 --- /dev/null +++ b/cmake/Modules/FindGIOmm.cmake @@ -0,0 +1,35 @@ +# - Try to find GIOmm 2.4 +# Once done, this will define +# +# GIOmm_FOUND - system has GIOmm +# GIOmm_INCLUDE_DIRS - the GIOmm include directories +# GIOmm_LIBRARIES - link these to use GIOmm + +include(LibFindMacros) + +# Dependencies +libfind_package(GIOmm GIO) +libfind_package(GIOmm Glibmm) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(GIOmm_PKGCONF giomm-2.4) + +# Main include dir +find_path(GIOmm_INCLUDE_DIR + NAMES giomm.h + HINTS ${GIOmm_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES giomm-2.4 +) + +# Finally the library itself +find_library(GIOmm_LIBRARY + NAMES giomm-2.4 + HINTS ${GIOmm_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(GIOmm_PROCESS_INCLUDES GIOmm_INCLUDE_DIR GIO_INCLUDE_DIRS Glibmm_INCLUDE_DIRS) +set(GIOmm_PROCESS_LIBS GIOmm_LIBRARY GIO_LIBRARIES Glibmm_LIBRARIES) +libfind_process(GIOmm) + diff --git a/cmake/Modules/FindGLEW.cmake b/cmake/Modules/FindGLEW.cmake new file mode 100644 index 0000000..5b01c42 --- /dev/null +++ b/cmake/Modules/FindGLEW.cmake @@ -0,0 +1,30 @@ +# - Try to find GLEW +# Once done, this will define +# +# GLEW_FOUND - system has OpenGL (GL and GLU) +# GLEW_INCLUDE_DIRS - the OpenGL include directories +# GLEW_LIBRARIES - link these to use OpenGL +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +# GLEW is often installed in the same place as OpenGL +libfind_pkg_check_modules(OpenGL_PKGCONF gl) + +find_path(GLEW_INCLUDE_DIR + NAMES glew.h + HINTS ${OpenGL_INCLUDE_DIRS} + PATH_SUFFIXES GL +) + +find_library(GLEW_LIBRARY + NAMES GLEW GLEW32.a GLEW32 + HINTS ${OpenGL_PKGCONF_LIBRARY_DIRS} +) + +set(GLEW_PROCESS_INCLUDES GLEW_INCLUDE_DIR) +set(GLEW_PROCESS_LIBS GLEW_LIBRARY) +libfind_process(GLEW) + diff --git a/cmake/Modules/FindGLFW.cmake b/cmake/Modules/FindGLFW.cmake new file mode 100644 index 0000000..ad85f64 --- /dev/null +++ b/cmake/Modules/FindGLFW.cmake @@ -0,0 +1,38 @@ +# - Try to find GLFW +# Once done, this will define +# +# GLFW_FOUND - system has OpenGL (GL and GLU) +# GLFW_INCLUDE_DIRS - the OpenGL include directories +# GLFW_LIBRARIES - link these to use OpenGL +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +# Dependencies +libfind_package(GDK OpenGL) + +libfind_pkg_check_modules(GLFW_PKGCONF libglfw) + +find_path(GLFW_INCLUDE_DIR + NAMES GL/glfw.h + HINTS ${GLFW_PKGCONF_INCLUDE_DIRS} +) + +find_library(GLFW_LIBRARY + NAMES glfw + HINTS ${GLFW_PKGCONF_LIBRARY_DIRS} +) + +set(GLFW_PROCESS_INCLUDES GLFW_INCLUDE_DIR OpenGL_INCLUDE_DIRS) +set(GLFW_PROCESS_LIBS GLFW_LIBRARY OpenGL_LIBRARIES) + +if(UNIX) + find_library(X11_LIBRARY NAMES X11) + find_library(Xrandr_LIBRARY NAMES Xrandr) + set(GLFW_PROCESS_LIBS ${GLFW_PROCESS_LIBS} X11_LIBRARY Xrandr_LIBRARY) +endif(UNIX) + +libfind_process(GLFW) + diff --git a/cmake/Modules/FindGLM.cmake b/cmake/Modules/FindGLM.cmake new file mode 100644 index 0000000..2d90092 --- /dev/null +++ b/cmake/Modules/FindGLM.cmake @@ -0,0 +1,63 @@ +# FindGLM - attempts to locate the glm matrix/vector library. +# +# This module defines the following variables (on success): +# GLM_INCLUDE_DIRS - where to find glm/glm.hpp +# GLM_FOUND - if the library was successfully located +# +# It is trying a few standard installation locations, but can be customized +# with the following variables: +# GLM_ROOT_DIR - root directory of a glm installation +# Headers are expected to be found in either: +# /glm/glm.hpp OR +# /include/glm/glm.hpp +# This variable can either be a cmake or environment +# variable. Note however that changing the value +# of the environment varible will NOT result in +# re-running the header search and therefore NOT +# adjust the variables set by this module. + +#============================================================================= +# Copyright 2012 Carsten Neumann +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# default search dirs +SET(_glm_HEADER_SEARCH_DIRS + "/usr/include" + "/usr/local/include") + +# check environment variable +SET(_glm_ENV_ROOT_DIR "$ENV{GLM_ROOT_DIR}") + +IF(NOT GLM_ROOT_DIR AND _glm_ENV_ROOT_DIR) + SET(GLM_ROOT_DIR "${_glm_ENV_ROOT_DIR}") +ENDIF(NOT GLM_ROOT_DIR AND _glm_ENV_ROOT_DIR) + +# put user specified location at beginning of search +IF(GLM_ROOT_DIR) + SET(_glm_HEADER_SEARCH_DIRS "${GLM_ROOT_DIR}" + "${GLM_ROOT_DIR}/include" + ${_glm_HEADER_SEARCH_DIRS}) +ENDIF(GLM_ROOT_DIR) + +# locate header +FIND_PATH(GLM_INCLUDE_DIR "glm/glm.hpp" + PATHS ${_glm_HEADER_SEARCH_DIRS}) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLM DEFAULT_MSG + GLM_INCLUDE_DIR) + +IF(GLM_FOUND) + SET(GLM_INCLUDE_DIRS "${GLM_INCLUDE_DIR}") + + MESSAGE(STATUS "GLM_INCLUDE_DIR = ${GLM_INCLUDE_DIR}") +ENDIF(GLM_FOUND) diff --git a/cmake/Modules/FindGObject.cmake b/cmake/Modules/FindGObject.cmake new file mode 100644 index 0000000..f75524f --- /dev/null +++ b/cmake/Modules/FindGObject.cmake @@ -0,0 +1,31 @@ +# - Try to find GObject 2.0 +# Once done, this will define +# +# GObject_FOUND - system has GObject +# GObject_INCLUDE_DIRS - the GObject include directories +# GObject_LIBRARIES - link these to use GObject + +include(LibFindMacros) + +# Dependencies +libfind_package(GObject Glib) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(GObject_PKGCONF gobject-2.0) + +# Find the library +find_library(GObject_LIBRARY + NAMES gobject-2.0 + HINTS ${GObject_PKGCONF_LIBRARY_DIRS} +) + +find_path(GObject_INCLUDE_DIR + NAMES gobject/gobject.h + HINTS ${GObject_PKGCONF_INCLUDE_DIRS} + HINTS ${Glib_INCLUDE_DIRS} +) + +set(GObject_PROCESS_INCLUDES GObject_INCLUDE_DIR Glib_INCLUDE_DIR) +set(GObject_PROCESS_LIBS GObject_LIBRARY Glib_LIBRARY) +libfind_process(GObject) + diff --git a/cmake/Modules/FindGStreamer.cmake b/cmake/Modules/FindGStreamer.cmake new file mode 100644 index 0000000..4002c60 --- /dev/null +++ b/cmake/Modules/FindGStreamer.cmake @@ -0,0 +1,33 @@ +# - Try to find GStreamer +# Once done, this will define +# +# GStreamer_FOUND - system has GStreamer +# GStreamer_INCLUDE_DIRS - the GStreamer include directories +# GStreamer_LIBRARIES - link these to use GStreamer + +include(LibFindMacros) + +# Dependencies +libfind_package(GStreamer GObject) +libfind_package(GStreamer LibXML2) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(GStreamer_PKGCONF gstreamer-0.10) + +# Include dir +find_path(GStreamer_INCLUDE_DIR + NAMES gst/gst.h + HINTS ${GStreamer_PKGCONF_INCLUDE_DIRS} +) + +# Finally the library itself +find_library(GStreamer_LIBRARY + NAMES gstreamer-0.10 + HINTS ${GStreamer_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(GStreamer_PROCESS_INCLUDES GStreamer_INCLUDE_DIR GObject_INCLUDE_DIRS LibXML2_INCLUDE_DIRS) +set(GStreamer_PROCESS_LIBS GStreamer_LIBRARY GObject_LIBRARIES LibXML2_LIBRARIES) +libfind_process(GStreamer) diff --git a/cmake/Modules/FindGTK.cmake b/cmake/Modules/FindGTK.cmake new file mode 100644 index 0000000..a7ead72 --- /dev/null +++ b/cmake/Modules/FindGTK.cmake @@ -0,0 +1,38 @@ +# - Try to find GTK 2.0 +# Once done, this will define +# +# GTK_FOUND - system has GTK +# GTK_INCLUDE_DIRS - the GTK include directories +# GTK_LIBRARIES - link these to use GTK + +include(LibFindMacros) + +# Dependencies +libfind_package(GTK GDK) +libfind_package(GTK Cairo) +libfind_package(GTK Atk) +libfind_package(GTK GIO) +libfind_package(GTK Pango) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(GTK_PKGCONF gtk+-2.0) + +# Main include dir +find_path(GTK_INCLUDE_DIR + NAMES gtk/gtk.h + HINTS ${GTK_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES gtk-2.0 +) + +# Finally the library itself +find_library(GTK_LIBRARY + NAMES gtk-x11-2.0 + HINTS ${GTK_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(GTK_PROCESS_INCLUDES GTK_INCLUDE_DIR GDK_INCLUDE_DIRS Cairo_INCLUDE_DIRS Atk_INCLUDE_DIRS GIO_INCLUDE_DIRS Pango_INCLUDE_DIRS) +set(GTK_PROCESS_LIBS GTK_LIBRARY GDK_LIBRARIES Cairo_LIBRARIES Atk_LIBRARIES GIO_LIBRARIES Pango_LIBRARIES) +libfind_process(GTK) + diff --git a/cmake/Modules/FindGTKmm.cmake b/cmake/Modules/FindGTKmm.cmake new file mode 100644 index 0000000..7e737c7 --- /dev/null +++ b/cmake/Modules/FindGTKmm.cmake @@ -0,0 +1,46 @@ +# - Try to find GTKmm 2.4 +# Once done, this will define +# +# GTKmm_FOUND - system has GTKmm +# GTKmm_INCLUDE_DIRS - the GTKmm include directories +# GTKmm_LIBRARIES - link these to use GTKmm + +include(LibFindMacros) + +# Dependencies +libfind_package(GTKmm GTK) +libfind_package(GTKmm Glibmm) +libfind_package(GTKmm GIOmm) +libfind_package(GTKmm GDKmm) +libfind_package(GTKmm Pangomm) +libfind_package(GTKmm Atkmm) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(GTKmm_PKGCONF gtkmm-2.4) + +# Main include dir +find_path(GTKmm_INCLUDE_DIR + NAMES gtkmm.h + HINTS ${GTKmm_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES gtkmm-2.4 +) + +# Glib-related libraries also use a separate config header, which is in lib dir +find_path(GTKmmConfig_INCLUDE_DIR + NAMES gtkmmconfig.h + HINTS ${GTKmm_PKGCONF_INCLUDE_DIRS} /usr + PATH_SUFFIXES lib/gtkmm-2.4/include +) + +# Finally the library itself +find_library(GTKmm_LIBRARY + NAMES gtkmm-2.4 + HINTS ${GTKmm_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(GTKmm_PROCESS_INCLUDES GTKmm_INCLUDE_DIR GTKmmConfig_INCLUDE_DIR GTK_INCLUDE_DIRS Glibmm_INCLUDE_DIRS GIOmm_INCLUDE_DIRS GDKmm_INCLUDE_DIRS Pangomm_INCLUDE_DIRS Atkmm_INCLUDE_DIRS) +set(GTKmm_PROCESS_LIBS GTKmm_LIBRARY GTK_LIBRARIES Glibmm_LIBRARIES GIOmm_LIBRARIES GDKmm_LIBRARIES Pangomm_LIBRARIES Atkmm_LIBRARIES) +libfind_process(GTKmm) + diff --git a/cmake/Modules/FindGlib.cmake b/cmake/Modules/FindGlib.cmake new file mode 100644 index 0000000..3b976e8 --- /dev/null +++ b/cmake/Modules/FindGlib.cmake @@ -0,0 +1,39 @@ +# - Try to find Glib-2.0 +# Once done, this will define +# +# Glib_FOUND - system has Glib +# Glib_INCLUDE_DIRS - the Glib include directories +# Glib_LIBRARIES - link these to use Glib + +include(LibFindMacros) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Glib_PKGCONF glib-2.0) + +# Main include dir +find_path(Glib_INCLUDE_DIR + NAMES glib.h + HINTS ${Glib_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES glib-2.0 +) + +# Glib-related libraries also use a separate config header, which is in lib dir +find_path(GlibConfig_INCLUDE_DIR + NAMES glibconfig.h + HINTS ${Glib_PKGCONF_INCLUDE_DIRS} /usr + PATH_SUFFIXES lib/glib-2.0/include ../lib/glib-2.0/include +) + +# Finally the library itself +find_library(Glib_LIBRARY + NAMES glib-2.0 + HINTS ${Glib_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(Glib_PROCESS_INCLUDES Glib_INCLUDE_DIR GlibConfig_INCLUDE_DIR) +set(Glib_PROCESS_LIBS Glib_LIBRARY) +libfind_process(Glib) + + diff --git a/cmake/Modules/FindGlibmm.cmake b/cmake/Modules/FindGlibmm.cmake new file mode 100644 index 0000000..c0089cc --- /dev/null +++ b/cmake/Modules/FindGlibmm.cmake @@ -0,0 +1,39 @@ +# - Try to find Glibmm-2.4 +# Once done, this will define +# +# Glibmm_FOUND - system has Glibmm +# Glibmm_INCLUDE_DIRS - the Glibmm include directories +# Glibmm_LIBRARIES - link these to use Glibmm + +include(LibFindMacros) + +# Dependencies +libfind_package(Glibmm Glib) +libfind_package(Glibmm SigC++) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Glibmm_PKGCONF glibmm-2.4) + +# Main include dir +find_path(Glibmm_INCLUDE_DIR + NAMES glibmm/main.h + HINTS ${Glibmm_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES glibmm-2.4 +) + +# Glib-related libraries also use a separate config header, which is in lib dir +find_path(GlibmmConfig_INCLUDE_DIR + NAMES glibmmconfig.h + HINTS ${Glibmm_PKGCONF_INCLUDE_DIRS} /usr + PATH_SUFFIXES lib/glibmm-2.4/include ../lib/glibmm-2.4/include +) + +# Finally the library itself +find_library(Glibmm_LIBRARY + NAMES glibmm-2.4 + HINTS ${Glibmm_PKGCONF_LIBRARY_DIRS} +) + +set(Glibmm_PROCESS_INCLUDES GlibmmConfig_INCLUDE_DIR) +libfind_process(Glibmm) + diff --git a/cmake/Modules/FindICU.cmake b/cmake/Modules/FindICU.cmake new file mode 100644 index 0000000..7dbc02c --- /dev/null +++ b/cmake/Modules/FindICU.cmake @@ -0,0 +1,352 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#.rst: +# FindICU +# ------- +# +# Find the International Components for Unicode (ICU) libraries and +# programs. +# +# This module supports multiple components. +# Components can include any of: ``data``, ``i18n``, ``io``, ``le``, +# ``lx``, ``test``, ``tu`` and ``uc``. +# +# Note that on Windows ``data`` is named ``dt`` and ``i18n`` is named +# ``in``; any of the names may be used, and the appropriate +# platform-specific library name will be automatically selected. +# +# This module reports information about the ICU installation in +# several variables. General variables:: +# +# ICU_VERSION - ICU release version +# ICU_FOUND - true if the main programs and libraries were found +# ICU_LIBRARIES - component libraries to be linked +# ICU_INCLUDE_DIRS - the directories containing the ICU headers +# +# Imported targets:: +# +# ICU:: +# +# Where ```` is the name of an ICU component, for example +# ``ICU::i18n``. +# +# ICU programs are reported in:: +# +# ICU_GENCNVAL_EXECUTABLE - path to gencnval executable +# ICU_ICUINFO_EXECUTABLE - path to icuinfo executable +# ICU_GENBRK_EXECUTABLE - path to genbrk executable +# ICU_ICU-CONFIG_EXECUTABLE - path to icu-config executable +# ICU_GENRB_EXECUTABLE - path to genrb executable +# ICU_GENDICT_EXECUTABLE - path to gendict executable +# ICU_DERB_EXECUTABLE - path to derb executable +# ICU_PKGDATA_EXECUTABLE - path to pkgdata executable +# ICU_UCONV_EXECUTABLE - path to uconv executable +# ICU_GENCFU_EXECUTABLE - path to gencfu executable +# ICU_MAKECONV_EXECUTABLE - path to makeconv executable +# ICU_GENNORM2_EXECUTABLE - path to gennorm2 executable +# ICU_GENCCODE_EXECUTABLE - path to genccode executable +# ICU_GENSPREP_EXECUTABLE - path to gensprep executable +# ICU_ICUPKG_EXECUTABLE - path to icupkg executable +# ICU_GENCMN_EXECUTABLE - path to gencmn executable +# +# ICU component libraries are reported in:: +# +# ICU__FOUND - ON if component was found +# ICU__LIBRARIES - libraries for component +# +# Note that ```` is the uppercased name of the component. +# +# This module reads hints about search results from:: +# +# ICU_ROOT - the root of the ICU installation +# +# The environment variable ``ICU_ROOT`` may also be used; the +# ICU_ROOT variable takes precedence. +# +# The following cache variables may also be set:: +# +# ICU_

_EXECUTABLE - the path to executable

+# ICU_INCLUDE_DIR - the directory containing the ICU headers +# ICU__LIBRARY - the library for component +# +# .. note:: +# +# In most cases none of the above variables will require setting, +# unless multiple ICU versions are available and a specific version +# is required. +# +# Other variables one may set to control this module are:: +# +# ICU_DEBUG - Set to ON to enable debug output from FindICU. + +# Written by Roger Leigh + +set(icu_programs + gencnval + icuinfo + genbrk + icu-config + genrb + gendict + derb + pkgdata + uconv + gencfu + makeconv + gennorm2 + genccode + gensprep + icupkg + gencmn) + +# The ICU checks are contained in a function due to the large number +# of temporary variables needed. +function(_ICU_FIND) + # Set up search paths, taking compiler into account. Search ICU_ROOT, + # with ICU_ROOT in the environment as a fallback if unset. + if(ICU_ROOT) + list(APPEND icu_roots "${ICU_ROOT}") + else() + if(NOT "$ENV{ICU_ROOT}" STREQUAL "") + file(TO_CMAKE_PATH "$ENV{ICU_ROOT}" NATIVE_PATH) + list(APPEND icu_roots "${NATIVE_PATH}") + set(ICU_ROOT "${NATIVE_PATH}" + CACHE PATH "Location of the ICU installation" FORCE) + endif() + endif() + # Try also MacOS homebrew install path + list(APPEND icu_roots "/usr/local/opt/icu4c") + + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + # 64-bit binary directory + set(_bin64 "bin64") + # 64-bit library directory + set(_lib64 "lib64") + endif() + + # Generic 64-bit and 32-bit directories + list(APPEND icu_binary_suffixes "${_bin64}" "bin") + list(APPEND icu_library_suffixes "${_lib64}" "lib") + list(APPEND icu_include_suffixes "include") + + # Find all ICU programs + foreach(program ${icu_programs}) + string(TOUPPER "${program}" program_upcase) + set(cache_var "ICU_${program_upcase}_EXECUTABLE") + set(program_var "ICU_${program_upcase}_EXECUTABLE") + find_program("${cache_var}" "${program}" + HINTS ${icu_roots} + PATH_SUFFIXES ${icu_binary_suffixes} + DOC "ICU ${program} executable") + mark_as_advanced(cache_var) + set("${program_var}" "${${cache_var}}" PARENT_SCOPE) + endforeach() + + # Find include directory + find_path(ICU_INCLUDE_DIR + NAMES "unicode/utypes.h" + HINTS ${icu_roots} + PATH_SUFFIXES ${icu_include_suffixes} + DOC "ICU include directory") + set(ICU_INCLUDE_DIR "${ICU_INCLUDE_DIR}" PARENT_SCOPE) + + # Get version + if(ICU_INCLUDE_DIR AND EXISTS "${ICU_INCLUDE_DIR}/unicode/uvernum.h") + file(STRINGS "${ICU_INCLUDE_DIR}/unicode/uvernum.h" icu_header_str + REGEX "^#define[\t ]+U_ICU_VERSION[\t ]+\".*\".*") + + string(REGEX REPLACE "^#define[\t ]+U_ICU_VERSION[\t ]+\"([^ \\n]*)\".*" + "\\1" icu_version_string "${icu_header_str}") + set(ICU_VERSION "${icu_version_string}" PARENT_SCOPE) + unset(icu_header_str) + unset(icu_version_string) + endif() + + # Find all ICU libraries + set(ICU_REQUIRED_LIBS_FOUND ON) + foreach(component ${ICU_FIND_COMPONENTS}) + string(TOUPPER "${component}" component_upcase) + set(component_cache "ICU_${component_upcase}_LIBRARY") + set(component_cache_release "${component_cache}_RELEASE") + set(component_cache_debug "${component_cache}_DEBUG") + set(component_found "${component_upcase}_FOUND") + set(component_libnames "icu${component}") + set(component_debug_libnames "icu${component}d") + + # Special case deliberate library naming mismatches between Unix + # and Windows builds + unset(component_libnames) + unset(component_debug_libnames) + list(APPEND component_libnames "icu${component}") + list(APPEND component_debug_libnames "icu${component}d") + if(component STREQUAL "data") + list(APPEND component_libnames "icudt") + # Note there is no debug variant at present + list(APPEND component_debug_libnames "icudtd") + endif() + if(component STREQUAL "dt") + list(APPEND component_libnames "icudata") + # Note there is no debug variant at present + list(APPEND component_debug_libnames "icudatad") + endif() + if(component STREQUAL "i18n") + list(APPEND component_libnames "icuin") + list(APPEND component_debug_libnames "icuind") + endif() + if(component STREQUAL "in") + list(APPEND component_libnames "icui18n") + list(APPEND component_debug_libnames "icui18nd") + endif() + + find_library("${component_cache_release}" ${component_libnames} + HINTS ${icu_roots} + PATH_SUFFIXES ${icu_library_suffixes} + DOC "ICU ${component} library (release)") + find_library("${component_cache_debug}" ${component_debug_libnames} + HINTS ${icu_roots} + PATH_SUFFIXES ${icu_library_suffixes} + DOC "ICU ${component} library (debug)") + include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) + select_library_configurations(ICU_${component_upcase}) + mark_as_advanced("${component_cache_release}" "${component_cache_debug}") + if(${component_cache}) + set("${component_found}" ON) + list(APPEND ICU_LIBRARY "${${component_cache}}") + endif() + mark_as_advanced("${component_found}") + set("${component_cache}" "${${component_cache}}" PARENT_SCOPE) + set("${component_found}" "${${component_found}}" PARENT_SCOPE) + if(${component_found}) + if (ICU_FIND_REQUIRED_${component}) + list(APPEND ICU_LIBS_FOUND "${component} (required)") + else() + list(APPEND ICU_LIBS_FOUND "${component} (optional)") + endif() + else() + if (ICU_FIND_REQUIRED_${component}) + set(ICU_REQUIRED_LIBS_FOUND OFF) + list(APPEND ICU_LIBS_NOTFOUND "${component} (required)") + else() + list(APPEND ICU_LIBS_NOTFOUND "${component} (optional)") + endif() + endif() + endforeach() + set(_ICU_REQUIRED_LIBS_FOUND "${ICU_REQUIRED_LIBS_FOUND}" PARENT_SCOPE) + set(ICU_LIBRARY "${ICU_LIBRARY}" PARENT_SCOPE) + + if(NOT ICU_FIND_QUIETLY) + if(ICU_LIBS_FOUND) + message(STATUS "Found the following ICU libraries:") + foreach(found ${ICU_LIBS_FOUND}) + message(STATUS " ${found}") + endforeach() + endif() + if(ICU_LIBS_NOTFOUND) + message(STATUS "The following ICU libraries were not found:") + foreach(notfound ${ICU_LIBS_NOTFOUND}) + message(STATUS " ${notfound}") + endforeach() + endif() + endif() + + if(ICU_DEBUG) + message(STATUS "--------FindICU.cmake search debug--------") + message(STATUS "ICU binary path search order: ${icu_roots}") + message(STATUS "ICU include path search order: ${icu_roots}") + message(STATUS "ICU library path search order: ${icu_roots}") + message(STATUS "----------------") + endif() +endfunction() + +_ICU_FIND() + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ICU + FOUND_VAR ICU_FOUND + REQUIRED_VARS ICU_INCLUDE_DIR + ICU_LIBRARY + _ICU_REQUIRED_LIBS_FOUND + VERSION_VAR ICU_VERSION + FAIL_MESSAGE "Failed to find all ICU components") + +unset(_ICU_REQUIRED_LIBS_FOUND) + +if(ICU_FOUND) + set(ICU_INCLUDE_DIRS "${ICU_INCLUDE_DIR}") + set(ICU_LIBRARIES "${ICU_LIBRARY}") + foreach(_ICU_component ${ICU_FIND_COMPONENTS}) + string(TOUPPER "${_ICU_component}" _ICU_component_upcase) + set(_ICU_component_cache "ICU_${_ICU_component_upcase}_LIBRARY") + set(_ICU_component_cache_release "ICU_${_ICU_component_upcase}_LIBRARY_RELEASE") + set(_ICU_component_cache_debug "ICU_${_ICU_component_upcase}_LIBRARY_DEBUG") + set(_ICU_component_lib "ICU_${_ICU_component_upcase}_LIBRARIES") + set(_ICU_component_found "${_ICU_component_upcase}_FOUND") + set(_ICU_imported_target "ICU::${_ICU_component}") + if(${_ICU_component_found}) + set("${_ICU_component_lib}" "${${_ICU_component_cache}}") + if(NOT TARGET ${_ICU_imported_target}) + add_library(${_ICU_imported_target} UNKNOWN IMPORTED) + if(ICU_INCLUDE_DIR) + set_target_properties(${_ICU_imported_target} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${ICU_INCLUDE_DIR}") + endif() + if(EXISTS "${${_ICU_component_cache}}") + set_target_properties(${_ICU_imported_target} PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${${_ICU_component_cache}}") + endif() + if(EXISTS "${${_ICU_component_cache_release}}") + set_property(TARGET ${_ICU_imported_target} APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(${_ICU_imported_target} PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX" + IMPORTED_LOCATION_RELEASE "${${_ICU_component_cache_release}}") + endif() + if(EXISTS "${${_ICU_component_cache_debug}}") + set_property(TARGET ${_ICU_imported_target} APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(${_ICU_imported_target} PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX" + IMPORTED_LOCATION_DEBUG "${${_ICU_component_cache_debug}}") + endif() + endif() + endif() + unset(_ICU_component_upcase) + unset(_ICU_component_cache) + unset(_ICU_component_lib) + unset(_ICU_component_found) + unset(_ICU_imported_target) + endforeach() +endif() + +if(ICU_DEBUG) + message(STATUS "--------FindICU.cmake results debug--------") + message(STATUS "ICU found: ${ICU_FOUND}") + message(STATUS "ICU_VERSION number: ${ICU_VERSION}") + message(STATUS "ICU_ROOT directory: ${ICU_ROOT}") + message(STATUS "ICU_INCLUDE_DIR directory: ${ICU_INCLUDE_DIR}") + message(STATUS "ICU_LIBRARIES: ${ICU_LIBRARIES}") + + foreach(program IN LISTS icu_programs) + string(TOUPPER "${program}" program_upcase) + set(program_lib "ICU_${program_upcase}_EXECUTABLE") + message(STATUS "${program} program: ${${program_lib}}") + unset(program_upcase) + unset(program_lib) + endforeach() + + foreach(component IN LISTS ICU_FIND_COMPONENTS) + string(TOUPPER "${component}" component_upcase) + set(component_lib "ICU_${component_upcase}_LIBRARIES") + set(component_found "${component_upcase}_FOUND") + message(STATUS "${component} library found: ${${component_found}}") + message(STATUS "${component} library: ${${component_lib}}") + unset(component_upcase) + unset(component_lib) + unset(component_found) + endforeach() + message(STATUS "----------------") +endif() + +unset(icu_programs) diff --git a/cmake/Modules/FindJack.cmake b/cmake/Modules/FindJack.cmake new file mode 100644 index 0000000..110ed9a --- /dev/null +++ b/cmake/Modules/FindJack.cmake @@ -0,0 +1,28 @@ +# - Try to find Jack +# Once done, this will define +# +# Jack_FOUND - system has Jack +# Jack_INCLUDE_DIRS - the Jack include directories +# Jack_LIBRARIES - link these to use Jack +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(Jack_PKGCONF jack) + +find_path(Jack_INCLUDE_DIR + NAMES jack/jack.h + HINTS ${Jack_PKGCONF_INCLUDE_DIRS} +) + +find_library(Jack_LIBRARY + NAMES jack + HINTS ${Jack_PKGCONF_LIBRARY_DIRS} +) + +set(Jack_PROCESS_INCLUDES Jack_INCLUDE_DIR) +set(Jack_PROCESS_LIBS Jack_LIBRARY) +libfind_process(Jack) + diff --git a/cmake/Modules/FindJpeg.cmake b/cmake/Modules/FindJpeg.cmake new file mode 100644 index 0000000..2d3ecbc --- /dev/null +++ b/cmake/Modules/FindJpeg.cmake @@ -0,0 +1,28 @@ +# - Try to find Jpeg +# Once done, this will define +# +# Jpeg_FOUND - system has Jpeg +# Jpeg_INCLUDE_DIRS - the Jpeg include directories +# Jpeg_LIBRARIES - link these to use Jpeg +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(Jpeg_PKGCONF jpeg) + +find_path(Jpeg_INCLUDE_DIR + NAMES jconfig.h jpeglib.h + HINTS ${Jpeg_PKGCONF_INCLUDE_DIRS} +) + +find_library(Jpeg_LIBRARY + NAMES jpeg + HINTS ${Jpeg_PKGCONF_LIBRARY_DIRS} +) + +set(Jpeg_PROCESS_INCLUDES Jpeg_INCLUDE_DIR) +set(Jpeg_PROCESS_LIBS Jpeg_LIBRARY) +libfind_process(Jpeg) + diff --git a/cmake/Modules/FindLibEpoxy.cmake b/cmake/Modules/FindLibEpoxy.cmake new file mode 100644 index 0000000..110f420 --- /dev/null +++ b/cmake/Modules/FindLibEpoxy.cmake @@ -0,0 +1,30 @@ +# - Try to find LibEpoxy +# Once done, this will define +# +# LibEpoxy_FOUND - system has LibEpoxy +# LibEpoxy_INCLUDE_DIRS - the LibEpoxy include directories +# LibEpoxy_LIBRARIES - link these to use LibEpoxy +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(LibEpoxy_PKGCONF epoxy) + +find_path(LibEpoxy_INCLUDE_DIR + NAMES epoxy/gl.h + HINTS ${LibEpoxy_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES LibEpoxy +) + +find_library(LibEpoxy_LIBRARY + NAMES epoxy + HINTS ${LibEpoxy_PKGCONF_LIBRARY_DIRS} +) + +set(LibEpoxy_PROCESS_INCLUDES LibEpoxy_INCLUDE_DIR) +set(LibEpoxy_PROCESS_LIBS LibEpoxy_LIBRARY) +set(LibEpoxy_VERSION ${LibEpoxy_PKGCONF_VERSION}) +libfind_process(LibEpoxy) + diff --git a/cmake/Modules/FindLibPulse.cmake b/cmake/Modules/FindLibPulse.cmake new file mode 100644 index 0000000..6e06202 --- /dev/null +++ b/cmake/Modules/FindLibPulse.cmake @@ -0,0 +1,28 @@ +# - Try to find LibPulse +# Once done, this will define +# +# LibPulse_FOUND - system has LibPulse +# LibPulse_INCLUDE_DIRS - the LibPulse include directories +# LibPulse_LIBRARIES - link these to use LibPulse +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(LibPulse_PKGCONF libpulse) + +find_path(LibPulse_INCLUDE_DIR + NAMES pulse/pulseaudio.h + HINTS ${LibPulse_PKGCONF_INCLUDE_DIRS} +) + +find_library(LibPulse_LIBRARY + NAMES pulse + HINTS ${LibPulse_PKGCONF_LIBRARY_DIRS} +) + +set(LibPulse_PROCESS_INCLUDES LibPulse_INCLUDE_DIR) +set(LibPulse_PROCESS_LIBS LibPulse_LIBRARY) +libfind_process(LibPulse) + diff --git a/cmake/Modules/FindLibPulseSimple.cmake b/cmake/Modules/FindLibPulseSimple.cmake new file mode 100644 index 0000000..25b5ac7 --- /dev/null +++ b/cmake/Modules/FindLibPulseSimple.cmake @@ -0,0 +1,28 @@ +# - Try to find LibPulseSimple +# Once done, this will define +# +# LibPulseSimple_FOUND - system has LibPulseSimple +# LibPulseSimple_INCLUDE_DIRS - the LibPulseSimple include directories +# LibPulseSimple_LIBRARIES - link these to use LibPulseSimple +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(LibPulseSimple_PKGCONF libpulse-simple) + +find_path(LibPulseSimple_INCLUDE_DIR + NAMES pulse/simple.h + HINTS ${LibPulseSimple_PKGCONF_INCLUDE_DIRS} +) + +find_library(LibPulseSimple_LIBRARY + NAMES pulse-simple + HINTS ${LibPulseSimple_PKGCONF_LIBRARY_DIRS} +) + +set(LibPulseSimple_PROCESS_INCLUDES LibPulseSimple_INCLUDE_DIR) +set(LibPulseSimple_PROCESS_LIBS LibPulseSimple_LIBRARY) +libfind_process(LibPulseSimple) + diff --git a/cmake/Modules/FindLibRSVG.cmake b/cmake/Modules/FindLibRSVG.cmake new file mode 100644 index 0000000..1a9698e --- /dev/null +++ b/cmake/Modules/FindLibRSVG.cmake @@ -0,0 +1,16 @@ +# - Try to find LibRSVG +# Once done, this will define +# +# LibRSVG_FOUND - system has LibRSVG +# LibRSVG_INCLUDE_DIRS - the LibRSVG include directories +# LibRSVG_LIBRARIES - link these to use LibRSVG + +include(LibFindMacros) +libfind_package(LibRSVG Cairo) +libfind_package(LibRSVG GDK-PixBuf) +libfind_pkg_detect(LibRSVG librsvg-2.0 + FIND_PATH librsvg/rsvg.h PATH_SUFFIXES librsvg-2 + FIND_LIBRARY rsvg-2 +) +libfind_process(LibRSVG) + diff --git a/cmake/Modules/FindLibXML++.cmake b/cmake/Modules/FindLibXML++.cmake new file mode 100644 index 0000000..5258a78 --- /dev/null +++ b/cmake/Modules/FindLibXML++.cmake @@ -0,0 +1,56 @@ +# - Try to find LibXML++ 3.0 or 2.6 (defaulting) +# Once done, this will define +# +# LibXML++_FOUND - system has LibXML++ +# LibXML++_INCLUDE_DIRS - the LibXML++ include directories +# LibXML++_LIBRARIES - link these to use LibXML++ + +include(LibFindMacros) + +# Dependencies +libfind_package(LibXML++ LibXML2) +libfind_package(LibXML++ Glibmm) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(LibXML++_PKGCONF_3_0 libxml++-3.0) + +if(LibXML++_PKGCONF_3_0_FOUND) + set(LibXML++_VERSION "3.0") + set(LibXML++_VERSION_2_6 "0") + set(LibXML++_VERSION_3_0 "1") + set(LibXML++_PKGCONF_INCLUDE_DIRS ${LibXML++_PKGCONF_3_0_INCLUDE_DIRS}) + set(LibXML++_PKGCONF_LIBRARY_DIRS ${LibXML++_PKGCONF_3_0_LIBRARY_DIRS}) +else(LixXML++_PKGCONF_3_0_FOUND) + libfind_pkg_check_modules(LibXML++_PKGCONF_2_6 libxml++-2.6) + if(LibXML++_PKGCONF_2_6_FOUND) + set(LibXML++_VERSION "2.6") + set(LibXML++_VERSION_2_6 "1") + set(LibXML++_VERSION_3_0 "0") + set(LibXML++_PKGCONF_INCLUDE_DIRS ${LibXML++_PKGCONF_2_6_INCLUDE_DIRS}) + set(LibXML++_PKGCONF_LIBRARY_DIRS ${LibXML++_PKGCONF_2_6_LIBRARY_DIRS}) + endif(LibXML++_PKGCONF_2_6_FOUND) +endif(LibXML++_PKGCONF_3_0_FOUND) + +# Main include dir +find_path(LibXML++_INCLUDE_DIR + NAMES libxml++/libxml++.h + HINTS ${LibXML++_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES libxml++-${LibXML++_VERSION} +) + +# Glib-related libraries also use a separate config header, which is in lib dir +find_path(LibXML++Config_INCLUDE_DIR + NAMES libxml++config.h + HINTS ${LibXML++_PKGCONF_INCLUDE_DIRS} /usr /usr/lib/x86_64-linux-gnu/libxml++-${LibXML++_VERSION}/include/ + PATH_SUFFIXES lib/libxml++-${LibXML++_VERSION}/include ../lib/libxml++-${LibXML++_VERSION}/include +) + +# Finally the library itself +find_library(LibXML++_LIBRARY + NAMES xml++-${LibXML++_VERSION} + HINTS ${LibXML++_PKGCONF_LIBRARY_DIRS} +) + +set(LibXML++_PROCESS_INCLUDES LibXML++Config_INCLUDE_DIR) +libfind_process(LibXML++) + diff --git a/cmake/Modules/FindLibXML2.cmake b/cmake/Modules/FindLibXML2.cmake new file mode 100644 index 0000000..5abd0bb --- /dev/null +++ b/cmake/Modules/FindLibXML2.cmake @@ -0,0 +1,30 @@ +# - Try to find LibXML2 +# Once done, this will define +# +# LibXML2_FOUND - system has LibXML2 +# LibXML2_INCLUDE_DIRS - the LibXML2 include directories +# LibXML2_LIBRARIES - link these to use LibXML2 +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(LibXML2_PKGCONF libxml-2.0) + +find_path(LibXML2_INCLUDE_DIR + NAMES libxml/xpath.h + HINTS ${LibXML2_PKGCONF_INCLUDE_DIRS} + HINTS ${LibXML2_PKGCONF_INCLUDE_DIRS}/libxml2 + PATH_SUFFIXES libxml2 +) + +find_library(LibXML2_LIBRARY + NAMES xml2 + HINTS ${LibXML2_PKGCONF_LIBRARY_DIRS} +) + +set(LibXML2_PROCESS_INCLUDES LibXML2_INCLUDE_DIR) +set(LibXML2_PROCESS_LIBS LibXML2_LIBRARY) +libfind_process(LibXML2) + diff --git a/cmake/Modules/FindMagick++.cmake b/cmake/Modules/FindMagick++.cmake new file mode 100644 index 0000000..e663e89 --- /dev/null +++ b/cmake/Modules/FindMagick++.cmake @@ -0,0 +1,30 @@ +# - Try to find ImageMagick++ +# Once done, this will define +# +# Magick++_FOUND - system has Magick++ +# Magick++_INCLUDE_DIRS - the Magick++ include directories +# Magick++_LIBRARIES - link these to use Magick++ + +include(LibFindMacros) + +# Dependencies +libfind_package(Magick++ Magick) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Magick++_PKGCONF ImageMagick++) + +# Include dir +find_path(Magick++_INCLUDE_DIR + NAMES Magick++.h + HINTS ${Magick++_PKGCONF_INCLUDE_DIRS} +) + +# Finally the library itself +find_library(Magick++_LIBRARY + NAMES Magick++ CORE_RL_magick++_ + HINTS ${Magick++_PKGCONF_LIBRARY_DIRS} +) + +# Process Magick++, depends on Magick +libfind_process(Magick++ Magick) + diff --git a/cmake/Modules/FindMagick.cmake b/cmake/Modules/FindMagick.cmake new file mode 100644 index 0000000..2915e72 --- /dev/null +++ b/cmake/Modules/FindMagick.cmake @@ -0,0 +1,35 @@ +# - Try to find ImageMagick +# Once done, this will define +# +# Magick_FOUND - system has Magick +# Magick_INCLUDE_DIRS - the Magick include directories +# Magick_LIBRARIES - link these to use Magick + +include(LibFindMacros) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Magick_PKGCONF ImageMagick) + +# Include dir +find_path(Magick_INCLUDE_DIR + NAMES magick/magick.h + HINTS ${Magick_PKGCONF_INCLUDE_DIRS} +) + +# Finally the library itself +find_library(Magick_LIBRARY + NAMES Magick MagickCore CORE_RL_magick_ + HINTS ${Magick_PKGCONF_LIBRARY_DIRS} +) + +if(MINGW) + find_library(MagickWand_LIBRARY + NAMES MagickWand + HINTS ${Magick_PKGCONF_LIBRARY_DIRS} + ) + set(Magick_PROCESS_LIBS MagickWand_LIBRARY) +endif(MINGW) + +libfind_version_header(Magick magick/version.h MagickLibVersionText) +libfind_process(Magick) + diff --git a/cmake/Modules/FindOpenGL.cmake b/cmake/Modules/FindOpenGL.cmake new file mode 100644 index 0000000..5cc8c98 --- /dev/null +++ b/cmake/Modules/FindOpenGL.cmake @@ -0,0 +1,44 @@ +# - Try to find OpenGL +# Once done, this will define +# +# OpenGL_FOUND - system has OpenGL (GL and GLU) +# OpenGL_INCLUDE_DIRS - the OpenGL include directories +# OpenGL_LIBRARIES - link these to use OpenGL +# OpenGL_GL_LIBRARY - only GL +# OpenGL_GLU_LIBRARY - only GLU +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(OpenGL_PKGCONF gl) + +find_path(OpenGL_INCLUDE_DIR + NAMES GL/gl.h + HINTS ${OpenGL_PKGCONF_INCLUDE_DIRS} +) + +if(MSVC) #In MSVC, no need to link, just this hack to get CMake happy + find_file(OpenGL_GL_LIBRARY + opengl32.dll + ) + + find_file(OpenGL_GLU_LIBRARY + glu32.dll + ) +else() + find_library(OpenGL_GL_LIBRARY + NAMES GL libopengl32.a opengl32 + HINTS ${OpenGL_PKGCONF_LIBRARY_DIRS} + ) + + find_library(OpenGL_GLU_LIBRARY + NAMES GLU libglu32.a glu32 + HINTS ${OpenGL_PKGCONF_LIBRARY_DIRS} + ) +endif(MSVC) +set(OpenGL_PROCESS_INCLUDES OpenGL_INCLUDE_DIR) +set(OpenGL_PROCESS_LIBS OpenGL_GL_LIBRARY OpenGL_GLU_LIBRARY) +libfind_process(OpenGL) + diff --git a/cmake/Modules/FindPThread.cmake b/cmake/Modules/FindPThread.cmake new file mode 100644 index 0000000..892c837 --- /dev/null +++ b/cmake/Modules/FindPThread.cmake @@ -0,0 +1,21 @@ +# - Try to find PThread +# Once done, this will define +# +# PThread_FOUND - system has PThread +# PThread_LIBRARIES - link these to use PThread +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(Png_PKGCONF PThread) + +find_library(PThread_LIBRARY + NAMES pthreadGC2 + HINTS ${PThread_PKGCONF_LIBRARY_DIRS} +) + +set(PThread_PROCESS_LIBS PThread_LIBRARY) +libfind_process(PThread) + diff --git a/cmake/Modules/FindPackageHandleStandardArgs.cmake b/cmake/Modules/FindPackageHandleStandardArgs.cmake new file mode 100644 index 0000000..b851a90 --- /dev/null +++ b/cmake/Modules/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,385 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindPackageHandleStandardArgs +----------------------------- + +This module provides a function intended to be used in :ref:`Find Modules` +implementing :command:`find_package()` calls. It handles the +``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``. +It also sets the ``_FOUND`` variable. The package is +considered found if all variables listed contain valid results, e.g. +valid filepaths. + +.. command:: find_package_handle_standard_args + + There are two signatures:: + + find_package_handle_standard_args( + (DEFAULT_MSG|) + ... + ) + + find_package_handle_standard_args( + [FOUND_VAR ] + [REQUIRED_VARS ...] + [VERSION_VAR ] + [HANDLE_COMPONENTS] + [CONFIG_MODE] + [FAIL_MESSAGE ] + ) + + The ``_FOUND`` variable will be set to ``TRUE`` if all + the variables ``...`` are valid and any optional + constraints are satisfied, and ``FALSE`` otherwise. A success or + failure message may be displayed based on the results and on + whether the ``REQUIRED`` and/or ``QUIET`` option was given to + the :command:`find_package` call. + + The options are: + + ``(DEFAULT_MSG|)`` + In the simple signature this specifies the failure message. + Use ``DEFAULT_MSG`` to ask for a default message to be computed + (recommended). Not valid in the full signature. + + ``FOUND_VAR `` + Obsolete. Specifies either ``_FOUND`` or + ``_FOUND`` as the result variable. This exists only + for compatibility with older versions of CMake and is now ignored. + Result variables of both names are always set for compatibility. + + ``REQUIRED_VARS ...`` + Specify the variables which are required for this package. + These may be named in the generated failure message asking the + user to set the missing variable values. Therefore these should + typically be cache entries such as ``FOO_LIBRARY`` and not output + variables like ``FOO_LIBRARIES``. + + ``VERSION_VAR `` + Specify the name of a variable that holds the version of the package + that has been found. This version will be checked against the + (potentially) specified required version given to the + :command:`find_package` call, including its ``EXACT`` option. + The default messages include information about the required + version and the version which has been actually found, both + if the version is ok or not. + + ``HANDLE_COMPONENTS`` + Enable handling of package components. In this case, the command + will report which components have been found and which are missing, + and the ``_FOUND`` variable will be set to ``FALSE`` + if any of the required components (i.e. not the ones listed after + the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are + missing. + + ``CONFIG_MODE`` + Specify that the calling find module is a wrapper around a + call to ``find_package( NO_MODULE)``. This implies + a ``VERSION_VAR`` value of ``_VERSION``. The command + will automatically check whether the package configuration file + was found. + + ``FAIL_MESSAGE `` + Specify a custom failure message instead of using the default + generated message. Not recommended. + +Example for the simple signature: + +.. code-block:: cmake + + find_package_handle_standard_args(LibXml2 DEFAULT_MSG + LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) + +The ``LibXml2`` package is considered to be found if both +``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. +Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found +and ``REQUIRED`` was used, it fails with a +:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was +used or not. If it is found, success will be reported, including +the content of the first ````. On repeated CMake runs, +the same message will not be printed again. + +Example for the full signature: + +.. code-block:: cmake + + find_package_handle_standard_args(LibArchive + REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR + VERSION_VAR LibArchive_VERSION) + +In this case, the ``LibArchive`` package is considered to be found if +both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. +Also the version of ``LibArchive`` will be checked by using the version +contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, +the default messages will be printed. + +Another example for the full signature: + +.. code-block:: cmake + + find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) + find_package_handle_standard_args(Automoc4 CONFIG_MODE) + +In this case, a ``FindAutmoc4.cmake`` module wraps a call to +``find_package(Automoc4 NO_MODULE)`` and adds an additional search +directory for ``automoc4``. Then the call to +``find_package_handle_standard_args`` produces a proper success/failure +message. +#]=======================================================================] + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake) + +# internal helper macro +macro(_FPHSA_FAILURE_MESSAGE _msg) + if (${_NAME}_FIND_REQUIRED) + message(FATAL_ERROR "${_msg}") + else () + if (NOT ${_NAME}_FIND_QUIETLY) + message(STATUS "${_msg}") + endif () + endif () +endmacro() + + +# internal helper macro to generate the failure message when used in CONFIG_MODE: +macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) + # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: + if(${_NAME}_CONFIG) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") + else() + # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. + # List them all in the error message: + if(${_NAME}_CONSIDERED_CONFIGS) + set(configsText "") + list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) + math(EXPR configsCount "${configsCount} - 1") + foreach(currentConfigIndex RANGE ${configsCount}) + list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) + list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) + string(APPEND configsText " ${filename} (version ${version})\n") + endforeach() + if (${_NAME}_NOT_FOUND_MESSAGE) + string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") + endif() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") + + else() + # Simple case: No Config-file was found at all: + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") + endif() + endif() +endmacro() + + +function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) + +# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in +# new extended or in the "old" mode: + set(options CONFIG_MODE HANDLE_COMPONENTS) + set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR) + set(multiValueArgs REQUIRED_VARS) + set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) + list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) + + if(${INDEX} EQUAL -1) + set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) + set(FPHSA_REQUIRED_VARS ${ARGN}) + set(FPHSA_VERSION_VAR) + else() + + CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) + + if(FPHSA_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") + endif() + + if(NOT FPHSA_FAIL_MESSAGE) + set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") + endif() + endif() + +# now that we collected all arguments, process them + + if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG") + set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") + endif() + + # In config-mode, we rely on the variable _CONFIG, which is set by find_package() + # when it successfully found the config-file, including version checking: + if(FPHSA_CONFIG_MODE) + list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) + list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) + set(FPHSA_VERSION_VAR ${_NAME}_VERSION) + endif() + + if(NOT FPHSA_REQUIRED_VARS) + message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") + endif() + + list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) + + string(TOUPPER ${_NAME} _NAME_UPPER) + string(TOLOWER ${_NAME} _NAME_LOWER) + + if(FPHSA_FOUND_VAR) + if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$") + set(_FOUND_VAR ${FPHSA_FOUND_VAR}) + else() + message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.") + endif() + else() + set(_FOUND_VAR ${_NAME_UPPER}_FOUND) + endif() + + # collect all variables which were not found, so they can be printed, so the + # user knows better what went wrong (#6375) + set(MISSING_VARS "") + set(DETAILS "") + # check if all passed variables are valid + set(FPHSA_FOUND_${_NAME} TRUE) + foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) + if(NOT ${_CURRENT_VAR}) + set(FPHSA_FOUND_${_NAME} FALSE) + string(APPEND MISSING_VARS " ${_CURRENT_VAR}") + else() + string(APPEND DETAILS "[${${_CURRENT_VAR}}]") + endif() + endforeach() + if(FPHSA_FOUND_${_NAME}) + set(${_NAME}_FOUND TRUE) + set(${_NAME_UPPER}_FOUND TRUE) + else() + set(${_NAME}_FOUND FALSE) + set(${_NAME_UPPER}_FOUND FALSE) + endif() + + # component handling + unset(FOUND_COMPONENTS_MSG) + unset(MISSING_COMPONENTS_MSG) + + if(FPHSA_HANDLE_COMPONENTS) + foreach(comp ${${_NAME}_FIND_COMPONENTS}) + if(${_NAME}_${comp}_FOUND) + + if(NOT DEFINED FOUND_COMPONENTS_MSG) + set(FOUND_COMPONENTS_MSG "found components: ") + endif() + string(APPEND FOUND_COMPONENTS_MSG " ${comp}") + + else() + + if(NOT DEFINED MISSING_COMPONENTS_MSG) + set(MISSING_COMPONENTS_MSG "missing components: ") + endif() + string(APPEND MISSING_COMPONENTS_MSG " ${comp}") + + if(${_NAME}_FIND_REQUIRED_${comp}) + set(${_NAME}_FOUND FALSE) + string(APPEND MISSING_VARS " ${comp}") + endif() + + endif() + endforeach() + set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}") + string(APPEND DETAILS "[c${COMPONENT_MSG}]") + endif() + + # version handling: + set(VERSION_MSG "") + set(VERSION_OK TRUE) + set(VERSION ${${FPHSA_VERSION_VAR}}) + + # check with DEFINED here as the requested or found version may be "0" + if (DEFINED ${_NAME}_FIND_VERSION) + if(DEFINED ${FPHSA_VERSION_VAR}) + + if(${_NAME}_FIND_VERSION_EXACT) # exact version required + # count the dots in the version string + string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${VERSION}") + # add one dot because there is one dot more than there are components + string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS) + if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT) + # Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT + # is at most 4 here. Therefore a simple lookup table is used. + if (${_NAME}_FIND_VERSION_COUNT EQUAL 1) + set(_VERSION_REGEX "[^.]*") + elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2) + set(_VERSION_REGEX "[^.]*\\.[^.]*") + elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3) + set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*") + else () + set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*") + endif () + string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${VERSION}") + unset(_VERSION_REGEX) + if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD) + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable exact version \"${VERSION}\")") + endif () + unset(_VERSION_HEAD) + else () + if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL VERSION) + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable exact version \"${VERSION}\")") + endif () + endif () + unset(_VERSION_DOTS) + + else() # minimum version specified: + if (${_NAME}_FIND_VERSION VERSION_GREATER VERSION) + set(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") + set(VERSION_OK FALSE) + else () + set(VERSION_MSG "(found suitable version \"${VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")") + endif () + endif() + + else() + + # if the package was not found, but a version was given, add that to the output: + if(${_NAME}_FIND_VERSION_EXACT) + set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") + else() + set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") + endif() + + endif() + else () + if(VERSION) + set(VERSION_MSG "(found version \"${VERSION}\")") + endif() + endif () + + if(VERSION_OK) + string(APPEND DETAILS "[v${VERSION}(${${_NAME}_FIND_VERSION})]") + else() + set(${_NAME}_FOUND FALSE) + endif() + + + # print the result: + if (${_NAME}_FOUND) + FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}") + else () + + if(FPHSA_CONFIG_MODE) + _FPHSA_HANDLE_FAILURE_CONFIG_MODE() + else() + if(NOT VERSION_OK) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") + else() + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}") + endif() + endif() + + endif () + + set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) + set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE) +endfunction() diff --git a/cmake/Modules/FindPackageMessage.cmake b/cmake/Modules/FindPackageMessage.cmake new file mode 100644 index 0000000..6821cee --- /dev/null +++ b/cmake/Modules/FindPackageMessage.cmake @@ -0,0 +1,47 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#.rst: +# FindPackageMessage +# ------------------ +# +# +# +# FIND_PACKAGE_MESSAGE( "message for user" "find result details") +# +# This macro is intended to be used in FindXXX.cmake modules files. It +# will print a message once for each unique find result. This is useful +# for telling the user where a package was found. The first argument +# specifies the name (XXX) of the package. The second argument +# specifies the message to display. The third argument lists details +# about the find result so that if they change the message will be +# displayed again. The macro also obeys the QUIET argument to the +# find_package command. +# +# Example: +# +# :: +# +# if(X11_FOUND) +# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}" +# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]") +# else() +# ... +# endif() + +function(FIND_PACKAGE_MESSAGE pkg msg details) + # Avoid printing a message repeatedly for the same find result. + if(NOT ${pkg}_FIND_QUIETLY) + string(REPLACE "\n" "" details "${details}") + set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg}) + if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}") + # The message has not yet been printed. + message(STATUS "${msg}") + + # Save the find details in the cache to avoid printing the same + # message again. + set("${DETAILS_VAR}" "${details}" + CACHE INTERNAL "Details about finding ${pkg}") + endif() + endif() +endfunction() diff --git a/cmake/Modules/FindPango.cmake b/cmake/Modules/FindPango.cmake new file mode 100644 index 0000000..bdddb9e --- /dev/null +++ b/cmake/Modules/FindPango.cmake @@ -0,0 +1,32 @@ +# - Try to find Pango +# Once done, this will define +# +# Pango_FOUND - system has Pango +# Pango_INCLUDE_DIRS - the Pango include directories +# Pango_LIBRARIES - link these to use Pango + +include(LibFindMacros) + +# Dependencies +libfind_package(Pango Freetype) +libfind_package(Pango Glib) +libfind_package(Pango GObject) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Pango_PKGCONF pango) + +# Include dir +find_path(Pango_INCLUDE_DIR + NAMES pango/pango.h + HINTS ${Pango_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES pango-1.0 +) + +# Finally the library itself +find_library(Pango_LIBRARY + NAMES pango-1.0 + HINTS ${Pango_PKGCONF_LIBRARY_DIRS} +) + +libfind_process(Pango) + diff --git a/cmake/Modules/FindPangoCairo.cmake b/cmake/Modules/FindPangoCairo.cmake new file mode 100644 index 0000000..a26f83b --- /dev/null +++ b/cmake/Modules/FindPangoCairo.cmake @@ -0,0 +1,35 @@ +# - Try to find PangoCairo +# Once done, this will define +# +# PangoCairo_FOUND - system has Pango +# PangoCairo_INCLUDE_DIRS - the Pango include directories +# PangoCairo_LIBRARIES - link these to use Pango + +include(LibFindMacros) + +# Dependencies +libfind_package(PangoCairo Pango) +libfind_package(PangoCairo Cairo) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(PangoCairo_PKGCONF pangocairo) + +# Include dir +find_path(PangoCairo_INCLUDE_DIR + NAMES pango/pangocairo.h + HINTS ${PangoCairo_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES pango-1.0 +) + +# Finally the library itself +find_library(PangoCairo_LIBRARY + NAMES pangocairo-1.0 + HINTS ${PangoCairo_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(PangoCairo_PROCESS_INCLUDES PangoCairo_INCLUDE_DIR Pango_INCLUDE_DIR Cairo_INCLUDE_DIR) +set(PangoCairo_PROCESS_LIBS PangoCairo_LIBRARY Pango_LIBRARY Cairo_LIBRARY) +libfind_process(PangoCairo) + diff --git a/cmake/Modules/FindPangomm.cmake b/cmake/Modules/FindPangomm.cmake new file mode 100644 index 0000000..7aeb678 --- /dev/null +++ b/cmake/Modules/FindPangomm.cmake @@ -0,0 +1,36 @@ +# - Try to find Pangomm 1.4 +# Once done, this will define +# +# Pangomm_FOUND - system has Pangomm +# Pangomm_INCLUDE_DIRS - the Pangomm include directories +# Pangomm_LIBRARIES - link these to use Pangomm + +include(LibFindMacros) + +# Dependencies +libfind_package(Pangomm Pango) +libfind_package(Pangomm Cairomm) +libfind_package(Pangomm Glibmm) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(Pangomm_PKGCONF pangomm-1.4) + +# Main include dir +find_path(Pangomm_INCLUDE_DIR + NAMES pangomm.h + HINTS ${Pangomm_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES pangomm-1.4 +) + +# Finally the library itself +find_library(Pangomm_LIBRARY + NAMES pangomm-1.4 + HINTS ${Pangomm_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(Pangomm_PROCESS_INCLUDES Pangomm_INCLUDE_DIR Pango_INCLUDE_DIRS Cairomm_INCLUDE_DIRS Glibmm_INCLUDE_DIRS) +set(Pangomm_PROCESS_LIBS Pangomm_LIBRARY Pango_LIBRARIES Cairomm_LIBRARIES Glibmm_LIBRARIES) +libfind_process(Pangomm) + diff --git a/cmake/Modules/FindPng.cmake b/cmake/Modules/FindPng.cmake new file mode 100644 index 0000000..9944a11 --- /dev/null +++ b/cmake/Modules/FindPng.cmake @@ -0,0 +1,28 @@ +# - Try to find Png +# Once done, this will define +# +# Png_FOUND - system has Png +# Png_INCLUDE_DIRS - the Png include directories +# Png_LIBRARIES - link these to use Png +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(Png_PKGCONF Png) + +find_path(Png_INCLUDE_DIR + NAMES pngconf.h + HINTS ${Png_PKGCONF_INCLUDE_DIRS} +) + +find_library(Png_LIBRARY + NAMES png png12 png14 + HINTS ${Png_PKGCONF_LIBRARY_DIRS} +) + +set(Png_PROCESS_INCLUDES Png_INCLUDE_DIR) +set(Png_PROCESS_LIBS Png_LIBRARY) +libfind_process(Png) + diff --git a/cmake/Modules/FindPortAudio.cmake b/cmake/Modules/FindPortAudio.cmake new file mode 100644 index 0000000..01cfe14 --- /dev/null +++ b/cmake/Modules/FindPortAudio.cmake @@ -0,0 +1,35 @@ +# - Try to find PortAudio +# Once done, this will define +# +# PortAudio_FOUND - system has PortAudio +# PortAudio_INCLUDE_DIRS - the PortAudio include directories +# PortAudio_LIBRARIES - link these to use PortAudio +# PortAudio_VERSION - detected version of PortAudio +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(PortAudio_PKGCONF portaudio-2.0) + +if(PortAudio_PKGCONF_FOUND) + set(PortAudio_VERSION 19) +else(PortAudio_PKGCONF_FOUND) + set(PortAudio_VERSION 18) +endif(PortAudio_PKGCONF_FOUND) + +find_path(PortAudio_INCLUDE_DIR + NAMES portaudio.h + HINTS ${PortAudio_PKGCONF_INCLUDE_DIRS} +) + +find_library(PortAudio_LIBRARY + NAMES portaudio + HINTS ${PortAudio_PKGCONF_LIBRARY_DIRS} +) + +set(PortAudio_PROCESS_INCLUDES PortAudio_INCLUDE_DIR) +set(PortAudio_PROCESS_LIBS PortAudio_LIBRARY) +libfind_process(PortAudio) + diff --git a/cmake/Modules/FindPortMidi.cmake b/cmake/Modules/FindPortMidi.cmake new file mode 100644 index 0000000..ef3fa1f --- /dev/null +++ b/cmake/Modules/FindPortMidi.cmake @@ -0,0 +1,28 @@ +# - Try to find PortMidi +# Once done, this will define +# +# PortMidi_FOUND - system has PortMidi +# PortMidi_INCLUDE_DIRS - the PortMidi include directories +# PortMidi_LIBRARIES - link these to use PortMidi +# PortMidi_VERSION - detected version of PortMidi +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +find_path(PortMidi_INCLUDE_DIR NAMES portmidi.h) +find_library(PortMidi_LIBRARY NAMES portmidi) +find_library(PortTime_LIBRARY NAMES porttime) + +set(PortMidi_PROCESS_INCLUDES PortMidi_INCLUDE_DIR) +set(PortMidi_PROCESS_LIBS PortMidi_LIBRARY) +# Porttime library is merged to Portmidi in new versions, so +# we work around problems by adding it only if it's present +if (${PortTime_LIBRARY}) + set(PortMidi_PROCESS_LIBS PortMidi_PROCESS_LIBS PortTime_LIBRARY) +endif (${PortTime_LIBRARY}) + +libfind_process(PortMidi) +mark_as_advanced(PortTime_LIBRARY) + diff --git a/cmake/Modules/FindProjectM.cmake b/cmake/Modules/FindProjectM.cmake new file mode 100644 index 0000000..17e0b23 --- /dev/null +++ b/cmake/Modules/FindProjectM.cmake @@ -0,0 +1,30 @@ +# - Try to find ProjectM +# Once done, this will define +# +# ProjectM_FOUND - system has ProjectM +# ProjectM_INCLUDE_DIRS - the ProjectM include directories +# ProjectM_LIBRARIES - link these to use ProjectM + +include(LibFindMacros) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(ProjectM_PKGCONF libprojectM) + +# Include dir +find_path(ProjectM_INCLUDE_DIR + NAMES libprojectM/projectM.hpp + HINTS ${ProjectM_PKGCONF_INCLUDE_DIRS} +) + +# Finally the library itself +find_library(ProjectM_LIBRARY + NAMES projectM + HINTS ${ProjectM_PKGCONF_LIBRARY_DIRS} +) + +# Set the include dir variables and the libraries and let libfind_process do the rest. +# NOTE: Singular variables for this library, plural for libraries this this lib depends on. +set(ProjectM_PROCESS_INCLUDES ProjectM_INCLUDE_DIR) +set(ProjectM_PROCESS_LIBS ProjectM_LIBRARY) +libfind_process(ProjectM) + diff --git a/cmake/Modules/FindSDL.cmake b/cmake/Modules/FindSDL.cmake new file mode 100644 index 0000000..2d4e557 --- /dev/null +++ b/cmake/Modules/FindSDL.cmake @@ -0,0 +1,59 @@ +# - Try to find SDL +# Once done, this will define +# +# SDL_FOUND - system has SDL +# SDL_INCLUDE_DIRS - the SDL include directories +# SDL_LIBRARIES - link these to use SDL +# SDL_SDL_LIBRARY - only libSDL +# SDL_SDLmain_LIBRARY - only libSDLmain +# SDL_SOURCES - add this in the source file list of your target (hack for OSX) +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(SDL_PKGCONF sdl) + +find_path(SDL_INCLUDE_DIR + NAMES SDL.h + PATH_SUFFIXES SDL + HINTS ${SDL_PKGCONF_INCLUDE_DIRS} +) + +find_library(SDL_SDL_LIBRARY + NAMES SDL + HINTS ${SDL_PKGCONF_LIBRARY_DIRS} +) + +# Process others than OSX with native SDL normally +if(NOT "${SDL_SDL_LIBRARY}" MATCHES "framework") + if(MINGW) + set(MINGW32_LIBRARY mingw32) + set(SDL_PROCESS_LIBS ${SDL_PROCESS_LIBS} MINGW32_LIBRARY) + endif(MINGW) + find_library(SDL_SDLmain_LIBRARY + NAMES libSDLmain.a SDLmain + HINTS ${SDL_PKGCONF_LIBRARY_DIRS} + ) + if (SDL_SDLmain_LIBRARY) + set(SDL_PROCESS_LIBS ${SDL_PROCESS_LIBS} SDL_SDLmain_LIBRARY) + endif (SDL_SDLmain_LIBRARY) + set(SDL_PROCESS_LIBS ${SDL_PROCESS_LIBS} SDL_SDL_LIBRARY) +endif(NOT "${SDL_SDL_LIBRARY}" MATCHES "framework") + +set(SDL_PROCESS_INCLUDES SDL_INCLUDE_DIR) +libfind_process(SDL) + +# Special processing for OSX native SDL +if("${SDL_SDL_LIBRARY}" MATCHES "SDL.framework") + set(SDL_SOURCES "osx/SDLmain.m") + set(SDL_LIBRARIES "-framework SDL") + +endif("${SDL_SDL_LIBRARY}" MATCHES "SDL.framework") + +# All OSX versions need Cocoa +if(APPLE) + set(SDL_LIBRARIES ${SDL_LIBRARIES} "-framework Cocoa") +endif(APPLE) + diff --git a/cmake/Modules/FindSDL2.cmake b/cmake/Modules/FindSDL2.cmake new file mode 100644 index 0000000..b3889d5 --- /dev/null +++ b/cmake/Modules/FindSDL2.cmake @@ -0,0 +1,45 @@ +# - Try to find SDL2 +# Once done, this will define +# +# SDL2_FOUND - system has SDL2 +# SDL2_INCLUDE_DIRS - the SDL2 include directories +# SDL2_LIBRARIES - link these to use SDL2 +# SDL2_SDL_LIBRARY - only libSDL2 +# SDL2_SDLmain_LIBRARY - only libSDL2main +# SDL2_SOURCES - add this in the source file list of your target (hack for OSX) +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) +libfind_pkg_detect(SDL2 sdl2 FIND_PATH SDL.h PATH_SUFFIXES SDL2 FIND_LIBRARY SDL2) + +# Process others than OSX with native SDL normally +if(NOT "${SDL2_SDL_LIBRARY}" MATCHES "framework") + if(MINGW) + set(MINGW32_LIBRARY mingw32) + set(SDL2_PROCESS_LIBS ${SDL2_PROCESS_LIBS} MINGW32_LIBRARY) + endif() + find_library(SDL2_SDLmain_LIBRARY + NAMES libSDL2main.a SDL2main + HINTS ${SDL2_PKGCONF_LIBRARY_DIRS} + ) + if (SDL2_SDLmain_LIBRARY) + set(SDL2_PROCESS_LIBS ${SDL2_PROCESS_LIBS} SDL2_SDLmain_LIBRARY) + endif() + set(SDL2_PROCESS_LIBS ${SDL2_PROCESS_LIBS} SDL2_SDL_LIBRARY) +endif() + +libfind_process(SDL2) + +# Special processing for OSX native SDL +if("${SDL2_SDL_LIBRARY}" MATCHES "SDL.framework") + set(SDL2_SOURCES "osx/SDLmain.m") + set(SDL2_LIBRARIES "-framework SDL2") +endif() + +# All OSX versions need Cocoa +if(APPLE) + set(SDL2_LIBRARIES ${SDL2_LIBRARIES} "-framework Cocoa") +endif(APPLE) + diff --git a/cmake/Modules/FindSDL_image.cmake b/cmake/Modules/FindSDL_image.cmake new file mode 100644 index 0000000..34e7011 --- /dev/null +++ b/cmake/Modules/FindSDL_image.cmake @@ -0,0 +1,29 @@ +# - Try to find SDL_image +# Once done, this will define +# +# SDL_image_FOUND - system has SDL_image +# SDL_image_INCLUDE_DIRS - the SDL include directories +# SDL_image_LIBRARIES - link these to use SDL_image +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(SDL_image_PKGCONF sdl) + +find_path(SDL_image_INCLUDE_DIR + NAMES SDL_image.h + PATH_SUFFIXES SDL + HINTS ${SDL_PKGCONF_INCLUDE_DIRS} +) + +find_library(SDL_image_LIBRARY + NAMES SDL_image + HINTS ${SDL_PKGCONF_LIBRARY_DIRS} +) + +set(SDL_image_PROCESS_INCLUDES SDL_image_INCLUDE_DIR) +set(SDL_image_PROCESS_LIBS SDL_image_LIBRARY) +libfind_process(SDL_image) + diff --git a/cmake/Modules/FindSDL_mixer.cmake b/cmake/Modules/FindSDL_mixer.cmake new file mode 100644 index 0000000..5e369a5 --- /dev/null +++ b/cmake/Modules/FindSDL_mixer.cmake @@ -0,0 +1,32 @@ +# - Try to find SDL +# Once done, this will define +# +# SDL_mixer_FOUND - system has SDL +# SDL_mixer_INCLUDE_DIRS - the SDL include directories +# SDL_mixer_LIBRARIES - link these to use SDL +# SDL_mixer_SDL_mixer_LIBRARY - only libSDL +# SDL_mixer_SDLmain_LIBRARY - only libSDLmain +# SDL_mixer_SOURCES - add this in the source file list of your target (hack for OSX) +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(SDL_mixer_PKGCONF sdl) + +find_path(SDL_mixer_INCLUDE_DIR + NAMES SDL_mixer.h + PATH_SUFFIXES SDL + HINTS ${SDL_PKGCONF_INCLUDE_DIRS} +) + +find_library(SDL_mixer_LIBRARY + NAMES SDL_mixer + HINTS ${SDL_PKGCONF_LIBRARY_DIRS} +) + +set(SDL_mixer_PROCESS_INCLUDES SDL_mixer_INCLUDE_DIR) +set(SDL_mixer_PROCESS_LIBS SDL_mixer_LIBRARY) +libfind_process(SDL_mixer) + diff --git a/cmake/Modules/FindSWResample.cmake b/cmake/Modules/FindSWResample.cmake new file mode 100644 index 0000000..ce4dffd --- /dev/null +++ b/cmake/Modules/FindSWResample.cmake @@ -0,0 +1,44 @@ +# - Try to find FFMPEG libswresample +# Once done, this will define +# +# SWResample_FOUND - the library is available +# SWResample_INCLUDE_DIRS - the include directories +# SWResample_LIBRARIES - the libraries +# SWResample_INCLUDE - the file to include (may be used in config.h) +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_package(SWResample AVUtil) + +libfind_pkg_check_modules(SWResample_PKGCONF libswresample) + +find_path(SWResample_INCLUDE_DIR + NAMES libswresample/swresample.h ffmpeg/swresample.h swresample.h + HINTS ${SWResample_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES ffmpeg +) + +if(SWResample_INCLUDE_DIR) + foreach(suffix libswresample/ ffmpeg/ "") + if(NOT SWResample_INCLUDE) + if(EXISTS "${SWResample_INCLUDE_DIR}/${suffix}swresample.h") + set(SWResample_INCLUDE "${suffix}swresample.h") + endif(EXISTS "${SWResample_INCLUDE_DIR}/${suffix}swresample.h") + endif(NOT SWResample_INCLUDE) + endforeach(suffix) + + if(NOT SWResample_INCLUDE) + message(FATAL_ERROR "Found swresample.h include dir, but not the header file. Maybe you need to clear CMake cache?") + endif(NOT SWResample_INCLUDE) +endif(SWResample_INCLUDE_DIR) + +find_library(SWResample_LIBRARY + NAMES libswresample.dll.a swresample + HINTS ${SWResample_PKGCONF_LIBRARY_DIRS} +) + +libfind_process(SWResample) + diff --git a/cmake/Modules/FindSWScale.cmake b/cmake/Modules/FindSWScale.cmake new file mode 100644 index 0000000..a125a65 --- /dev/null +++ b/cmake/Modules/FindSWScale.cmake @@ -0,0 +1,44 @@ +# - Try to find FFMPEG libswscale +# Once done, this will define +# +# SWScale_FOUND - the library is available +# SWScale_INCLUDE_DIRS - the include directories +# SWScale_LIBRARIES - the libraries +# SWScale_INCLUDE - the file to include (may be used in config.h) +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_package(SWScale AVUtil) + +libfind_pkg_check_modules(SWScale_PKGCONF libswscale) + +find_path(SWScale_INCLUDE_DIR + NAMES libswscale/swscale.h ffmpeg/swscale.h swscale.h + HINTS ${SWScale_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES ffmpeg +) + +if(SWScale_INCLUDE_DIR) + foreach(suffix libswscale/ ffmpeg/ "") + if(NOT SWScale_INCLUDE) + if(EXISTS "${SWScale_INCLUDE_DIR}/${suffix}swscale.h") + set(SWScale_INCLUDE "${suffix}swscale.h") + endif(EXISTS "${SWScale_INCLUDE_DIR}/${suffix}swscale.h") + endif(NOT SWScale_INCLUDE) + endforeach(suffix) + + if(NOT SWScale_INCLUDE) + message(FATAL_ERROR "Found swscale.h include dir, but not the header file. Maybe you need to clear CMake cache?") + endif(NOT SWScale_INCLUDE) +endif(SWScale_INCLUDE_DIR) + +find_library(SWScale_LIBRARY + NAMES libswscale.dll.a swscale + HINTS ${SWScale_PKGCONF_LIBRARY_DIRS} +) + +libfind_process(SWScale) + diff --git a/cmake/Modules/FindSigC++.cmake b/cmake/Modules/FindSigC++.cmake new file mode 100644 index 0000000..0d7ea0c --- /dev/null +++ b/cmake/Modules/FindSigC++.cmake @@ -0,0 +1,36 @@ +# - Try to find SigC++-2.0 +# Once done, this will define +# +# SigC++_FOUND - system has SigC++ +# SigC++_INCLUDE_DIRS - the SigC++ include directories +# SigC++_LIBRARIES - link these to use SigC++ + +include(LibFindMacros) + +# Use pkg-config to get hints about paths +libfind_pkg_check_modules(SigC++_PKGCONF sigc++-2.0) + +# Main include dir +find_path(SigC++_INCLUDE_DIR + NAMES sigc++/sigc++.h + HINTS ${SigC++_PKGCONF_INCLUDE_DIRS} + PATH_SUFFIXES sigc++-2.0 +) + +# Glib-related libraries also use a separate config header, which is in lib dir +find_path(SigC++Config_INCLUDE_DIR + NAMES sigc++config.h + HINTS ${SigC++_PKGCONF_INCLUDE_DIRS} /usr + PATH_SUFFIXES lib/sigc++-2.0/include ../lib/sigc++-2.0/include +) + +# Finally the library itself +find_library(SigC++_LIBRARY + NAMES sigc-2.0 + HINTS ${SigC++_PKGCONF_LIBRARY_DIRS} +) + +set(SigC++_PROCESS_INCLUDES SigC++_INCLUDE_DIR SigC++Config_INCLUDE_DIR) +set(SigC++_PROCESS_LIBS SigC++_LIBRARY) +libfind_process(SigC++) + diff --git a/cmake/Modules/FindSsl.cmake b/cmake/Modules/FindSsl.cmake new file mode 100644 index 0000000..9bcf682 --- /dev/null +++ b/cmake/Modules/FindSsl.cmake @@ -0,0 +1,14 @@ +# - Try to find Ssl +# Once done, this will define +# +# Ssl_FOUND - system has Ssl +# Ssl_INCLUDE_DIRS - the Ssl include directories +# Ssl_LIBRARIES - link these to use Ssl +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) +libfind_pkg_detect(Ssl libssl FIND_PATH openssl/ssl.h FIND_LIBRARY ssl) +set(Ssl_VERSION ${Ssl_PKGCONF_VERSION}) +libfind_process(Ssl) diff --git a/cmake/Modules/FindZ.cmake b/cmake/Modules/FindZ.cmake new file mode 100644 index 0000000..af647f7 --- /dev/null +++ b/cmake/Modules/FindZ.cmake @@ -0,0 +1,28 @@ +# - Try to find Z +# Once done, this will define +# +# Z_FOUND - system has Z +# Z_INCLUDE_DIRS - the Z include directories +# Z_LIBRARIES - link these to use Z +# +# See documentation on how to write CMake scripts at +# http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries + +include(LibFindMacros) + +libfind_pkg_check_modules(Z_PKGCONF Z) + +find_path(Z_INCLUDE_DIR + NAMES zlib.h + HINTS ${Z_PKGCONF_INCLUDE_DIRS} +) + +find_library(Z_LIBRARY + NAMES z + HINTS ${Z_PKGCONF_LIBRARY_DIRS} +) + +set(Z_PROCESS_INCLUDES Z_INCLUDE_DIR) +set(Z_PROCESS_LIBS Z_LIBRARY) +libfind_process(Z) + diff --git a/cmake/Modules/GetGitRevisionDescription.cmake b/cmake/Modules/GetGitRevisionDescription.cmake new file mode 100644 index 0000000..1d3c82a --- /dev/null +++ b/cmake/Modules/GetGitRevisionDescription.cmake @@ -0,0 +1,130 @@ +# - Returns a version string from Git +# +# These functions force a re-configure on each git commit so that you can +# trust the values of the variables in your build system. +# +# get_git_head_revision( [ ...]) +# +# Returns the refspec and sha hash of the current head revision +# +# git_describe( [ ...]) +# +# Returns the results of git describe on the source tree, and adjusting +# the output so that it tests false if an error occurs. +# +# git_get_exact_tag( [ ...]) +# +# Returns the results of git describe --exact-match on the source tree, +# and adjusting the output so that it tests false if there was no exact +# matching tag. +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file docs/license/Boost-LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(__get_git_revision_description) + return() +endif() +set(__get_git_revision_description YES) + +# We must run the following at "include" time, not at function call time, +# to find the path to this module rather than the path to a calling list file +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) + +function(get_git_head_revision _refspecvar _hashvar) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories + set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") + get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) + if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) + # We have reached the root directory, we are not in git + set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) + return() + endif() + set(GIT_DIR "${GIT_PARENT_DIR}/.git") + endwhile() + # check if this is a submodule + if(NOT IS_DIRECTORY ${GIT_DIR}) + file(READ ${GIT_DIR} submodule) + string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) + get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) + get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) + endif() + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() + + if(NOT EXISTS "${GIT_DIR}/HEAD") + return() + endif() + set(HEAD_FILE "${GIT_DATA}/HEAD") + configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" + "${GIT_DATA}/grabRef.cmake" + @ONLY) + include("${GIT_DATA}/grabRef.cmake") + + set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) + set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) +endfunction() + +function(git_describe _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + #message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + describe + ${hash} + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() diff --git a/cmake/Modules/GetGitRevisionDescription.cmake.in b/cmake/Modules/GetGitRevisionDescription.cmake.in new file mode 100644 index 0000000..a2d390c --- /dev/null +++ b/cmake/Modules/GetGitRevisionDescription.cmake.in @@ -0,0 +1,38 @@ +# +# Internal file for GetGitRevisionDescription.cmake +# +# Requires CMake 2.6 or newer (uses the 'function' command) +# +# Original Author: +# 2009-2010 Ryan Pavlik +# http://academic.cleardefinition.com +# Iowa State University HCI Graduate Program/VRAC +# +# Copyright Iowa State University 2009-2010. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file docs/license/Boost-LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +set(HEAD_HASH) + +file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) + +string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) +if(HEAD_CONTENTS MATCHES "ref") + # named branch + string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") + if(EXISTS "@GIT_DIR@/${HEAD_REF}") + configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") + configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) + set(HEAD_HASH "${HEAD_REF}") + endif() +else() + # detached HEAD + configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) +endif() + +if(NOT HEAD_HASH) + file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) + string(STRIP "${HEAD_HASH}" HEAD_HASH) +endif() diff --git a/cmake/Modules/LibFindMacros.cmake b/cmake/Modules/LibFindMacros.cmake new file mode 100644 index 0000000..3ef5844 --- /dev/null +++ b/cmake/Modules/LibFindMacros.cmake @@ -0,0 +1,266 @@ +# Version 2.2 +# Public Domain, originally written by Lasse Kärkkäinen +# Maintained at https://github.com/Tronic/cmake-modules +# Please send your improvements as pull requests on Github. + +# Find another package and make it a dependency of the current package. +# This also automatically forwards the "REQUIRED" argument. +# Usage: libfind_package( [extra args to find_package]) +macro (libfind_package PREFIX PKG) + set(${PREFIX}_args ${PKG} ${ARGN}) + if (${PREFIX}_FIND_REQUIRED) + set(${PREFIX}_args ${${PREFIX}_args} REQUIRED) + endif() + find_package(${${PREFIX}_args}) + set(${PREFIX}_DEPENDENCIES ${${PREFIX}_DEPENDENCIES};${PKG}) + unset(${PREFIX}_args) +endmacro() + +# A simple wrapper to make pkg-config searches a bit easier. +# Works the same as CMake's internal pkg_check_modules but is always quiet. +macro (libfind_pkg_check_modules) + find_package(PkgConfig QUIET) + if (PKG_CONFIG_FOUND) + pkg_check_modules(${ARGN} QUIET) + endif() +endmacro() + +# Avoid useless copy&pasta by doing what most simple libraries do anyway: +# pkg-config, find headers, find library. +# Usage: libfind_pkg_detect( FIND_PATH [other args] FIND_LIBRARY [other args]) +# E.g. libfind_pkg_detect(SDL2 sdl2 FIND_PATH SDL.h PATH_SUFFIXES SDL2 FIND_LIBRARY SDL2) +function (libfind_pkg_detect PREFIX) + # Parse arguments + set(argname pkgargs) + foreach (i ${ARGN}) + if ("${i}" STREQUAL "FIND_PATH") + set(argname pathargs) + elseif ("${i}" STREQUAL "FIND_LIBRARY") + set(argname libraryargs) + else() + set(${argname} ${${argname}} ${i}) + endif() + endforeach() + if (NOT pkgargs) + message(FATAL_ERROR "libfind_pkg_detect requires at least a pkg_config package name to be passed.") + endif() + # Find library + libfind_pkg_check_modules(${PREFIX}_PKGCONF ${pkgargs}) + if (pathargs) + find_path(${PREFIX}_INCLUDE_DIR NAMES ${pathargs} HINTS ${${PREFIX}_PKGCONF_INCLUDE_DIRS}) + endif() + if (libraryargs) + find_library(${PREFIX}_LIBRARY NAMES ${libraryargs} HINTS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}) + endif() +endfunction() + +# Extracts a version #define from a version.h file, output stored to _VERSION. +# Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR) +# Fourth argument "QUIET" may be used for silently testing different define names. +# This function does nothing if the version variable is already defined. +function (libfind_version_header PREFIX VERSION_H DEFINE_NAME) + # Skip processing if we already have a version or if the include dir was not found + if (${PREFIX}_VERSION OR NOT ${PREFIX}_INCLUDE_DIR) + return() + endif() + set(quiet ${${PREFIX}_FIND_QUIETLY}) + # Process optional arguments + foreach(arg ${ARGN}) + if (arg STREQUAL "QUIET") + set(quiet TRUE) + else() + message(AUTHOR_WARNING "Unknown argument ${arg} to libfind_version_header ignored.") + endif() + endforeach() + # Read the header and parse for version number + set(filename "${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") + if (NOT EXISTS ${filename}) + if (NOT quiet) + message(AUTHOR_WARNING "Unable to find ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") + endif() + return() + endif() + file(READ "${filename}" header) + string(REGEX REPLACE ".*#[ \t]*define[ \t]*${DEFINE_NAME}[ \t]*\"([^\n]*)\".*" "\\1" match "${header}") + # No regex match? + if (match STREQUAL header) + if (NOT quiet) + message(AUTHOR_WARNING "Unable to find \#define ${DEFINE_NAME} \"\" from ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") + endif() + return() + endif() + # Export the version string + set(${PREFIX}_VERSION "${match}" PARENT_SCOPE) +endfunction() + +# Do the final processing once the paths have been detected. +# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain +# all the variables, each of which contain one include directory. +# Ditto for ${PREFIX}_PROCESS_LIBS and library files. +# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES. +# Also handles errors in case library detection was required, etc. +function (libfind_process PREFIX) + # Skip processing if already processed during this configuration run + if (${PREFIX}_FOUND) + return() + endif() + + set(found TRUE) # Start with the assumption that the package was found + + # Did we find any files? Did we miss includes? These are for formatting better error messages. + set(some_files FALSE) + set(missing_headers FALSE) + + # Shorthands for some variables that we need often + set(quiet ${${PREFIX}_FIND_QUIETLY}) + set(required ${${PREFIX}_FIND_REQUIRED}) + set(exactver ${${PREFIX}_FIND_VERSION_EXACT}) + set(findver "${${PREFIX}_FIND_VERSION}") + set(version "${${PREFIX}_VERSION}") + + # Lists of config option names (all, includes, libs) + unset(configopts) + set(includeopts ${${PREFIX}_PROCESS_INCLUDES}) + set(libraryopts ${${PREFIX}_PROCESS_LIBS}) + + # Process deps to add to + foreach (i ${PREFIX} ${${PREFIX}_DEPENDENCIES}) + if (DEFINED ${i}_INCLUDE_OPTS OR DEFINED ${i}_LIBRARY_OPTS) + # The package seems to export option lists that we can use, woohoo! + list(APPEND includeopts ${${i}_INCLUDE_OPTS}) + list(APPEND libraryopts ${${i}_LIBRARY_OPTS}) + else() + # If plural forms don't exist or they equal singular forms + if ((NOT DEFINED ${i}_INCLUDE_DIRS AND NOT DEFINED ${i}_LIBRARIES) OR + ({i}_INCLUDE_DIR STREQUAL ${i}_INCLUDE_DIRS AND ${i}_LIBRARY STREQUAL ${i}_LIBRARIES)) + # Singular forms can be used + if (DEFINED ${i}_INCLUDE_DIR) + list(APPEND includeopts ${i}_INCLUDE_DIR) + endif() + if (DEFINED ${i}_LIBRARY) + list(APPEND libraryopts ${i}_LIBRARY) + endif() + else() + # Oh no, we don't know the option names + message(FATAL_ERROR "We couldn't determine config variable names for ${i} includes and libs. Aieeh!") + endif() + endif() + endforeach() + + if (includeopts) + list(REMOVE_DUPLICATES includeopts) + endif() + + if (libraryopts) + list(REMOVE_DUPLICATES libraryopts) + endif() + + string(REGEX REPLACE ".*[ ;]([^ ;]*(_INCLUDE_DIRS|_LIBRARIES))" "\\1" tmp "${includeopts} ${libraryopts}") + if (NOT tmp STREQUAL "${includeopts} ${libraryopts}") + message(AUTHOR_WARNING "Plural form ${tmp} found in config options of ${PREFIX}. This works as before but is now deprecated. Please only use singular forms INCLUDE_DIR and LIBRARY, and update your find scripts for LibFindMacros > 2.0 automatic dependency system (most often you can simply remove the PROCESS variables entirely).") + endif() + + # Include/library names separated by spaces (notice: not CMake lists) + unset(includes) + unset(libs) + + # Process all includes and set found false if any are missing + foreach (i ${includeopts}) + list(APPEND configopts ${i}) + if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND") + list(APPEND includes "${${i}}") + else() + set(found FALSE) + set(missing_headers TRUE) + endif() + endforeach() + + # Process all libraries and set found false if any are missing + foreach (i ${libraryopts}) + list(APPEND configopts ${i}) + if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND") + list(APPEND libs "${${i}}") + else() + set (found FALSE) + endif() + endforeach() + + # Version checks + if (found AND findver) + if (NOT version) + message(WARNING "The find module for ${PREFIX} does not provide version information, so we'll just assume that it is OK. Please fix the module or remove package version requirements to get rid of this warning.") + elseif (version VERSION_LESS findver OR (exactver AND NOT version VERSION_EQUAL findver)) + set(found FALSE) + set(version_unsuitable TRUE) + endif() + endif() + + # If all-OK, hide all config options, export variables, print status and exit + if (found) + foreach (i ${configopts}) + mark_as_advanced(${i}) + endforeach() + if (NOT quiet) + message(STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}") + if (LIBFIND_DEBUG) + message(STATUS " ${PREFIX}_DEPENDENCIES=${${PREFIX}_DEPENDENCIES}") + message(STATUS " ${PREFIX}_INCLUDE_OPTS=${includeopts}") + message(STATUS " ${PREFIX}_INCLUDE_DIRS=${includes}") + message(STATUS " ${PREFIX}_LIBRARY_OPTS=${libraryopts}") + message(STATUS " ${PREFIX}_LIBRARIES=${libs}") + endif() + set (${PREFIX}_INCLUDE_OPTS ${includeopts} PARENT_SCOPE) + set (${PREFIX}_LIBRARY_OPTS ${libraryopts} PARENT_SCOPE) + set (${PREFIX}_INCLUDE_DIRS ${includes} PARENT_SCOPE) + set (${PREFIX}_LIBRARIES ${libs} PARENT_SCOPE) + set (${PREFIX}_FOUND TRUE PARENT_SCOPE) + endif() + return() + endif() + + # Format messages for debug info and the type of error + set(vars "Relevant CMake configuration variables:\n") + foreach (i ${configopts}) + mark_as_advanced(CLEAR ${i}) + set(val ${${i}}) + if ("${val}" STREQUAL "${i}-NOTFOUND") + set (val "") + elseif (val AND NOT EXISTS ${val}) + set (val "${val} (does not exist)") + else() + set(some_files TRUE) + endif() + set(vars "${vars} ${i}=${val}\n") + endforeach() + set(vars "${vars}You may use CMake GUI, cmake -D or ccmake to modify the values. Delete CMakeCache.txt to discard all values and force full re-detection if necessary.\n") + if (version_unsuitable) + set(msg "${PREFIX} ${${PREFIX}_VERSION} was found but") + if (exactver) + set(msg "${msg} only version ${findver} is acceptable.") + else() + set(msg "${msg} version ${findver} is the minimum requirement.") + endif() + else() + if (missing_headers) + set(msg "We could not find development headers for ${PREFIX}. Do you have the necessary dev package installed?") + elseif (some_files) + set(msg "We only found some files of ${PREFIX}, not all of them. Perhaps your installation is incomplete or maybe we just didn't look in the right place?") + if(findver) + set(msg "${msg} This could also be caused by incompatible version (if it helps, at least ${PREFIX} ${findver} should work).") + endif() + else() + set(msg "We were unable to find package ${PREFIX}.") + endif() + endif() + + # Fatal error out if REQUIRED + if (required) + set(msg "REQUIRED PACKAGE NOT FOUND\n${msg} This package is REQUIRED and you need to install it or adjust CMake configuration in order to continue building ${CMAKE_PROJECT_NAME}.") + message(FATAL_ERROR "${msg}\n${vars}") + endif() + # Otherwise just print a nasty warning + if (NOT quiet) + message(WARNING "WARNING: MISSING PACKAGE\n${msg} This package is NOT REQUIRED and you may ignore this warning but by doing so you may miss some functionality of ${CMAKE_PROJECT_NAME}. \n${vars}") + endif() +endfunction() + diff --git a/cmake/Modules/SelectLibraryConfigurations.cmake b/cmake/Modules/SelectLibraryConfigurations.cmake new file mode 100644 index 0000000..dce6f99 --- /dev/null +++ b/cmake/Modules/SelectLibraryConfigurations.cmake @@ -0,0 +1,70 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#.rst: +# SelectLibraryConfigurations +# --------------------------- +# +# +# +# select_library_configurations( basename ) +# +# This macro takes a library base name as an argument, and will choose +# good values for basename_LIBRARY, basename_LIBRARIES, +# basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what +# has been found and set. If only basename_LIBRARY_RELEASE is defined, +# basename_LIBRARY will be set to the release value, and +# basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND. +# If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will +# take the debug value, and basename_LIBRARY_RELEASE will be set to +# basename_LIBRARY_RELEASE-NOTFOUND. +# +# If the generator supports configuration types, then basename_LIBRARY +# and basename_LIBRARIES will be set with debug and optimized flags +# specifying the library to be used for the given configuration. If no +# build type has been set or the generator in use does not support +# configuration types, then basename_LIBRARY and basename_LIBRARIES will +# take only the release value, or the debug value if the release one is +# not set. + +# This macro was adapted from the FindQt4 CMake module and is maintained by Will +# Dicharry . + +macro( select_library_configurations basename ) + if(NOT ${basename}_LIBRARY_RELEASE) + set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.") + endif() + if(NOT ${basename}_LIBRARY_DEBUG) + set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.") + endif() + + if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND + NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND + ( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) ) + # if the generator supports configuration types or CMAKE_BUILD_TYPE + # is set, then set optimized and debug options. + set( ${basename}_LIBRARY "" ) + foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) + list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) + endforeach() + foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG ) + list( APPEND ${basename}_LIBRARY debug "${_libname}" ) + endforeach() + elseif( ${basename}_LIBRARY_RELEASE ) + set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} ) + elseif( ${basename}_LIBRARY_DEBUG ) + set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} ) + else() + set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND") + endif() + + set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" ) + + if( ${basename}_LIBRARY ) + set( ${basename}_FOUND TRUE ) + endif() + + mark_as_advanced( ${basename}_LIBRARY_RELEASE + ${basename}_LIBRARY_DEBUG + ) +endmacro() diff --git a/cmake/performous.sh.cmake b/cmake/performous.sh.cmake new file mode 100644 index 0000000..a8896b2 --- /dev/null +++ b/cmake/performous.sh.cmake @@ -0,0 +1,4 @@ +#!/bin/sh + +env DYLD_LIBRARY_PATH='@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@:$DYLD_LIBRARY_PATH' LD_LIBRARY_PATH='@CMAKE_INSTALL_PREFIX@/lib@LIB_SUFFIX@:$LD_LIBRARY_PATH' PERFORMOUS_DATA_DIR='@CMAKE_INSTALL_PREFIX@/@SHARE_INSTALL@' PLUGIN_PATH='@PERFORMOUS_PLUGIN_PATH@' '@PERFORMOUS_EXECUTABLE@' "$@" + diff --git a/common/image.cc b/common/image.cc new file mode 100644 index 0000000..5f58645 --- /dev/null +++ b/common/image.cc @@ -0,0 +1,223 @@ +#include "image.hh" + +#include +#include +#include +#include + +#include +#include + +using fs::ofstream; +using fs::ifstream; + +namespace { + void writePngHelper(png_structp pngPtr, png_bytep data, png_size_t length) { + static_cast(png_get_io_ptr(pngPtr))->write((char*)data, length); + } + + void readPngHelper(png_structp pngPtr, png_bytep data, png_size_t length) { + static_cast(png_get_io_ptr(pngPtr))->read((char*)data, length); + } + void loadPNG_internal(png_structp pngPtr, png_infop infoPtr, ifstream& file, Bitmap& bitmap, std::vector& rows) { + if (setjmp(png_jmpbuf(pngPtr))) throw std::runtime_error("Reading PNG failed"); + png_set_read_fn(pngPtr,(png_voidp)&file, readPngHelper); + png_read_info(pngPtr, infoPtr); + png_set_expand(pngPtr); // Expand everything to RGB(A) + png_set_strip_16(pngPtr); // Strip everything down to 8 bit/component + png_set_gray_to_rgb(pngPtr); // Convert even grayscale to RGB(A) + png_set_filler(pngPtr, 0xFF, PNG_FILLER_AFTER); // Add alpha channel if it is missing + bitmap.resize(png_get_image_width(pngPtr, infoPtr), png_get_image_height(pngPtr, infoPtr)); + rows.resize(bitmap.height); + for (unsigned y = 0; y < bitmap.height; ++y) rows[y] = reinterpret_cast(&bitmap.buf[y * bitmap.width * 4]); + png_read_image(pngPtr, &rows[0]); + } + + static void writePNG_internal(png_structp pngPtr, png_infop infoPtr, ofstream& file, unsigned w, unsigned h, int colorType, std::vector& rows) { + // There must be no objects initialized within this function because longjmp will mess them up + if (setjmp(png_jmpbuf(pngPtr))) throw std::runtime_error("Writing PNG failed"); + png_set_write_fn(pngPtr, &file, writePngHelper, NULL); + png_set_IHDR(pngPtr, infoPtr, w, h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_write_info(pngPtr, infoPtr); + png_write_image(pngPtr, &rows[0]); + png_write_end(pngPtr, NULL); + } + + struct my_jpeg_error_mgr { + struct jpeg_error_mgr pub; /* "public" fields */ + jmp_buf setjmp_buffer; /* for return to caller */ + }; + + typedef struct my_jpeg_error_mgr * my_jpeg_error_mgr_ptr; + + static inline void my_jpeg_error_exit(j_common_ptr cinfo) { + my_jpeg_error_mgr_ptr myerr = (my_jpeg_error_mgr_ptr) cinfo->err; + (*cinfo->err->output_message) (cinfo); + longjmp(myerr->setjmp_buffer, 1); + } + + #if JPEG_LIB_VERSION < 80 && !defined(MEM_SRCDST_SUPPORTED) + // Implementation of jpeg_mem_src from + // http://stackoverflow.com/questions/5280756/libjpeg-ver-6b-jpeg-stdio-src-vs-jpeg-mem-src + + /* Read JPEG image from a memory segment */ + static void init_source(j_decompress_ptr /*cinfo*/) {} + static boolean fill_input_buffer(j_decompress_ptr /*cinfo*/) { + //ERREXIT(cinfo, JERR_INPUT_EMPTY); + return true; + } + static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { + auto src = static_cast(cinfo->src); + if (num_bytes > 0) { + src->next_input_byte += num_bytes; + src->bytes_in_buffer -= num_bytes; + } + } + static void term_source(j_decompress_ptr /*cinfo*/) {} + static void jpeg_mem_src(j_decompress_ptr cinfo, void* buffer, long nbytes) { + if (!cinfo->src) { /* first time for this JPEG object? */ + cinfo->src = static_cast( + (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(jpeg_source_mgr)) + ); + } + auto src = static_cast(cinfo->src); + src->init_source = init_source; + src->fill_input_buffer = fill_input_buffer; + src->skip_input_data = skip_input_data; + src->resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->term_source = term_source; + src->bytes_in_buffer = nbytes; + src->next_input_byte = static_cast(buffer); + } + #endif + + typedef std::vector BinaryBuffer; + + BinaryBuffer readFile(fs::path const& path) { + BinaryBuffer ret; + fs::ifstream f(path, std::ios::binary); + f.seekg(0, std::ios::end); + ret.resize(f.tellg()); + f.seekg(0); + f.read(reinterpret_cast(ret.data()), ret.size()); + if (!f) throw std::runtime_error("File cannot be read: " + path.string()); + return ret; + } +} + +void writePNG(fs::path const& filename, Bitmap const& img, unsigned stride) { + fs::path name = filename; + // We use PNG in a non-standard way, with premultiplied alpha, signified by .premul.png extension. + std::clog << "image/debug: Saving PNG: " + name.string() << std::endl; + std::vector rows(img.height); + // Determine color type and bytes per pixel + unsigned char bpp; + int colorType; + switch (img.fmt) { + case pix::RGB: bpp = 3; colorType = PNG_COLOR_TYPE_RGB; break; + case pix::CHAR_RGBA: bpp = 4; colorType = PNG_COLOR_TYPE_RGBA; break; + default: + // Byte order would need to be changed for other formats and we don't currently need them... + throw std::logic_error("Unsupported pixel format in writePNG_internal"); + } + // Construct row pointers + bool reverse = img.bottomFirst; + if (stride == 0) stride = img.width * bpp; + unsigned pos = reverse ? img.height * stride : -stride; + for (unsigned y = 0; y < img.height; ++y) { + pos += (reverse ? -stride : stride); + rows[y] = (png_bytep)(&img.data()[pos]); + } + // Initialize libpng structures + png_structp pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!pngPtr) throw std::runtime_error("png_create_read_struct failed"); + png_infop infoPtr = NULL; + struct Cleanup { + png_structpp pngPP; + png_infopp infoPP; + Cleanup(png_structp& pngP, png_infop& infoP): pngPP(&pngP), infoPP(&infoP) {} + ~Cleanup() { png_destroy_write_struct(pngPP, infoPP); } + } cleanup(pngPtr, infoPtr); + infoPtr = png_create_info_struct(pngPtr); + if (!infoPtr) throw std::runtime_error("png_create_info_struct failed"); + png_set_gAMA(pngPtr, infoPtr, img.linearPremul ? 1.0 : 2.2); + // Write file + ofstream file(name, std::ios::binary); + writePNG_internal(pngPtr, infoPtr, file, img.width, img.height, colorType, rows); +} + +void loadPNG(Bitmap& bitmap, fs::path const& filename) { + std::clog << "image/debug: Loading PNG: " + filename.string() << std::endl; + // A hack to assume linear premultiplied data if file extension is .premul.png (used for cached SVGs) + if (filename.stem().extension() == "premul") bitmap.linearPremul = true; + ifstream file(filename, std::ios::binary); + png_structp pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!pngPtr) throw std::runtime_error("png_create_read_struct failed"); + png_infop infoPtr = NULL; + struct Cleanup { + png_structpp pngPP; + png_infopp infoPP; + Cleanup(png_structp& pngP, png_infop& infoP): pngPP(&pngP), infoPP(&infoP) {} + ~Cleanup() { png_destroy_read_struct(pngPP, infoPP, (png_infopp)NULL); } + } cleanup(pngPtr, infoPtr); + infoPtr = png_create_info_struct(pngPtr); + if (!infoPtr) throw std::runtime_error("png_create_info_struct failed"); + std::vector rows; + loadPNG_internal(pngPtr, infoPtr, file, bitmap, rows); +} + +void loadJPEG(Bitmap& bitmap, fs::path const& filename) { + std::clog << "image/debug: Loading JPEG: " + filename.string() << std::endl; + bitmap.fmt = pix::RGB; + struct my_jpeg_error_mgr jerr; + BinaryBuffer data = readFile(filename); + jpeg_decompress_struct cinfo; + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_jpeg_error_exit; + if (setjmp(jerr.setjmp_buffer)) { + jpeg_destroy_decompress(&cinfo); + throw std::runtime_error("Error in libjpeg when decoding " + filename.string()); + } + jpeg_create_decompress(&cinfo); + jpeg_mem_src(&cinfo, data.data(), data.size()); + if (jpeg_read_header(&cinfo, true) != JPEG_HEADER_OK) throw std::runtime_error("Cannot read header of " + filename.string()); + jpeg_start_decompress(&cinfo); + bitmap.resize(cinfo.output_width, cinfo.output_height); + unsigned stride = (bitmap.width * 3 + 3) & ~3; // Number of bytes per row (word-aligned) + unsigned char* ptr = &bitmap.buf[0]; + while (cinfo.output_scanline < bitmap.height) { + jpeg_read_scanlines(&cinfo, &ptr, 1); + ptr += stride; + } + jpeg_destroy_decompress(&cinfo); +} + +void Bitmap::crop(const unsigned width, const unsigned height, const unsigned x, const unsigned y) { + if (ptr) throw std::logic_error("Cannot Bitmap::crop foreign pointers."); + if (x + width > this->width || y+ height > this->height) + throw std::logic_error("Cannot crop to a size bigger then source image."); + + unsigned char bpp; + switch (fmt) { + case pix::INT_ARGB: bpp = 4; break; // Correct? + case pix::BGR: bpp = 3; break; + case pix::RGB: bpp = 3; break; + case pix::CHAR_RGBA: bpp = 4; break; + default: throw std::logic_error("Unsupported picture format."); + } + + unsigned newpos = 0; + for (unsigned row = y; row < y + height; row++) { + for (unsigned col = x; col < x + width; col++) { + for (char subp = 0; subp < bpp; subp++) { + unsigned oldpos = (row * this->width + col) * bpp + subp; + if (oldpos != newpos) { + buf[newpos] = buf[oldpos]; + } + newpos++; + } + } + } + this->width = width; + this->height = height; +} diff --git a/common/image.hh b/common/image.hh new file mode 100644 index 0000000..64d3db0 --- /dev/null +++ b/common/image.hh @@ -0,0 +1,54 @@ +#pragma once + +#include + +#include +#include +#include +#include + +namespace fs = boost::filesystem; + +namespace pix { enum Format { + INT_ARGB, // Cairo's pixel format (SVG, text): premultiplied linear RGB (BGRA byte order) + CHAR_RGBA, // libpng w/ alpha: non-premul sRGB (RGBA byte order) + RGB, // libpng w/o alpha, libjpeg, ffmpeg: sRGB (RGB byte order, no padding) + BGR // OpenCV/webcam: sRGB (BGR byte order, no padding) +}; } + +struct Bitmap { + std::vector buf; // Pixel data if owned by Bitmap + unsigned char* ptr; // Pixel data if owned by someone else + unsigned width, height; + double ar; // Aspect ratio + double timestamp; // Used for video frames + pix::Format fmt; + bool linearPremul; // Is the data linear RGB and premultiplied (as opposed to sRGB and non-premultiplied) + bool bottomFirst; // Upside-down (only used for taking screenshots) + Bitmap(unsigned char* ptr = NULL): ptr(ptr), width(), height(), ar(), timestamp(), fmt(pix::CHAR_RGBA), linearPremul(), bottomFirst() {} + void resize(unsigned w, unsigned h) { + if (!ptr) buf.resize(w * h * 4); else buf.clear(); + width = w; + height = h; + ar = double(w) / h; + } + void swap(Bitmap& b) { + if (ptr || b.ptr) throw std::logic_error("Cannot Bitmap::swap foreign pointers."); + buf.swap(b.buf); + std::swap(width, b.width); + std::swap(height, b.height); + std::swap(ar, b.ar); + std::swap(timestamp, b.timestamp); + std::swap(fmt, b.fmt); + } + unsigned char const* data() const { return ptr ? ptr : &buf[0]; } + unsigned char* data() { return ptr ? ptr : &buf[0]; } + + void crop(const unsigned width, const unsigned height, const unsigned x, const unsigned y); +}; + +// The total number of bytes per line (stride) may be specified. By default no padding at end of line is assumed. +void writePNG(fs::path const& filename, Bitmap const& bitmap, unsigned stride = 0); +void loadPNG(Bitmap& bitmap, fs::path const& filename); +void loadJPEG(Bitmap& bitmap, fs::path const& filename); + diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt new file mode 100644 index 0000000..cf1e5a4 --- /dev/null +++ b/data/CMakeLists.txt @@ -0,0 +1,18 @@ +set(APPLICATION_FILE "performous.desktop") +set(PIXMAP_FILE "themes/default/icon.svg") + +# Install launcher and fonts on system level +if(APPLE) + install(FILES ${APPLICATION_FILE} DESTINATION "Resources/applications/") + install(FILES ${PIXMAP_FILE} DESTINATION "Resources/pixmaps/" RENAME "performous.svg") + #file(GLOB FONT_FILES "fonts/*") + #install(FILES ${FONT_FILES} DESTINATION "Resources/fonts/truetype/performous") +elseif(UNIX) + install(FILES ${APPLICATION_FILE} DESTINATION "share/applications/") + install(FILES ${PIXMAP_FILE} DESTINATION "share/pixmaps/" RENAME "performous.svg") + #file(GLOB FONT_FILES "fonts/*") + #install(FILES ${FONT_FILES} DESTINATION "share/fonts/truetype/performous") +endif() + +install(DIRECTORY backgrounds config fonts shaders sounds themes xsl DESTINATION ${SHARE_INSTALL}) + diff --git a/data/backgrounds/blue_band.svg b/data/backgrounds/blue_band.svg new file mode 100644 index 0000000..b2af087 --- /dev/null +++ b/data/backgrounds/blue_band.svg @@ -0,0 +1,321 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/backgrounds/classic_bg.svg b/data/backgrounds/classic_bg.svg new file mode 100644 index 0000000..b6e7299 --- /dev/null +++ b/data/backgrounds/classic_bg.svg @@ -0,0 +1,237 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/backgrounds/default_bg.svg b/data/backgrounds/default_bg.svg new file mode 100644 index 0000000..17d94d9 --- /dev/null +++ b/data/backgrounds/default_bg.svg @@ -0,0 +1,1333 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/backgrounds/flying_notes.svg b/data/backgrounds/flying_notes.svg new file mode 100644 index 0000000..95850a0 --- /dev/null +++ b/data/backgrounds/flying_notes.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/backgrounds/guitar_bg.svg b/data/backgrounds/guitar_bg.svg new file mode 100644 index 0000000..ebd9f0c --- /dev/null +++ b/data/backgrounds/guitar_bg.svg @@ -0,0 +1,331 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/backgrounds/singer_bg.svg b/data/backgrounds/singer_bg.svg new file mode 100644 index 0000000..c96e712 --- /dev/null +++ b/data/backgrounds/singer_bg.svg @@ -0,0 +1,730 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/config/controllers.xml b/data/config/controllers.xml new file mode 100644 index 0000000..23c0b2d --- /dev/null +++ b/data/config/controllers.xml @@ -0,0 +1,482 @@ + + + + + + + OEM wireless guitar in Guitar Hero I/II/III mode + + +