From 19b2617fa8e2e8ec7c5181a6a2c97aa7908886c3 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 26 May 2020 11:31:47 +0100 Subject: [PATCH] [Rework] Use google-ced instead of libicu chardet as the former sucks --- CMakeLists.txt | 3 + contrib/google-ced/CMakeLists.txt | 26 + contrib/google-ced/LICENSE | 202 + contrib/google-ced/ced_c.cc | 25 + contrib/google-ced/ced_c.h | 29 + contrib/google-ced/compact_enc_det.cc | 5719 +++++++++++++++ contrib/google-ced/compact_enc_det.h | 83 + .../compact_enc_det_generated_tables.h | 6326 +++++++++++++++++ .../compact_enc_det_generated_tables2.h | 856 +++ .../google-ced/compact_enc_det_hint_code.cc | 169 + .../google-ced/compact_enc_det_hint_code.h | 45 + contrib/google-ced/detail_head_string.inc | 152 + contrib/google-ced/util/basictypes.h | 331 + .../google-ced/util/case_insensitive_hash.h | 88 + contrib/google-ced/util/commandlineflags.h | 39 + .../google-ced/util/encodings/encodings.cc | 891 +++ contrib/google-ced/util/encodings/encodings.h | 299 + .../google-ced/util/encodings/encodings.pb.h | 181 + .../util/encodings/encodings_unittest.cc | 34 + .../google-ced/util/languages/languages.cc | 349 + contrib/google-ced/util/languages/languages.h | 381 + .../google-ced/util/languages/languages.pb.h | 191 + contrib/google-ced/util/logging.h | 25 + contrib/google-ced/util/port.h | 53 + contrib/google-ced/util/string_util.h | 61 + contrib/google-ced/util/varsetter.h | 66 + src/libmime/mime_encoding.c | 33 +- 27 files changed, 16633 insertions(+), 24 deletions(-) create mode 100644 contrib/google-ced/CMakeLists.txt create mode 100644 contrib/google-ced/LICENSE create mode 100644 contrib/google-ced/ced_c.cc create mode 100644 contrib/google-ced/ced_c.h create mode 100644 contrib/google-ced/compact_enc_det.cc create mode 100644 contrib/google-ced/compact_enc_det.h create mode 100644 contrib/google-ced/compact_enc_det_generated_tables.h create mode 100644 contrib/google-ced/compact_enc_det_generated_tables2.h create mode 100644 contrib/google-ced/compact_enc_det_hint_code.cc create mode 100644 contrib/google-ced/compact_enc_det_hint_code.h create mode 100644 contrib/google-ced/detail_head_string.inc create mode 100644 contrib/google-ced/util/basictypes.h create mode 100644 contrib/google-ced/util/case_insensitive_hash.h create mode 100644 contrib/google-ced/util/commandlineflags.h create mode 100644 contrib/google-ced/util/encodings/encodings.cc create mode 100644 contrib/google-ced/util/encodings/encodings.h create mode 100644 contrib/google-ced/util/encodings/encodings.pb.h create mode 100644 contrib/google-ced/util/encodings/encodings_unittest.cc create mode 100644 contrib/google-ced/util/languages/languages.cc create mode 100644 contrib/google-ced/util/languages/languages.h create mode 100644 contrib/google-ced/util/languages/languages.pb.h create mode 100644 contrib/google-ced/util/logging.h create mode 100644 contrib/google-ced/util/port.h create mode 100644 contrib/google-ced/util/string_util.h create mode 100644 contrib/google-ced/util/varsetter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 71c5d1761..e60b9cf84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -623,6 +623,8 @@ ADD_SUBDIRECTORY(contrib/t1ha) ADD_SUBDIRECTORY(contrib/libev) ADD_SUBDIRECTORY(contrib/kann) ADD_SUBDIRECTORY(contrib/fastutf8) +ADD_SUBDIRECTORY(contrib/google-ced) + IF (NOT WITH_LUAJIT) ADD_SUBDIRECTORY(contrib/lua-bit) @@ -643,6 +645,7 @@ LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-actrie) LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-t1ha) LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-ev) LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-kann) +LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-ced) IF(ENABLE_CLANG_PLUGIN MATCHES "ON") ADD_SUBDIRECTORY(clang-plugin) diff --git a/contrib/google-ced/CMakeLists.txt b/contrib/google-ced/CMakeLists.txt new file mode 100644 index 000000000..e1c1c3edb --- /dev/null +++ b/contrib/google-ced/CMakeLists.txt @@ -0,0 +1,26 @@ +# 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. + +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") +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +set(CED_LIBRARY_SOURCES + compact_enc_det.cc + compact_enc_det_hint_code.cc + util/encodings/encodings.cc + util/languages/languages.cc + ced_c.cc + ) + +add_library(rspamd-ced STATIC ${CED_LIBRARY_SOURCES}) diff --git a/contrib/google-ced/LICENSE b/contrib/google-ced/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/contrib/google-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/contrib/google-ced/ced_c.cc b/contrib/google-ced/ced_c.cc new file mode 100644 index 000000000..d8f70a87e --- /dev/null +++ b/contrib/google-ced/ced_c.cc @@ -0,0 +1,25 @@ +#include "ced_c.h" +#include "compact_enc_det.h" + +const char* ced_encoding_detect(const char* text, int text_length, + const char* url_hint, + const char* http_charset_hint, + const char* meta_charset_hint, + const int encoding_hint, + CedTextCorpusType corpus_type, bool ignore_7bit_mail_encodings, + int* bytes_consumed, bool* is_reliable) +{ + CompactEncDet::TextCorpusType ct = CompactEncDet::NUM_CORPA; + + ct = static_cast(corpus_type); + + auto enc = CompactEncDet::DetectEncoding(text, text_length, url_hint, + http_charset_hint, meta_charset_hint, encoding_hint, default_language(), + ct, ignore_7bit_mail_encodings, bytes_consumed, is_reliable); + + if (IsValidEncoding(enc)) { + return EncodingName(enc); + } + + return nullptr; +} diff --git a/contrib/google-ced/ced_c.h b/contrib/google-ced/ced_c.h new file mode 100644 index 000000000..c8cb16a2a --- /dev/null +++ b/contrib/google-ced/ced_c.h @@ -0,0 +1,29 @@ +#ifndef RSPAMD_CED_C_H +#define RSPAMD_CED_C_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif +enum CedTextCorpusType { + CED_WEB_CORPUS, + CED_XML_CORPUS, + CED_QUERY_CORPUS, + CED_EMAIL_CORPUS, + CED_NUM_CORPA, +}; + +const char *ced_encoding_detect (const char *text, int text_length, + const char *url_hint, + const char *http_charset_hint, + const char *meta_charset_hint, + const int encoding_hint, + enum CedTextCorpusType corpus_type, + bool ignore_7bit_mail_encodings, + int *bytes_consumed, bool *is_reliable); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/contrib/google-ced/compact_enc_det.cc b/contrib/google-ced/compact_enc_det.cc new file mode 100644 index 000000000..9f9c3a840 --- /dev/null +++ b/contrib/google-ced/compact_enc_det.cc @@ -0,0 +1,5719 @@ +// 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.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_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 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_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) +// Return 1 if name match found +int ApplyDefaultHint(const CompactEncDet::TextCorpusType corpus_type, + 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, 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;} + + uint32 pair01 = (src[0] << 8) | src[1]; + uint32 pair23 = (src[2] << 8) | src[3]; + uint32 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 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; +} + + +// 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, 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 + if (UTF8Active(destatep)) { + CheckUTF8Seq(destatep, biggest_weightshift); + } + + if (UTF8UTF8Active(destatep)) { + CheckUTF8UTF8Seq(destatep, biggest_weightshift); + } + + 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 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; + +// 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* 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(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(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/contrib/google-ced/compact_enc_det.h b/contrib/google-ced/compact_enc_det.h new file mode 100644 index 000000000..01adf456c --- /dev/null +++ b/contrib/google-ced/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/contrib/google-ced/compact_enc_det_generated_tables.h b/contrib/google-ced/compact_enc_det_generated_tables.h new file mode 100644 index 000000000..bd5317a0d --- /dev/null +++ b/contrib/google-ced/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.h" +#include "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/contrib/google-ced/compact_enc_det_generated_tables2.h b/contrib/google-ced/compact_enc_det_generated_tables2.h new file mode 100644 index 000000000..4ecf9665c --- /dev/null +++ b/contrib/google-ced/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/contrib/google-ced/compact_enc_det_hint_code.cc b/contrib/google-ced/compact_enc_det_hint_code.cc new file mode 100644 index 000000000..7e7b77ae8 --- /dev/null +++ b/contrib/google-ced/compact_enc_det_hint_code.cc @@ -0,0 +1,169 @@ +// 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_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 "~"; +} + + +// 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 (uint32 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 (uint32 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 (uint32 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/contrib/google-ced/compact_enc_det_hint_code.h b/contrib/google-ced/compact_enc_det_hint_code.h new file mode 100644 index 000000000..53fe67ae1 --- /dev/null +++ b/contrib/google-ced/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/contrib/google-ced/detail_head_string.inc b/contrib/google-ced/detail_head_string.inc new file mode 100644 index 000000000..e70e5ff58 --- /dev/null +++ b/contrib/google-ced/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/contrib/google-ced/util/basictypes.h b/contrib/google-ced/util/basictypes.h new file mode 100644 index 000000000..af391c742 --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/case_insensitive_hash.h b/contrib/google-ced/util/case_insensitive_hash.h new file mode 100644 index 000000000..7b0c9db76 --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/commandlineflags.h b/contrib/google-ced/util/commandlineflags.h new file mode 100644 index 000000000..341a659ba --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/encodings/encodings.cc b/contrib/google-ced/util/encodings/encodings.cc new file mode 100644 index 000000000..b5f8dc5fa --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/encodings/encodings.h b/contrib/google-ced/util/encodings/encodings.h new file mode 100644 index 000000000..647797432 --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/encodings/encodings.pb.h b/contrib/google-ced/util/encodings/encodings.pb.h new file mode 100644 index 000000000..ffbd716ec --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/encodings/encodings_unittest.cc b/contrib/google-ced/util/encodings/encodings_unittest.cc new file mode 100644 index 000000000..223e3e45b --- /dev/null +++ b/contrib/google-ced/util/encodings/encodings_unittest.cc @@ -0,0 +1,34 @@ +// 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 "gtest/gtest.h" + +TEST(EncodingsTest, EncodingNameAliasToEncoding) { + // Test that cases, non-alpha-numeric chars are ignored. + EXPECT_EQ(ISO_8859_1, EncodingNameAliasToEncoding("iso_8859_1")); + EXPECT_EQ(ISO_8859_1, EncodingNameAliasToEncoding("iso-8859-1")); + + // Test that spaces are ignored. + EXPECT_EQ(UTF8, EncodingNameAliasToEncoding("UTF8")); + EXPECT_EQ(UTF8, EncodingNameAliasToEncoding("UTF 8")); + EXPECT_EQ(UTF8, EncodingNameAliasToEncoding("UTF-8")); + + // Test alphanumeric differences are counted. + EXPECT_NE(UTF8, EncodingNameAliasToEncoding("UTF-7")); + EXPECT_NE(KOREAN_EUC_KR, EncodingNameAliasToEncoding("euc-jp")); +} diff --git a/contrib/google-ced/util/languages/languages.cc b/contrib/google-ced/util/languages/languages.cc new file mode 100644 index 000000000..852351fc6 --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/languages/languages.h b/contrib/google-ced/util/languages/languages.h new file mode 100644 index 000000000..4237961e3 --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/languages/languages.pb.h b/contrib/google-ced/util/languages/languages.pb.h new file mode 100644 index 000000000..84f1d6a79 --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/logging.h b/contrib/google-ced/util/logging.h new file mode 100644 index 000000000..16e50f209 --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/port.h b/contrib/google-ced/util/port.h new file mode 100644 index 000000000..3799b1696 --- /dev/null +++ b/contrib/google-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/contrib/google-ced/util/string_util.h b/contrib/google-ced/util/string_util.h new file mode 100644 index 000000000..5977f4fd8 --- /dev/null +++ b/contrib/google-ced/util/string_util.h @@ -0,0 +1,61 @@ +// 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 +} + +#ifndef HAVE_MEMRCHR +#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))) +#define HAVE_MEMRCHR +#endif +#endif + +#ifndef HAVE_MEMRCHR +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/contrib/google-ced/util/varsetter.h b/contrib/google-ced/util/varsetter.h new file mode 100644 index 000000000..8e8cbf2c0 --- /dev/null +++ b/contrib/google-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/src/libmime/mime_encoding.c b/src/libmime/mime_encoding.c index 73b68fe06..8e7e54356 100644 --- a/src/libmime/mime_encoding.c +++ b/src/libmime/mime_encoding.c @@ -23,6 +23,7 @@ #include "mime_encoding.h" #include "message.h" #include "contrib/fastutf8/fastutf8.h" +#include "contrib/google-ced/ced_c.h" #include #include #if U_ICU_VERSION_MAJOR_NUM >= 44 @@ -561,38 +562,22 @@ rspamd_mime_charset_utf_enforce (gchar *in, gsize len) const char * rspamd_mime_charset_find_by_content (const gchar *in, gsize inlen) { - static UCharsetDetector *csd; - const UCharsetMatch **csm, *sel = NULL; - UErrorCode uc_err = U_ZERO_ERROR; - gint32 matches, i, max_conf = G_MININT32, conf; - gdouble mean = 0.0, stddev = 0.0; - - if (csd == NULL) { - csd = ucsdet_open (&uc_err); - - g_assert (csd != NULL); - } + int nconsumed; + bool is_reliable; + const gchar *ced_name; if (rspamd_fast_utf8_validate (in, inlen) == 0) { return UTF8_CHARSET; } - ucsdet_setText (csd, in, inlen, &uc_err); - csm = ucsdet_detectAll (csd, &matches, &uc_err); - for (i = 0; i < matches; i ++) { - if ((conf = ucsdet_getConfidence (csm[i], &uc_err)) > max_conf) { - max_conf = conf; - sel = csm[i]; - } + ced_name = ced_encoding_detect (in, inlen, NULL, NULL, + NULL, 0, CED_EMAIL_CORPUS, + false, &nconsumed, &is_reliable); - mean += (conf - mean) / (i + 1); - gdouble err = fabs (conf - mean); - stddev += (err - stddev) / (i + 1); - } + if (ced_name) { - if (sel && ((max_conf > 50) || (max_conf - mean > stddev * 1.25))) { - return ucsdet_getName (sel, &uc_err); + return ced_name; } return NULL; -- 2.39.5