From 2e125c1c7e75db14a88f0b8b09e61a132977c63e Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Mon, 20 May 2024 17:56:55 +0200 Subject: Support the 4 forms of Unicode string normalization --- README | 6 +- data/CompositionExclusions | 221 +++++++++ gen/prop/cm.c | 166 +++++++ include/unicode/_cm.h | 990 +++++++++++++++++++++++++++++++++++++++ include/unicode/string.h | 20 +- lib/unicode/string/u8norm.c | 192 ++++++++ lib/unicode/string/u8norm_nfd.c | 94 ---- lib/unicode/string/u8norm_nfkd.c | 94 ---- make.c | 2 +- test/_norm-test.h | 20 +- test/norm-nfc-test.c | 2 + test/norm-nfd-test.c | 2 +- test/norm-nfkc-test.c | 2 + test/norm-nfkd-test.c | 2 +- 14 files changed, 1606 insertions(+), 207 deletions(-) create mode 100644 data/CompositionExclusions create mode 100755 gen/prop/cm.c create mode 100644 include/unicode/_cm.h create mode 100644 lib/unicode/string/u8norm.c delete mode 100644 lib/unicode/string/u8norm_nfd.c delete mode 100644 lib/unicode/string/u8norm_nfkd.c create mode 100644 test/norm-nfc-test.c create mode 100644 test/norm-nfkc-test.c diff --git a/README b/README index 9df1fc8..3d0397a 100644 --- a/README +++ b/README @@ -123,7 +123,7 @@ FEATURES: • Encoding-generic macros (ucs*() instead of u8*()) • Iteration and counting of graphemes, words, and human-precieved words in a string - • NFD- and NFKD string normalization + • NFC-, NFD-, NFKC-, and NFKD string normalization • Unicode-aware case-mapping of strings with custom allocator support @@ -132,8 +132,8 @@ PLANNED FEATURES: • Line- and sentence segmentation (unicode/string.h) • String collation (unicode/string.h) - • NFC-, and NFKC string normalization (unicode/string.h) - • Merger of normalization functions into one (unicode/string.h) + • Use gperf to generate hashtables for (unicode/string.h) + unicode composition? BUGS: diff --git a/data/CompositionExclusions b/data/CompositionExclusions new file mode 100644 index 0000000..db708a7 --- /dev/null +++ b/data/CompositionExclusions @@ -0,0 +1,221 @@ +# CompositionExclusions-15.1.0.txt +# Date: 2023-01-05 +# © 2023 Unicode®, Inc. +# For terms of use, see https://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see https://www.unicode.org/reports/tr44/ +# +# This file lists the characters for the Composition Exclusion Table +# defined in UAX #15, Unicode Normalization Forms. +# +# This file is a normative contributory data file in the +# Unicode Character Database. +# +# For more information, see +# https://www.unicode.org/reports/tr15/#Primary_Exclusion_List_Table +# +# For a full derivation of composition exclusions, see the derived property +# Full_Composition_Exclusion in DerivedNormalizationProps.txt +# + +# ================================================ +# (1) Script Specifics +# +# This list of characters cannot be derived from the UnicodeData.txt file. +# +# Included are the following subcategories: +# +# - Many precomposed characters using a nukta diacritic in the Devanagari, +# Bangla/Bengali, Gurmukhi, or Odia/Oriya scripts. +# - Tibetan letters and subjoined letters with decompositions including +# U+0FB7 TIBETAN SUBJOINED LETTER HA or U+0FB5 TIBETAN SUBJOINED LETTER SSA. +# - Two two-part Tibetan vowel signs involving top and bottom pieces. +# - A large collection of compatibility precomposed characters for Hebrew +# involving dagesh and/or other combining marks. +# +# This list is unlikely to grow. +# +# ================================================ + +0958 # DEVANAGARI LETTER QA +0959 # DEVANAGARI LETTER KHHA +095A # DEVANAGARI LETTER GHHA +095B # DEVANAGARI LETTER ZA +095C # DEVANAGARI LETTER DDDHA +095D # DEVANAGARI LETTER RHA +095E # DEVANAGARI LETTER FA +095F # DEVANAGARI LETTER YYA +09DC # BENGALI LETTER RRA +09DD # BENGALI LETTER RHA +09DF # BENGALI LETTER YYA +0A33 # GURMUKHI LETTER LLA +0A36 # GURMUKHI LETTER SHA +0A59 # GURMUKHI LETTER KHHA +0A5A # GURMUKHI LETTER GHHA +0A5B # GURMUKHI LETTER ZA +0A5E # GURMUKHI LETTER FA +0B5C # ORIYA LETTER RRA +0B5D # ORIYA LETTER RHA +0F43 # TIBETAN LETTER GHA +0F4D # TIBETAN LETTER DDHA +0F52 # TIBETAN LETTER DHA +0F57 # TIBETAN LETTER BHA +0F5C # TIBETAN LETTER DZHA +0F69 # TIBETAN LETTER KSSA +0F76 # TIBETAN VOWEL SIGN VOCALIC R +0F78 # TIBETAN VOWEL SIGN VOCALIC L +0F93 # TIBETAN SUBJOINED LETTER GHA +0F9D # TIBETAN SUBJOINED LETTER DDHA +0FA2 # TIBETAN SUBJOINED LETTER DHA +0FA7 # TIBETAN SUBJOINED LETTER BHA +0FAC # TIBETAN SUBJOINED LETTER DZHA +0FB9 # TIBETAN SUBJOINED LETTER KSSA +FB1D # HEBREW LETTER YOD WITH HIRIQ +FB1F # HEBREW LIGATURE YIDDISH YOD YOD PATAH +FB2A # HEBREW LETTER SHIN WITH SHIN DOT +FB2B # HEBREW LETTER SHIN WITH SIN DOT +FB2C # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT +FB2D # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT +FB2E # HEBREW LETTER ALEF WITH PATAH +FB2F # HEBREW LETTER ALEF WITH QAMATS +FB30 # HEBREW LETTER ALEF WITH MAPIQ +FB31 # HEBREW LETTER BET WITH DAGESH +FB32 # HEBREW LETTER GIMEL WITH DAGESH +FB33 # HEBREW LETTER DALET WITH DAGESH +FB34 # HEBREW LETTER HE WITH MAPIQ +FB35 # HEBREW LETTER VAV WITH DAGESH +FB36 # HEBREW LETTER ZAYIN WITH DAGESH +FB38 # HEBREW LETTER TET WITH DAGESH +FB39 # HEBREW LETTER YOD WITH DAGESH +FB3A # HEBREW LETTER FINAL KAF WITH DAGESH +FB3B # HEBREW LETTER KAF WITH DAGESH +FB3C # HEBREW LETTER LAMED WITH DAGESH +FB3E # HEBREW LETTER MEM WITH DAGESH +FB40 # HEBREW LETTER NUN WITH DAGESH +FB41 # HEBREW LETTER SAMEKH WITH DAGESH +FB43 # HEBREW LETTER FINAL PE WITH DAGESH +FB44 # HEBREW LETTER PE WITH DAGESH +FB46 # HEBREW LETTER TSADI WITH DAGESH +FB47 # HEBREW LETTER QOF WITH DAGESH +FB48 # HEBREW LETTER RESH WITH DAGESH +FB49 # HEBREW LETTER SHIN WITH DAGESH +FB4A # HEBREW LETTER TAV WITH DAGESH +FB4B # HEBREW LETTER VAV WITH HOLAM +FB4C # HEBREW LETTER BET WITH RAFE +FB4D # HEBREW LETTER KAF WITH RAFE +FB4E # HEBREW LETTER PE WITH RAFE + +# Total code points: 67 + +# ================================================ +# (2) Post Composition Version precomposed characters +# +# These characters cannot be derived solely from the UnicodeData.txt file +# in this version of Unicode. +# +# Note that characters added to the standard after the +# Composition Version and which have canonical decomposition mappings +# are not automatically added to this list of Post Composition +# Version precomposed characters. +# ================================================ + +2ADC # FORKING +1D15E # MUSICAL SYMBOL HALF NOTE +1D15F # MUSICAL SYMBOL QUARTER NOTE +1D160 # MUSICAL SYMBOL EIGHTH NOTE +1D161 # MUSICAL SYMBOL SIXTEENTH NOTE +1D162 # MUSICAL SYMBOL THIRTY-SECOND NOTE +1D163 # MUSICAL SYMBOL SIXTY-FOURTH NOTE +1D164 # MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE +1D1BB # MUSICAL SYMBOL MINIMA +1D1BC # MUSICAL SYMBOL MINIMA BLACK +1D1BD # MUSICAL SYMBOL SEMIMINIMA WHITE +1D1BE # MUSICAL SYMBOL SEMIMINIMA BLACK +1D1BF # MUSICAL SYMBOL FUSA WHITE +1D1C0 # MUSICAL SYMBOL FUSA BLACK + +# Total code points: 14 + +# ================================================ +# (3) Singleton Decompositions +# +# These characters can be derived from the UnicodeData.txt file +# by including all canonically decomposable characters whose +# canonical decomposition consists of a single character. +# +# These characters are simply quoted here for reference. +# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt +# ================================================ + +# 0340..0341 [2] COMBINING GRAVE TONE MARK..COMBINING ACUTE TONE MARK +# 0343 COMBINING GREEK KORONIS +# 0374 GREEK NUMERAL SIGN +# 037E GREEK QUESTION MARK +# 0387 GREEK ANO TELEIA +# 1F71 GREEK SMALL LETTER ALPHA WITH OXIA +# 1F73 GREEK SMALL LETTER EPSILON WITH OXIA +# 1F75 GREEK SMALL LETTER ETA WITH OXIA +# 1F77 GREEK SMALL LETTER IOTA WITH OXIA +# 1F79 GREEK SMALL LETTER OMICRON WITH OXIA +# 1F7B GREEK SMALL LETTER UPSILON WITH OXIA +# 1F7D GREEK SMALL LETTER OMEGA WITH OXIA +# 1FBB GREEK CAPITAL LETTER ALPHA WITH OXIA +# 1FBE GREEK PROSGEGRAMMENI +# 1FC9 GREEK CAPITAL LETTER EPSILON WITH OXIA +# 1FCB GREEK CAPITAL LETTER ETA WITH OXIA +# 1FD3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA +# 1FDB GREEK CAPITAL LETTER IOTA WITH OXIA +# 1FE3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA +# 1FEB GREEK CAPITAL LETTER UPSILON WITH OXIA +# 1FEE..1FEF [2] GREEK DIALYTIKA AND OXIA..GREEK VARIA +# 1FF9 GREEK CAPITAL LETTER OMICRON WITH OXIA +# 1FFB GREEK CAPITAL LETTER OMEGA WITH OXIA +# 1FFD GREEK OXIA +# 2000..2001 [2] EN QUAD..EM QUAD +# 2126 OHM SIGN +# 212A..212B [2] KELVIN SIGN..ANGSTROM SIGN +# 2329 LEFT-POINTING ANGLE BRACKET +# 232A RIGHT-POINTING ANGLE BRACKET +# F900..FA0D [270] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA0D +# FA10 CJK COMPATIBILITY IDEOGRAPH-FA10 +# FA12 CJK COMPATIBILITY IDEOGRAPH-FA12 +# FA15..FA1E [10] CJK COMPATIBILITY IDEOGRAPH-FA15..CJK COMPATIBILITY IDEOGRAPH-FA1E +# FA20 CJK COMPATIBILITY IDEOGRAPH-FA20 +# FA22 CJK COMPATIBILITY IDEOGRAPH-FA22 +# FA25..FA26 [2] CJK COMPATIBILITY IDEOGRAPH-FA25..CJK COMPATIBILITY IDEOGRAPH-FA26 +# FA2A..FA6D [68] CJK COMPATIBILITY IDEOGRAPH-FA2A..CJK COMPATIBILITY IDEOGRAPH-FA6D +# FA70..FAD9 [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9 +# 2F800..2FA1D [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D + +# Total code points: 1035 + +# ================================================ +# (4) Non-Starter Decompositions +# +# These characters can be derived from the UnicodeData.txt file +# by including each expanding canonical decomposition +# (i.e., those which canonically decompose to a sequence +# of characters instead of a single character), such that: +# +# A. The character is not a Starter. +# +# OR (inclusive) +# +# B. The character's canonical decomposition begins +# with a character that is not a Starter. +# +# Note that a "Starter" is any character with a zero combining class. +# +# These characters are simply quoted here for reference. +# See also Full_Composition_Exclusion in DerivedNormalizationProps.txt +# ================================================ + +# 0344 COMBINING GREEK DIALYTIKA TONOS +# 0F73 TIBETAN VOWEL SIGN II +# 0F75 TIBETAN VOWEL SIGN UU +# 0F81 TIBETAN VOWEL SIGN REVERSED II + +# Total code points: 4 + +# EOF diff --git a/gen/prop/cm.c b/gen/prop/cm.c new file mode 100755 index 0000000..5188ccd --- /dev/null +++ b/gen/prop/cm.c @@ -0,0 +1,166 @@ +#if 0 +cd "${0%/*}/../.." +trap 'rm -f /tmp/cm' EXIT +cc -Iinclude -std=c23 -Wno-attributes -fsanitize=address,undefined \ + -o /tmp/cm gen/prop/cm.c libmlib.a +/tmp/cm +exit 0 +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +constexpr int N = 1; + +struct mapping { + uint64_t k; + rune v; +}; + +struct ht { + struct mapping *ht; + size_t len; +}; + +static uint32_t lookup(uint64_t, int, uint32_t); +static uint64_t hash(uint64_t); + +int +main(void) +{ + dynarr(struct mapping) maps = {.alloc = alloc_heap}; + + for (rune ch = 0; ch <= RUNE_MAX; ch++) { + if (uprop_get_dt(ch) != DT_CAN || uprop_is_comp_ex(ch)) + continue; + struct rview rv = uprop_get_dm(ch); + if (rv.len == 1 && rv.p[0] == ch) + continue; + assert(rv.len == 2); + + /* Sanity check */ + int n, m; + char8_t buf[U8_LEN_MAX]; + n = m = 0; + n += rtoucs(buf, sizeof(buf), rv.p[0]); + n += rtoucs(buf, sizeof(buf), rv.p[1]); + m += rtoucs(buf, sizeof(buf), ch); + assert(n >= m); + + DAPUSH(&maps, ((struct mapping){ + .k = (uint64_t)rv.p[0] << 32 | rv.p[1], + .v = ch, + })); + } + + struct ht t = {}; + size_t sz = (size_t)1 << (SIZE_WIDTH - stdc_leading_zeros(maps.len) + N); + int e = stdc_trailing_zeros(sz); + t.ht = bufalloc(nullptr, sizeof(*t.ht), sz); + memset(t.ht, 0, sizeof(*t.ht) * sz); + assert(sz == ((size_t)1 << e)); + + /* Build up hashtable */ + da_foreach (maps, m) { + uint64_t h = hash(m->k); + uint32_t i = h; + for (;;) { + i = lookup(h, e, i); + if (t.ht[i].k == 0) { + t.ht[i] = *m; + t.len++; + break; + } + } + } + + stdout = fopen("include/unicode/_cm.h", "w"); + assert(stdout != nullptr); + + puts("/* This file is autogenerated by gen/prop/cm.c; DO NOT EDIT. */\n"); + puts("#include \n\n" + "#include \"_attrs.h\"\n" + "#include \"rune.h\"\n"); + printf("constexpr int HT_EXP = %d;\n\n", e); + puts("static const struct {\n" + "\tuint64_t k;\n" + "\trune v;\n" + "} uprop_cm_ht[] = {"); + + for (size_t i = 0; i < sz; i++) { + if (t.ht[i].k != 0) { + printf("\t[%4zu] = {UINT64_C(0x%016" PRIX64 + "), RUNE_C(0x%06" PRIXRUNE ")},\n", + i, t.ht[i].k, t.ht[i].v); + } + } + + puts("};\n"); + + puts("[[_mlib_pure, _mlib_inline]]\n" + "static uint64_t\n" + "hash(uint64_t x)\n" + "{\n" + "\tx ^= x >> 30;\n" + "\tx *= 0xbf58476d1ce4e5b9U;\n" + "\tx ^= x >> 27;\n" + "\tx *= 0x94d049bb133111ebU;\n" + "\tx ^= x >> 31;\n" + "\treturn x;\n" + "}\n"); + + puts("[[_mlib_pure, _mlib_inline]]\n" + "static unsigned int\n" + "lookup(uint64_t hash, unsigned int idx)\n" + "{\n" + "\tunsigned int mask = (1U << HT_EXP) - 1;\n" + "\tunsigned int step = (hash >> (64 - HT_EXP)) | 1;\n" + "\treturn (idx + step) & mask;\n" + "}\n"); + + puts("static rune\n" + "uprop_get_cm(rune a, rune b)\n" + "{\n" + "\tuint64_t k, h;\n" + "\tk = (uint64_t)a << 32 | b;\n" + "\th = hash(k);\n" + "\tfor (unsigned int i = h;;) {\n" + "\t\ti = lookup(h, i);\n" + "\t\tauto e = uprop_cm_ht[i];\n" + "\t\tif (e.k == 0 || e.k == k)\n" + "\t\t\treturn e.v;\n" + "\t}\n" + "}"); + + free(t.ht); + free(maps.buf); +} + +uint32_t +lookup(uint64_t hash, int exp, uint32_t idx) +{ + uint32_t mask = ((uint32_t)1 << exp) - 1; + uint32_t step = (hash >> (64 - exp)) | 1; + return (idx + step) & mask; +} + +uint64_t +hash(uint64_t x) +{ + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9U; + x ^= x >> 27; + x *= 0x94d049bb133111ebU; + x ^= x >> 31; + return x; +} diff --git a/include/unicode/_cm.h b/include/unicode/_cm.h new file mode 100644 index 0000000..fdeb361 --- /dev/null +++ b/include/unicode/_cm.h @@ -0,0 +1,990 @@ +/* This file is autogenerated by gen/prop/cm.c; DO NOT EDIT. */ + +#include + +#include "_attrs.h" +#include "rune.h" + +constexpr int HT_EXP = 11; + +static const struct { + uint64_t k; + rune v; +} uprop_cm_ht[] = { + [ 3] = {UINT64_C(0x000003B100000345), RUNE_C(0x001FB3)}, + [ 5] = {UINT64_C(0x0000229100000338), RUNE_C(0x0022E2)}, + [ 6] = {UINT64_C(0x00000DD900000DCA), RUNE_C(0x000DDA)}, + [ 8] = {UINT64_C(0x0000005700000308), RUNE_C(0x001E84)}, + [ 10] = {UINT64_C(0x000002920000030C), RUNE_C(0x0001EF)}, + [ 11] = {UINT64_C(0x00001F0800000300), RUNE_C(0x001F0A)}, + [ 14] = {UINT64_C(0x0000004700000327), RUNE_C(0x000122)}, + [ 15] = {UINT64_C(0x00001F5100000301), RUNE_C(0x001F55)}, + [ 18] = {UINT64_C(0x0000004700000307), RUNE_C(0x000120)}, + [ 21] = {UINT64_C(0x000001AF00000300), RUNE_C(0x001EEA)}, + [ 22] = {UINT64_C(0x000000770000030A), RUNE_C(0x001E98)}, + [ 23] = {UINT64_C(0x00001F5900000301), RUNE_C(0x001F5D)}, + [ 28] = {UINT64_C(0x000000E200000300), RUNE_C(0x001EA7)}, + [ 29] = {UINT64_C(0x0000007900000304), RUNE_C(0x000233)}, + [ 31] = {UINT64_C(0x000000FC00000301), RUNE_C(0x0001D8)}, + [ 33] = {UINT64_C(0x0000043700000308), RUNE_C(0x0004DF)}, + [ 35] = {UINT64_C(0x000030BD00003099), RUNE_C(0x0030BE)}, + [ 37] = {UINT64_C(0x0000006500000301), RUNE_C(0x0000E9)}, + [ 39] = {UINT64_C(0x00001F5100000300), RUNE_C(0x001F53)}, + [ 40] = {UINT64_C(0x0000006900000330), RUNE_C(0x001E2D)}, + [ 42] = {UINT64_C(0x0000006600000307), RUNE_C(0x001E1F)}, + [ 43] = {UINT64_C(0x0000006500000327), RUNE_C(0x000229)}, + [ 49] = {UINT64_C(0x0000007500000330), RUNE_C(0x001E75)}, + [ 50] = {UINT64_C(0x0000007300000323), RUNE_C(0x001E63)}, + [ 51] = {UINT64_C(0x000030720000309A), RUNE_C(0x003074)}, + [ 55] = {UINT64_C(0x0000305100003099), RUNE_C(0x003052)}, + [ 57] = {UINT64_C(0x0000006F00000309), RUNE_C(0x001ECF)}, + [ 58] = {UINT64_C(0x00001EA000000306), RUNE_C(0x001EB6)}, + [ 59] = {UINT64_C(0x0000224D00000338), RUNE_C(0x00226D)}, + [ 61] = {UINT64_C(0x000003BF00000301), RUNE_C(0x0003CC)}, + [ 65] = {UINT64_C(0x00001F4100000301), RUNE_C(0x001F45)}, + [ 69] = {UINT64_C(0x00001F2C00000345), RUNE_C(0x001F9C)}, + [ 70] = {UINT64_C(0x000009280000093C), RUNE_C(0x000929)}, + [ 76] = {UINT64_C(0x00001F3000000300), RUNE_C(0x001F32)}, + [ 78] = {UINT64_C(0x000000FC00000300), RUNE_C(0x0001DC)}, + [ 79] = {UINT64_C(0x0000004500000307), RUNE_C(0x000116)}, + [ 82] = {UINT64_C(0x00001F6900000345), RUNE_C(0x001FA9)}, + [ 83] = {UINT64_C(0x0000004700000304), RUNE_C(0x001E20)}, + [ 86] = {UINT64_C(0x000030780000309A), RUNE_C(0x00307A)}, + [ 87] = {UINT64_C(0x0000005300000326), RUNE_C(0x000218)}, + [ 90] = {UINT64_C(0x0000005200000331), RUNE_C(0x001E5E)}, + [ 92] = {UINT64_C(0x0000006F00000303), RUNE_C(0x0000F5)}, + [ 95] = {UINT64_C(0x0000005400000331), RUNE_C(0x001E6E)}, + [ 97] = {UINT64_C(0x0000039500000313), RUNE_C(0x001F18)}, + [ 99] = {UINT64_C(0x000003A900000314), RUNE_C(0x001F69)}, + [ 100] = {UINT64_C(0x0000004800000307), RUNE_C(0x001E22)}, + [ 101] = {UINT64_C(0x000000C400000304), RUNE_C(0x0001DE)}, + [ 104] = {UINT64_C(0x0000005300000307), RUNE_C(0x001E60)}, + [ 106] = {UINT64_C(0x00001F6000000342), RUNE_C(0x001F66)}, + [ 107] = {UINT64_C(0x000000690000030C), RUNE_C(0x0001D0)}, + [ 109] = {UINT64_C(0x000000450000032D), RUNE_C(0x001E18)}, + [ 113] = {UINT64_C(0x000003B700000342), RUNE_C(0x001FC6)}, + [ 114] = {UINT64_C(0x000000D400000309), RUNE_C(0x001ED4)}, + [ 115] = {UINT64_C(0x00001B0B00001B35), RUNE_C(0x001B0C)}, + [ 116] = {UINT64_C(0x000000CA00000300), RUNE_C(0x001EC0)}, + [ 118] = {UINT64_C(0x000003C100000313), RUNE_C(0x001FE4)}, + [ 120] = {UINT64_C(0x00001FBF00000301), RUNE_C(0x001FCE)}, + [ 121] = {UINT64_C(0x000003BF00000314), RUNE_C(0x001F41)}, + [ 123] = {UINT64_C(0x000000550000030A), RUNE_C(0x00016E)}, + [ 124] = {UINT64_C(0x0000006E00000327), RUNE_C(0x000146)}, + [ 126] = {UINT64_C(0x000000720000030C), RUNE_C(0x000159)}, + [ 130] = {UINT64_C(0x00001F2100000345), RUNE_C(0x001F91)}, + [ 131] = {UINT64_C(0x0000226100000338), RUNE_C(0x002262)}, + [ 133] = {UINT64_C(0x0000005700000300), RUNE_C(0x001E80)}, + [ 134] = {UINT64_C(0x000009300000093C), RUNE_C(0x000931)}, + [ 136] = {UINT64_C(0x000000630000030C), RUNE_C(0x00010D)}, + [ 137] = {UINT64_C(0x00000DDC00000DCA), RUNE_C(0x000DDD)}, + [ 139] = {UINT64_C(0x00001E3600000304), RUNE_C(0x001E38)}, + [ 140] = {UINT64_C(0x0000004100000303), RUNE_C(0x0000C3)}, + [ 141] = {UINT64_C(0x0000004100000302), RUNE_C(0x0000C2)}, + [ 142] = {UINT64_C(0x0000005400000323), RUNE_C(0x001E6C)}, + [ 143] = {UINT64_C(0x0000007500000303), RUNE_C(0x000169)}, + [ 144] = {UINT64_C(0x0000006500000328), RUNE_C(0x000119)}, + [ 145] = {UINT64_C(0x0000004300000301), RUNE_C(0x000106)}, + [ 147] = {UINT64_C(0x0000040600000308), RUNE_C(0x000407)}, + [ 148] = {UINT64_C(0x0000006C00000323), RUNE_C(0x001E37)}, + [ 149] = {UINT64_C(0x0000224800000338), RUNE_C(0x002249)}, + [ 150] = {UINT64_C(0x00000BC600000BD7), RUNE_C(0x000BCC)}, + [ 153] = {UINT64_C(0x0000039700000301), RUNE_C(0x000389)}, + [ 155] = {UINT64_C(0x0000006100000303), RUNE_C(0x0000E3)}, + [ 156] = {UINT64_C(0x0000005500000303), RUNE_C(0x000168)}, + [ 157] = {UINT64_C(0x0000041600000308), RUNE_C(0x0004DC)}, + [ 168] = {UINT64_C(0x0000043000000308), RUNE_C(0x0004D3)}, + [ 170] = {UINT64_C(0x000000650000030C), RUNE_C(0x00011B)}, + [ 171] = {UINT64_C(0x0000005300000302), RUNE_C(0x00015C)}, + [ 172] = {UINT64_C(0x0000228300000338), RUNE_C(0x002285)}, + [ 174] = {UINT64_C(0x0000006200000307), RUNE_C(0x001E03)}, + [ 180] = {UINT64_C(0x0000010300000300), RUNE_C(0x001EB1)}, + [ 182] = {UINT64_C(0x0000041800000308), RUNE_C(0x0004E4)}, + [ 185] = {UINT64_C(0x0000005700000302), RUNE_C(0x000174)}, + [ 186] = {UINT64_C(0x0000004800000327), RUNE_C(0x001E28)}, + [ 187] = {UINT64_C(0x0000006200000331), RUNE_C(0x001E07)}, + [ 189] = {UINT64_C(0x00000CC600000CC2), RUNE_C(0x000CCA)}, + [ 190] = {UINT64_C(0x0000010200000309), RUNE_C(0x001EB2)}, + [ 191] = {UINT64_C(0x0000006800000323), RUNE_C(0x001E25)}, + [ 194] = {UINT64_C(0x0000004F00000301), RUNE_C(0x0000D3)}, + [ 195] = {UINT64_C(0x0000004F0000030B), RUNE_C(0x000150)}, + [ 196] = {UINT64_C(0x000003C500000304), RUNE_C(0x001FE1)}, + [ 198] = {UINT64_C(0x00000CC600000CD6), RUNE_C(0x000CC8)}, + [ 199] = {UINT64_C(0x00001F2800000300), RUNE_C(0x001F2A)}, + [ 208] = {UINT64_C(0x00001F6600000345), RUNE_C(0x001FA6)}, + [ 210] = {UINT64_C(0x0000007300000326), RUNE_C(0x000219)}, + [ 213] = {UINT64_C(0x0000003D00000338), RUNE_C(0x002260)}, + [ 214] = {UINT64_C(0x0000004200000323), RUNE_C(0x001E04)}, + [ 220] = {UINT64_C(0x000003C100000314), RUNE_C(0x001FE5)}, + [ 221] = {UINT64_C(0x000000F500000308), RUNE_C(0x001E4F)}, + [ 223] = {UINT64_C(0x0000004900000308), RUNE_C(0x0000CF)}, + [ 224] = {UINT64_C(0x00001F2A00000345), RUNE_C(0x001F9A)}, + [ 225] = {UINT64_C(0x00001F2900000342), RUNE_C(0x001F2F)}, + [ 226] = {UINT64_C(0x0000004100000328), RUNE_C(0x000104)}, + [ 229] = {UINT64_C(0x00001F6100000345), RUNE_C(0x001FA1)}, + [ 233] = {UINT64_C(0x0000041E00000308), RUNE_C(0x0004E6)}, + [ 234] = {UINT64_C(0x000003B900000313), RUNE_C(0x001F30)}, + [ 238] = {UINT64_C(0x000000E200000301), RUNE_C(0x001EA5)}, + [ 239] = {UINT64_C(0x0000306F0000309A), RUNE_C(0x003071)}, + [ 240] = {UINT64_C(0x0000011200000300), RUNE_C(0x001E14)}, + [ 244] = {UINT64_C(0x000009C7000009D7), RUNE_C(0x0009CC)}, + [ 248] = {UINT64_C(0x0000004900000303), RUNE_C(0x000128)}, + [ 250] = {UINT64_C(0x000000690000030F), RUNE_C(0x000209)}, + [ 254] = {UINT64_C(0x0000006900000311), RUNE_C(0x00020B)}, + [ 255] = {UINT64_C(0x000000F500000301), RUNE_C(0x001E4D)}, + [ 258] = {UINT64_C(0x00001F4800000300), RUNE_C(0x001F4A)}, + [ 260] = {UINT64_C(0x000030C400003099), RUNE_C(0x0030C5)}, + [ 261] = {UINT64_C(0x000003B100000306), RUNE_C(0x001FB0)}, + [ 262] = {UINT64_C(0x0000005300000301), RUNE_C(0x00015A)}, + [ 263] = {UINT64_C(0x000003D200000308), RUNE_C(0x0003D4)}, + [ 265] = {UINT64_C(0x000003CB00000300), RUNE_C(0x001FE2)}, + [ 266] = {UINT64_C(0x000030C600003099), RUNE_C(0x0030C7)}, + [ 273] = {UINT64_C(0x000000D400000301), RUNE_C(0x001ED0)}, + [ 275] = {UINT64_C(0x000003B700000314), RUNE_C(0x001F21)}, + [ 276] = {UINT64_C(0x000001A100000309), RUNE_C(0x001EDF)}, + [ 280] = {UINT64_C(0x0000005400000327), RUNE_C(0x000162)}, + [ 288] = {UINT64_C(0x00000DD900000DCF), RUNE_C(0x000DDC)}, + [ 291] = {UINT64_C(0x000030EF00003099), RUNE_C(0x0030F7)}, + [ 292] = {UINT64_C(0x000000A800000300), RUNE_C(0x001FED)}, + [ 294] = {UINT64_C(0x0000005500000330), RUNE_C(0x001E74)}, + [ 296] = {UINT64_C(0x0000005400000326), RUNE_C(0x00021A)}, + [ 299] = {UINT64_C(0x0000004F00000323), RUNE_C(0x001ECC)}, + [ 303] = {UINT64_C(0x000022B200000338), RUNE_C(0x0022EA)}, + [ 304] = {UINT64_C(0x00001F0100000300), RUNE_C(0x001F03)}, + [ 309] = {UINT64_C(0x0000043800000304), RUNE_C(0x0004E3)}, + [ 310] = {UINT64_C(0x0000006900000323), RUNE_C(0x001ECB)}, + [ 312] = {UINT64_C(0x0000006E00000331), RUNE_C(0x001E49)}, + [ 315] = {UINT64_C(0x000001A000000303), RUNE_C(0x001EE0)}, + [ 318] = {UINT64_C(0x0000015B00000307), RUNE_C(0x001E65)}, + [ 319] = {UINT64_C(0x00000D4600000D57), RUNE_C(0x000D4C)}, + [ 323] = {UINT64_C(0x0000007900000300), RUNE_C(0x001EF3)}, + [ 324] = {UINT64_C(0x00001F2100000342), RUNE_C(0x001F27)}, + [ 326] = {UINT64_C(0x0000004900000309), RUNE_C(0x001EC8)}, + [ 332] = {UINT64_C(0x00001EA000000302), RUNE_C(0x001EAC)}, + [ 334] = {UINT64_C(0x0000004400000323), RUNE_C(0x001E0C)}, + [ 338] = {UINT64_C(0x0000004500000300), RUNE_C(0x0000C8)}, + [ 339] = {UINT64_C(0x0000007700000302), RUNE_C(0x000175)}, + [ 343] = {UINT64_C(0x000030B100003099), RUNE_C(0x0030B2)}, + [ 344] = {UINT64_C(0x0000022900000306), RUNE_C(0x001E1D)}, + [ 345] = {UINT64_C(0x0000007900000323), RUNE_C(0x001EF5)}, + [ 348] = {UINT64_C(0x000000750000031B), RUNE_C(0x0001B0)}, + [ 349] = {UINT64_C(0x0000042700000308), RUNE_C(0x0004F4)}, + [ 350] = {UINT64_C(0x000010250000102E), RUNE_C(0x001026)}, + [ 355] = {UINT64_C(0x0000006900000302), RUNE_C(0x0000EE)}, + [ 357] = {UINT64_C(0x0000004B00000323), RUNE_C(0x001E32)}, + [ 358] = {UINT64_C(0x0000004E00000303), RUNE_C(0x0000D1)}, + [ 359] = {UINT64_C(0x0000226500000338), RUNE_C(0x002271)}, + [ 362] = {UINT64_C(0x00001FF600000345), RUNE_C(0x001FF7)}, + [ 366] = {UINT64_C(0x00001F1000000300), RUNE_C(0x001F12)}, + [ 369] = {UINT64_C(0x00001F1800000300), RUNE_C(0x001F1A)}, + [ 370] = {UINT64_C(0x000003C500000313), RUNE_C(0x001F50)}, + [ 371] = {UINT64_C(0x000003B500000300), RUNE_C(0x001F72)}, + [ 373] = {UINT64_C(0x000004E800000308), RUNE_C(0x0004EA)}, + [ 374] = {UINT64_C(0x00001F6100000342), RUNE_C(0x001F67)}, + [ 375] = {UINT64_C(0x0000006D00000323), RUNE_C(0x001E43)}, + [ 378] = {UINT64_C(0x00001F3800000300), RUNE_C(0x001F3A)}, + [ 379] = {UINT64_C(0x000000CA00000301), RUNE_C(0x001EBE)}, + [ 382] = {UINT64_C(0x0000006B00000301), RUNE_C(0x001E31)}, + [ 384] = {UINT64_C(0x0000044300000306), RUNE_C(0x00045E)}, + [ 385] = {UINT64_C(0x0000041600000306), RUNE_C(0x0004C1)}, + [ 388] = {UINT64_C(0x0000307B00003099), RUNE_C(0x00307C)}, + [ 391] = {UINT64_C(0x0000005200000301), RUNE_C(0x000154)}, + [ 392] = {UINT64_C(0x00001F0300000345), RUNE_C(0x001F83)}, + [ 394] = {UINT64_C(0x00001F7C00000345), RUNE_C(0x001FF2)}, + [ 395] = {UINT64_C(0x0000228600000338), RUNE_C(0x002288)}, + [ 396] = {UINT64_C(0x0000039500000301), RUNE_C(0x000388)}, + [ 397] = {UINT64_C(0x00001F3800000342), RUNE_C(0x001F3E)}, + [ 399] = {UINT64_C(0x0000220B00000338), RUNE_C(0x00220C)}, + [ 400] = {UINT64_C(0x0000043800000300), RUNE_C(0x00045D)}, + [ 401] = {UINT64_C(0x0000006700000327), RUNE_C(0x000123)}, + [ 403] = {UINT64_C(0x0000007A0000030C), RUNE_C(0x00017E)}, + [ 407] = {UINT64_C(0x0000006B00000323), RUNE_C(0x001E33)}, + [ 408] = {UINT64_C(0x0000006900000301), RUNE_C(0x0000ED)}, + [ 409] = {UINT64_C(0x0000010200000301), RUNE_C(0x001EAE)}, + [ 411] = {UINT64_C(0x0000006D00000301), RUNE_C(0x001E3F)}, + [ 415] = {UINT64_C(0x0000006100000311), RUNE_C(0x000203)}, + [ 416] = {UINT64_C(0x00001F0E00000345), RUNE_C(0x001F8E)}, + [ 423] = {UINT64_C(0x000003A900000300), RUNE_C(0x001FFA)}, + [ 428] = {UINT64_C(0x0000304F00003099), RUNE_C(0x003050)}, + [ 429] = {UINT64_C(0x00001F7400000345), RUNE_C(0x001FC2)}, + [ 431] = {UINT64_C(0x000030AB00003099), RUNE_C(0x0030AC)}, + [ 433] = {UINT64_C(0x0000043600000306), RUNE_C(0x0004C2)}, + [ 435] = {UINT64_C(0x00001F4000000300), RUNE_C(0x001F42)}, + [ 436] = {UINT64_C(0x00001F0B00000345), RUNE_C(0x001F8B)}, + [ 438] = {UINT64_C(0x0000004200000331), RUNE_C(0x001E06)}, + [ 439] = {UINT64_C(0x0000006500000323), RUNE_C(0x001EB9)}, + [ 440] = {UINT64_C(0x00001F5000000300), RUNE_C(0x001F52)}, + [ 442] = {UINT64_C(0x000000480000032E), RUNE_C(0x001E2A)}, + [ 445] = {UINT64_C(0x0000041A00000301), RUNE_C(0x00040C)}, + [ 449] = {UINT64_C(0x000000430000030C), RUNE_C(0x00010C)}, + [ 450] = {UINT64_C(0x0000005600000323), RUNE_C(0x001E7E)}, + [ 451] = {UINT64_C(0x0000007500000328), RUNE_C(0x000173)}, + [ 454] = {UINT64_C(0x0000016B00000308), RUNE_C(0x001E7B)}, + [ 459] = {UINT64_C(0x00000B9200000BD7), RUNE_C(0x000B94)}, + [ 461] = {UINT64_C(0x0000219200000338), RUNE_C(0x00219B)}, + [ 462] = {UINT64_C(0x0000007400000327), RUNE_C(0x000163)}, + [ 465] = {UINT64_C(0x000003B700000345), RUNE_C(0x001FC3)}, + [ 468] = {UINT64_C(0x0000219000000338), RUNE_C(0x00219A)}, + [ 469] = {UINT64_C(0x0000004B00000327), RUNE_C(0x000136)}, + [ 470] = {UINT64_C(0x000000DC00000300), RUNE_C(0x0001DB)}, + [ 471] = {UINT64_C(0x0000006100000309), RUNE_C(0x001EA3)}, + [ 473] = {UINT64_C(0x00001FBF00000342), RUNE_C(0x001FCF)}, + [ 475] = {UINT64_C(0x000000750000030C), RUNE_C(0x0001D4)}, + [ 478] = {UINT64_C(0x00001F0800000345), RUNE_C(0x001F88)}, + [ 479] = {UINT64_C(0x000003BF00000300), RUNE_C(0x001F78)}, + [ 481] = {UINT64_C(0x0000226400000338), RUNE_C(0x002270)}, + [ 482] = {UINT64_C(0x0000007400000308), RUNE_C(0x001E97)}, + [ 483] = {UINT64_C(0x0000043800000308), RUNE_C(0x0004E5)}, + [ 484] = {UINT64_C(0x0000006500000300), RUNE_C(0x0000E8)}, + [ 487] = {UINT64_C(0x0000007300000301), RUNE_C(0x00015B)}, + [ 488] = {UINT64_C(0x000003CB00000342), RUNE_C(0x001FE7)}, + [ 491] = {UINT64_C(0x000003C900000314), RUNE_C(0x001F61)}, + [ 492] = {UINT64_C(0x0000005500000302), RUNE_C(0x0000DB)}, + [ 496] = {UINT64_C(0x0000041500000306), RUNE_C(0x0004D6)}, + [ 497] = {UINT64_C(0x0000045600000308), RUNE_C(0x000457)}, + [ 500] = {UINT64_C(0x00001B4200001B35), RUNE_C(0x001B43)}, + [ 502] = {UINT64_C(0x00001F6200000345), RUNE_C(0x001FA2)}, + [ 503] = {UINT64_C(0x000000640000030C), RUNE_C(0x00010F)}, + [ 504] = {UINT64_C(0x00000B4700000B57), RUNE_C(0x000B4C)}, + [ 507] = {UINT64_C(0x0000039900000304), RUNE_C(0x001FD9)}, + [ 508] = {UINT64_C(0x0000007900000307), RUNE_C(0x001E8F)}, + [ 509] = {UINT64_C(0x000004D800000308), RUNE_C(0x0004DA)}, + [ 511] = {UINT64_C(0x0000006900000306), RUNE_C(0x00012D)}, + [ 513] = {UINT64_C(0x000000D400000303), RUNE_C(0x001ED6)}, + [ 514] = {UINT64_C(0x0000006100000328), RUNE_C(0x000105)}, + [ 517] = {UINT64_C(0x0000006900000309), RUNE_C(0x001EC9)}, + [ 520] = {UINT64_C(0x0000039900000308), RUNE_C(0x0003AA)}, + [ 521] = {UINT64_C(0x0000005500000324), RUNE_C(0x001E72)}, + [ 529] = {UINT64_C(0x000000680000030C), RUNE_C(0x00021F)}, + [ 530] = {UINT64_C(0x0000043600000308), RUNE_C(0x0004DD)}, + [ 531] = {UINT64_C(0x00001F2100000301), RUNE_C(0x001F25)}, + [ 534] = {UINT64_C(0x00001B3C00001B35), RUNE_C(0x001B3D)}, + [ 537] = {UINT64_C(0x0000042300000308), RUNE_C(0x0004F0)}, + [ 541] = {UINT64_C(0x0000007700000323), RUNE_C(0x001E89)}, + [ 542] = {UINT64_C(0x000000E200000309), RUNE_C(0x001EA9)}, + [ 547] = {UINT64_C(0x000030D800003099), RUNE_C(0x0030D9)}, + [ 548] = {UINT64_C(0x0000305F00003099), RUNE_C(0x003060)}, + [ 549] = {UINT64_C(0x00001F0000000300), RUNE_C(0x001F02)}, + [ 550] = {UINT64_C(0x00001FFE00000300), RUNE_C(0x001FDD)}, + [ 553] = {UINT64_C(0x000001AF00000301), RUNE_C(0x001EE8)}, + [ 554] = {UINT64_C(0x0000007300000307), RUNE_C(0x001E61)}, + [ 556] = {UINT64_C(0x00001F2800000345), RUNE_C(0x001F98)}, + [ 558] = {UINT64_C(0x0000007000000307), RUNE_C(0x001E57)}, + [ 562] = {UINT64_C(0x0000007700000300), RUNE_C(0x001E81)}, + [ 563] = {UINT64_C(0x0000007500000308), RUNE_C(0x0000FC)}, + [ 566] = {UINT64_C(0x0000006F00000300), RUNE_C(0x0000F2)}, + [ 567] = {UINT64_C(0x000000D800000301), RUNE_C(0x0001FE)}, + [ 568] = {UINT64_C(0x000000C200000303), RUNE_C(0x001EAA)}, + [ 572] = {UINT64_C(0x0000005200000311), RUNE_C(0x000212)}, + [ 573] = {UINT64_C(0x0000007500000306), RUNE_C(0x00016D)}, + [ 576] = {UINT64_C(0x0000227A00000338), RUNE_C(0x002280)}, + [ 577] = {UINT64_C(0x0000005A00000301), RUNE_C(0x000179)}, + [ 579] = {UINT64_C(0x0000039900000301), RUNE_C(0x00038A)}, + [ 586] = {UINT64_C(0x0000006500000302), RUNE_C(0x0000EA)}, + [ 587] = {UINT64_C(0x00001F6900000300), RUNE_C(0x001F6B)}, + [ 588] = {UINT64_C(0x000000D500000304), RUNE_C(0x00022C)}, + [ 589] = {UINT64_C(0x000000EA00000301), RUNE_C(0x001EBF)}, + [ 591] = {UINT64_C(0x00001F6900000301), RUNE_C(0x001F6D)}, + [ 592] = {UINT64_C(0x0000305700003099), RUNE_C(0x003058)}, + [ 593] = {UINT64_C(0x000000D400000300), RUNE_C(0x001ED2)}, + [ 594] = {UINT64_C(0x000000720000030F), RUNE_C(0x000211)}, + [ 595] = {UINT64_C(0x000000FC0000030C), RUNE_C(0x0001DA)}, + [ 596] = {UINT64_C(0x000030AF00003099), RUNE_C(0x0030B0)}, + [ 598] = {UINT64_C(0x000000520000030F), RUNE_C(0x000210)}, + [ 601] = {UINT64_C(0x0000039F00000314), RUNE_C(0x001F49)}, + [ 605] = {UINT64_C(0x00001F1900000301), RUNE_C(0x001F1D)}, + [ 607] = {UINT64_C(0x0000004800000302), RUNE_C(0x000124)}, + [ 608] = {UINT64_C(0x0000006900000300), RUNE_C(0x0000EC)}, + [ 617] = {UINT64_C(0x000000520000030C), RUNE_C(0x000158)}, + [ 624] = {UINT64_C(0x0000007500000324), RUNE_C(0x001E73)}, + [ 628] = {UINT64_C(0x0000005500000306), RUNE_C(0x00016C)}, + [ 633] = {UINT64_C(0x00001F0900000300), RUNE_C(0x001F0B)}, + [ 634] = {UINT64_C(0x0000006400000307), RUNE_C(0x001E0B)}, + [ 635] = {UINT64_C(0x000113470001133E), RUNE_C(0x01134B)}, + [ 640] = {UINT64_C(0x0000006400000323), RUNE_C(0x001E0D)}, + [ 645] = {UINT64_C(0x0000005A00000302), RUNE_C(0x001E90)}, + [ 647] = {UINT64_C(0x00001F3100000300), RUNE_C(0x001F33)}, + [ 649] = {UINT64_C(0x00001F3900000301), RUNE_C(0x001F3D)}, + [ 651] = {UINT64_C(0x0000005900000301), RUNE_C(0x0000DD)}, + [ 654] = {UINT64_C(0x0000305500003099), RUNE_C(0x003056)}, + [ 656] = {UINT64_C(0x0001109B000110BA), RUNE_C(0x01109C)}, + [ 658] = {UINT64_C(0x0000005900000304), RUNE_C(0x000232)}, + [ 659] = {UINT64_C(0x0000305B00003099), RUNE_C(0x00305C)}, + [ 660] = {UINT64_C(0x0000005A0000030C), RUNE_C(0x00017D)}, + [ 661] = {UINT64_C(0x000003A500000308), RUNE_C(0x0003AB)}, + [ 663] = {UINT64_C(0x0000004100000308), RUNE_C(0x0000C4)}, + [ 664] = {UINT64_C(0x0000007700000301), RUNE_C(0x001E83)}, + [ 666] = {UINT64_C(0x00001B3E00001B35), RUNE_C(0x001B40)}, + [ 667] = {UINT64_C(0x00001F2D00000345), RUNE_C(0x001F9D)}, + [ 670] = {UINT64_C(0x00001B3A00001B35), RUNE_C(0x001B3B)}, + [ 671] = {UINT64_C(0x000000610000030A), RUNE_C(0x0000E5)}, + [ 672] = {UINT64_C(0x0001113200011127), RUNE_C(0x01112F)}, + [ 673] = {UINT64_C(0x0000306400003099), RUNE_C(0x003065)}, + [ 676] = {UINT64_C(0x000003B500000313), RUNE_C(0x001F10)}, + [ 677] = {UINT64_C(0x000030CF00003099), RUNE_C(0x0030D0)}, + [ 682] = {UINT64_C(0x000003B900000301), RUNE_C(0x0003AF)}, + [ 684] = {UINT64_C(0x0000039900000313), RUNE_C(0x001F38)}, + [ 687] = {UINT64_C(0x000030B900003099), RUNE_C(0x0030BA)}, + [ 689] = {UINT64_C(0x0000004700000306), RUNE_C(0x00011E)}, + [ 691] = {UINT64_C(0x0000004E00000300), RUNE_C(0x0001F8)}, + [ 692] = {UINT64_C(0x00001B0500001B35), RUNE_C(0x001B06)}, + [ 693] = {UINT64_C(0x0000007900000309), RUNE_C(0x001EF7)}, + [ 700] = {UINT64_C(0x0000220800000338), RUNE_C(0x002209)}, + [ 702] = {UINT64_C(0x0000016800000301), RUNE_C(0x001E78)}, + [ 704] = {UINT64_C(0x000000640000032D), RUNE_C(0x001E13)}, + [ 705] = {UINT64_C(0x0000005A00000307), RUNE_C(0x00017B)}, + [ 706] = {UINT64_C(0x0000004900000304), RUNE_C(0x00012A)}, + [ 713] = {UINT64_C(0x000003B900000306), RUNE_C(0x001FD0)}, + [ 714] = {UINT64_C(0x0000004F0000030F), RUNE_C(0x00020C)}, + [ 715] = {UINT64_C(0x0000004F00000306), RUNE_C(0x00014E)}, + [ 720] = {UINT64_C(0x00001F2000000342), RUNE_C(0x001F26)}, + [ 721] = {UINT64_C(0x0000041300000301), RUNE_C(0x000403)}, + [ 723] = {UINT64_C(0x000006C100000654), RUNE_C(0x0006C2)}, + [ 726] = {UINT64_C(0x000000790000030A), RUNE_C(0x001E99)}, + [ 727] = {UINT64_C(0x0000014C00000300), RUNE_C(0x001E50)}, + [ 729] = {UINT64_C(0x000003CB00000301), RUNE_C(0x0003B0)}, + [ 731] = {UINT64_C(0x00000C4600000C56), RUNE_C(0x000C48)}, + [ 732] = {UINT64_C(0x0000006900000304), RUNE_C(0x00012B)}, + [ 736] = {UINT64_C(0x00001F4900000300), RUNE_C(0x001F4B)}, + [ 737] = {UINT64_C(0x0000004100000300), RUNE_C(0x0000C0)}, + [ 741] = {UINT64_C(0x0000006300000307), RUNE_C(0x00010B)}, + [ 742] = {UINT64_C(0x000000680000032E), RUNE_C(0x001E2B)}, + [ 743] = {UINT64_C(0x00001F2100000300), RUNE_C(0x001F23)}, + [ 747] = {UINT64_C(0x0000004500000306), RUNE_C(0x000114)}, + [ 750] = {UINT64_C(0x000000EA00000303), RUNE_C(0x001EC5)}, + [ 753] = {UINT64_C(0x0000007700000308), RUNE_C(0x001E85)}, + [ 756] = {UINT64_C(0x000021D000000338), RUNE_C(0x0021CD)}, + [ 763] = {UINT64_C(0x0000004B00000301), RUNE_C(0x001E30)}, + [ 766] = {UINT64_C(0x0000015A00000307), RUNE_C(0x001E64)}, + [ 770] = {UINT64_C(0x00000B4700000B3E), RUNE_C(0x000B4B)}, + [ 771] = {UINT64_C(0x0000006800000331), RUNE_C(0x001E96)}, + [ 772] = {UINT64_C(0x00001F1100000301), RUNE_C(0x001F15)}, + [ 773] = {UINT64_C(0x0000006F0000030C), RUNE_C(0x0001D2)}, + [ 774] = {UINT64_C(0x000003CE00000345), RUNE_C(0x001FF4)}, + [ 777] = {UINT64_C(0x00001F2F00000345), RUNE_C(0x001F9F)}, + [ 778] = {UINT64_C(0x0000004100000309), RUNE_C(0x001EA2)}, + [ 781] = {UINT64_C(0x0000006900000303), RUNE_C(0x000129)}, + [ 785] = {UINT64_C(0x000001B70000030C), RUNE_C(0x0001EE)}, + [ 788] = {UINT64_C(0x00001F6000000345), RUNE_C(0x001FA0)}, + [ 789] = {UINT64_C(0x0000041000000306), RUNE_C(0x0004D0)}, + [ 790] = {UINT64_C(0x0000006E00000307), RUNE_C(0x001E45)}, + [ 792] = {UINT64_C(0x000003B900000342), RUNE_C(0x001FD6)}, + [ 794] = {UINT64_C(0x000021D400000338), RUNE_C(0x0021CE)}, + [ 798] = {UINT64_C(0x0000007A00000302), RUNE_C(0x001E91)}, + [ 799] = {UINT64_C(0x000022B500000338), RUNE_C(0x0022ED)}, + [ 800] = {UINT64_C(0x0000006100000323), RUNE_C(0x001EA1)}, + [ 804] = {UINT64_C(0x000003A500000304), RUNE_C(0x001FE9)}, + [ 806] = {UINT64_C(0x000003CA00000342), RUNE_C(0x001FD7)}, + [ 807] = {UINT64_C(0x000000530000030C), RUNE_C(0x000160)}, + [ 808] = {UINT64_C(0x00001F5900000342), RUNE_C(0x001F5F)}, + [ 812] = {UINT64_C(0x0000306F00003099), RUNE_C(0x003070)}, + [ 815] = {UINT64_C(0x0000006100000307), RUNE_C(0x000227)}, + [ 819] = {UINT64_C(0x000003B900000300), RUNE_C(0x001F76)}, + [ 820] = {UINT64_C(0x000030B700003099), RUNE_C(0x0030B8)}, + [ 821] = {UINT64_C(0x0000006900000328), RUNE_C(0x00012F)}, + [ 825] = {UINT64_C(0x000022A900000338), RUNE_C(0x0022AE)}, + [ 830] = {UINT64_C(0x000003BF00000313), RUNE_C(0x001F40)}, + [ 832] = {UINT64_C(0x0000007A00000331), RUNE_C(0x001E95)}, + [ 833] = {UINT64_C(0x0000007500000301), RUNE_C(0x0000FA)}, + [ 836] = {UINT64_C(0x0000041000000308), RUNE_C(0x0004D2)}, + [ 837] = {UINT64_C(0x000030C800003099), RUNE_C(0x0030C9)}, + [ 839] = {UINT64_C(0x0000004800000308), RUNE_C(0x001E26)}, + [ 842] = {UINT64_C(0x0000004300000307), RUNE_C(0x00010A)}, + [ 846] = {UINT64_C(0x0000006A0000030C), RUNE_C(0x0001F0)}, + [ 847] = {UINT64_C(0x0000043500000308), RUNE_C(0x000451)}, + [ 849] = {UINT64_C(0x0001113100011127), RUNE_C(0x01112E)}, + [ 852] = {UINT64_C(0x0000007200000301), RUNE_C(0x000155)}, + [ 855] = {UINT64_C(0x0000006E0000030C), RUNE_C(0x000148)}, + [ 859] = {UINT64_C(0x0000043A00000301), RUNE_C(0x00045C)}, + [ 860] = {UINT64_C(0x0000039700000314), RUNE_C(0x001F29)}, + [ 861] = {UINT64_C(0x000003C900000345), RUNE_C(0x001FF3)}, + [ 862] = {UINT64_C(0x0000042300000304), RUNE_C(0x0004EE)}, + [ 863] = {UINT64_C(0x0000005500000308), RUNE_C(0x0000DC)}, + [ 867] = {UINT64_C(0x000030D50000309A), RUNE_C(0x0030D7)}, + [ 876] = {UINT64_C(0x0000004500000308), RUNE_C(0x0000CB)}, + [ 878] = {UINT64_C(0x00001F1900000300), RUNE_C(0x001F1B)}, + [ 880] = {UINT64_C(0x0000006E00000300), RUNE_C(0x0001F9)}, + [ 883] = {UINT64_C(0x000030BB00003099), RUNE_C(0x0030BC)}, + [ 890] = {UINT64_C(0x0000004E00000327), RUNE_C(0x000145)}, + [ 891] = {UINT64_C(0x000003B100000314), RUNE_C(0x001F01)}, + [ 892] = {UINT64_C(0x00001FC600000345), RUNE_C(0x001FC7)}, + [ 893] = {UINT64_C(0x0000307800003099), RUNE_C(0x003079)}, + [ 894] = {UINT64_C(0x0000007800000308), RUNE_C(0x001E8D)}, + [ 900] = {UINT64_C(0x000030B300003099), RUNE_C(0x0030B4)}, + [ 904] = {UINT64_C(0x000000E600000304), RUNE_C(0x0001E3)}, + [ 905] = {UINT64_C(0x00001F3800000301), RUNE_C(0x001F3C)}, + [ 906] = {UINT64_C(0x00001F2800000342), RUNE_C(0x001F2E)}, + [ 907] = {UINT64_C(0x00001EA100000302), RUNE_C(0x001EAD)}, + [ 914] = {UINT64_C(0x00001F3000000301), RUNE_C(0x001F34)}, + [ 915] = {UINT64_C(0x0000004900000311), RUNE_C(0x00020A)}, + [ 917] = {UINT64_C(0x000001B000000323), RUNE_C(0x001EF1)}, + [ 918] = {UINT64_C(0x00000BC600000BBE), RUNE_C(0x000BCA)}, + [ 920] = {UINT64_C(0x0000006F0000031B), RUNE_C(0x0001A1)}, + [ 922] = {UINT64_C(0x0000007500000311), RUNE_C(0x000217)}, + [ 925] = {UINT64_C(0x000114B9000114BA), RUNE_C(0x0114BB)}, + [ 930] = {UINT64_C(0x0000007400000323), RUNE_C(0x001E6D)}, + [ 931] = {UINT64_C(0x000001AF00000309), RUNE_C(0x001EEC)}, + [ 932] = {UINT64_C(0x0000039100000345), RUNE_C(0x001FBC)}, + [ 935] = {UINT64_C(0x0000007200000331), RUNE_C(0x001E5F)}, + [ 939] = {UINT64_C(0x000000740000032D), RUNE_C(0x001E71)}, + [ 940] = {UINT64_C(0x000000C600000301), RUNE_C(0x0001FC)}, + [ 942] = {UINT64_C(0x000003A500000306), RUNE_C(0x001FE8)}, + [ 944] = {UINT64_C(0x0000006900000308), RUNE_C(0x0000EF)}, + [ 950] = {UINT64_C(0x0000006C00000331), RUNE_C(0x001E3B)}, + [ 954] = {UINT64_C(0x0000016A00000308), RUNE_C(0x001E7A)}, + [ 956] = {UINT64_C(0x0000041500000308), RUNE_C(0x000401)}, + [ 958] = {UINT64_C(0x0000007200000307), RUNE_C(0x001E59)}, + [ 959] = {UINT64_C(0x0000222500000338), RUNE_C(0x002226)}, + [ 961] = {UINT64_C(0x000000410000030A), RUNE_C(0x0000C5)}, + [ 962] = {UINT64_C(0x000000750000030F), RUNE_C(0x000215)}, + [ 965] = {UINT64_C(0x0000017F00000307), RUNE_C(0x001E9B)}, + [ 967] = {UINT64_C(0x000000410000030F), RUNE_C(0x000200)}, + [ 972] = {UINT64_C(0x0000007A00000301), RUNE_C(0x00017A)}, + [ 973] = {UINT64_C(0x0000039F00000313), RUNE_C(0x001F48)}, + [ 975] = {UINT64_C(0x000003B100000300), RUNE_C(0x001F70)}, + [ 977] = {UINT64_C(0x0000006F00000307), RUNE_C(0x00022F)}, + [ 979] = {UINT64_C(0x000003C900000301), RUNE_C(0x0003CE)}, + [ 981] = {UINT64_C(0x000003A900000313), RUNE_C(0x001F68)}, + [ 982] = {UINT64_C(0x0000005A00000331), RUNE_C(0x001E94)}, + [ 983] = {UINT64_C(0x0000039100000300), RUNE_C(0x001FBA)}, + [ 984] = {UINT64_C(0x00001FFE00000301), RUNE_C(0x001FDE)}, + [ 985] = {UINT64_C(0x000003B900000308), RUNE_C(0x0003CA)}, + [ 987] = {UINT64_C(0x0000007400000307), RUNE_C(0x001E6B)}, + [ 989] = {UINT64_C(0x00001E6300000307), RUNE_C(0x001E69)}, + [ 991] = {UINT64_C(0x00001F0500000345), RUNE_C(0x001F85)}, + [ 994] = {UINT64_C(0x0000006F00000306), RUNE_C(0x00014F)}, + [ 995] = {UINT64_C(0x000030CF0000309A), RUNE_C(0x0030D1)}, + [1000] = {UINT64_C(0x00001F2400000345), RUNE_C(0x001F94)}, + [1001] = {UINT64_C(0x0000062700000654), RUNE_C(0x000623)}, + [1004] = {UINT64_C(0x0000042300000306), RUNE_C(0x00040E)}, + [1008] = {UINT64_C(0x000030B500003099), RUNE_C(0x0030B6)}, + [1009] = {UINT64_C(0x00001F6800000300), RUNE_C(0x001F6A)}, + [1010] = {UINT64_C(0x0000004600000307), RUNE_C(0x001E1E)}, + [1011] = {UINT64_C(0x00001F0700000345), RUNE_C(0x001F87)}, + [1012] = {UINT64_C(0x000000610000030C), RUNE_C(0x0001CE)}, + [1013] = {UINT64_C(0x0000004400000327), RUNE_C(0x001E10)}, + [1014] = {UINT64_C(0x000000490000030C), RUNE_C(0x0001CF)}, + [1015] = {UINT64_C(0x00001ECD00000302), RUNE_C(0x001ED9)}, + [1018] = {UINT64_C(0x0001193500011930), RUNE_C(0x011938)}, + [1019] = {UINT64_C(0x000000F400000309), RUNE_C(0x001ED5)}, + [1020] = {UINT64_C(0x000021D200000338), RUNE_C(0x0021CF)}, + [1022] = {UINT64_C(0x000000440000032D), RUNE_C(0x001E12)}, + [1023] = {UINT64_C(0x0000004900000328), RUNE_C(0x00012E)}, + [1025] = {UINT64_C(0x00001FFE00000342), RUNE_C(0x001FDF)}, + [1026] = {UINT64_C(0x000000470000030C), RUNE_C(0x0001E6)}, + [1030] = {UINT64_C(0x0000039100000313), RUNE_C(0x001F08)}, + [1031] = {UINT64_C(0x0000007300000302), RUNE_C(0x00015D)}, + [1034] = {UINT64_C(0x0000005300000327), RUNE_C(0x00015E)}, + [1035] = {UINT64_C(0x0000004700000302), RUNE_C(0x00011C)}, + [1038] = {UINT64_C(0x000000E400000304), RUNE_C(0x0001DF)}, + [1039] = {UINT64_C(0x0000005900000300), RUNE_C(0x001EF2)}, + [1040] = {UINT64_C(0x00001FB600000345), RUNE_C(0x001FB7)}, + [1042] = {UINT64_C(0x0000062700000655), RUNE_C(0x000625)}, + [1043] = {UINT64_C(0x0000004400000331), RUNE_C(0x001E0E)}, + [1044] = {UINT64_C(0x000000F400000300), RUNE_C(0x001ED3)}, + [1045] = {UINT64_C(0x000000550000030F), RUNE_C(0x000214)}, + [1046] = {UINT64_C(0x0000006300000327), RUNE_C(0x0000E7)}, + [1048] = {UINT64_C(0x0000004100000301), RUNE_C(0x0000C1)}, + [1050] = {UINT64_C(0x0000004F00000303), RUNE_C(0x0000D5)}, + [1051] = {UINT64_C(0x00001F3100000301), RUNE_C(0x001F35)}, + [1053] = {UINT64_C(0x00001F2E00000345), RUNE_C(0x001F9E)}, + [1054] = {UINT64_C(0x00001F0A00000345), RUNE_C(0x001F8A)}, + [1055] = {UINT64_C(0x00000B4700000B56), RUNE_C(0x000B48)}, + [1056] = {UINT64_C(0x000030D80000309A), RUNE_C(0x0030DA)}, + [1058] = {UINT64_C(0x000001A000000301), RUNE_C(0x001EDA)}, + [1060] = {UINT64_C(0x000000DC00000304), RUNE_C(0x0001D5)}, + [1062] = {UINT64_C(0x0000005700000301), RUNE_C(0x001E82)}, + [1066] = {UINT64_C(0x000000730000030C), RUNE_C(0x000161)}, + [1067] = {UINT64_C(0x0000007500000302), RUNE_C(0x0000FB)}, + [1068] = {UINT64_C(0x000030AD00003099), RUNE_C(0x0030AE)}, + [1070] = {UINT64_C(0x0000039700000345), RUNE_C(0x001FCC)}, + [1072] = {UINT64_C(0x0000005200000327), RUNE_C(0x000156)}, + [1075] = {UINT64_C(0x0000014D00000301), RUNE_C(0x001E53)}, + [1077] = {UINT64_C(0x000003B500000301), RUNE_C(0x0003AD)}, + [1078] = {UINT64_C(0x00000CBF00000CD5), RUNE_C(0x000CC0)}, + [1080] = {UINT64_C(0x000004D900000308), RUNE_C(0x0004DB)}, + [1083] = {UINT64_C(0x000003A500000314), RUNE_C(0x001F59)}, + [1085] = {UINT64_C(0x0000006A00000302), RUNE_C(0x000135)}, + [1086] = {UINT64_C(0x00001F2000000300), RUNE_C(0x001F22)}, + [1087] = {UINT64_C(0x00001F3100000342), RUNE_C(0x001F37)}, + [1089] = {UINT64_C(0x00001F0100000342), RUNE_C(0x001F07)}, + [1090] = {UINT64_C(0x0000007200000323), RUNE_C(0x001E5B)}, + [1091] = {UINT64_C(0x0000006E00000323), RUNE_C(0x001E47)}, + [1092] = {UINT64_C(0x00001F4000000301), RUNE_C(0x001F44)}, + [1093] = {UINT64_C(0x000003A900000301), RUNE_C(0x00038F)}, + [1095] = {UINT64_C(0x000000EF00000301), RUNE_C(0x001E2F)}, + [1100] = {UINT64_C(0x0000039F00000300), RUNE_C(0x001FF8)}, + [1104] = {UINT64_C(0x0000006100000308), RUNE_C(0x0000E4)}, + [1105] = {UINT64_C(0x0000003C00000338), RUNE_C(0x00226E)}, + [1109] = {UINT64_C(0x0000006B00000327), RUNE_C(0x000137)}, + [1110] = {UINT64_C(0x00001F3000000342), RUNE_C(0x001F36)}, + [1112] = {UINT64_C(0x0000004E00000331), RUNE_C(0x001E48)}, + [1113] = {UINT64_C(0x00001EB800000302), RUNE_C(0x001EC6)}, + [1114] = {UINT64_C(0x000003B900000314), RUNE_C(0x001F31)}, + [1115] = {UINT64_C(0x0000006500000308), RUNE_C(0x0000EB)}, + [1116] = {UINT64_C(0x000000C200000300), RUNE_C(0x001EA6)}, + [1117] = {UINT64_C(0x000003A500000300), RUNE_C(0x001FEA)}, + [1118] = {UINT64_C(0x000004430000030B), RUNE_C(0x0004F3)}, + [1120] = {UINT64_C(0x000001AF00000323), RUNE_C(0x001EF0)}, + [1123] = {UINT64_C(0x000000440000030C), RUNE_C(0x00010E)}, + [1127] = {UINT64_C(0x000114B9000114B0), RUNE_C(0x0114BC)}, + [1128] = {UINT64_C(0x0000043300000301), RUNE_C(0x000453)}, + [1129] = {UINT64_C(0x000030C100003099), RUNE_C(0x0030C2)}, + [1130] = {UINT64_C(0x000000F400000303), RUNE_C(0x001ED7)}, + [1136] = {UINT64_C(0x0000005200000323), RUNE_C(0x001E5A)}, + [1137] = {UINT64_C(0x000001B000000303), RUNE_C(0x001EEF)}, + [1140] = {UINT64_C(0x0000005700000323), RUNE_C(0x001E88)}, + [1141] = {UINT64_C(0x0000004900000302), RUNE_C(0x0000CE)}, + [1144] = {UINT64_C(0x00001F0F00000345), RUNE_C(0x001F8F)}, + [1146] = {UINT64_C(0x000000650000030F), RUNE_C(0x000205)}, + [1147] = {UINT64_C(0x0000005900000303), RUNE_C(0x001EF8)}, + [1148] = {UINT64_C(0x00001F6000000301), RUNE_C(0x001F64)}, + [1150] = {UINT64_C(0x0000007500000304), RUNE_C(0x00016B)}, + [1151] = {UINT64_C(0x0000039100000304), RUNE_C(0x001FB9)}, + [1154] = {UINT64_C(0x00001E6200000307), RUNE_C(0x001E68)}, + [1158] = {UINT64_C(0x00001F2000000301), RUNE_C(0x001F24)}, + [1160] = {UINT64_C(0x000001A000000300), RUNE_C(0x001EDC)}, + [1161] = {UINT64_C(0x0000006C00000327), RUNE_C(0x00013C)}, + [1164] = {UINT64_C(0x000000C200000301), RUNE_C(0x001EA4)}, + [1165] = {UINT64_C(0x000001A100000323), RUNE_C(0x001EE3)}, + [1166] = {UINT64_C(0x0000006C00000301), RUNE_C(0x00013A)}, + [1167] = {UINT64_C(0x0000004E0000032D), RUNE_C(0x001E4A)}, + [1169] = {UINT64_C(0x00001F0900000345), RUNE_C(0x001F89)}, + [1171] = {UINT64_C(0x0000227300000338), RUNE_C(0x002275)}, + [1176] = {UINT64_C(0x000003C500000301), RUNE_C(0x0003CD)}, + [1179] = {UINT64_C(0x0000042B00000308), RUNE_C(0x0004F8)}, + [1180] = {UINT64_C(0x0000022800000306), RUNE_C(0x001E1C)}, + [1184] = {UINT64_C(0x00001F2700000345), RUNE_C(0x001F97)}, + [1186] = {UINT64_C(0x0000006800000327), RUNE_C(0x001E29)}, + [1189] = {UINT64_C(0x000000A800000342), RUNE_C(0x001FC1)}, + [1192] = {UINT64_C(0x0000022E00000304), RUNE_C(0x000230)}, + [1194] = {UINT64_C(0x00001F0900000301), RUNE_C(0x001F0D)}, + [1197] = {UINT64_C(0x000000480000030C), RUNE_C(0x00021E)}, + [1198] = {UINT64_C(0x000030FD00003099), RUNE_C(0x0030FE)}, + [1199] = {UINT64_C(0x0000004500000302), RUNE_C(0x0000CA)}, + [1201] = {UINT64_C(0x0000005600000303), RUNE_C(0x001E7C)}, + [1202] = {UINT64_C(0x0000005A00000323), RUNE_C(0x001E92)}, + [1205] = {UINT64_C(0x0000039700000300), RUNE_C(0x001FCA)}, + [1209] = {UINT64_C(0x0000306100003099), RUNE_C(0x003062)}, + [1212] = {UINT64_C(0x0000022700000304), RUNE_C(0x0001E1)}, + [1214] = {UINT64_C(0x0000004E00000307), RUNE_C(0x001E44)}, + [1216] = {UINT64_C(0x0000016900000301), RUNE_C(0x001E79)}, + [1217] = {UINT64_C(0x0000016000000307), RUNE_C(0x001E66)}, + [1219] = {UINT64_C(0x000001EA00000304), RUNE_C(0x0001EC)}, + [1224] = {UINT64_C(0x00000D4700000D3E), RUNE_C(0x000D4B)}, + [1225] = {UINT64_C(0x000009C7000009BE), RUNE_C(0x0009CB)}, + [1227] = {UINT64_C(0x0000007200000327), RUNE_C(0x000157)}, + [1228] = {UINT64_C(0x00001F2300000345), RUNE_C(0x001F93)}, + [1231] = {UINT64_C(0x000000EA00000309), RUNE_C(0x001EC3)}, + [1234] = {UINT64_C(0x000030D20000309A), RUNE_C(0x0030D4)}, + [1235] = {UINT64_C(0x000030F000003099), RUNE_C(0x0030F8)}, + [1237] = {UINT64_C(0x0000007500000323), RUNE_C(0x001EE5)}, + [1238] = {UINT64_C(0x00001F6800000301), RUNE_C(0x001F6C)}, + [1239] = {UINT64_C(0x00001F6800000345), RUNE_C(0x001FA8)}, + [1240] = {UINT64_C(0x0000006C0000032D), RUNE_C(0x001E3D)}, + [1242] = {UINT64_C(0x000000C600000304), RUNE_C(0x0001E2)}, + [1243] = {UINT64_C(0x0000004500000328), RUNE_C(0x000118)}, + [1244] = {UINT64_C(0x000000550000030C), RUNE_C(0x0001D3)}, + [1245] = {UINT64_C(0x0000004500000304), RUNE_C(0x000112)}, + [1248] = {UINT64_C(0x000030D500003099), RUNE_C(0x0030D6)}, + [1253] = {UINT64_C(0x0000004400000307), RUNE_C(0x001E0A)}, + [1255] = {UINT64_C(0x0000005400000307), RUNE_C(0x001E6A)}, + [1256] = {UINT64_C(0x00001ECC00000302), RUNE_C(0x001ED8)}, + [1257] = {UINT64_C(0x0000005900000307), RUNE_C(0x001E8E)}, + [1258] = {UINT64_C(0x0000004200000307), RUNE_C(0x001E02)}, + [1261] = {UINT64_C(0x0000007600000303), RUNE_C(0x001E7D)}, + [1265] = {UINT64_C(0x0000228700000338), RUNE_C(0x002289)}, + [1266] = {UINT64_C(0x0000004500000301), RUNE_C(0x0000C9)}, + [1269] = {UINT64_C(0x0000004500000311), RUNE_C(0x000206)}, + [1270] = {UINT64_C(0x00001F1000000301), RUNE_C(0x001F14)}, + [1274] = {UINT64_C(0x0000306800003099), RUNE_C(0x003069)}, + [1277] = {UINT64_C(0x0000227B00000338), RUNE_C(0x002281)}, + [1279] = {UINT64_C(0x000000450000030C), RUNE_C(0x00011A)}, + [1282] = {UINT64_C(0x0000004900000301), RUNE_C(0x0000CD)}, + [1284] = {UINT64_C(0x0000041700000308), RUNE_C(0x0004DE)}, + [1289] = {UINT64_C(0x0000044D00000308), RUNE_C(0x0004ED)}, + [1290] = {UINT64_C(0x0000005200000307), RUNE_C(0x001E58)}, + [1291] = {UINT64_C(0x0000039100000306), RUNE_C(0x001FB8)}, + [1292] = {UINT64_C(0x0000006F00000311), RUNE_C(0x00020F)}, + [1295] = {UINT64_C(0x000003AE00000345), RUNE_C(0x001FC4)}, + [1298] = {UINT64_C(0x0000004100000307), RUNE_C(0x000226)}, + [1302] = {UINT64_C(0x0000227700000338), RUNE_C(0x002279)}, + [1303] = {UINT64_C(0x00001E5B00000304), RUNE_C(0x001E5D)}, + [1304] = {UINT64_C(0x00001F5000000301), RUNE_C(0x001F54)}, + [1305] = {UINT64_C(0x000003B100000313), RUNE_C(0x001F00)}, + [1306] = {UINT64_C(0x0000043800000306), RUNE_C(0x000439)}, + [1311] = {UINT64_C(0x0000022600000304), RUNE_C(0x0001E0)}, + [1312] = {UINT64_C(0x0000005500000328), RUNE_C(0x000172)}, + [1316] = {UINT64_C(0x000030BF00003099), RUNE_C(0x0030C0)}, + [1318] = {UINT64_C(0x0000004E00000323), RUNE_C(0x001E46)}, + [1321] = {UINT64_C(0x0000010200000303), RUNE_C(0x001EB4)}, + [1325] = {UINT64_C(0x000003C500000306), RUNE_C(0x001FE0)}, + [1329] = {UINT64_C(0x0000005500000309), RUNE_C(0x001EE6)}, + [1332] = {UINT64_C(0x00000DD900000DDF), RUNE_C(0x000DDE)}, + [1333] = {UINT64_C(0x0000006500000309), RUNE_C(0x001EBB)}, + [1336] = {UINT64_C(0x0000004500000303), RUNE_C(0x001EBC)}, + [1337] = {UINT64_C(0x0000043E00000308), RUNE_C(0x0004E7)}, + [1339] = {UINT64_C(0x0000006F00000308), RUNE_C(0x0000F6)}, + [1340] = {UINT64_C(0x000006D200000654), RUNE_C(0x0006D3)}, + [1344] = {UINT64_C(0x00001F6100000300), RUNE_C(0x001F63)}, + [1347] = {UINT64_C(0x0000044B00000308), RUNE_C(0x0004F9)}, + [1348] = {UINT64_C(0x000022A800000338), RUNE_C(0x0022AD)}, + [1352] = {UINT64_C(0x000000FC00000304), RUNE_C(0x0001D6)}, + [1354] = {UINT64_C(0x000000F400000301), RUNE_C(0x001ED1)}, + [1356] = {UINT64_C(0x000001B000000300), RUNE_C(0x001EEB)}, + [1364] = {UINT64_C(0x000000650000032D), RUNE_C(0x001E19)}, + [1365] = {UINT64_C(0x0000007500000300), RUNE_C(0x0000F9)}, + [1366] = {UINT64_C(0x0000007900000302), RUNE_C(0x000177)}, + [1367] = {UINT64_C(0x0000004900000300), RUNE_C(0x0000CC)}, + [1368] = {UINT64_C(0x000030F200003099), RUNE_C(0x0030FA)}, + [1369] = {UINT64_C(0x0000004F00000300), RUNE_C(0x0000D2)}, + [1371] = {UINT64_C(0x00001F0800000342), RUNE_C(0x001F0E)}, + [1373] = {UINT64_C(0x000003CA00000301), RUNE_C(0x000390)}, + [1375] = {UINT64_C(0x0000004F0000030C), RUNE_C(0x0001D1)}, + [1376] = {UINT64_C(0x000000410000030C), RUNE_C(0x0001CD)}, + [1378] = {UINT64_C(0x000001A000000323), RUNE_C(0x001EE2)}, + [1380] = {UINT64_C(0x00001F4900000301), RUNE_C(0x001F4D)}, + [1381] = {UINT64_C(0x00001F2500000345), RUNE_C(0x001F95)}, + [1383] = {UINT64_C(0x0000006100000304), RUNE_C(0x000101)}, + [1384] = {UINT64_C(0x000000540000030C), RUNE_C(0x000164)}, + [1388] = {UINT64_C(0x0000006700000302), RUNE_C(0x00011D)}, + [1391] = {UINT64_C(0x0000004C0000030C), RUNE_C(0x00013D)}, + [1393] = {UINT64_C(0x00001F0400000345), RUNE_C(0x001F84)}, + [1395] = {UINT64_C(0x0000044700000308), RUNE_C(0x0004F5)}, + [1400] = {UINT64_C(0x0000006800000302), RUNE_C(0x000125)}, + [1404] = {UINT64_C(0x0000005500000323), RUNE_C(0x001EE4)}, + [1405] = {UINT64_C(0x000115B8000115AF), RUNE_C(0x0115BA)}, + [1408] = {UINT64_C(0x00001F2B00000345), RUNE_C(0x001F9B)}, + [1409] = {UINT64_C(0x00001F6C00000345), RUNE_C(0x001FAC)}, + [1410] = {UINT64_C(0x0000006F00000301), RUNE_C(0x0000F3)}, + [1412] = {UINT64_C(0x00000CC600000CD5), RUNE_C(0x000CC7)}, + [1413] = {UINT64_C(0x0000004900000307), RUNE_C(0x000130)}, + [1415] = {UINT64_C(0x0000304600003099), RUNE_C(0x003094)}, + [1419] = {UINT64_C(0x00001F5900000300), RUNE_C(0x001F5B)}, + [1420] = {UINT64_C(0x00001B1100001B35), RUNE_C(0x001B12)}, + [1421] = {UINT64_C(0x000030750000309A), RUNE_C(0x003077)}, + [1423] = {UINT64_C(0x0000229200000338), RUNE_C(0x0022E3)}, + [1427] = {UINT64_C(0x0000004F00000304), RUNE_C(0x00014C)}, + [1431] = {UINT64_C(0x0000006400000331), RUNE_C(0x001E0F)}, + [1433] = {UINT64_C(0x00001F6300000345), RUNE_C(0x001FA3)}, + [1445] = {UINT64_C(0x0000224300000338), RUNE_C(0x002244)}, + [1450] = {UINT64_C(0x000003C900000342), RUNE_C(0x001FF6)}, + [1451] = {UINT64_C(0x0000228200000338), RUNE_C(0x002284)}, + [1452] = {UINT64_C(0x000003D200000301), RUNE_C(0x0003D3)}, + [1456] = {UINT64_C(0x0000006F00000302), RUNE_C(0x0000F4)}, + [1458] = {UINT64_C(0x0000006100000325), RUNE_C(0x001E01)}, + [1459] = {UINT64_C(0x0000005000000307), RUNE_C(0x001E56)}, + [1460] = {UINT64_C(0x0000305900003099), RUNE_C(0x00305A)}, + [1461] = {UINT64_C(0x00001F5000000342), RUNE_C(0x001F56)}, + [1464] = {UINT64_C(0x000000CF00000301), RUNE_C(0x001E2E)}, + [1481] = {UINT64_C(0x0000006100000300), RUNE_C(0x0000E0)}, + [1482] = {UINT64_C(0x000000490000030F), RUNE_C(0x000208)}, + [1484] = {UINT64_C(0x00001F0100000301), RUNE_C(0x001F05)}, + [1485] = {UINT64_C(0x0000007300000327), RUNE_C(0x00015F)}, + [1487] = {UINT64_C(0x000000750000030B), RUNE_C(0x000171)}, + [1491] = {UINT64_C(0x0000007000000301), RUNE_C(0x001E55)}, + [1496] = {UINT64_C(0x0000062700000653), RUNE_C(0x000622)}, + [1498] = {UINT64_C(0x00001F0C00000345), RUNE_C(0x001F8C)}, + [1499] = {UINT64_C(0x000003AC00000345), RUNE_C(0x001FB4)}, + [1504] = {UINT64_C(0x0000005500000304), RUNE_C(0x00016A)}, + [1505] = {UINT64_C(0x0000039900000300), RUNE_C(0x001FDA)}, + [1506] = {UINT64_C(0x00001F2900000300), RUNE_C(0x001F2B)}, + [1516] = {UINT64_C(0x0000004F00000302), RUNE_C(0x0000D4)}, + [1517] = {UINT64_C(0x0000043000000306), RUNE_C(0x0004D1)}, + [1520] = {UINT64_C(0x0000010300000303), RUNE_C(0x001EB5)}, + [1523] = {UINT64_C(0x0000006F0000030F), RUNE_C(0x00020D)}, + [1524] = {UINT64_C(0x0001134700011357), RUNE_C(0x01134C)}, + [1528] = {UINT64_C(0x0000007900000308), RUNE_C(0x0000FF)}, + [1531] = {UINT64_C(0x0000305300003099), RUNE_C(0x003054)}, + [1533] = {UINT64_C(0x000003A900000345), RUNE_C(0x001FFC)}, + [1537] = {UINT64_C(0x0000004500000309), RUNE_C(0x001EBA)}, + [1540] = {UINT64_C(0x0000005900000323), RUNE_C(0x001EF4)}, + [1541] = {UINT64_C(0x00001F6A00000345), RUNE_C(0x001FAA)}, + [1542] = {UINT64_C(0x000000EA00000300), RUNE_C(0x001EC1)}, + [1543] = {UINT64_C(0x00001F6400000345), RUNE_C(0x001FA4)}, + [1544] = {UINT64_C(0x0000039500000314), RUNE_C(0x001F19)}, + [1546] = {UINT64_C(0x0000042D00000308), RUNE_C(0x0004EC)}, + [1549] = {UINT64_C(0x0000006700000304), RUNE_C(0x001E21)}, + [1551] = {UINT64_C(0x0000004D00000307), RUNE_C(0x001E40)}, + [1552] = {UINT64_C(0x000000D500000301), RUNE_C(0x001E4C)}, + [1555] = {UINT64_C(0x000000D500000308), RUNE_C(0x001E4E)}, + [1557] = {UINT64_C(0x0000004E00000301), RUNE_C(0x000143)}, + [1562] = {UINT64_C(0x0000006E0000032D), RUNE_C(0x001E4B)}, + [1564] = {UINT64_C(0x00001F0000000342), RUNE_C(0x001F06)}, + [1565] = {UINT64_C(0x0000005300000323), RUNE_C(0x001E62)}, + [1567] = {UINT64_C(0x0000006800000308), RUNE_C(0x001E27)}, + [1569] = {UINT64_C(0x00001F0200000345), RUNE_C(0x001F82)}, + [1570] = {UINT64_C(0x000000670000030C), RUNE_C(0x0001E7)}, + [1571] = {UINT64_C(0x0000041800000304), RUNE_C(0x0004E2)}, + [1572] = {UINT64_C(0x0000039F00000301), RUNE_C(0x00038C)}, + [1574] = {UINT64_C(0x0000011300000300), RUNE_C(0x001E15)}, + [1576] = {UINT64_C(0x0000004F00000311), RUNE_C(0x00020E)}, + [1579] = {UINT64_C(0x0000004100000325), RUNE_C(0x001E00)}, + [1580] = {UINT64_C(0x0000004E0000030C), RUNE_C(0x000147)}, + [1581] = {UINT64_C(0x0000004500000323), RUNE_C(0x001EB8)}, + [1582] = {UINT64_C(0x000022B400000338), RUNE_C(0x0022EC)}, + [1585] = {UINT64_C(0x000000E700000301), RUNE_C(0x001E09)}, + [1586] = {UINT64_C(0x00001F4100000300), RUNE_C(0x001F43)}, + [1587] = {UINT64_C(0x000009330000093C), RUNE_C(0x000934)}, + [1589] = {UINT64_C(0x0000006F00000328), RUNE_C(0x0001EB)}, + [1591] = {UINT64_C(0x000001EB00000304), RUNE_C(0x0001ED)}, + [1593] = {UINT64_C(0x000003A500000301), RUNE_C(0x00038E)}, + [1595] = {UINT64_C(0x0000309D00003099), RUNE_C(0x00309E)}, + [1596] = {UINT64_C(0x00001F6E00000345), RUNE_C(0x001FAE)}, + [1599] = {UINT64_C(0x00001F2800000301), RUNE_C(0x001F2C)}, + [1602] = {UINT64_C(0x000003C500000308), RUNE_C(0x0003CB)}, + [1603] = {UINT64_C(0x0000006E00000301), RUNE_C(0x000144)}, + [1604] = {UINT64_C(0x00001F5100000342), RUNE_C(0x001F57)}, + [1606] = {UINT64_C(0x0000004C00000331), RUNE_C(0x001E3A)}, + [1608] = {UINT64_C(0x000030A600003099), RUNE_C(0x0030F4)}, + [1609] = {UINT64_C(0x0000306600003099), RUNE_C(0x003067)}, + [1610] = {UINT64_C(0x0000007A00000323), RUNE_C(0x001E93)}, + [1612] = {UINT64_C(0x000000F800000301), RUNE_C(0x0001FF)}, + [1613] = {UINT64_C(0x0000041500000300), RUNE_C(0x000400)}, + [1615] = {UINT64_C(0x000001B000000301), RUNE_C(0x001EE9)}, + [1616] = {UINT64_C(0x0000010200000300), RUNE_C(0x001EB0)}, + [1617] = {UINT64_C(0x0000039700000313), RUNE_C(0x001F28)}, + [1619] = {UINT64_C(0x0000307B0000309A), RUNE_C(0x00307D)}, + [1624] = {UINT64_C(0x0000006F00000323), RUNE_C(0x001ECD)}, + [1625] = {UINT64_C(0x000000610000030F), RUNE_C(0x000201)}, + [1627] = {UINT64_C(0x0000004100000304), RUNE_C(0x000100)}, + [1629] = {UINT64_C(0x000004E900000308), RUNE_C(0x0004EB)}, + [1630] = {UINT64_C(0x00001B0700001B35), RUNE_C(0x001B08)}, + [1633] = {UINT64_C(0x0000004F00000309), RUNE_C(0x001ECE)}, + [1634] = {UINT64_C(0x0000004F0000031B), RUNE_C(0x0001A0)}, + [1635] = {UINT64_C(0x0000006500000306), RUNE_C(0x000115)}, + [1637] = {UINT64_C(0x0000227D00000338), RUNE_C(0x0022E1)}, + [1639] = {UINT64_C(0x0000039900000306), RUNE_C(0x001FD8)}, + [1641] = {UINT64_C(0x00001F0000000301), RUNE_C(0x001F04)}, + [1645] = {UINT64_C(0x0000007900000303), RUNE_C(0x001EF9)}, + [1650] = {UINT64_C(0x0000219400000338), RUNE_C(0x0021AE)}, + [1651] = {UINT64_C(0x0000304B00003099), RUNE_C(0x00304C)}, + [1654] = {UINT64_C(0x0000005800000308), RUNE_C(0x001E8C)}, + [1655] = {UINT64_C(0x000001A100000301), RUNE_C(0x001EDB)}, + [1658] = {UINT64_C(0x0000006100000302), RUNE_C(0x0000E2)}, + [1662] = {UINT64_C(0x000000DC0000030C), RUNE_C(0x0001D9)}, + [1664] = {UINT64_C(0x00001F1100000300), RUNE_C(0x001F13)}, + [1666] = {UINT64_C(0x00011099000110BA), RUNE_C(0x01109A)}, + [1668] = {UINT64_C(0x0000006D00000307), RUNE_C(0x001E41)}, + [1670] = {UINT64_C(0x0000005500000301), RUNE_C(0x0000DA)}, + [1671] = {UINT64_C(0x000000C200000309), RUNE_C(0x001EA8)}, + [1673] = {UINT64_C(0x0000039100000301), RUNE_C(0x000386)}, + [1674] = {UINT64_C(0x000000DC00000301), RUNE_C(0x0001D7)}, + [1675] = {UINT64_C(0x0000006300000302), RUNE_C(0x000109)}, + [1676] = {UINT64_C(0x0000007800000307), RUNE_C(0x001E8B)}, + [1678] = {UINT64_C(0x0000014C00000301), RUNE_C(0x001E52)}, + [1681] = {UINT64_C(0x000003A100000314), RUNE_C(0x001FEC)}, + [1684] = {UINT64_C(0x0000004300000327), RUNE_C(0x0000C7)}, + [1686] = {UINT64_C(0x00001B0900001B35), RUNE_C(0x001B0A)}, + [1688] = {UINT64_C(0x000003B100000304), RUNE_C(0x001FB1)}, + [1691] = {UINT64_C(0x0000006500000311), RUNE_C(0x000207)}, + [1692] = {UINT64_C(0x00001FBF00000300), RUNE_C(0x001FCD)}, + [1694] = {UINT64_C(0x0000004100000311), RUNE_C(0x000202)}, + [1695] = {UINT64_C(0x000003C500000314), RUNE_C(0x001F51)}, + [1696] = {UINT64_C(0x0000006E00000303), RUNE_C(0x0000F1)}, + [1698] = {UINT64_C(0x0000227200000338), RUNE_C(0x002274)}, + [1699] = {UINT64_C(0x0000004900000330), RUNE_C(0x001E2C)}, + [1700] = {UINT64_C(0x0000044300000304), RUNE_C(0x0004EF)}, + [1703] = {UINT64_C(0x00001F1800000301), RUNE_C(0x001F1C)}, + [1705] = {UINT64_C(0x0000005700000307), RUNE_C(0x001E86)}, + [1706] = {UINT64_C(0x0000006100000301), RUNE_C(0x0000E1)}, + [1708] = {UINT64_C(0x0000003E00000338), RUNE_C(0x00226F)}, + [1709] = {UINT64_C(0x000000750000032D), RUNE_C(0x001E77)}, + [1710] = {UINT64_C(0x0000004800000323), RUNE_C(0x001E24)}, + [1712] = {UINT64_C(0x0000305D00003099), RUNE_C(0x00305E)}, + [1713] = {UINT64_C(0x00001F0D00000345), RUNE_C(0x001F8D)}, + [1714] = {UINT64_C(0x000003B700000313), RUNE_C(0x001F20)}, + [1715] = {UINT64_C(0x0000304D00003099), RUNE_C(0x00304E)}, + [1719] = {UINT64_C(0x000001AF00000303), RUNE_C(0x001EEE)}, + [1721] = {UINT64_C(0x0000004500000330), RUNE_C(0x001E1A)}, + [1722] = {UINT64_C(0x0000006300000301), RUNE_C(0x000107)}, + [1723] = {UINT64_C(0x000000D600000304), RUNE_C(0x00022A)}, + [1724] = {UINT64_C(0x00001EB900000302), RUNE_C(0x001EC7)}, + [1726] = {UINT64_C(0x0000022F00000304), RUNE_C(0x000231)}, + [1733] = {UINT64_C(0x00001F0900000342), RUNE_C(0x001F0F)}, + [1735] = {UINT64_C(0x00001F6800000342), RUNE_C(0x001F6E)}, + [1739] = {UINT64_C(0x000000E500000301), RUNE_C(0x0001FB)}, + [1741] = {UINT64_C(0x000115B9000115AF), RUNE_C(0x0115BB)}, + [1744] = {UINT64_C(0x0000006500000304), RUNE_C(0x000113)}, + [1747] = {UINT64_C(0x000004740000030F), RUNE_C(0x000476)}, + [1748] = {UINT64_C(0x000000740000030C), RUNE_C(0x000165)}, + [1750] = {UINT64_C(0x0000005500000300), RUNE_C(0x0000D9)}, + [1752] = {UINT64_C(0x000022AB00000338), RUNE_C(0x0022AF)}, + [1753] = {UINT64_C(0x0000005500000311), RUNE_C(0x000216)}, + [1754] = {UINT64_C(0x0000004D00000323), RUNE_C(0x001E42)}, + [1755] = {UINT64_C(0x00001F6D00000345), RUNE_C(0x001FAD)}, + [1756] = {UINT64_C(0x000000540000032D), RUNE_C(0x001E70)}, + [1757] = {UINT64_C(0x000022B300000338), RUNE_C(0x0022EB)}, + [1761] = {UINT64_C(0x000000CA00000309), RUNE_C(0x001EC2)}, + [1762] = {UINT64_C(0x0000043500000306), RUNE_C(0x0004D7)}, + [1763] = {UINT64_C(0x0000004900000306), RUNE_C(0x00012C)}, + [1764] = {UINT64_C(0x000000550000030B), RUNE_C(0x000170)}, + [1765] = {UINT64_C(0x000000F600000304), RUNE_C(0x00022B)}, + [1766] = {UINT64_C(0x000030DB00003099), RUNE_C(0x0030DC)}, + [1767] = {UINT64_C(0x0000039900000314), RUNE_C(0x001F39)}, + [1768] = {UINT64_C(0x000030DB0000309A), RUNE_C(0x0030DD)}, + [1771] = {UINT64_C(0x00001F6F00000345), RUNE_C(0x001FAF)}, + [1774] = {UINT64_C(0x0000004300000302), RUNE_C(0x000108)}, + [1775] = {UINT64_C(0x00001F0100000345), RUNE_C(0x001F81)}, + [1777] = {UINT64_C(0x000000C500000301), RUNE_C(0x0001FA)}, + [1780] = {UINT64_C(0x0000006400000327), RUNE_C(0x001E11)}, + [1784] = {UINT64_C(0x000003C500000342), RUNE_C(0x001FE6)}, + [1786] = {UINT64_C(0x0000227C00000338), RUNE_C(0x0022E0)}, + [1787] = {UINT64_C(0x0000004700000301), RUNE_C(0x0001F4)}, + [1788] = {UINT64_C(0x000000450000030F), RUNE_C(0x000204)}, + [1790] = {UINT64_C(0x0000227600000338), RUNE_C(0x002278)}, + [1791] = {UINT64_C(0x0000006700000306), RUNE_C(0x00011F)}, + [1794] = {UINT64_C(0x0000016100000307), RUNE_C(0x001E67)}, + [1795] = {UINT64_C(0x00001F2200000345), RUNE_C(0x001F92)}, + [1797] = {UINT64_C(0x000000550000031B), RUNE_C(0x0001AF)}, + [1798] = {UINT64_C(0x0000004500000327), RUNE_C(0x000228)}, + [1799] = {UINT64_C(0x0000039100000314), RUNE_C(0x001F09)}, + [1800] = {UINT64_C(0x000004750000030F), RUNE_C(0x000477)}, + [1802] = {UINT64_C(0x0000004A00000302), RUNE_C(0x000134)}, + [1803] = {UINT64_C(0x0000006700000301), RUNE_C(0x0001F5)}, + [1804] = {UINT64_C(0x00001F0800000301), RUNE_C(0x001F0C)}, + [1808] = {UINT64_C(0x000000C700000301), RUNE_C(0x001E08)}, + [1809] = {UINT64_C(0x0000006100000306), RUNE_C(0x000103)}, + [1810] = {UINT64_C(0x00001F6500000345), RUNE_C(0x001FA5)}, + [1814] = {UINT64_C(0x000006D500000654), RUNE_C(0x0006C0)}, + [1815] = {UINT64_C(0x000003B700000301), RUNE_C(0x0003AE)}, + [1816] = {UINT64_C(0x0000039500000300), RUNE_C(0x001FC8)}, + [1817] = {UINT64_C(0x00001F3900000342), RUNE_C(0x001F3F)}, + [1823] = {UINT64_C(0x00001F6100000301), RUNE_C(0x001F65)}, + [1825] = {UINT64_C(0x000030D200003099), RUNE_C(0x0030D3)}, + [1828] = {UINT64_C(0x0000005900000309), RUNE_C(0x001EF6)}, + [1829] = {UINT64_C(0x000114B9000114BD), RUNE_C(0x0114BE)}, + [1834] = {UINT64_C(0x000000750000030A), RUNE_C(0x00016F)}, + [1835] = {UINT64_C(0x0000005000000301), RUNE_C(0x001E54)}, + [1836] = {UINT64_C(0x0000222300000338), RUNE_C(0x002224)}, + [1837] = {UINT64_C(0x0000014D00000300), RUNE_C(0x001E51)}, + [1841] = {UINT64_C(0x0000064A00000654), RUNE_C(0x000626)}, + [1845] = {UINT64_C(0x000000A800000301), RUNE_C(0x000385)}, + [1847] = {UINT64_C(0x0000004F00000307), RUNE_C(0x00022E)}, + [1848] = {UINT64_C(0x00000CCA00000CD5), RUNE_C(0x000CCB)}, + [1849] = {UINT64_C(0x0000004D00000301), RUNE_C(0x001E3E)}, + [1850] = {UINT64_C(0x0000006F0000030B), RUNE_C(0x000151)}, + [1852] = {UINT64_C(0x0000006500000330), RUNE_C(0x001E1B)}, + [1857] = {UINT64_C(0x0000006500000307), RUNE_C(0x000117)}, + [1858] = {UINT64_C(0x0000007500000309), RUNE_C(0x001EE7)}, + [1860] = {UINT64_C(0x000003B900000304), RUNE_C(0x001FD1)}, + [1861] = {UINT64_C(0x000000E600000301), RUNE_C(0x0001FD)}, + [1866] = {UINT64_C(0x00001F6700000345), RUNE_C(0x001FA7)}, + [1869] = {UINT64_C(0x00001F0600000345), RUNE_C(0x001F86)}, + [1878] = {UINT64_C(0x0000007900000301), RUNE_C(0x0000FD)}, + [1879] = {UINT64_C(0x0000004100000306), RUNE_C(0x000102)}, + [1881] = {UINT64_C(0x000001A100000300), RUNE_C(0x001EDD)}, + [1883] = {UINT64_C(0x0000220300000338), RUNE_C(0x002204)}, + [1886] = {UINT64_C(0x000003C500000300), RUNE_C(0x001F7A)}, + [1887] = {UINT64_C(0x000003B700000300), RUNE_C(0x001F74)}, + [1888] = {UINT64_C(0x00001F3900000300), RUNE_C(0x001F3B)}, + [1890] = {UINT64_C(0x0000007200000311), RUNE_C(0x000213)}, + [1891] = {UINT64_C(0x00001F4800000301), RUNE_C(0x001F4C)}, + [1893] = {UINT64_C(0x000003C900000313), RUNE_C(0x001F60)}, + [1896] = {UINT64_C(0x0000307200003099), RUNE_C(0x003073)}, + [1897] = {UINT64_C(0x0000064800000654), RUNE_C(0x000624)}, + [1902] = {UINT64_C(0x000003B100000301), RUNE_C(0x0003AC)}, + [1906] = {UINT64_C(0x00001F2600000345), RUNE_C(0x001F96)}, + [1907] = {UINT64_C(0x0000004900000323), RUNE_C(0x001ECA)}, + [1908] = {UINT64_C(0x0000223C00000338), RUNE_C(0x002241)}, + [1909] = {UINT64_C(0x00001F2900000301), RUNE_C(0x001F2D)}, + [1911] = {UINT64_C(0x0000004F00000328), RUNE_C(0x0001EA)}, + [1912] = {UINT64_C(0x00001E3700000304), RUNE_C(0x001E39)}, + [1914] = {UINT64_C(0x0000010300000301), RUNE_C(0x001EAF)}, + [1918] = {UINT64_C(0x0000043500000300), RUNE_C(0x000450)}, + [1919] = {UINT64_C(0x0000041800000306), RUNE_C(0x000419)}, + [1921] = {UINT64_C(0x000110A5000110BA), RUNE_C(0x0110AB)}, + [1922] = {UINT64_C(0x000001A000000309), RUNE_C(0x001EDE)}, + [1924] = {UINT64_C(0x0000007400000331), RUNE_C(0x001E6F)}, + [1925] = {UINT64_C(0x000000CA00000303), RUNE_C(0x001EC4)}, + [1927] = {UINT64_C(0x00000D4600000D3E), RUNE_C(0x000D4A)}, + [1928] = {UINT64_C(0x00001F2900000345), RUNE_C(0x001F99)}, + [1932] = {UINT64_C(0x000030F100003099), RUNE_C(0x0030F9)}, + [1935] = {UINT64_C(0x0000004C00000301), RUNE_C(0x000139)}, + [1936] = {UINT64_C(0x000000F500000304), RUNE_C(0x00022D)}, + [1939] = {UINT64_C(0x000022A200000338), RUNE_C(0x0022AC)}, + [1940] = {UINT64_C(0x0000005800000307), RUNE_C(0x001E8A)}, + [1941] = {UINT64_C(0x0000011200000301), RUNE_C(0x001E16)}, + [1948] = {UINT64_C(0x00000BC700000BBE), RUNE_C(0x000BCB)}, + [1951] = {UINT64_C(0x0000007700000307), RUNE_C(0x001E87)}, + [1953] = {UINT64_C(0x0000004B00000331), RUNE_C(0x001E34)}, + [1955] = {UINT64_C(0x000001A100000303), RUNE_C(0x001EE1)}, + [1958] = {UINT64_C(0x0000307500003099), RUNE_C(0x003076)}, + [1959] = {UINT64_C(0x0000007400000326), RUNE_C(0x00021B)}, + [1960] = {UINT64_C(0x0000005900000302), RUNE_C(0x000176)}, + [1961] = {UINT64_C(0x00001F2000000345), RUNE_C(0x001F90)}, + [1965] = {UINT64_C(0x00001F6000000300), RUNE_C(0x001F62)}, + [1967] = {UINT64_C(0x0000006700000307), RUNE_C(0x000121)}, + [1968] = {UINT64_C(0x00001EA100000306), RUNE_C(0x001EB7)}, + [1969] = {UINT64_C(0x0000011300000301), RUNE_C(0x001E17)}, + [1970] = {UINT64_C(0x00001F6900000342), RUNE_C(0x001F6F)}, + [1971] = {UINT64_C(0x0000004C0000032D), RUNE_C(0x001E3C)}, + [1972] = {UINT64_C(0x000003B100000342), RUNE_C(0x001FB6)}, + [1978] = {UINT64_C(0x0000006F00000304), RUNE_C(0x00014D)}, + [1988] = {UINT64_C(0x0000041800000300), RUNE_C(0x00040D)}, + [1990] = {UINT64_C(0x00001B0D00001B35), RUNE_C(0x001B0E)}, + [1991] = {UINT64_C(0x00001F6B00000345), RUNE_C(0x001FAB)}, + [1992] = {UINT64_C(0x0000004100000323), RUNE_C(0x001EA0)}, + [1994] = {UINT64_C(0x00001E5A00000304), RUNE_C(0x001E5C)}, + [1998] = {UINT64_C(0x0000224500000338), RUNE_C(0x002247)}, + [1999] = {UINT64_C(0x0000044300000308), RUNE_C(0x0004F1)}, + [2001] = {UINT64_C(0x0000004B0000030C), RUNE_C(0x0001E8)}, + [2002] = {UINT64_C(0x0000006800000307), RUNE_C(0x001E23)}, + [2003] = {UINT64_C(0x0000006B0000030C), RUNE_C(0x0001E9)}, + [2004] = {UINT64_C(0x000001B000000309), RUNE_C(0x001EED)}, + [2006] = {UINT64_C(0x00001F7000000345), RUNE_C(0x001FB2)}, + [2007] = {UINT64_C(0x0000004C00000327), RUNE_C(0x00013B)}, + [2010] = {UINT64_C(0x000003CA00000300), RUNE_C(0x001FD2)}, + [2011] = {UINT64_C(0x000004230000030B), RUNE_C(0x0004F2)}, + [2015] = {UINT64_C(0x0000007A00000307), RUNE_C(0x00017C)}, + [2016] = {UINT64_C(0x0000010300000309), RUNE_C(0x001EB3)}, + [2018] = {UINT64_C(0x000003B500000314), RUNE_C(0x001F11)}, + [2019] = {UINT64_C(0x000000550000032D), RUNE_C(0x001E76)}, + [2021] = {UINT64_C(0x0000006500000303), RUNE_C(0x001EBD)}, + [2022] = {UINT64_C(0x0000005900000308), RUNE_C(0x000178)}, + [2026] = {UINT64_C(0x0000006C0000030C), RUNE_C(0x00013E)}, + [2028] = {UINT64_C(0x0000004C00000323), RUNE_C(0x001E36)}, + [2031] = {UINT64_C(0x00001F0000000345), RUNE_C(0x001F80)}, + [2032] = {UINT64_C(0x000003C900000300), RUNE_C(0x001F7C)}, + [2034] = {UINT64_C(0x000000E200000303), RUNE_C(0x001EAB)}, + [2036] = {UINT64_C(0x00001B3F00001B35), RUNE_C(0x001B41)}, + [2039] = {UINT64_C(0x0000007600000323), RUNE_C(0x001E7F)}, + [2041] = {UINT64_C(0x0000006B00000331), RUNE_C(0x001E35)}, + [2044] = {UINT64_C(0x0000004F00000308), RUNE_C(0x0000D6)}, + [2047] = {UINT64_C(0x0000006200000323), RUNE_C(0x001E05)}, +}; + +[[_mlib_pure, _mlib_inline]] +static uint64_t +hash(uint64_t x) +{ + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9U; + x ^= x >> 27; + x *= 0x94d049bb133111ebU; + x ^= x >> 31; + return x; +} + +[[_mlib_pure, _mlib_inline]] +static unsigned int +lookup(uint64_t hash, unsigned int idx) +{ + unsigned int mask = (1U << HT_EXP) - 1; + unsigned int step = (hash >> (64 - HT_EXP)) | 1; + return (idx + step) & mask; +} + +static rune +uprop_get_cm(rune a, rune b) +{ + uint64_t k, h; + k = (uint64_t)a << 32 | b; + h = hash(k); + for (unsigned int i = h;;) { + i = lookup(h, i); + auto e = uprop_cm_ht[i]; + if (e.k == 0 || e.k == k) + return e.v; + } +} diff --git a/include/unicode/string.h b/include/unicode/string.h index 06edb6c..17ce561 100644 --- a/include/unicode/string.h +++ b/include/unicode/string.h @@ -18,6 +18,16 @@ enum [[clang::flag_enum]] caseflags { CF_ẞ = 1 << 3, /* Use ‘ẞ’ as the uppercase of ‘ß’; alias for CF_SS */ }; +enum normtype { + /* If bit 0 is set, then composition is performed after decomposition. If + bit-1 is set then compatibility (de)composition is used as opposed to + canonical (de)composition. */ + NT_NFD = 0b00, + NT_NFC = 0b01, + NT_NFKD = 0b10, + NT_NFKC = 0b11, +}; + /* clang-format on */ [[nodiscard]] size_t u8gcnt(struct u8view); @@ -34,8 +44,8 @@ size_t u8wnext_human(struct u8view *, struct u8view *); alloc_fn, void *); [[nodiscard]] char8_t *u8upper(size_t *, struct u8view, enum caseflags, alloc_fn, void *); -[[nodiscard]] char8_t *u8norm_nfd(size_t *, struct u8view, alloc_fn, void *); -[[nodiscard]] char8_t *u8norm_nfkd(size_t *, struct u8view, alloc_fn, void *); +[[nodiscard]] char8_t *u8norm(size_t *, struct u8view, alloc_fn, void *, + enum normtype); /* Encoding-generic macros */ #define ucsgcnt(sv) _Generic((sv), struct u8view: u8gcnt)((sv)) @@ -57,10 +67,8 @@ size_t u8wnext_human(struct u8view *, struct u8view *); #define ucsupper(dstn, sv, flags, alloc, ctx) \ _Generic((sv), struct u8view: u8upper)((dstn), (sv), (flags), (alloc), \ (ctx)) -#define ucsnorm_nfd(dstn, sv, alloc, ctx) \ - _Generic((sv), struct u8view: u8norm_nfd)((dstn), (sv), (alloc), (ctx)) -#define ucsnorm_nfkd(dstn, sv, alloc, ctx) \ - _Generic((sv), struct u8view: u8norm_nfkd)((dstn), (sv), (alloc), (ctx)) +#define ucsnorm(dstn, sv, alloc, ctx, nt) \ + _Generic((sv), struct u8view: u8norm)((dstn), (sv), (alloc), (ctx), (nt)) constexpr double U8CASEFOLD_SCALE = 3; constexpr double U8LOWER_SCALE = 1.5; diff --git a/lib/unicode/string/u8norm.c b/lib/unicode/string/u8norm.c new file mode 100644 index 0000000..a918479 --- /dev/null +++ b/lib/unicode/string/u8norm.c @@ -0,0 +1,192 @@ +#include + +#include "macros.h" +#include "mbstring.h" +#include "unicode/_cm.h" +#include "unicode/prop.h" +#include "unicode/string.h" + +#define BETWEEN(x, y, z) ((x) <= (y) && (y) <= (z)) + +static void decomp(char8_t *, size_t *, size_t, rune, enum normtype); +static void compbuf(char8_t *, size_t *); + +/* Computed using a gen/scale-norm.c */ +constexpr int NFD_SCALE = 3; +constexpr int NFKD_SCALE = 11; + +/* For Hangul syllable decomposition */ +constexpr rune SBASE = 0xAC00; +constexpr rune LBASE = 0x1100; +constexpr rune VBASE = 0x1161; +constexpr rune TBASE = 0x11A7; +constexpr int LCNT = 19; +constexpr int VCNT = 21; +constexpr int TCNT = 28; +constexpr int NCNT = VCNT * TCNT; +constexpr int SCNT = LCNT * NCNT; + +char8_t * +u8norm(size_t *dstn, struct u8view src, alloc_fn alloc, void *ctx, + enum normtype nt) +{ + ASSUME(dstn != nullptr); + ASSUME(alloc != nullptr); + ASSUME(BETWEEN(0, nt, 4)); + + /* Pre-allocate a buffer with some initial capacity; there is no need to + check for overflow when computing bufsz because alloc() will handle the + overflow error for us. */ + int scale = (nt & 0b10) ? NFKD_SCALE : NFD_SCALE; + size_t bufsz = src.len * scale; + char8_t *dst = alloc(ctx, nullptr, 0, src.len, scale, alignof(char8_t)); + + *dstn = 0; + for (rune ch; ucsnext(&ch, &src) != 0; decomp(dst, dstn, bufsz, ch, nt)) + ; + if (nt & 0b01) + compbuf(dst, dstn); + return alloc(ctx, dst, src.len, *dstn, 1, alignof(char8_t)); +} + +#define WRITE(ch) *dstn += rtoucs(dst + *dstn, bufsz - *dstn, (ch)) + +void +decomp(char8_t *dst, size_t *dstn, size_t bufsz, rune ch, enum normtype nt) +{ + if (uprop_get_hst(ch) != HST_NA) { + int si = ch - SBASE; + if (si < 0 || si > SCNT) { + WRITE(ch); + return; + } + rune l, v, t; + l = LBASE + si / NCNT; + v = VBASE + (si % NCNT) / TCNT; + t = TBASE + si % TCNT; + WRITE(l); + WRITE(v); + if (t != TBASE) + WRITE(t); + } else if (((nt & 0b10) && uprop_get_dt(ch) != DT_NONE) + || ((nt & 0b10) == 0 && uprop_get_dt(ch) == DT_CAN)) + { + struct rview rv = uprop_get_dm(ch); + for (size_t i = 0; i < rv.len; i++) + decomp(dst, dstn, bufsz, rv.p[i], nt); + } else { + enum uprop_ccc ccc = uprop_get_ccc(ch); + if (ccc == CCC_NR) { + WRITE(ch); + return; + } + + int w; + rune hc; + char8_t *p = dst + *dstn; + while (w = ucsprev(&hc, (const char8_t **)&p, dst)) { + enum uprop_ccc ccc2 = uprop_get_ccc(hc); + if (ccc2 == CCC_NR || ccc2 <= ccc) { +out: + char8_t tmp[U8_LEN_MAX]; + int w2 = rtoucs(tmp, sizeof(tmp), ch); + p += w; + memmove(p + w2, p, dst + *dstn - p); + memcpy(p, tmp, w2); + *dstn += w2; + return; + } + } + + /* Loop didn’t early-return; append to the start */ + goto out; + } +} + +#undef WRITE + +/* The following implements the canonical composition algorithm, and it may be + useful to read it to understand what’s going on. It can be found under + §3.11 Normalization Forms of the Unicode standard, subsection ‘Canonical + Composition Algorithm’. */ + +void +compbuf(char8_t *dst, size_t *dstn) +{ + int wC, wL; + rune C, L; + struct u8view sv = {dst, *dstn}; + + while ((wL = ucsnext(&L, &sv)) != 0) { + if (uprop_get_ccc(L) != CCC_NR) + continue; + char8_t *after_L = (char8_t *)sv.p; + + enum uprop_ccc prevcc = 0; + struct u8view sv_ = sv; + + while ((wC = ucsnext(&C, &sv_)) != 0) { + enum uprop_ccc curcc = uprop_get_ccc(C); + bool blocked = curcc <= prevcc; + + if (blocked) { + if (curcc != CCC_NR) + continue; + if (curcc != prevcc) + break; + } + + prevcc = curcc; + rune comp = uprop_get_cm(L, C); + + /* Try Hangul composition */ + if (comp == 0) { + if (BETWEEN(LBASE, L, LBASE + LCNT - 1) + && BETWEEN(VBASE, C, VBASE + VCNT - 1)) + { + comp = SBASE + ((L - LBASE) * NCNT + (C - VBASE) * TCNT); + } else if (BETWEEN(TBASE, C, TBASE + TCNT - 1) + && BETWEEN(SBASE, L, SBASE + SCNT - 1) + && ((L - SBASE) % TCNT) == 0) + { + comp = L + (C - TBASE); + } + } + + if (comp != 0) { + char8_t *after_C = (char8_t *)sv_.p; + + /* Shift bytes between L & C so that they’re contiguous with the + bytes after C */ + memmove(after_L + wC, after_L, after_C - wC - after_L); + + /* Write the composition into where L was */ + int w = rtoucs(after_L - wL, wL + wC, comp); + + /* Shift the bytes after L & C to be right after the new + composition */ + memmove(after_L - wL + w, after_L + wC, + *dstn - (after_L + wC - dst)); + + /* Correct *dstn */ + int shift = wL + wC - w; + *dstn -= shift; + + /* Fix the inner string view */ + sv_.p = after_C - shift; + sv_.len = *dstn - (sv_.p - dst); + + /* Fix outer string view */ + sv.p = sv.p - wL + w; + sv.len = *dstn - (sv.p - dst); + after_L = (char8_t *)sv.p; + + /* Update the value of L */ + L = comp; + wL = w; + prevcc = CCC_NR; + } else if (blocked) + break; + } + } +} diff --git a/lib/unicode/string/u8norm_nfd.c b/lib/unicode/string/u8norm_nfd.c deleted file mode 100644 index a89a1b5..0000000 --- a/lib/unicode/string/u8norm_nfd.c +++ /dev/null @@ -1,94 +0,0 @@ -#include - -#include "macros.h" -#include "mbstring.h" -#include "unicode/prop.h" -#include "unicode/string.h" - -static void decomp(char8_t *, size_t *, size_t, rune); - -/* Computed using a gen/scale-norm.c */ -constexpr int NFD_SCALE = 3; - -/* For Hangul syllable decomposition */ -constexpr rune SBASE = 0xAC00; -constexpr rune LBASE = 0x1100; -constexpr rune VBASE = 0x1161; -constexpr rune TBASE = 0x11A7; -constexpr int LCNT = 19; -constexpr int VCNT = 21; -constexpr int TCNT = 28; -constexpr int NCNT = VCNT * TCNT; -constexpr int SCNT = LCNT * NCNT; - -char8_t * -u8norm_nfd(size_t *dstn, struct u8view src, alloc_fn alloc, void *ctx) -{ - ASSUME(dstn != nullptr); - ASSUME(alloc != nullptr); - - /* Pre-allocate a buffer with some initial capacity; there is no need to - check for overflow when computing bufsz because alloc() will handle the - overflow error for us. */ - size_t bufsz = src.len * NFD_SCALE; - char8_t *dst = alloc(ctx, nullptr, 0, src.len, NFD_SCALE, alignof(char8_t)); - - *dstn = 0; - for (rune ch; ucsnext(&ch, &src) != 0; decomp(dst, dstn, bufsz, ch)) - ; - return alloc(ctx, dst, src.len, *dstn, 1, alignof(char8_t)); -} - -#define WRITE(ch) *dstn += rtoucs(dst + *dstn, bufsz - *dstn, (ch)) - -void -decomp(char8_t *dst, size_t *dstn, size_t bufsz, rune ch) -{ - if (uprop_get_hst(ch) != HST_NA) { - int si = ch - SBASE; - if (si < 0 || si > SCNT) { - WRITE(ch); - return; - } - rune l, v, t; - l = LBASE + si / NCNT; - v = VBASE + (si % NCNT) / TCNT; - t = TBASE + si % TCNT; - WRITE(l); - WRITE(v); - if (t != TBASE) - WRITE(t); - } else if (uprop_get_dt(ch) == DT_CAN) { - struct rview rv = uprop_get_dm(ch); - for (size_t i = 0; i < rv.len; i++) - decomp(dst, dstn, bufsz, rv.p[i]); - } else { - enum uprop_ccc ccc = uprop_get_ccc(ch); - if (ccc == CCC_NR) { - WRITE(ch); - return; - } - - int w; - rune hc; - char8_t *p = dst + *dstn; - while (w = ucsprev(&hc, (const char8_t **)&p, dst)) { - enum uprop_ccc ccc2 = uprop_get_ccc(hc); - if (ccc2 == CCC_NR || ccc2 <= ccc) { -out: - char8_t tmp[U8_LEN_MAX]; - int w2 = rtoucs(tmp, sizeof(tmp), ch); - p += w; - memmove(p + w2, p, dst + *dstn - p); - memcpy(p, tmp, w2); - *dstn += w2; - return; - } - } - - /* Loop didn’t early-return; append to the start */ - goto out; - } -} - -#undef WRITE diff --git a/lib/unicode/string/u8norm_nfkd.c b/lib/unicode/string/u8norm_nfkd.c deleted file mode 100644 index 898b650..0000000 --- a/lib/unicode/string/u8norm_nfkd.c +++ /dev/null @@ -1,94 +0,0 @@ -#include - -#include "macros.h" -#include "mbstring.h" -#include "unicode/prop.h" -#include "unicode/string.h" - -static void decomp(char8_t *, size_t *, size_t, rune); - -/* Computed using a gen/scale-norm.c */ -constexpr int NFKD_SCALE = 11; - -/* For Hangul syllable decomposition */ -constexpr rune SBASE = 0xAC00; -constexpr rune LBASE = 0x1100; -constexpr rune VBASE = 0x1161; -constexpr rune TBASE = 0x11A7; -constexpr int LCNT = 19; -constexpr int VCNT = 21; -constexpr int TCNT = 28; -constexpr int NCNT = VCNT * TCNT; -constexpr int SCNT = LCNT * NCNT; - -char8_t * -u8norm_nfkd(size_t *dstn, struct u8view src, alloc_fn alloc, void *ctx) -{ - ASSUME(dstn != nullptr); - ASSUME(alloc != nullptr); - - /* Pre-allocate a buffer with some initial capacity; there is no need to - check for overflow when computing bufsz because alloc() will handle the - overflow error for us. */ - size_t bufsz = src.len * NFKD_SCALE; - char8_t *dst = alloc(ctx, nullptr, 0, src.len, NFKD_SCALE, alignof(char8_t)); - - *dstn = 0; - for (rune ch; ucsnext(&ch, &src) != 0; decomp(dst, dstn, bufsz, ch)) - ; - return alloc(ctx, dst, src.len, *dstn, 1, alignof(char8_t)); -} - -#define WRITE(ch) *dstn += rtoucs(dst + *dstn, bufsz - *dstn, (ch)) - -void -decomp(char8_t *dst, size_t *dstn, size_t bufsz, rune ch) -{ - if (uprop_get_hst(ch) != HST_NA) { - int si = ch - SBASE; - if (si < 0 || si > SCNT) { - WRITE(ch); - return; - } - rune l, v, t; - l = LBASE + si / NCNT; - v = VBASE + (si % NCNT) / TCNT; - t = TBASE + si % TCNT; - WRITE(l); - WRITE(v); - if (t != TBASE) - WRITE(t); - } else if (uprop_get_dt(ch) != DT_NONE) { - struct rview rv = uprop_get_dm(ch); - for (size_t i = 0; i < rv.len; i++) - decomp(dst, dstn, bufsz, rv.p[i]); - } else { - enum uprop_ccc ccc = uprop_get_ccc(ch); - if (ccc == CCC_NR) { - WRITE(ch); - return; - } - - int w; - rune hc; - char8_t *p = dst + *dstn; - while (w = ucsprev(&hc, (const char8_t **)&p, dst)) { - enum uprop_ccc ccc2 = uprop_get_ccc(hc); - if (ccc2 == CCC_NR || ccc2 <= ccc) { -out: - char8_t tmp[U8_LEN_MAX]; - int w2 = rtoucs(tmp, sizeof(tmp), ch); - p += w; - memmove(p + w2, p, dst + *dstn - p); - memcpy(p, tmp, w2); - *dstn += w2; - return; - } - } - - /* Loop didn’t early-return; append to the start */ - goto out; - } -} - -#undef WRITE diff --git a/make.c b/make.c index f972f3f..afc1a06 100644 --- a/make.c +++ b/make.c @@ -15,7 +15,7 @@ #define LIBNAME "libmlib" #define CFLAGS_ALL WARNINGS, "-pipe", "-std=c23", "-Iinclude" GLIB_EXTRAS -#define CFLAGS_DBG "-g", "-ggdb3", "-Og", "-fsanitize=address,undefined" +#define CFLAGS_DBG "-g", "-ggdb3", "-O0", "-fsanitize=address,undefined" #define CFLAGS_RLS "-O3", "-flto", "-DNDEBUG" NOT_APPLE_EXTRAS #define WARNINGS \ diff --git a/test/_norm-test.h b/test/_norm-test.h index 68209f1..8df9f3f 100644 --- a/test/_norm-test.h +++ b/test/_norm-test.h @@ -15,7 +15,6 @@ #include #define TESTFILE "norm.in" -#define FUNC CONCAT(ucsnorm_, NORMTYPE) static bool test(struct u8view, int); @@ -39,10 +38,8 @@ main(int, char **argv) if (line[nr - 1] == '\n') line[--nr] = '\0'; - if (!test((struct u8view){line, (size_t)nr}, id)) { + if (!test((struct u8view){line, (size_t)nr}, id)) rv = EXIT_FAILURE; - break; - } } if (ferror(fp)) err("getline: %s:", TESTFILE); @@ -87,12 +84,21 @@ test(struct u8view sv, int id) for (size_t i = 0; i < 5; i++) { size_t base; - if (streq(STR(NORMTYPE), "nfkd")) + const char *nt = STR(NORMTYPE); + if (streq(nt, "NT_NFC")) + base = i < 3 ? 1 : 3; + else if (streq(nt, "NT_NFD")) + base = i < 3 ? 2 : 4; + else if (streq(nt, "NT_NFKC")) + base = 3; + else if (streq(nt, "NT_NFKD")) base = 4; else - base = i < 3 ? 2 : 4; + err("invalid NORMTYPE ‘%s’", nt); + struct u8view normd = {}; - normd.p = FUNC(&normd.len, columns.buf[i], alloc_arena, &ctx); + normd.p = + ucsnorm(&normd.len, columns.buf[i], alloc_arena, &ctx, NORMTYPE); if (!ucseq(columns.buf[base], normd)) { warn("case %d: expected c%zu to be ‘%.*s’ but got ‘%.*s’", id, i + 1, SV_PRI_ARGS(columns.buf[base]), SV_PRI_ARGS(normd)); diff --git a/test/norm-nfc-test.c b/test/norm-nfc-test.c new file mode 100644 index 0000000..176cd69 --- /dev/null +++ b/test/norm-nfc-test.c @@ -0,0 +1,2 @@ +#define NORMTYPE NT_NFC +#include "_norm-test.h" diff --git a/test/norm-nfd-test.c b/test/norm-nfd-test.c index 6067352..816bba5 100644 --- a/test/norm-nfd-test.c +++ b/test/norm-nfd-test.c @@ -1,2 +1,2 @@ -#define NORMTYPE nfd +#define NORMTYPE NT_NFD #include "_norm-test.h" diff --git a/test/norm-nfkc-test.c b/test/norm-nfkc-test.c new file mode 100644 index 0000000..cddce1c --- /dev/null +++ b/test/norm-nfkc-test.c @@ -0,0 +1,2 @@ +#define NORMTYPE NT_NFKC +#include "_norm-test.h" diff --git a/test/norm-nfkd-test.c b/test/norm-nfkd-test.c index 3fe8ff2..34bebca 100644 --- a/test/norm-nfkd-test.c +++ b/test/norm-nfkd-test.c @@ -1,2 +1,2 @@ -#define NORMTYPE nfkd +#define NORMTYPE NT_NFKD #include "_norm-test.h" -- cgit v1.2.3