aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-05-20 17:56:55 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-05-20 17:56:55 +0200
commit2e125c1c7e75db14a88f0b8b09e61a132977c63e (patch)
tree30c37263315e07f983c2b05b69c17e47c827b849
parentd6b1db5c14ca1e731db299748d2df9eb955c9f7c (diff)
Support the 4 forms of Unicode string normalization
-rw-r--r--README6
-rw-r--r--data/CompositionExclusions221
-rwxr-xr-xgen/prop/cm.c166
-rw-r--r--include/unicode/_cm.h990
-rw-r--r--include/unicode/string.h20
-rw-r--r--lib/unicode/string/u8norm.c192
-rw-r--r--lib/unicode/string/u8norm_nfd.c94
-rw-r--r--lib/unicode/string/u8norm_nfkd.c94
-rw-r--r--make.c2
-rw-r--r--test/_norm-test.h20
-rw-r--r--test/norm-nfc-test.c2
-rw-r--r--test/norm-nfd-test.c2
-rw-r--r--test/norm-nfkc-test.c2
-rw-r--r--test/norm-nfkd-test.c2
14 files changed, 1606 insertions, 207 deletions
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 <assert.h>
+#include <inttypes.h>
+#include <stdbit.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <alloc.h>
+#include <dynarr.h>
+#include <mbstring.h>
+#include <rune.h>
+#include <unicode/prop.h>
+
+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 <inttypes.h>\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 <inttypes.h>
+
+#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 <string.h>
+
+#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 <string.h>
-
-#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 <string.h>
-
-#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 <unicode/string.h>
#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"