diff --git a/CMakeLists.txt b/CMakeLists.txt index b94d9b60..7e62d0a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,11 @@ add_executable(test_decode_utf8 target_compile_definitions(test_decode_utf8 PRIVATE TEST) target_link_libraries(test_decode_utf8 utils ${platform_libraries}) +add_executable(test_unicode_norm + utils/unicode-norm.c) +target_compile_definitions(test_unicode_norm PRIVATE TEST) +target_link_libraries(test_unicode_norm utils ${platform_libraries}) + add_executable(test_tree234 utils/tree234.c) target_compile_definitions(test_tree234 PRIVATE TEST) diff --git a/misc.h b/misc.h index c8a8f5ea..ab8c137f 100644 --- a/misc.h +++ b/misc.h @@ -265,6 +265,9 @@ unsigned decode_utf8(BinarySource *src); * number written. */ size_t decode_utf8_to_wchar(BinarySource *src, wchar_t *out); +/* Normalise a UTF-8 string into Normalisation Form C. */ +strbuf *utf8_to_nfc(ptrlen input); + /* Write a string out in C string-literal format. */ void write_c_string_literal(FILE *fp, ptrlen str); diff --git a/unicode/canonical_comp.h b/unicode/canonical_comp.h new file mode 100644 index 00000000..3813418e --- /dev/null +++ b/unicode/canonical_comp.h @@ -0,0 +1,950 @@ +/* + * Autogenerated by read_ucd.py from The Unicode Standard 15.0.0 + * + * List the pairs of Unicode characters that canonically recompose to a + * single character in NFC. + * + * Used by utils/unicode-norm.c. + */ + +{0x003c, 0x0338, 0x226e}, +{0x003d, 0x0338, 0x2260}, +{0x003e, 0x0338, 0x226f}, +{0x0041, 0x0300, 0x00c0}, +{0x0041, 0x0301, 0x00c1}, +{0x0041, 0x0302, 0x00c2}, +{0x0041, 0x0303, 0x00c3}, +{0x0041, 0x0304, 0x0100}, +{0x0041, 0x0306, 0x0102}, +{0x0041, 0x0307, 0x0226}, +{0x0041, 0x0308, 0x00c4}, +{0x0041, 0x0309, 0x1ea2}, +{0x0041, 0x030a, 0x00c5}, +{0x0041, 0x030c, 0x01cd}, +{0x0041, 0x030f, 0x0200}, +{0x0041, 0x0311, 0x0202}, +{0x0041, 0x0323, 0x1ea0}, +{0x0041, 0x0325, 0x1e00}, +{0x0041, 0x0328, 0x0104}, +{0x0042, 0x0307, 0x1e02}, +{0x0042, 0x0323, 0x1e04}, +{0x0042, 0x0331, 0x1e06}, +{0x0043, 0x0301, 0x0106}, +{0x0043, 0x0302, 0x0108}, +{0x0043, 0x0307, 0x010a}, +{0x0043, 0x030c, 0x010c}, +{0x0043, 0x0327, 0x00c7}, +{0x0044, 0x0307, 0x1e0a}, +{0x0044, 0x030c, 0x010e}, +{0x0044, 0x0323, 0x1e0c}, +{0x0044, 0x0327, 0x1e10}, +{0x0044, 0x032d, 0x1e12}, +{0x0044, 0x0331, 0x1e0e}, +{0x0045, 0x0300, 0x00c8}, +{0x0045, 0x0301, 0x00c9}, +{0x0045, 0x0302, 0x00ca}, +{0x0045, 0x0303, 0x1ebc}, +{0x0045, 0x0304, 0x0112}, +{0x0045, 0x0306, 0x0114}, +{0x0045, 0x0307, 0x0116}, +{0x0045, 0x0308, 0x00cb}, +{0x0045, 0x0309, 0x1eba}, +{0x0045, 0x030c, 0x011a}, +{0x0045, 0x030f, 0x0204}, +{0x0045, 0x0311, 0x0206}, +{0x0045, 0x0323, 0x1eb8}, +{0x0045, 0x0327, 0x0228}, +{0x0045, 0x0328, 0x0118}, +{0x0045, 0x032d, 0x1e18}, +{0x0045, 0x0330, 0x1e1a}, +{0x0046, 0x0307, 0x1e1e}, +{0x0047, 0x0301, 0x01f4}, +{0x0047, 0x0302, 0x011c}, +{0x0047, 0x0304, 0x1e20}, +{0x0047, 0x0306, 0x011e}, +{0x0047, 0x0307, 0x0120}, +{0x0047, 0x030c, 0x01e6}, +{0x0047, 0x0327, 0x0122}, +{0x0048, 0x0302, 0x0124}, +{0x0048, 0x0307, 0x1e22}, +{0x0048, 0x0308, 0x1e26}, +{0x0048, 0x030c, 0x021e}, +{0x0048, 0x0323, 0x1e24}, +{0x0048, 0x0327, 0x1e28}, +{0x0048, 0x032e, 0x1e2a}, +{0x0049, 0x0300, 0x00cc}, +{0x0049, 0x0301, 0x00cd}, +{0x0049, 0x0302, 0x00ce}, +{0x0049, 0x0303, 0x0128}, +{0x0049, 0x0304, 0x012a}, +{0x0049, 0x0306, 0x012c}, +{0x0049, 0x0307, 0x0130}, +{0x0049, 0x0308, 0x00cf}, +{0x0049, 0x0309, 0x1ec8}, +{0x0049, 0x030c, 0x01cf}, +{0x0049, 0x030f, 0x0208}, +{0x0049, 0x0311, 0x020a}, +{0x0049, 0x0323, 0x1eca}, +{0x0049, 0x0328, 0x012e}, +{0x0049, 0x0330, 0x1e2c}, +{0x004a, 0x0302, 0x0134}, +{0x004b, 0x0301, 0x1e30}, +{0x004b, 0x030c, 0x01e8}, +{0x004b, 0x0323, 0x1e32}, +{0x004b, 0x0327, 0x0136}, +{0x004b, 0x0331, 0x1e34}, +{0x004c, 0x0301, 0x0139}, +{0x004c, 0x030c, 0x013d}, +{0x004c, 0x0323, 0x1e36}, +{0x004c, 0x0327, 0x013b}, +{0x004c, 0x032d, 0x1e3c}, +{0x004c, 0x0331, 0x1e3a}, +{0x004d, 0x0301, 0x1e3e}, +{0x004d, 0x0307, 0x1e40}, +{0x004d, 0x0323, 0x1e42}, +{0x004e, 0x0300, 0x01f8}, +{0x004e, 0x0301, 0x0143}, +{0x004e, 0x0303, 0x00d1}, +{0x004e, 0x0307, 0x1e44}, +{0x004e, 0x030c, 0x0147}, +{0x004e, 0x0323, 0x1e46}, +{0x004e, 0x0327, 0x0145}, +{0x004e, 0x032d, 0x1e4a}, +{0x004e, 0x0331, 0x1e48}, +{0x004f, 0x0300, 0x00d2}, +{0x004f, 0x0301, 0x00d3}, +{0x004f, 0x0302, 0x00d4}, +{0x004f, 0x0303, 0x00d5}, +{0x004f, 0x0304, 0x014c}, +{0x004f, 0x0306, 0x014e}, +{0x004f, 0x0307, 0x022e}, +{0x004f, 0x0308, 0x00d6}, +{0x004f, 0x0309, 0x1ece}, +{0x004f, 0x030b, 0x0150}, +{0x004f, 0x030c, 0x01d1}, +{0x004f, 0x030f, 0x020c}, +{0x004f, 0x0311, 0x020e}, +{0x004f, 0x031b, 0x01a0}, +{0x004f, 0x0323, 0x1ecc}, +{0x004f, 0x0328, 0x01ea}, +{0x0050, 0x0301, 0x1e54}, +{0x0050, 0x0307, 0x1e56}, +{0x0052, 0x0301, 0x0154}, +{0x0052, 0x0307, 0x1e58}, +{0x0052, 0x030c, 0x0158}, +{0x0052, 0x030f, 0x0210}, +{0x0052, 0x0311, 0x0212}, +{0x0052, 0x0323, 0x1e5a}, +{0x0052, 0x0327, 0x0156}, +{0x0052, 0x0331, 0x1e5e}, +{0x0053, 0x0301, 0x015a}, +{0x0053, 0x0302, 0x015c}, +{0x0053, 0x0307, 0x1e60}, +{0x0053, 0x030c, 0x0160}, +{0x0053, 0x0323, 0x1e62}, +{0x0053, 0x0326, 0x0218}, +{0x0053, 0x0327, 0x015e}, +{0x0054, 0x0307, 0x1e6a}, +{0x0054, 0x030c, 0x0164}, +{0x0054, 0x0323, 0x1e6c}, +{0x0054, 0x0326, 0x021a}, +{0x0054, 0x0327, 0x0162}, +{0x0054, 0x032d, 0x1e70}, +{0x0054, 0x0331, 0x1e6e}, +{0x0055, 0x0300, 0x00d9}, +{0x0055, 0x0301, 0x00da}, +{0x0055, 0x0302, 0x00db}, +{0x0055, 0x0303, 0x0168}, +{0x0055, 0x0304, 0x016a}, +{0x0055, 0x0306, 0x016c}, +{0x0055, 0x0308, 0x00dc}, +{0x0055, 0x0309, 0x1ee6}, +{0x0055, 0x030a, 0x016e}, +{0x0055, 0x030b, 0x0170}, +{0x0055, 0x030c, 0x01d3}, +{0x0055, 0x030f, 0x0214}, +{0x0055, 0x0311, 0x0216}, +{0x0055, 0x031b, 0x01af}, +{0x0055, 0x0323, 0x1ee4}, +{0x0055, 0x0324, 0x1e72}, +{0x0055, 0x0328, 0x0172}, +{0x0055, 0x032d, 0x1e76}, +{0x0055, 0x0330, 0x1e74}, +{0x0056, 0x0303, 0x1e7c}, +{0x0056, 0x0323, 0x1e7e}, +{0x0057, 0x0300, 0x1e80}, +{0x0057, 0x0301, 0x1e82}, +{0x0057, 0x0302, 0x0174}, +{0x0057, 0x0307, 0x1e86}, +{0x0057, 0x0308, 0x1e84}, +{0x0057, 0x0323, 0x1e88}, +{0x0058, 0x0307, 0x1e8a}, +{0x0058, 0x0308, 0x1e8c}, +{0x0059, 0x0300, 0x1ef2}, +{0x0059, 0x0301, 0x00dd}, +{0x0059, 0x0302, 0x0176}, +{0x0059, 0x0303, 0x1ef8}, +{0x0059, 0x0304, 0x0232}, +{0x0059, 0x0307, 0x1e8e}, +{0x0059, 0x0308, 0x0178}, +{0x0059, 0x0309, 0x1ef6}, +{0x0059, 0x0323, 0x1ef4}, +{0x005a, 0x0301, 0x0179}, +{0x005a, 0x0302, 0x1e90}, +{0x005a, 0x0307, 0x017b}, +{0x005a, 0x030c, 0x017d}, +{0x005a, 0x0323, 0x1e92}, +{0x005a, 0x0331, 0x1e94}, +{0x0061, 0x0300, 0x00e0}, +{0x0061, 0x0301, 0x00e1}, +{0x0061, 0x0302, 0x00e2}, +{0x0061, 0x0303, 0x00e3}, +{0x0061, 0x0304, 0x0101}, +{0x0061, 0x0306, 0x0103}, +{0x0061, 0x0307, 0x0227}, +{0x0061, 0x0308, 0x00e4}, +{0x0061, 0x0309, 0x1ea3}, +{0x0061, 0x030a, 0x00e5}, +{0x0061, 0x030c, 0x01ce}, +{0x0061, 0x030f, 0x0201}, +{0x0061, 0x0311, 0x0203}, +{0x0061, 0x0323, 0x1ea1}, +{0x0061, 0x0325, 0x1e01}, +{0x0061, 0x0328, 0x0105}, +{0x0062, 0x0307, 0x1e03}, +{0x0062, 0x0323, 0x1e05}, +{0x0062, 0x0331, 0x1e07}, +{0x0063, 0x0301, 0x0107}, +{0x0063, 0x0302, 0x0109}, +{0x0063, 0x0307, 0x010b}, +{0x0063, 0x030c, 0x010d}, +{0x0063, 0x0327, 0x00e7}, +{0x0064, 0x0307, 0x1e0b}, +{0x0064, 0x030c, 0x010f}, +{0x0064, 0x0323, 0x1e0d}, +{0x0064, 0x0327, 0x1e11}, +{0x0064, 0x032d, 0x1e13}, +{0x0064, 0x0331, 0x1e0f}, +{0x0065, 0x0300, 0x00e8}, +{0x0065, 0x0301, 0x00e9}, +{0x0065, 0x0302, 0x00ea}, +{0x0065, 0x0303, 0x1ebd}, +{0x0065, 0x0304, 0x0113}, +{0x0065, 0x0306, 0x0115}, +{0x0065, 0x0307, 0x0117}, +{0x0065, 0x0308, 0x00eb}, +{0x0065, 0x0309, 0x1ebb}, +{0x0065, 0x030c, 0x011b}, +{0x0065, 0x030f, 0x0205}, +{0x0065, 0x0311, 0x0207}, +{0x0065, 0x0323, 0x1eb9}, +{0x0065, 0x0327, 0x0229}, +{0x0065, 0x0328, 0x0119}, +{0x0065, 0x032d, 0x1e19}, +{0x0065, 0x0330, 0x1e1b}, +{0x0066, 0x0307, 0x1e1f}, +{0x0067, 0x0301, 0x01f5}, +{0x0067, 0x0302, 0x011d}, +{0x0067, 0x0304, 0x1e21}, +{0x0067, 0x0306, 0x011f}, +{0x0067, 0x0307, 0x0121}, +{0x0067, 0x030c, 0x01e7}, +{0x0067, 0x0327, 0x0123}, +{0x0068, 0x0302, 0x0125}, +{0x0068, 0x0307, 0x1e23}, +{0x0068, 0x0308, 0x1e27}, +{0x0068, 0x030c, 0x021f}, +{0x0068, 0x0323, 0x1e25}, +{0x0068, 0x0327, 0x1e29}, +{0x0068, 0x032e, 0x1e2b}, +{0x0068, 0x0331, 0x1e96}, +{0x0069, 0x0300, 0x00ec}, +{0x0069, 0x0301, 0x00ed}, +{0x0069, 0x0302, 0x00ee}, +{0x0069, 0x0303, 0x0129}, +{0x0069, 0x0304, 0x012b}, +{0x0069, 0x0306, 0x012d}, +{0x0069, 0x0308, 0x00ef}, +{0x0069, 0x0309, 0x1ec9}, +{0x0069, 0x030c, 0x01d0}, +{0x0069, 0x030f, 0x0209}, +{0x0069, 0x0311, 0x020b}, +{0x0069, 0x0323, 0x1ecb}, +{0x0069, 0x0328, 0x012f}, +{0x0069, 0x0330, 0x1e2d}, +{0x006a, 0x0302, 0x0135}, +{0x006a, 0x030c, 0x01f0}, +{0x006b, 0x0301, 0x1e31}, +{0x006b, 0x030c, 0x01e9}, +{0x006b, 0x0323, 0x1e33}, +{0x006b, 0x0327, 0x0137}, +{0x006b, 0x0331, 0x1e35}, +{0x006c, 0x0301, 0x013a}, +{0x006c, 0x030c, 0x013e}, +{0x006c, 0x0323, 0x1e37}, +{0x006c, 0x0327, 0x013c}, +{0x006c, 0x032d, 0x1e3d}, +{0x006c, 0x0331, 0x1e3b}, +{0x006d, 0x0301, 0x1e3f}, +{0x006d, 0x0307, 0x1e41}, +{0x006d, 0x0323, 0x1e43}, +{0x006e, 0x0300, 0x01f9}, +{0x006e, 0x0301, 0x0144}, +{0x006e, 0x0303, 0x00f1}, +{0x006e, 0x0307, 0x1e45}, +{0x006e, 0x030c, 0x0148}, +{0x006e, 0x0323, 0x1e47}, +{0x006e, 0x0327, 0x0146}, +{0x006e, 0x032d, 0x1e4b}, +{0x006e, 0x0331, 0x1e49}, +{0x006f, 0x0300, 0x00f2}, +{0x006f, 0x0301, 0x00f3}, +{0x006f, 0x0302, 0x00f4}, +{0x006f, 0x0303, 0x00f5}, +{0x006f, 0x0304, 0x014d}, +{0x006f, 0x0306, 0x014f}, +{0x006f, 0x0307, 0x022f}, +{0x006f, 0x0308, 0x00f6}, +{0x006f, 0x0309, 0x1ecf}, +{0x006f, 0x030b, 0x0151}, +{0x006f, 0x030c, 0x01d2}, +{0x006f, 0x030f, 0x020d}, +{0x006f, 0x0311, 0x020f}, +{0x006f, 0x031b, 0x01a1}, +{0x006f, 0x0323, 0x1ecd}, +{0x006f, 0x0328, 0x01eb}, +{0x0070, 0x0301, 0x1e55}, +{0x0070, 0x0307, 0x1e57}, +{0x0072, 0x0301, 0x0155}, +{0x0072, 0x0307, 0x1e59}, +{0x0072, 0x030c, 0x0159}, +{0x0072, 0x030f, 0x0211}, +{0x0072, 0x0311, 0x0213}, +{0x0072, 0x0323, 0x1e5b}, +{0x0072, 0x0327, 0x0157}, +{0x0072, 0x0331, 0x1e5f}, +{0x0073, 0x0301, 0x015b}, +{0x0073, 0x0302, 0x015d}, +{0x0073, 0x0307, 0x1e61}, +{0x0073, 0x030c, 0x0161}, +{0x0073, 0x0323, 0x1e63}, +{0x0073, 0x0326, 0x0219}, +{0x0073, 0x0327, 0x015f}, +{0x0074, 0x0307, 0x1e6b}, +{0x0074, 0x0308, 0x1e97}, +{0x0074, 0x030c, 0x0165}, +{0x0074, 0x0323, 0x1e6d}, +{0x0074, 0x0326, 0x021b}, +{0x0074, 0x0327, 0x0163}, +{0x0074, 0x032d, 0x1e71}, +{0x0074, 0x0331, 0x1e6f}, +{0x0075, 0x0300, 0x00f9}, +{0x0075, 0x0301, 0x00fa}, +{0x0075, 0x0302, 0x00fb}, +{0x0075, 0x0303, 0x0169}, +{0x0075, 0x0304, 0x016b}, +{0x0075, 0x0306, 0x016d}, +{0x0075, 0x0308, 0x00fc}, +{0x0075, 0x0309, 0x1ee7}, +{0x0075, 0x030a, 0x016f}, +{0x0075, 0x030b, 0x0171}, +{0x0075, 0x030c, 0x01d4}, +{0x0075, 0x030f, 0x0215}, +{0x0075, 0x0311, 0x0217}, +{0x0075, 0x031b, 0x01b0}, +{0x0075, 0x0323, 0x1ee5}, +{0x0075, 0x0324, 0x1e73}, +{0x0075, 0x0328, 0x0173}, +{0x0075, 0x032d, 0x1e77}, +{0x0075, 0x0330, 0x1e75}, +{0x0076, 0x0303, 0x1e7d}, +{0x0076, 0x0323, 0x1e7f}, +{0x0077, 0x0300, 0x1e81}, +{0x0077, 0x0301, 0x1e83}, +{0x0077, 0x0302, 0x0175}, +{0x0077, 0x0307, 0x1e87}, +{0x0077, 0x0308, 0x1e85}, +{0x0077, 0x030a, 0x1e98}, +{0x0077, 0x0323, 0x1e89}, +{0x0078, 0x0307, 0x1e8b}, +{0x0078, 0x0308, 0x1e8d}, +{0x0079, 0x0300, 0x1ef3}, +{0x0079, 0x0301, 0x00fd}, +{0x0079, 0x0302, 0x0177}, +{0x0079, 0x0303, 0x1ef9}, +{0x0079, 0x0304, 0x0233}, +{0x0079, 0x0307, 0x1e8f}, +{0x0079, 0x0308, 0x00ff}, +{0x0079, 0x0309, 0x1ef7}, +{0x0079, 0x030a, 0x1e99}, +{0x0079, 0x0323, 0x1ef5}, +{0x007a, 0x0301, 0x017a}, +{0x007a, 0x0302, 0x1e91}, +{0x007a, 0x0307, 0x017c}, +{0x007a, 0x030c, 0x017e}, +{0x007a, 0x0323, 0x1e93}, +{0x007a, 0x0331, 0x1e95}, +{0x00a8, 0x0300, 0x1fed}, +{0x00a8, 0x0301, 0x0385}, +{0x00a8, 0x0342, 0x1fc1}, +{0x00c2, 0x0300, 0x1ea6}, +{0x00c2, 0x0301, 0x1ea4}, +{0x00c2, 0x0303, 0x1eaa}, +{0x00c2, 0x0309, 0x1ea8}, +{0x00c4, 0x0304, 0x01de}, +{0x00c5, 0x0301, 0x01fa}, +{0x00c6, 0x0301, 0x01fc}, +{0x00c6, 0x0304, 0x01e2}, +{0x00c7, 0x0301, 0x1e08}, +{0x00ca, 0x0300, 0x1ec0}, +{0x00ca, 0x0301, 0x1ebe}, +{0x00ca, 0x0303, 0x1ec4}, +{0x00ca, 0x0309, 0x1ec2}, +{0x00cf, 0x0301, 0x1e2e}, +{0x00d4, 0x0300, 0x1ed2}, +{0x00d4, 0x0301, 0x1ed0}, +{0x00d4, 0x0303, 0x1ed6}, +{0x00d4, 0x0309, 0x1ed4}, +{0x00d5, 0x0301, 0x1e4c}, +{0x00d5, 0x0304, 0x022c}, +{0x00d5, 0x0308, 0x1e4e}, +{0x00d6, 0x0304, 0x022a}, +{0x00d8, 0x0301, 0x01fe}, +{0x00dc, 0x0300, 0x01db}, +{0x00dc, 0x0301, 0x01d7}, +{0x00dc, 0x0304, 0x01d5}, +{0x00dc, 0x030c, 0x01d9}, +{0x00e2, 0x0300, 0x1ea7}, +{0x00e2, 0x0301, 0x1ea5}, +{0x00e2, 0x0303, 0x1eab}, +{0x00e2, 0x0309, 0x1ea9}, +{0x00e4, 0x0304, 0x01df}, +{0x00e5, 0x0301, 0x01fb}, +{0x00e6, 0x0301, 0x01fd}, +{0x00e6, 0x0304, 0x01e3}, +{0x00e7, 0x0301, 0x1e09}, +{0x00ea, 0x0300, 0x1ec1}, +{0x00ea, 0x0301, 0x1ebf}, +{0x00ea, 0x0303, 0x1ec5}, +{0x00ea, 0x0309, 0x1ec3}, +{0x00ef, 0x0301, 0x1e2f}, +{0x00f4, 0x0300, 0x1ed3}, +{0x00f4, 0x0301, 0x1ed1}, +{0x00f4, 0x0303, 0x1ed7}, +{0x00f4, 0x0309, 0x1ed5}, +{0x00f5, 0x0301, 0x1e4d}, +{0x00f5, 0x0304, 0x022d}, +{0x00f5, 0x0308, 0x1e4f}, +{0x00f6, 0x0304, 0x022b}, +{0x00f8, 0x0301, 0x01ff}, +{0x00fc, 0x0300, 0x01dc}, +{0x00fc, 0x0301, 0x01d8}, +{0x00fc, 0x0304, 0x01d6}, +{0x00fc, 0x030c, 0x01da}, +{0x0102, 0x0300, 0x1eb0}, +{0x0102, 0x0301, 0x1eae}, +{0x0102, 0x0303, 0x1eb4}, +{0x0102, 0x0309, 0x1eb2}, +{0x0103, 0x0300, 0x1eb1}, +{0x0103, 0x0301, 0x1eaf}, +{0x0103, 0x0303, 0x1eb5}, +{0x0103, 0x0309, 0x1eb3}, +{0x0112, 0x0300, 0x1e14}, +{0x0112, 0x0301, 0x1e16}, +{0x0113, 0x0300, 0x1e15}, +{0x0113, 0x0301, 0x1e17}, +{0x014c, 0x0300, 0x1e50}, +{0x014c, 0x0301, 0x1e52}, +{0x014d, 0x0300, 0x1e51}, +{0x014d, 0x0301, 0x1e53}, +{0x015a, 0x0307, 0x1e64}, +{0x015b, 0x0307, 0x1e65}, +{0x0160, 0x0307, 0x1e66}, +{0x0161, 0x0307, 0x1e67}, +{0x0168, 0x0301, 0x1e78}, +{0x0169, 0x0301, 0x1e79}, +{0x016a, 0x0308, 0x1e7a}, +{0x016b, 0x0308, 0x1e7b}, +{0x017f, 0x0307, 0x1e9b}, +{0x01a0, 0x0300, 0x1edc}, +{0x01a0, 0x0301, 0x1eda}, +{0x01a0, 0x0303, 0x1ee0}, +{0x01a0, 0x0309, 0x1ede}, +{0x01a0, 0x0323, 0x1ee2}, +{0x01a1, 0x0300, 0x1edd}, +{0x01a1, 0x0301, 0x1edb}, +{0x01a1, 0x0303, 0x1ee1}, +{0x01a1, 0x0309, 0x1edf}, +{0x01a1, 0x0323, 0x1ee3}, +{0x01af, 0x0300, 0x1eea}, +{0x01af, 0x0301, 0x1ee8}, +{0x01af, 0x0303, 0x1eee}, +{0x01af, 0x0309, 0x1eec}, +{0x01af, 0x0323, 0x1ef0}, +{0x01b0, 0x0300, 0x1eeb}, +{0x01b0, 0x0301, 0x1ee9}, +{0x01b0, 0x0303, 0x1eef}, +{0x01b0, 0x0309, 0x1eed}, +{0x01b0, 0x0323, 0x1ef1}, +{0x01b7, 0x030c, 0x01ee}, +{0x01ea, 0x0304, 0x01ec}, +{0x01eb, 0x0304, 0x01ed}, +{0x0226, 0x0304, 0x01e0}, +{0x0227, 0x0304, 0x01e1}, +{0x0228, 0x0306, 0x1e1c}, +{0x0229, 0x0306, 0x1e1d}, +{0x022e, 0x0304, 0x0230}, +{0x022f, 0x0304, 0x0231}, +{0x0292, 0x030c, 0x01ef}, +{0x0391, 0x0300, 0x1fba}, +{0x0391, 0x0301, 0x0386}, +{0x0391, 0x0304, 0x1fb9}, +{0x0391, 0x0306, 0x1fb8}, +{0x0391, 0x0313, 0x1f08}, +{0x0391, 0x0314, 0x1f09}, +{0x0391, 0x0345, 0x1fbc}, +{0x0395, 0x0300, 0x1fc8}, +{0x0395, 0x0301, 0x0388}, +{0x0395, 0x0313, 0x1f18}, +{0x0395, 0x0314, 0x1f19}, +{0x0397, 0x0300, 0x1fca}, +{0x0397, 0x0301, 0x0389}, +{0x0397, 0x0313, 0x1f28}, +{0x0397, 0x0314, 0x1f29}, +{0x0397, 0x0345, 0x1fcc}, +{0x0399, 0x0300, 0x1fda}, +{0x0399, 0x0301, 0x038a}, +{0x0399, 0x0304, 0x1fd9}, +{0x0399, 0x0306, 0x1fd8}, +{0x0399, 0x0308, 0x03aa}, +{0x0399, 0x0313, 0x1f38}, +{0x0399, 0x0314, 0x1f39}, +{0x039f, 0x0300, 0x1ff8}, +{0x039f, 0x0301, 0x038c}, +{0x039f, 0x0313, 0x1f48}, +{0x039f, 0x0314, 0x1f49}, +{0x03a1, 0x0314, 0x1fec}, +{0x03a5, 0x0300, 0x1fea}, +{0x03a5, 0x0301, 0x038e}, +{0x03a5, 0x0304, 0x1fe9}, +{0x03a5, 0x0306, 0x1fe8}, +{0x03a5, 0x0308, 0x03ab}, +{0x03a5, 0x0314, 0x1f59}, +{0x03a9, 0x0300, 0x1ffa}, +{0x03a9, 0x0301, 0x038f}, +{0x03a9, 0x0313, 0x1f68}, +{0x03a9, 0x0314, 0x1f69}, +{0x03a9, 0x0345, 0x1ffc}, +{0x03ac, 0x0345, 0x1fb4}, +{0x03ae, 0x0345, 0x1fc4}, +{0x03b1, 0x0300, 0x1f70}, +{0x03b1, 0x0301, 0x03ac}, +{0x03b1, 0x0304, 0x1fb1}, +{0x03b1, 0x0306, 0x1fb0}, +{0x03b1, 0x0313, 0x1f00}, +{0x03b1, 0x0314, 0x1f01}, +{0x03b1, 0x0342, 0x1fb6}, +{0x03b1, 0x0345, 0x1fb3}, +{0x03b5, 0x0300, 0x1f72}, +{0x03b5, 0x0301, 0x03ad}, +{0x03b5, 0x0313, 0x1f10}, +{0x03b5, 0x0314, 0x1f11}, +{0x03b7, 0x0300, 0x1f74}, +{0x03b7, 0x0301, 0x03ae}, +{0x03b7, 0x0313, 0x1f20}, +{0x03b7, 0x0314, 0x1f21}, +{0x03b7, 0x0342, 0x1fc6}, +{0x03b7, 0x0345, 0x1fc3}, +{0x03b9, 0x0300, 0x1f76}, +{0x03b9, 0x0301, 0x03af}, +{0x03b9, 0x0304, 0x1fd1}, +{0x03b9, 0x0306, 0x1fd0}, +{0x03b9, 0x0308, 0x03ca}, +{0x03b9, 0x0313, 0x1f30}, +{0x03b9, 0x0314, 0x1f31}, +{0x03b9, 0x0342, 0x1fd6}, +{0x03bf, 0x0300, 0x1f78}, +{0x03bf, 0x0301, 0x03cc}, +{0x03bf, 0x0313, 0x1f40}, +{0x03bf, 0x0314, 0x1f41}, +{0x03c1, 0x0313, 0x1fe4}, +{0x03c1, 0x0314, 0x1fe5}, +{0x03c5, 0x0300, 0x1f7a}, +{0x03c5, 0x0301, 0x03cd}, +{0x03c5, 0x0304, 0x1fe1}, +{0x03c5, 0x0306, 0x1fe0}, +{0x03c5, 0x0308, 0x03cb}, +{0x03c5, 0x0313, 0x1f50}, +{0x03c5, 0x0314, 0x1f51}, +{0x03c5, 0x0342, 0x1fe6}, +{0x03c9, 0x0300, 0x1f7c}, +{0x03c9, 0x0301, 0x03ce}, +{0x03c9, 0x0313, 0x1f60}, +{0x03c9, 0x0314, 0x1f61}, +{0x03c9, 0x0342, 0x1ff6}, +{0x03c9, 0x0345, 0x1ff3}, +{0x03ca, 0x0300, 0x1fd2}, +{0x03ca, 0x0301, 0x0390}, +{0x03ca, 0x0342, 0x1fd7}, +{0x03cb, 0x0300, 0x1fe2}, +{0x03cb, 0x0301, 0x03b0}, +{0x03cb, 0x0342, 0x1fe7}, +{0x03ce, 0x0345, 0x1ff4}, +{0x03d2, 0x0301, 0x03d3}, +{0x03d2, 0x0308, 0x03d4}, +{0x0406, 0x0308, 0x0407}, +{0x0410, 0x0306, 0x04d0}, +{0x0410, 0x0308, 0x04d2}, +{0x0413, 0x0301, 0x0403}, +{0x0415, 0x0300, 0x0400}, +{0x0415, 0x0306, 0x04d6}, +{0x0415, 0x0308, 0x0401}, +{0x0416, 0x0306, 0x04c1}, +{0x0416, 0x0308, 0x04dc}, +{0x0417, 0x0308, 0x04de}, +{0x0418, 0x0300, 0x040d}, +{0x0418, 0x0304, 0x04e2}, +{0x0418, 0x0306, 0x0419}, +{0x0418, 0x0308, 0x04e4}, +{0x041a, 0x0301, 0x040c}, +{0x041e, 0x0308, 0x04e6}, +{0x0423, 0x0304, 0x04ee}, +{0x0423, 0x0306, 0x040e}, +{0x0423, 0x0308, 0x04f0}, +{0x0423, 0x030b, 0x04f2}, +{0x0427, 0x0308, 0x04f4}, +{0x042b, 0x0308, 0x04f8}, +{0x042d, 0x0308, 0x04ec}, +{0x0430, 0x0306, 0x04d1}, +{0x0430, 0x0308, 0x04d3}, +{0x0433, 0x0301, 0x0453}, +{0x0435, 0x0300, 0x0450}, +{0x0435, 0x0306, 0x04d7}, +{0x0435, 0x0308, 0x0451}, +{0x0436, 0x0306, 0x04c2}, +{0x0436, 0x0308, 0x04dd}, +{0x0437, 0x0308, 0x04df}, +{0x0438, 0x0300, 0x045d}, +{0x0438, 0x0304, 0x04e3}, +{0x0438, 0x0306, 0x0439}, +{0x0438, 0x0308, 0x04e5}, +{0x043a, 0x0301, 0x045c}, +{0x043e, 0x0308, 0x04e7}, +{0x0443, 0x0304, 0x04ef}, +{0x0443, 0x0306, 0x045e}, +{0x0443, 0x0308, 0x04f1}, +{0x0443, 0x030b, 0x04f3}, +{0x0447, 0x0308, 0x04f5}, +{0x044b, 0x0308, 0x04f9}, +{0x044d, 0x0308, 0x04ed}, +{0x0456, 0x0308, 0x0457}, +{0x0474, 0x030f, 0x0476}, +{0x0475, 0x030f, 0x0477}, +{0x04d8, 0x0308, 0x04da}, +{0x04d9, 0x0308, 0x04db}, +{0x04e8, 0x0308, 0x04ea}, +{0x04e9, 0x0308, 0x04eb}, +{0x0627, 0x0653, 0x0622}, +{0x0627, 0x0654, 0x0623}, +{0x0627, 0x0655, 0x0625}, +{0x0648, 0x0654, 0x0624}, +{0x064a, 0x0654, 0x0626}, +{0x06c1, 0x0654, 0x06c2}, +{0x06d2, 0x0654, 0x06d3}, +{0x06d5, 0x0654, 0x06c0}, +{0x0928, 0x093c, 0x0929}, +{0x0930, 0x093c, 0x0931}, +{0x0933, 0x093c, 0x0934}, +{0x09c7, 0x09be, 0x09cb}, +{0x09c7, 0x09d7, 0x09cc}, +{0x0b47, 0x0b3e, 0x0b4b}, +{0x0b47, 0x0b56, 0x0b48}, +{0x0b47, 0x0b57, 0x0b4c}, +{0x0b92, 0x0bd7, 0x0b94}, +{0x0bc6, 0x0bbe, 0x0bca}, +{0x0bc6, 0x0bd7, 0x0bcc}, +{0x0bc7, 0x0bbe, 0x0bcb}, +{0x0c46, 0x0c56, 0x0c48}, +{0x0cbf, 0x0cd5, 0x0cc0}, +{0x0cc6, 0x0cc2, 0x0cca}, +{0x0cc6, 0x0cd5, 0x0cc7}, +{0x0cc6, 0x0cd6, 0x0cc8}, +{0x0cca, 0x0cd5, 0x0ccb}, +{0x0d46, 0x0d3e, 0x0d4a}, +{0x0d46, 0x0d57, 0x0d4c}, +{0x0d47, 0x0d3e, 0x0d4b}, +{0x0dd9, 0x0dca, 0x0dda}, +{0x0dd9, 0x0dcf, 0x0ddc}, +{0x0dd9, 0x0ddf, 0x0dde}, +{0x0ddc, 0x0dca, 0x0ddd}, +{0x1025, 0x102e, 0x1026}, +{0x1b05, 0x1b35, 0x1b06}, +{0x1b07, 0x1b35, 0x1b08}, +{0x1b09, 0x1b35, 0x1b0a}, +{0x1b0b, 0x1b35, 0x1b0c}, +{0x1b0d, 0x1b35, 0x1b0e}, +{0x1b11, 0x1b35, 0x1b12}, +{0x1b3a, 0x1b35, 0x1b3b}, +{0x1b3c, 0x1b35, 0x1b3d}, +{0x1b3e, 0x1b35, 0x1b40}, +{0x1b3f, 0x1b35, 0x1b41}, +{0x1b42, 0x1b35, 0x1b43}, +{0x1e36, 0x0304, 0x1e38}, +{0x1e37, 0x0304, 0x1e39}, +{0x1e5a, 0x0304, 0x1e5c}, +{0x1e5b, 0x0304, 0x1e5d}, +{0x1e62, 0x0307, 0x1e68}, +{0x1e63, 0x0307, 0x1e69}, +{0x1ea0, 0x0302, 0x1eac}, +{0x1ea0, 0x0306, 0x1eb6}, +{0x1ea1, 0x0302, 0x1ead}, +{0x1ea1, 0x0306, 0x1eb7}, +{0x1eb8, 0x0302, 0x1ec6}, +{0x1eb9, 0x0302, 0x1ec7}, +{0x1ecc, 0x0302, 0x1ed8}, +{0x1ecd, 0x0302, 0x1ed9}, +{0x1f00, 0x0300, 0x1f02}, +{0x1f00, 0x0301, 0x1f04}, +{0x1f00, 0x0342, 0x1f06}, +{0x1f00, 0x0345, 0x1f80}, +{0x1f01, 0x0300, 0x1f03}, +{0x1f01, 0x0301, 0x1f05}, +{0x1f01, 0x0342, 0x1f07}, +{0x1f01, 0x0345, 0x1f81}, +{0x1f02, 0x0345, 0x1f82}, +{0x1f03, 0x0345, 0x1f83}, +{0x1f04, 0x0345, 0x1f84}, +{0x1f05, 0x0345, 0x1f85}, +{0x1f06, 0x0345, 0x1f86}, +{0x1f07, 0x0345, 0x1f87}, +{0x1f08, 0x0300, 0x1f0a}, +{0x1f08, 0x0301, 0x1f0c}, +{0x1f08, 0x0342, 0x1f0e}, +{0x1f08, 0x0345, 0x1f88}, +{0x1f09, 0x0300, 0x1f0b}, +{0x1f09, 0x0301, 0x1f0d}, +{0x1f09, 0x0342, 0x1f0f}, +{0x1f09, 0x0345, 0x1f89}, +{0x1f0a, 0x0345, 0x1f8a}, +{0x1f0b, 0x0345, 0x1f8b}, +{0x1f0c, 0x0345, 0x1f8c}, +{0x1f0d, 0x0345, 0x1f8d}, +{0x1f0e, 0x0345, 0x1f8e}, +{0x1f0f, 0x0345, 0x1f8f}, +{0x1f10, 0x0300, 0x1f12}, +{0x1f10, 0x0301, 0x1f14}, +{0x1f11, 0x0300, 0x1f13}, +{0x1f11, 0x0301, 0x1f15}, +{0x1f18, 0x0300, 0x1f1a}, +{0x1f18, 0x0301, 0x1f1c}, +{0x1f19, 0x0300, 0x1f1b}, +{0x1f19, 0x0301, 0x1f1d}, +{0x1f20, 0x0300, 0x1f22}, +{0x1f20, 0x0301, 0x1f24}, +{0x1f20, 0x0342, 0x1f26}, +{0x1f20, 0x0345, 0x1f90}, +{0x1f21, 0x0300, 0x1f23}, +{0x1f21, 0x0301, 0x1f25}, +{0x1f21, 0x0342, 0x1f27}, +{0x1f21, 0x0345, 0x1f91}, +{0x1f22, 0x0345, 0x1f92}, +{0x1f23, 0x0345, 0x1f93}, +{0x1f24, 0x0345, 0x1f94}, +{0x1f25, 0x0345, 0x1f95}, +{0x1f26, 0x0345, 0x1f96}, +{0x1f27, 0x0345, 0x1f97}, +{0x1f28, 0x0300, 0x1f2a}, +{0x1f28, 0x0301, 0x1f2c}, +{0x1f28, 0x0342, 0x1f2e}, +{0x1f28, 0x0345, 0x1f98}, +{0x1f29, 0x0300, 0x1f2b}, +{0x1f29, 0x0301, 0x1f2d}, +{0x1f29, 0x0342, 0x1f2f}, +{0x1f29, 0x0345, 0x1f99}, +{0x1f2a, 0x0345, 0x1f9a}, +{0x1f2b, 0x0345, 0x1f9b}, +{0x1f2c, 0x0345, 0x1f9c}, +{0x1f2d, 0x0345, 0x1f9d}, +{0x1f2e, 0x0345, 0x1f9e}, +{0x1f2f, 0x0345, 0x1f9f}, +{0x1f30, 0x0300, 0x1f32}, +{0x1f30, 0x0301, 0x1f34}, +{0x1f30, 0x0342, 0x1f36}, +{0x1f31, 0x0300, 0x1f33}, +{0x1f31, 0x0301, 0x1f35}, +{0x1f31, 0x0342, 0x1f37}, +{0x1f38, 0x0300, 0x1f3a}, +{0x1f38, 0x0301, 0x1f3c}, +{0x1f38, 0x0342, 0x1f3e}, +{0x1f39, 0x0300, 0x1f3b}, +{0x1f39, 0x0301, 0x1f3d}, +{0x1f39, 0x0342, 0x1f3f}, +{0x1f40, 0x0300, 0x1f42}, +{0x1f40, 0x0301, 0x1f44}, +{0x1f41, 0x0300, 0x1f43}, +{0x1f41, 0x0301, 0x1f45}, +{0x1f48, 0x0300, 0x1f4a}, +{0x1f48, 0x0301, 0x1f4c}, +{0x1f49, 0x0300, 0x1f4b}, +{0x1f49, 0x0301, 0x1f4d}, +{0x1f50, 0x0300, 0x1f52}, +{0x1f50, 0x0301, 0x1f54}, +{0x1f50, 0x0342, 0x1f56}, +{0x1f51, 0x0300, 0x1f53}, +{0x1f51, 0x0301, 0x1f55}, +{0x1f51, 0x0342, 0x1f57}, +{0x1f59, 0x0300, 0x1f5b}, +{0x1f59, 0x0301, 0x1f5d}, +{0x1f59, 0x0342, 0x1f5f}, +{0x1f60, 0x0300, 0x1f62}, +{0x1f60, 0x0301, 0x1f64}, +{0x1f60, 0x0342, 0x1f66}, +{0x1f60, 0x0345, 0x1fa0}, +{0x1f61, 0x0300, 0x1f63}, +{0x1f61, 0x0301, 0x1f65}, +{0x1f61, 0x0342, 0x1f67}, +{0x1f61, 0x0345, 0x1fa1}, +{0x1f62, 0x0345, 0x1fa2}, +{0x1f63, 0x0345, 0x1fa3}, +{0x1f64, 0x0345, 0x1fa4}, +{0x1f65, 0x0345, 0x1fa5}, +{0x1f66, 0x0345, 0x1fa6}, +{0x1f67, 0x0345, 0x1fa7}, +{0x1f68, 0x0300, 0x1f6a}, +{0x1f68, 0x0301, 0x1f6c}, +{0x1f68, 0x0342, 0x1f6e}, +{0x1f68, 0x0345, 0x1fa8}, +{0x1f69, 0x0300, 0x1f6b}, +{0x1f69, 0x0301, 0x1f6d}, +{0x1f69, 0x0342, 0x1f6f}, +{0x1f69, 0x0345, 0x1fa9}, +{0x1f6a, 0x0345, 0x1faa}, +{0x1f6b, 0x0345, 0x1fab}, +{0x1f6c, 0x0345, 0x1fac}, +{0x1f6d, 0x0345, 0x1fad}, +{0x1f6e, 0x0345, 0x1fae}, +{0x1f6f, 0x0345, 0x1faf}, +{0x1f70, 0x0345, 0x1fb2}, +{0x1f74, 0x0345, 0x1fc2}, +{0x1f7c, 0x0345, 0x1ff2}, +{0x1fb6, 0x0345, 0x1fb7}, +{0x1fbf, 0x0300, 0x1fcd}, +{0x1fbf, 0x0301, 0x1fce}, +{0x1fbf, 0x0342, 0x1fcf}, +{0x1fc6, 0x0345, 0x1fc7}, +{0x1ff6, 0x0345, 0x1ff7}, +{0x1ffe, 0x0300, 0x1fdd}, +{0x1ffe, 0x0301, 0x1fde}, +{0x1ffe, 0x0342, 0x1fdf}, +{0x2190, 0x0338, 0x219a}, +{0x2192, 0x0338, 0x219b}, +{0x2194, 0x0338, 0x21ae}, +{0x21d0, 0x0338, 0x21cd}, +{0x21d2, 0x0338, 0x21cf}, +{0x21d4, 0x0338, 0x21ce}, +{0x2203, 0x0338, 0x2204}, +{0x2208, 0x0338, 0x2209}, +{0x220b, 0x0338, 0x220c}, +{0x2223, 0x0338, 0x2224}, +{0x2225, 0x0338, 0x2226}, +{0x223c, 0x0338, 0x2241}, +{0x2243, 0x0338, 0x2244}, +{0x2245, 0x0338, 0x2247}, +{0x2248, 0x0338, 0x2249}, +{0x224d, 0x0338, 0x226d}, +{0x2261, 0x0338, 0x2262}, +{0x2264, 0x0338, 0x2270}, +{0x2265, 0x0338, 0x2271}, +{0x2272, 0x0338, 0x2274}, +{0x2273, 0x0338, 0x2275}, +{0x2276, 0x0338, 0x2278}, +{0x2277, 0x0338, 0x2279}, +{0x227a, 0x0338, 0x2280}, +{0x227b, 0x0338, 0x2281}, +{0x227c, 0x0338, 0x22e0}, +{0x227d, 0x0338, 0x22e1}, +{0x2282, 0x0338, 0x2284}, +{0x2283, 0x0338, 0x2285}, +{0x2286, 0x0338, 0x2288}, +{0x2287, 0x0338, 0x2289}, +{0x2291, 0x0338, 0x22e2}, +{0x2292, 0x0338, 0x22e3}, +{0x22a2, 0x0338, 0x22ac}, +{0x22a8, 0x0338, 0x22ad}, +{0x22a9, 0x0338, 0x22ae}, +{0x22ab, 0x0338, 0x22af}, +{0x22b2, 0x0338, 0x22ea}, +{0x22b3, 0x0338, 0x22eb}, +{0x22b4, 0x0338, 0x22ec}, +{0x22b5, 0x0338, 0x22ed}, +{0x3046, 0x3099, 0x3094}, +{0x304b, 0x3099, 0x304c}, +{0x304d, 0x3099, 0x304e}, +{0x304f, 0x3099, 0x3050}, +{0x3051, 0x3099, 0x3052}, +{0x3053, 0x3099, 0x3054}, +{0x3055, 0x3099, 0x3056}, +{0x3057, 0x3099, 0x3058}, +{0x3059, 0x3099, 0x305a}, +{0x305b, 0x3099, 0x305c}, +{0x305d, 0x3099, 0x305e}, +{0x305f, 0x3099, 0x3060}, +{0x3061, 0x3099, 0x3062}, +{0x3064, 0x3099, 0x3065}, +{0x3066, 0x3099, 0x3067}, +{0x3068, 0x3099, 0x3069}, +{0x306f, 0x3099, 0x3070}, +{0x306f, 0x309a, 0x3071}, +{0x3072, 0x3099, 0x3073}, +{0x3072, 0x309a, 0x3074}, +{0x3075, 0x3099, 0x3076}, +{0x3075, 0x309a, 0x3077}, +{0x3078, 0x3099, 0x3079}, +{0x3078, 0x309a, 0x307a}, +{0x307b, 0x3099, 0x307c}, +{0x307b, 0x309a, 0x307d}, +{0x309d, 0x3099, 0x309e}, +{0x30a6, 0x3099, 0x30f4}, +{0x30ab, 0x3099, 0x30ac}, +{0x30ad, 0x3099, 0x30ae}, +{0x30af, 0x3099, 0x30b0}, +{0x30b1, 0x3099, 0x30b2}, +{0x30b3, 0x3099, 0x30b4}, +{0x30b5, 0x3099, 0x30b6}, +{0x30b7, 0x3099, 0x30b8}, +{0x30b9, 0x3099, 0x30ba}, +{0x30bb, 0x3099, 0x30bc}, +{0x30bd, 0x3099, 0x30be}, +{0x30bf, 0x3099, 0x30c0}, +{0x30c1, 0x3099, 0x30c2}, +{0x30c4, 0x3099, 0x30c5}, +{0x30c6, 0x3099, 0x30c7}, +{0x30c8, 0x3099, 0x30c9}, +{0x30cf, 0x3099, 0x30d0}, +{0x30cf, 0x309a, 0x30d1}, +{0x30d2, 0x3099, 0x30d3}, +{0x30d2, 0x309a, 0x30d4}, +{0x30d5, 0x3099, 0x30d6}, +{0x30d5, 0x309a, 0x30d7}, +{0x30d8, 0x3099, 0x30d9}, +{0x30d8, 0x309a, 0x30da}, +{0x30db, 0x3099, 0x30dc}, +{0x30db, 0x309a, 0x30dd}, +{0x30ef, 0x3099, 0x30f7}, +{0x30f0, 0x3099, 0x30f8}, +{0x30f1, 0x3099, 0x30f9}, +{0x30f2, 0x3099, 0x30fa}, +{0x30fd, 0x3099, 0x30fe}, +{0x11099, 0x110ba, 0x1109a}, +{0x1109b, 0x110ba, 0x1109c}, +{0x110a5, 0x110ba, 0x110ab}, +{0x11131, 0x11127, 0x1112e}, +{0x11132, 0x11127, 0x1112f}, +{0x11347, 0x1133e, 0x1134b}, +{0x11347, 0x11357, 0x1134c}, +{0x114b9, 0x114b0, 0x114bc}, +{0x114b9, 0x114ba, 0x114bb}, +{0x114b9, 0x114bd, 0x114be}, +{0x115b8, 0x115af, 0x115ba}, +{0x115b9, 0x115af, 0x115bb}, +{0x11935, 0x11930, 0x11938}, diff --git a/unicode/canonical_decomp.h b/unicode/canonical_decomp.h new file mode 100644 index 00000000..1544e738 --- /dev/null +++ b/unicode/canonical_decomp.h @@ -0,0 +1,2071 @@ +/* + * Autogenerated by read_ucd.py from The Unicode Standard 15.0.0 + * + * List the canonical decomposition of every Unicode character that has + * one. This consists of up to two characters, but those may need + * decomposition in turn. + * + * Used by utils/unicode-norm.c. + */ + +{0x00c0, 0x0041, 0x0300}, +{0x00c1, 0x0041, 0x0301}, +{0x00c2, 0x0041, 0x0302}, +{0x00c3, 0x0041, 0x0303}, +{0x00c4, 0x0041, 0x0308}, +{0x00c5, 0x0041, 0x030a}, +{0x00c7, 0x0043, 0x0327}, +{0x00c8, 0x0045, 0x0300}, +{0x00c9, 0x0045, 0x0301}, +{0x00ca, 0x0045, 0x0302}, +{0x00cb, 0x0045, 0x0308}, +{0x00cc, 0x0049, 0x0300}, +{0x00cd, 0x0049, 0x0301}, +{0x00ce, 0x0049, 0x0302}, +{0x00cf, 0x0049, 0x0308}, +{0x00d1, 0x004e, 0x0303}, +{0x00d2, 0x004f, 0x0300}, +{0x00d3, 0x004f, 0x0301}, +{0x00d4, 0x004f, 0x0302}, +{0x00d5, 0x004f, 0x0303}, +{0x00d6, 0x004f, 0x0308}, +{0x00d9, 0x0055, 0x0300}, +{0x00da, 0x0055, 0x0301}, +{0x00db, 0x0055, 0x0302}, +{0x00dc, 0x0055, 0x0308}, +{0x00dd, 0x0059, 0x0301}, +{0x00e0, 0x0061, 0x0300}, +{0x00e1, 0x0061, 0x0301}, +{0x00e2, 0x0061, 0x0302}, +{0x00e3, 0x0061, 0x0303}, +{0x00e4, 0x0061, 0x0308}, +{0x00e5, 0x0061, 0x030a}, +{0x00e7, 0x0063, 0x0327}, +{0x00e8, 0x0065, 0x0300}, +{0x00e9, 0x0065, 0x0301}, +{0x00ea, 0x0065, 0x0302}, +{0x00eb, 0x0065, 0x0308}, +{0x00ec, 0x0069, 0x0300}, +{0x00ed, 0x0069, 0x0301}, +{0x00ee, 0x0069, 0x0302}, +{0x00ef, 0x0069, 0x0308}, +{0x00f1, 0x006e, 0x0303}, +{0x00f2, 0x006f, 0x0300}, +{0x00f3, 0x006f, 0x0301}, +{0x00f4, 0x006f, 0x0302}, +{0x00f5, 0x006f, 0x0303}, +{0x00f6, 0x006f, 0x0308}, +{0x00f9, 0x0075, 0x0300}, +{0x00fa, 0x0075, 0x0301}, +{0x00fb, 0x0075, 0x0302}, +{0x00fc, 0x0075, 0x0308}, +{0x00fd, 0x0079, 0x0301}, +{0x00ff, 0x0079, 0x0308}, +{0x0100, 0x0041, 0x0304}, +{0x0101, 0x0061, 0x0304}, +{0x0102, 0x0041, 0x0306}, +{0x0103, 0x0061, 0x0306}, +{0x0104, 0x0041, 0x0328}, +{0x0105, 0x0061, 0x0328}, +{0x0106, 0x0043, 0x0301}, +{0x0107, 0x0063, 0x0301}, +{0x0108, 0x0043, 0x0302}, +{0x0109, 0x0063, 0x0302}, +{0x010a, 0x0043, 0x0307}, +{0x010b, 0x0063, 0x0307}, +{0x010c, 0x0043, 0x030c}, +{0x010d, 0x0063, 0x030c}, +{0x010e, 0x0044, 0x030c}, +{0x010f, 0x0064, 0x030c}, +{0x0112, 0x0045, 0x0304}, +{0x0113, 0x0065, 0x0304}, +{0x0114, 0x0045, 0x0306}, +{0x0115, 0x0065, 0x0306}, +{0x0116, 0x0045, 0x0307}, +{0x0117, 0x0065, 0x0307}, +{0x0118, 0x0045, 0x0328}, +{0x0119, 0x0065, 0x0328}, +{0x011a, 0x0045, 0x030c}, +{0x011b, 0x0065, 0x030c}, +{0x011c, 0x0047, 0x0302}, +{0x011d, 0x0067, 0x0302}, +{0x011e, 0x0047, 0x0306}, +{0x011f, 0x0067, 0x0306}, +{0x0120, 0x0047, 0x0307}, +{0x0121, 0x0067, 0x0307}, +{0x0122, 0x0047, 0x0327}, +{0x0123, 0x0067, 0x0327}, +{0x0124, 0x0048, 0x0302}, +{0x0125, 0x0068, 0x0302}, +{0x0128, 0x0049, 0x0303}, +{0x0129, 0x0069, 0x0303}, +{0x012a, 0x0049, 0x0304}, +{0x012b, 0x0069, 0x0304}, +{0x012c, 0x0049, 0x0306}, +{0x012d, 0x0069, 0x0306}, +{0x012e, 0x0049, 0x0328}, +{0x012f, 0x0069, 0x0328}, +{0x0130, 0x0049, 0x0307}, +{0x0134, 0x004a, 0x0302}, +{0x0135, 0x006a, 0x0302}, +{0x0136, 0x004b, 0x0327}, +{0x0137, 0x006b, 0x0327}, +{0x0139, 0x004c, 0x0301}, +{0x013a, 0x006c, 0x0301}, +{0x013b, 0x004c, 0x0327}, +{0x013c, 0x006c, 0x0327}, +{0x013d, 0x004c, 0x030c}, +{0x013e, 0x006c, 0x030c}, +{0x0143, 0x004e, 0x0301}, +{0x0144, 0x006e, 0x0301}, +{0x0145, 0x004e, 0x0327}, +{0x0146, 0x006e, 0x0327}, +{0x0147, 0x004e, 0x030c}, +{0x0148, 0x006e, 0x030c}, +{0x014c, 0x004f, 0x0304}, +{0x014d, 0x006f, 0x0304}, +{0x014e, 0x004f, 0x0306}, +{0x014f, 0x006f, 0x0306}, +{0x0150, 0x004f, 0x030b}, +{0x0151, 0x006f, 0x030b}, +{0x0154, 0x0052, 0x0301}, +{0x0155, 0x0072, 0x0301}, +{0x0156, 0x0052, 0x0327}, +{0x0157, 0x0072, 0x0327}, +{0x0158, 0x0052, 0x030c}, +{0x0159, 0x0072, 0x030c}, +{0x015a, 0x0053, 0x0301}, +{0x015b, 0x0073, 0x0301}, +{0x015c, 0x0053, 0x0302}, +{0x015d, 0x0073, 0x0302}, +{0x015e, 0x0053, 0x0327}, +{0x015f, 0x0073, 0x0327}, +{0x0160, 0x0053, 0x030c}, +{0x0161, 0x0073, 0x030c}, +{0x0162, 0x0054, 0x0327}, +{0x0163, 0x0074, 0x0327}, +{0x0164, 0x0054, 0x030c}, +{0x0165, 0x0074, 0x030c}, +{0x0168, 0x0055, 0x0303}, +{0x0169, 0x0075, 0x0303}, +{0x016a, 0x0055, 0x0304}, +{0x016b, 0x0075, 0x0304}, +{0x016c, 0x0055, 0x0306}, +{0x016d, 0x0075, 0x0306}, +{0x016e, 0x0055, 0x030a}, +{0x016f, 0x0075, 0x030a}, +{0x0170, 0x0055, 0x030b}, +{0x0171, 0x0075, 0x030b}, +{0x0172, 0x0055, 0x0328}, +{0x0173, 0x0075, 0x0328}, +{0x0174, 0x0057, 0x0302}, +{0x0175, 0x0077, 0x0302}, +{0x0176, 0x0059, 0x0302}, +{0x0177, 0x0079, 0x0302}, +{0x0178, 0x0059, 0x0308}, +{0x0179, 0x005a, 0x0301}, +{0x017a, 0x007a, 0x0301}, +{0x017b, 0x005a, 0x0307}, +{0x017c, 0x007a, 0x0307}, +{0x017d, 0x005a, 0x030c}, +{0x017e, 0x007a, 0x030c}, +{0x01a0, 0x004f, 0x031b}, +{0x01a1, 0x006f, 0x031b}, +{0x01af, 0x0055, 0x031b}, +{0x01b0, 0x0075, 0x031b}, +{0x01cd, 0x0041, 0x030c}, +{0x01ce, 0x0061, 0x030c}, +{0x01cf, 0x0049, 0x030c}, +{0x01d0, 0x0069, 0x030c}, +{0x01d1, 0x004f, 0x030c}, +{0x01d2, 0x006f, 0x030c}, +{0x01d3, 0x0055, 0x030c}, +{0x01d4, 0x0075, 0x030c}, +{0x01d5, 0x00dc, 0x0304}, +{0x01d6, 0x00fc, 0x0304}, +{0x01d7, 0x00dc, 0x0301}, +{0x01d8, 0x00fc, 0x0301}, +{0x01d9, 0x00dc, 0x030c}, +{0x01da, 0x00fc, 0x030c}, +{0x01db, 0x00dc, 0x0300}, +{0x01dc, 0x00fc, 0x0300}, +{0x01de, 0x00c4, 0x0304}, +{0x01df, 0x00e4, 0x0304}, +{0x01e0, 0x0226, 0x0304}, +{0x01e1, 0x0227, 0x0304}, +{0x01e2, 0x00c6, 0x0304}, +{0x01e3, 0x00e6, 0x0304}, +{0x01e6, 0x0047, 0x030c}, +{0x01e7, 0x0067, 0x030c}, +{0x01e8, 0x004b, 0x030c}, +{0x01e9, 0x006b, 0x030c}, +{0x01ea, 0x004f, 0x0328}, +{0x01eb, 0x006f, 0x0328}, +{0x01ec, 0x01ea, 0x0304}, +{0x01ed, 0x01eb, 0x0304}, +{0x01ee, 0x01b7, 0x030c}, +{0x01ef, 0x0292, 0x030c}, +{0x01f0, 0x006a, 0x030c}, +{0x01f4, 0x0047, 0x0301}, +{0x01f5, 0x0067, 0x0301}, +{0x01f8, 0x004e, 0x0300}, +{0x01f9, 0x006e, 0x0300}, +{0x01fa, 0x00c5, 0x0301}, +{0x01fb, 0x00e5, 0x0301}, +{0x01fc, 0x00c6, 0x0301}, +{0x01fd, 0x00e6, 0x0301}, +{0x01fe, 0x00d8, 0x0301}, +{0x01ff, 0x00f8, 0x0301}, +{0x0200, 0x0041, 0x030f}, +{0x0201, 0x0061, 0x030f}, +{0x0202, 0x0041, 0x0311}, +{0x0203, 0x0061, 0x0311}, +{0x0204, 0x0045, 0x030f}, +{0x0205, 0x0065, 0x030f}, +{0x0206, 0x0045, 0x0311}, +{0x0207, 0x0065, 0x0311}, +{0x0208, 0x0049, 0x030f}, +{0x0209, 0x0069, 0x030f}, +{0x020a, 0x0049, 0x0311}, +{0x020b, 0x0069, 0x0311}, +{0x020c, 0x004f, 0x030f}, +{0x020d, 0x006f, 0x030f}, +{0x020e, 0x004f, 0x0311}, +{0x020f, 0x006f, 0x0311}, +{0x0210, 0x0052, 0x030f}, +{0x0211, 0x0072, 0x030f}, +{0x0212, 0x0052, 0x0311}, +{0x0213, 0x0072, 0x0311}, +{0x0214, 0x0055, 0x030f}, +{0x0215, 0x0075, 0x030f}, +{0x0216, 0x0055, 0x0311}, +{0x0217, 0x0075, 0x0311}, +{0x0218, 0x0053, 0x0326}, +{0x0219, 0x0073, 0x0326}, +{0x021a, 0x0054, 0x0326}, +{0x021b, 0x0074, 0x0326}, +{0x021e, 0x0048, 0x030c}, +{0x021f, 0x0068, 0x030c}, +{0x0226, 0x0041, 0x0307}, +{0x0227, 0x0061, 0x0307}, +{0x0228, 0x0045, 0x0327}, +{0x0229, 0x0065, 0x0327}, +{0x022a, 0x00d6, 0x0304}, +{0x022b, 0x00f6, 0x0304}, +{0x022c, 0x00d5, 0x0304}, +{0x022d, 0x00f5, 0x0304}, +{0x022e, 0x004f, 0x0307}, +{0x022f, 0x006f, 0x0307}, +{0x0230, 0x022e, 0x0304}, +{0x0231, 0x022f, 0x0304}, +{0x0232, 0x0059, 0x0304}, +{0x0233, 0x0079, 0x0304}, +{0x0340, 0x0300, 0}, +{0x0341, 0x0301, 0}, +{0x0343, 0x0313, 0}, +{0x0344, 0x0308, 0x0301}, +{0x0374, 0x02b9, 0}, +{0x037e, 0x003b, 0}, +{0x0385, 0x00a8, 0x0301}, +{0x0386, 0x0391, 0x0301}, +{0x0387, 0x00b7, 0}, +{0x0388, 0x0395, 0x0301}, +{0x0389, 0x0397, 0x0301}, +{0x038a, 0x0399, 0x0301}, +{0x038c, 0x039f, 0x0301}, +{0x038e, 0x03a5, 0x0301}, +{0x038f, 0x03a9, 0x0301}, +{0x0390, 0x03ca, 0x0301}, +{0x03aa, 0x0399, 0x0308}, +{0x03ab, 0x03a5, 0x0308}, +{0x03ac, 0x03b1, 0x0301}, +{0x03ad, 0x03b5, 0x0301}, +{0x03ae, 0x03b7, 0x0301}, +{0x03af, 0x03b9, 0x0301}, +{0x03b0, 0x03cb, 0x0301}, +{0x03ca, 0x03b9, 0x0308}, +{0x03cb, 0x03c5, 0x0308}, +{0x03cc, 0x03bf, 0x0301}, +{0x03cd, 0x03c5, 0x0301}, +{0x03ce, 0x03c9, 0x0301}, +{0x03d3, 0x03d2, 0x0301}, +{0x03d4, 0x03d2, 0x0308}, +{0x0400, 0x0415, 0x0300}, +{0x0401, 0x0415, 0x0308}, +{0x0403, 0x0413, 0x0301}, +{0x0407, 0x0406, 0x0308}, +{0x040c, 0x041a, 0x0301}, +{0x040d, 0x0418, 0x0300}, +{0x040e, 0x0423, 0x0306}, +{0x0419, 0x0418, 0x0306}, +{0x0439, 0x0438, 0x0306}, +{0x0450, 0x0435, 0x0300}, +{0x0451, 0x0435, 0x0308}, +{0x0453, 0x0433, 0x0301}, +{0x0457, 0x0456, 0x0308}, +{0x045c, 0x043a, 0x0301}, +{0x045d, 0x0438, 0x0300}, +{0x045e, 0x0443, 0x0306}, +{0x0476, 0x0474, 0x030f}, +{0x0477, 0x0475, 0x030f}, +{0x04c1, 0x0416, 0x0306}, +{0x04c2, 0x0436, 0x0306}, +{0x04d0, 0x0410, 0x0306}, +{0x04d1, 0x0430, 0x0306}, +{0x04d2, 0x0410, 0x0308}, +{0x04d3, 0x0430, 0x0308}, +{0x04d6, 0x0415, 0x0306}, +{0x04d7, 0x0435, 0x0306}, +{0x04da, 0x04d8, 0x0308}, +{0x04db, 0x04d9, 0x0308}, +{0x04dc, 0x0416, 0x0308}, +{0x04dd, 0x0436, 0x0308}, +{0x04de, 0x0417, 0x0308}, +{0x04df, 0x0437, 0x0308}, +{0x04e2, 0x0418, 0x0304}, +{0x04e3, 0x0438, 0x0304}, +{0x04e4, 0x0418, 0x0308}, +{0x04e5, 0x0438, 0x0308}, +{0x04e6, 0x041e, 0x0308}, +{0x04e7, 0x043e, 0x0308}, +{0x04ea, 0x04e8, 0x0308}, +{0x04eb, 0x04e9, 0x0308}, +{0x04ec, 0x042d, 0x0308}, +{0x04ed, 0x044d, 0x0308}, +{0x04ee, 0x0423, 0x0304}, +{0x04ef, 0x0443, 0x0304}, +{0x04f0, 0x0423, 0x0308}, +{0x04f1, 0x0443, 0x0308}, +{0x04f2, 0x0423, 0x030b}, +{0x04f3, 0x0443, 0x030b}, +{0x04f4, 0x0427, 0x0308}, +{0x04f5, 0x0447, 0x0308}, +{0x04f8, 0x042b, 0x0308}, +{0x04f9, 0x044b, 0x0308}, +{0x0622, 0x0627, 0x0653}, +{0x0623, 0x0627, 0x0654}, +{0x0624, 0x0648, 0x0654}, +{0x0625, 0x0627, 0x0655}, +{0x0626, 0x064a, 0x0654}, +{0x06c0, 0x06d5, 0x0654}, +{0x06c2, 0x06c1, 0x0654}, +{0x06d3, 0x06d2, 0x0654}, +{0x0929, 0x0928, 0x093c}, +{0x0931, 0x0930, 0x093c}, +{0x0934, 0x0933, 0x093c}, +{0x0958, 0x0915, 0x093c}, +{0x0959, 0x0916, 0x093c}, +{0x095a, 0x0917, 0x093c}, +{0x095b, 0x091c, 0x093c}, +{0x095c, 0x0921, 0x093c}, +{0x095d, 0x0922, 0x093c}, +{0x095e, 0x092b, 0x093c}, +{0x095f, 0x092f, 0x093c}, +{0x09cb, 0x09c7, 0x09be}, +{0x09cc, 0x09c7, 0x09d7}, +{0x09dc, 0x09a1, 0x09bc}, +{0x09dd, 0x09a2, 0x09bc}, +{0x09df, 0x09af, 0x09bc}, +{0x0a33, 0x0a32, 0x0a3c}, +{0x0a36, 0x0a38, 0x0a3c}, +{0x0a59, 0x0a16, 0x0a3c}, +{0x0a5a, 0x0a17, 0x0a3c}, +{0x0a5b, 0x0a1c, 0x0a3c}, +{0x0a5e, 0x0a2b, 0x0a3c}, +{0x0b48, 0x0b47, 0x0b56}, +{0x0b4b, 0x0b47, 0x0b3e}, +{0x0b4c, 0x0b47, 0x0b57}, +{0x0b5c, 0x0b21, 0x0b3c}, +{0x0b5d, 0x0b22, 0x0b3c}, +{0x0b94, 0x0b92, 0x0bd7}, +{0x0bca, 0x0bc6, 0x0bbe}, +{0x0bcb, 0x0bc7, 0x0bbe}, +{0x0bcc, 0x0bc6, 0x0bd7}, +{0x0c48, 0x0c46, 0x0c56}, +{0x0cc0, 0x0cbf, 0x0cd5}, +{0x0cc7, 0x0cc6, 0x0cd5}, +{0x0cc8, 0x0cc6, 0x0cd6}, +{0x0cca, 0x0cc6, 0x0cc2}, +{0x0ccb, 0x0cca, 0x0cd5}, +{0x0d4a, 0x0d46, 0x0d3e}, +{0x0d4b, 0x0d47, 0x0d3e}, +{0x0d4c, 0x0d46, 0x0d57}, +{0x0dda, 0x0dd9, 0x0dca}, +{0x0ddc, 0x0dd9, 0x0dcf}, +{0x0ddd, 0x0ddc, 0x0dca}, +{0x0dde, 0x0dd9, 0x0ddf}, +{0x0f43, 0x0f42, 0x0fb7}, +{0x0f4d, 0x0f4c, 0x0fb7}, +{0x0f52, 0x0f51, 0x0fb7}, +{0x0f57, 0x0f56, 0x0fb7}, +{0x0f5c, 0x0f5b, 0x0fb7}, +{0x0f69, 0x0f40, 0x0fb5}, +{0x0f73, 0x0f71, 0x0f72}, +{0x0f75, 0x0f71, 0x0f74}, +{0x0f76, 0x0fb2, 0x0f80}, +{0x0f78, 0x0fb3, 0x0f80}, +{0x0f81, 0x0f71, 0x0f80}, +{0x0f93, 0x0f92, 0x0fb7}, +{0x0f9d, 0x0f9c, 0x0fb7}, +{0x0fa2, 0x0fa1, 0x0fb7}, +{0x0fa7, 0x0fa6, 0x0fb7}, +{0x0fac, 0x0fab, 0x0fb7}, +{0x0fb9, 0x0f90, 0x0fb5}, +{0x1026, 0x1025, 0x102e}, +{0x1b06, 0x1b05, 0x1b35}, +{0x1b08, 0x1b07, 0x1b35}, +{0x1b0a, 0x1b09, 0x1b35}, +{0x1b0c, 0x1b0b, 0x1b35}, +{0x1b0e, 0x1b0d, 0x1b35}, +{0x1b12, 0x1b11, 0x1b35}, +{0x1b3b, 0x1b3a, 0x1b35}, +{0x1b3d, 0x1b3c, 0x1b35}, +{0x1b40, 0x1b3e, 0x1b35}, +{0x1b41, 0x1b3f, 0x1b35}, +{0x1b43, 0x1b42, 0x1b35}, +{0x1e00, 0x0041, 0x0325}, +{0x1e01, 0x0061, 0x0325}, +{0x1e02, 0x0042, 0x0307}, +{0x1e03, 0x0062, 0x0307}, +{0x1e04, 0x0042, 0x0323}, +{0x1e05, 0x0062, 0x0323}, +{0x1e06, 0x0042, 0x0331}, +{0x1e07, 0x0062, 0x0331}, +{0x1e08, 0x00c7, 0x0301}, +{0x1e09, 0x00e7, 0x0301}, +{0x1e0a, 0x0044, 0x0307}, +{0x1e0b, 0x0064, 0x0307}, +{0x1e0c, 0x0044, 0x0323}, +{0x1e0d, 0x0064, 0x0323}, +{0x1e0e, 0x0044, 0x0331}, +{0x1e0f, 0x0064, 0x0331}, +{0x1e10, 0x0044, 0x0327}, +{0x1e11, 0x0064, 0x0327}, +{0x1e12, 0x0044, 0x032d}, +{0x1e13, 0x0064, 0x032d}, +{0x1e14, 0x0112, 0x0300}, +{0x1e15, 0x0113, 0x0300}, +{0x1e16, 0x0112, 0x0301}, +{0x1e17, 0x0113, 0x0301}, +{0x1e18, 0x0045, 0x032d}, +{0x1e19, 0x0065, 0x032d}, +{0x1e1a, 0x0045, 0x0330}, +{0x1e1b, 0x0065, 0x0330}, +{0x1e1c, 0x0228, 0x0306}, +{0x1e1d, 0x0229, 0x0306}, +{0x1e1e, 0x0046, 0x0307}, +{0x1e1f, 0x0066, 0x0307}, +{0x1e20, 0x0047, 0x0304}, +{0x1e21, 0x0067, 0x0304}, +{0x1e22, 0x0048, 0x0307}, +{0x1e23, 0x0068, 0x0307}, +{0x1e24, 0x0048, 0x0323}, +{0x1e25, 0x0068, 0x0323}, +{0x1e26, 0x0048, 0x0308}, +{0x1e27, 0x0068, 0x0308}, +{0x1e28, 0x0048, 0x0327}, +{0x1e29, 0x0068, 0x0327}, +{0x1e2a, 0x0048, 0x032e}, +{0x1e2b, 0x0068, 0x032e}, +{0x1e2c, 0x0049, 0x0330}, +{0x1e2d, 0x0069, 0x0330}, +{0x1e2e, 0x00cf, 0x0301}, +{0x1e2f, 0x00ef, 0x0301}, +{0x1e30, 0x004b, 0x0301}, +{0x1e31, 0x006b, 0x0301}, +{0x1e32, 0x004b, 0x0323}, +{0x1e33, 0x006b, 0x0323}, +{0x1e34, 0x004b, 0x0331}, +{0x1e35, 0x006b, 0x0331}, +{0x1e36, 0x004c, 0x0323}, +{0x1e37, 0x006c, 0x0323}, +{0x1e38, 0x1e36, 0x0304}, +{0x1e39, 0x1e37, 0x0304}, +{0x1e3a, 0x004c, 0x0331}, +{0x1e3b, 0x006c, 0x0331}, +{0x1e3c, 0x004c, 0x032d}, +{0x1e3d, 0x006c, 0x032d}, +{0x1e3e, 0x004d, 0x0301}, +{0x1e3f, 0x006d, 0x0301}, +{0x1e40, 0x004d, 0x0307}, +{0x1e41, 0x006d, 0x0307}, +{0x1e42, 0x004d, 0x0323}, +{0x1e43, 0x006d, 0x0323}, +{0x1e44, 0x004e, 0x0307}, +{0x1e45, 0x006e, 0x0307}, +{0x1e46, 0x004e, 0x0323}, +{0x1e47, 0x006e, 0x0323}, +{0x1e48, 0x004e, 0x0331}, +{0x1e49, 0x006e, 0x0331}, +{0x1e4a, 0x004e, 0x032d}, +{0x1e4b, 0x006e, 0x032d}, +{0x1e4c, 0x00d5, 0x0301}, +{0x1e4d, 0x00f5, 0x0301}, +{0x1e4e, 0x00d5, 0x0308}, +{0x1e4f, 0x00f5, 0x0308}, +{0x1e50, 0x014c, 0x0300}, +{0x1e51, 0x014d, 0x0300}, +{0x1e52, 0x014c, 0x0301}, +{0x1e53, 0x014d, 0x0301}, +{0x1e54, 0x0050, 0x0301}, +{0x1e55, 0x0070, 0x0301}, +{0x1e56, 0x0050, 0x0307}, +{0x1e57, 0x0070, 0x0307}, +{0x1e58, 0x0052, 0x0307}, +{0x1e59, 0x0072, 0x0307}, +{0x1e5a, 0x0052, 0x0323}, +{0x1e5b, 0x0072, 0x0323}, +{0x1e5c, 0x1e5a, 0x0304}, +{0x1e5d, 0x1e5b, 0x0304}, +{0x1e5e, 0x0052, 0x0331}, +{0x1e5f, 0x0072, 0x0331}, +{0x1e60, 0x0053, 0x0307}, +{0x1e61, 0x0073, 0x0307}, +{0x1e62, 0x0053, 0x0323}, +{0x1e63, 0x0073, 0x0323}, +{0x1e64, 0x015a, 0x0307}, +{0x1e65, 0x015b, 0x0307}, +{0x1e66, 0x0160, 0x0307}, +{0x1e67, 0x0161, 0x0307}, +{0x1e68, 0x1e62, 0x0307}, +{0x1e69, 0x1e63, 0x0307}, +{0x1e6a, 0x0054, 0x0307}, +{0x1e6b, 0x0074, 0x0307}, +{0x1e6c, 0x0054, 0x0323}, +{0x1e6d, 0x0074, 0x0323}, +{0x1e6e, 0x0054, 0x0331}, +{0x1e6f, 0x0074, 0x0331}, +{0x1e70, 0x0054, 0x032d}, +{0x1e71, 0x0074, 0x032d}, +{0x1e72, 0x0055, 0x0324}, +{0x1e73, 0x0075, 0x0324}, +{0x1e74, 0x0055, 0x0330}, +{0x1e75, 0x0075, 0x0330}, +{0x1e76, 0x0055, 0x032d}, +{0x1e77, 0x0075, 0x032d}, +{0x1e78, 0x0168, 0x0301}, +{0x1e79, 0x0169, 0x0301}, +{0x1e7a, 0x016a, 0x0308}, +{0x1e7b, 0x016b, 0x0308}, +{0x1e7c, 0x0056, 0x0303}, +{0x1e7d, 0x0076, 0x0303}, +{0x1e7e, 0x0056, 0x0323}, +{0x1e7f, 0x0076, 0x0323}, +{0x1e80, 0x0057, 0x0300}, +{0x1e81, 0x0077, 0x0300}, +{0x1e82, 0x0057, 0x0301}, +{0x1e83, 0x0077, 0x0301}, +{0x1e84, 0x0057, 0x0308}, +{0x1e85, 0x0077, 0x0308}, +{0x1e86, 0x0057, 0x0307}, +{0x1e87, 0x0077, 0x0307}, +{0x1e88, 0x0057, 0x0323}, +{0x1e89, 0x0077, 0x0323}, +{0x1e8a, 0x0058, 0x0307}, +{0x1e8b, 0x0078, 0x0307}, +{0x1e8c, 0x0058, 0x0308}, +{0x1e8d, 0x0078, 0x0308}, +{0x1e8e, 0x0059, 0x0307}, +{0x1e8f, 0x0079, 0x0307}, +{0x1e90, 0x005a, 0x0302}, +{0x1e91, 0x007a, 0x0302}, +{0x1e92, 0x005a, 0x0323}, +{0x1e93, 0x007a, 0x0323}, +{0x1e94, 0x005a, 0x0331}, +{0x1e95, 0x007a, 0x0331}, +{0x1e96, 0x0068, 0x0331}, +{0x1e97, 0x0074, 0x0308}, +{0x1e98, 0x0077, 0x030a}, +{0x1e99, 0x0079, 0x030a}, +{0x1e9b, 0x017f, 0x0307}, +{0x1ea0, 0x0041, 0x0323}, +{0x1ea1, 0x0061, 0x0323}, +{0x1ea2, 0x0041, 0x0309}, +{0x1ea3, 0x0061, 0x0309}, +{0x1ea4, 0x00c2, 0x0301}, +{0x1ea5, 0x00e2, 0x0301}, +{0x1ea6, 0x00c2, 0x0300}, +{0x1ea7, 0x00e2, 0x0300}, +{0x1ea8, 0x00c2, 0x0309}, +{0x1ea9, 0x00e2, 0x0309}, +{0x1eaa, 0x00c2, 0x0303}, +{0x1eab, 0x00e2, 0x0303}, +{0x1eac, 0x1ea0, 0x0302}, +{0x1ead, 0x1ea1, 0x0302}, +{0x1eae, 0x0102, 0x0301}, +{0x1eaf, 0x0103, 0x0301}, +{0x1eb0, 0x0102, 0x0300}, +{0x1eb1, 0x0103, 0x0300}, +{0x1eb2, 0x0102, 0x0309}, +{0x1eb3, 0x0103, 0x0309}, +{0x1eb4, 0x0102, 0x0303}, +{0x1eb5, 0x0103, 0x0303}, +{0x1eb6, 0x1ea0, 0x0306}, +{0x1eb7, 0x1ea1, 0x0306}, +{0x1eb8, 0x0045, 0x0323}, +{0x1eb9, 0x0065, 0x0323}, +{0x1eba, 0x0045, 0x0309}, +{0x1ebb, 0x0065, 0x0309}, +{0x1ebc, 0x0045, 0x0303}, +{0x1ebd, 0x0065, 0x0303}, +{0x1ebe, 0x00ca, 0x0301}, +{0x1ebf, 0x00ea, 0x0301}, +{0x1ec0, 0x00ca, 0x0300}, +{0x1ec1, 0x00ea, 0x0300}, +{0x1ec2, 0x00ca, 0x0309}, +{0x1ec3, 0x00ea, 0x0309}, +{0x1ec4, 0x00ca, 0x0303}, +{0x1ec5, 0x00ea, 0x0303}, +{0x1ec6, 0x1eb8, 0x0302}, +{0x1ec7, 0x1eb9, 0x0302}, +{0x1ec8, 0x0049, 0x0309}, +{0x1ec9, 0x0069, 0x0309}, +{0x1eca, 0x0049, 0x0323}, +{0x1ecb, 0x0069, 0x0323}, +{0x1ecc, 0x004f, 0x0323}, +{0x1ecd, 0x006f, 0x0323}, +{0x1ece, 0x004f, 0x0309}, +{0x1ecf, 0x006f, 0x0309}, +{0x1ed0, 0x00d4, 0x0301}, +{0x1ed1, 0x00f4, 0x0301}, +{0x1ed2, 0x00d4, 0x0300}, +{0x1ed3, 0x00f4, 0x0300}, +{0x1ed4, 0x00d4, 0x0309}, +{0x1ed5, 0x00f4, 0x0309}, +{0x1ed6, 0x00d4, 0x0303}, +{0x1ed7, 0x00f4, 0x0303}, +{0x1ed8, 0x1ecc, 0x0302}, +{0x1ed9, 0x1ecd, 0x0302}, +{0x1eda, 0x01a0, 0x0301}, +{0x1edb, 0x01a1, 0x0301}, +{0x1edc, 0x01a0, 0x0300}, +{0x1edd, 0x01a1, 0x0300}, +{0x1ede, 0x01a0, 0x0309}, +{0x1edf, 0x01a1, 0x0309}, +{0x1ee0, 0x01a0, 0x0303}, +{0x1ee1, 0x01a1, 0x0303}, +{0x1ee2, 0x01a0, 0x0323}, +{0x1ee3, 0x01a1, 0x0323}, +{0x1ee4, 0x0055, 0x0323}, +{0x1ee5, 0x0075, 0x0323}, +{0x1ee6, 0x0055, 0x0309}, +{0x1ee7, 0x0075, 0x0309}, +{0x1ee8, 0x01af, 0x0301}, +{0x1ee9, 0x01b0, 0x0301}, +{0x1eea, 0x01af, 0x0300}, +{0x1eeb, 0x01b0, 0x0300}, +{0x1eec, 0x01af, 0x0309}, +{0x1eed, 0x01b0, 0x0309}, +{0x1eee, 0x01af, 0x0303}, +{0x1eef, 0x01b0, 0x0303}, +{0x1ef0, 0x01af, 0x0323}, +{0x1ef1, 0x01b0, 0x0323}, +{0x1ef2, 0x0059, 0x0300}, +{0x1ef3, 0x0079, 0x0300}, +{0x1ef4, 0x0059, 0x0323}, +{0x1ef5, 0x0079, 0x0323}, +{0x1ef6, 0x0059, 0x0309}, +{0x1ef7, 0x0079, 0x0309}, +{0x1ef8, 0x0059, 0x0303}, +{0x1ef9, 0x0079, 0x0303}, +{0x1f00, 0x03b1, 0x0313}, +{0x1f01, 0x03b1, 0x0314}, +{0x1f02, 0x1f00, 0x0300}, +{0x1f03, 0x1f01, 0x0300}, +{0x1f04, 0x1f00, 0x0301}, +{0x1f05, 0x1f01, 0x0301}, +{0x1f06, 0x1f00, 0x0342}, +{0x1f07, 0x1f01, 0x0342}, +{0x1f08, 0x0391, 0x0313}, +{0x1f09, 0x0391, 0x0314}, +{0x1f0a, 0x1f08, 0x0300}, +{0x1f0b, 0x1f09, 0x0300}, +{0x1f0c, 0x1f08, 0x0301}, +{0x1f0d, 0x1f09, 0x0301}, +{0x1f0e, 0x1f08, 0x0342}, +{0x1f0f, 0x1f09, 0x0342}, +{0x1f10, 0x03b5, 0x0313}, +{0x1f11, 0x03b5, 0x0314}, +{0x1f12, 0x1f10, 0x0300}, +{0x1f13, 0x1f11, 0x0300}, +{0x1f14, 0x1f10, 0x0301}, +{0x1f15, 0x1f11, 0x0301}, +{0x1f18, 0x0395, 0x0313}, +{0x1f19, 0x0395, 0x0314}, +{0x1f1a, 0x1f18, 0x0300}, +{0x1f1b, 0x1f19, 0x0300}, +{0x1f1c, 0x1f18, 0x0301}, +{0x1f1d, 0x1f19, 0x0301}, +{0x1f20, 0x03b7, 0x0313}, +{0x1f21, 0x03b7, 0x0314}, +{0x1f22, 0x1f20, 0x0300}, +{0x1f23, 0x1f21, 0x0300}, +{0x1f24, 0x1f20, 0x0301}, +{0x1f25, 0x1f21, 0x0301}, +{0x1f26, 0x1f20, 0x0342}, +{0x1f27, 0x1f21, 0x0342}, +{0x1f28, 0x0397, 0x0313}, +{0x1f29, 0x0397, 0x0314}, +{0x1f2a, 0x1f28, 0x0300}, +{0x1f2b, 0x1f29, 0x0300}, +{0x1f2c, 0x1f28, 0x0301}, +{0x1f2d, 0x1f29, 0x0301}, +{0x1f2e, 0x1f28, 0x0342}, +{0x1f2f, 0x1f29, 0x0342}, +{0x1f30, 0x03b9, 0x0313}, +{0x1f31, 0x03b9, 0x0314}, +{0x1f32, 0x1f30, 0x0300}, +{0x1f33, 0x1f31, 0x0300}, +{0x1f34, 0x1f30, 0x0301}, +{0x1f35, 0x1f31, 0x0301}, +{0x1f36, 0x1f30, 0x0342}, +{0x1f37, 0x1f31, 0x0342}, +{0x1f38, 0x0399, 0x0313}, +{0x1f39, 0x0399, 0x0314}, +{0x1f3a, 0x1f38, 0x0300}, +{0x1f3b, 0x1f39, 0x0300}, +{0x1f3c, 0x1f38, 0x0301}, +{0x1f3d, 0x1f39, 0x0301}, +{0x1f3e, 0x1f38, 0x0342}, +{0x1f3f, 0x1f39, 0x0342}, +{0x1f40, 0x03bf, 0x0313}, +{0x1f41, 0x03bf, 0x0314}, +{0x1f42, 0x1f40, 0x0300}, +{0x1f43, 0x1f41, 0x0300}, +{0x1f44, 0x1f40, 0x0301}, +{0x1f45, 0x1f41, 0x0301}, +{0x1f48, 0x039f, 0x0313}, +{0x1f49, 0x039f, 0x0314}, +{0x1f4a, 0x1f48, 0x0300}, +{0x1f4b, 0x1f49, 0x0300}, +{0x1f4c, 0x1f48, 0x0301}, +{0x1f4d, 0x1f49, 0x0301}, +{0x1f50, 0x03c5, 0x0313}, +{0x1f51, 0x03c5, 0x0314}, +{0x1f52, 0x1f50, 0x0300}, +{0x1f53, 0x1f51, 0x0300}, +{0x1f54, 0x1f50, 0x0301}, +{0x1f55, 0x1f51, 0x0301}, +{0x1f56, 0x1f50, 0x0342}, +{0x1f57, 0x1f51, 0x0342}, +{0x1f59, 0x03a5, 0x0314}, +{0x1f5b, 0x1f59, 0x0300}, +{0x1f5d, 0x1f59, 0x0301}, +{0x1f5f, 0x1f59, 0x0342}, +{0x1f60, 0x03c9, 0x0313}, +{0x1f61, 0x03c9, 0x0314}, +{0x1f62, 0x1f60, 0x0300}, +{0x1f63, 0x1f61, 0x0300}, +{0x1f64, 0x1f60, 0x0301}, +{0x1f65, 0x1f61, 0x0301}, +{0x1f66, 0x1f60, 0x0342}, +{0x1f67, 0x1f61, 0x0342}, +{0x1f68, 0x03a9, 0x0313}, +{0x1f69, 0x03a9, 0x0314}, +{0x1f6a, 0x1f68, 0x0300}, +{0x1f6b, 0x1f69, 0x0300}, +{0x1f6c, 0x1f68, 0x0301}, +{0x1f6d, 0x1f69, 0x0301}, +{0x1f6e, 0x1f68, 0x0342}, +{0x1f6f, 0x1f69, 0x0342}, +{0x1f70, 0x03b1, 0x0300}, +{0x1f71, 0x03ac, 0}, +{0x1f72, 0x03b5, 0x0300}, +{0x1f73, 0x03ad, 0}, +{0x1f74, 0x03b7, 0x0300}, +{0x1f75, 0x03ae, 0}, +{0x1f76, 0x03b9, 0x0300}, +{0x1f77, 0x03af, 0}, +{0x1f78, 0x03bf, 0x0300}, +{0x1f79, 0x03cc, 0}, +{0x1f7a, 0x03c5, 0x0300}, +{0x1f7b, 0x03cd, 0}, +{0x1f7c, 0x03c9, 0x0300}, +{0x1f7d, 0x03ce, 0}, +{0x1f80, 0x1f00, 0x0345}, +{0x1f81, 0x1f01, 0x0345}, +{0x1f82, 0x1f02, 0x0345}, +{0x1f83, 0x1f03, 0x0345}, +{0x1f84, 0x1f04, 0x0345}, +{0x1f85, 0x1f05, 0x0345}, +{0x1f86, 0x1f06, 0x0345}, +{0x1f87, 0x1f07, 0x0345}, +{0x1f88, 0x1f08, 0x0345}, +{0x1f89, 0x1f09, 0x0345}, +{0x1f8a, 0x1f0a, 0x0345}, +{0x1f8b, 0x1f0b, 0x0345}, +{0x1f8c, 0x1f0c, 0x0345}, +{0x1f8d, 0x1f0d, 0x0345}, +{0x1f8e, 0x1f0e, 0x0345}, +{0x1f8f, 0x1f0f, 0x0345}, +{0x1f90, 0x1f20, 0x0345}, +{0x1f91, 0x1f21, 0x0345}, +{0x1f92, 0x1f22, 0x0345}, +{0x1f93, 0x1f23, 0x0345}, +{0x1f94, 0x1f24, 0x0345}, +{0x1f95, 0x1f25, 0x0345}, +{0x1f96, 0x1f26, 0x0345}, +{0x1f97, 0x1f27, 0x0345}, +{0x1f98, 0x1f28, 0x0345}, +{0x1f99, 0x1f29, 0x0345}, +{0x1f9a, 0x1f2a, 0x0345}, +{0x1f9b, 0x1f2b, 0x0345}, +{0x1f9c, 0x1f2c, 0x0345}, +{0x1f9d, 0x1f2d, 0x0345}, +{0x1f9e, 0x1f2e, 0x0345}, +{0x1f9f, 0x1f2f, 0x0345}, +{0x1fa0, 0x1f60, 0x0345}, +{0x1fa1, 0x1f61, 0x0345}, +{0x1fa2, 0x1f62, 0x0345}, +{0x1fa3, 0x1f63, 0x0345}, +{0x1fa4, 0x1f64, 0x0345}, +{0x1fa5, 0x1f65, 0x0345}, +{0x1fa6, 0x1f66, 0x0345}, +{0x1fa7, 0x1f67, 0x0345}, +{0x1fa8, 0x1f68, 0x0345}, +{0x1fa9, 0x1f69, 0x0345}, +{0x1faa, 0x1f6a, 0x0345}, +{0x1fab, 0x1f6b, 0x0345}, +{0x1fac, 0x1f6c, 0x0345}, +{0x1fad, 0x1f6d, 0x0345}, +{0x1fae, 0x1f6e, 0x0345}, +{0x1faf, 0x1f6f, 0x0345}, +{0x1fb0, 0x03b1, 0x0306}, +{0x1fb1, 0x03b1, 0x0304}, +{0x1fb2, 0x1f70, 0x0345}, +{0x1fb3, 0x03b1, 0x0345}, +{0x1fb4, 0x03ac, 0x0345}, +{0x1fb6, 0x03b1, 0x0342}, +{0x1fb7, 0x1fb6, 0x0345}, +{0x1fb8, 0x0391, 0x0306}, +{0x1fb9, 0x0391, 0x0304}, +{0x1fba, 0x0391, 0x0300}, +{0x1fbb, 0x0386, 0}, +{0x1fbc, 0x0391, 0x0345}, +{0x1fbe, 0x03b9, 0}, +{0x1fc1, 0x00a8, 0x0342}, +{0x1fc2, 0x1f74, 0x0345}, +{0x1fc3, 0x03b7, 0x0345}, +{0x1fc4, 0x03ae, 0x0345}, +{0x1fc6, 0x03b7, 0x0342}, +{0x1fc7, 0x1fc6, 0x0345}, +{0x1fc8, 0x0395, 0x0300}, +{0x1fc9, 0x0388, 0}, +{0x1fca, 0x0397, 0x0300}, +{0x1fcb, 0x0389, 0}, +{0x1fcc, 0x0397, 0x0345}, +{0x1fcd, 0x1fbf, 0x0300}, +{0x1fce, 0x1fbf, 0x0301}, +{0x1fcf, 0x1fbf, 0x0342}, +{0x1fd0, 0x03b9, 0x0306}, +{0x1fd1, 0x03b9, 0x0304}, +{0x1fd2, 0x03ca, 0x0300}, +{0x1fd3, 0x0390, 0}, +{0x1fd6, 0x03b9, 0x0342}, +{0x1fd7, 0x03ca, 0x0342}, +{0x1fd8, 0x0399, 0x0306}, +{0x1fd9, 0x0399, 0x0304}, +{0x1fda, 0x0399, 0x0300}, +{0x1fdb, 0x038a, 0}, +{0x1fdd, 0x1ffe, 0x0300}, +{0x1fde, 0x1ffe, 0x0301}, +{0x1fdf, 0x1ffe, 0x0342}, +{0x1fe0, 0x03c5, 0x0306}, +{0x1fe1, 0x03c5, 0x0304}, +{0x1fe2, 0x03cb, 0x0300}, +{0x1fe3, 0x03b0, 0}, +{0x1fe4, 0x03c1, 0x0313}, +{0x1fe5, 0x03c1, 0x0314}, +{0x1fe6, 0x03c5, 0x0342}, +{0x1fe7, 0x03cb, 0x0342}, +{0x1fe8, 0x03a5, 0x0306}, +{0x1fe9, 0x03a5, 0x0304}, +{0x1fea, 0x03a5, 0x0300}, +{0x1feb, 0x038e, 0}, +{0x1fec, 0x03a1, 0x0314}, +{0x1fed, 0x00a8, 0x0300}, +{0x1fee, 0x0385, 0}, +{0x1fef, 0x0060, 0}, +{0x1ff2, 0x1f7c, 0x0345}, +{0x1ff3, 0x03c9, 0x0345}, +{0x1ff4, 0x03ce, 0x0345}, +{0x1ff6, 0x03c9, 0x0342}, +{0x1ff7, 0x1ff6, 0x0345}, +{0x1ff8, 0x039f, 0x0300}, +{0x1ff9, 0x038c, 0}, +{0x1ffa, 0x03a9, 0x0300}, +{0x1ffb, 0x038f, 0}, +{0x1ffc, 0x03a9, 0x0345}, +{0x1ffd, 0x00b4, 0}, +{0x2000, 0x2002, 0}, +{0x2001, 0x2003, 0}, +{0x2126, 0x03a9, 0}, +{0x212a, 0x004b, 0}, +{0x212b, 0x00c5, 0}, +{0x219a, 0x2190, 0x0338}, +{0x219b, 0x2192, 0x0338}, +{0x21ae, 0x2194, 0x0338}, +{0x21cd, 0x21d0, 0x0338}, +{0x21ce, 0x21d4, 0x0338}, +{0x21cf, 0x21d2, 0x0338}, +{0x2204, 0x2203, 0x0338}, +{0x2209, 0x2208, 0x0338}, +{0x220c, 0x220b, 0x0338}, +{0x2224, 0x2223, 0x0338}, +{0x2226, 0x2225, 0x0338}, +{0x2241, 0x223c, 0x0338}, +{0x2244, 0x2243, 0x0338}, +{0x2247, 0x2245, 0x0338}, +{0x2249, 0x2248, 0x0338}, +{0x2260, 0x003d, 0x0338}, +{0x2262, 0x2261, 0x0338}, +{0x226d, 0x224d, 0x0338}, +{0x226e, 0x003c, 0x0338}, +{0x226f, 0x003e, 0x0338}, +{0x2270, 0x2264, 0x0338}, +{0x2271, 0x2265, 0x0338}, +{0x2274, 0x2272, 0x0338}, +{0x2275, 0x2273, 0x0338}, +{0x2278, 0x2276, 0x0338}, +{0x2279, 0x2277, 0x0338}, +{0x2280, 0x227a, 0x0338}, +{0x2281, 0x227b, 0x0338}, +{0x2284, 0x2282, 0x0338}, +{0x2285, 0x2283, 0x0338}, +{0x2288, 0x2286, 0x0338}, +{0x2289, 0x2287, 0x0338}, +{0x22ac, 0x22a2, 0x0338}, +{0x22ad, 0x22a8, 0x0338}, +{0x22ae, 0x22a9, 0x0338}, +{0x22af, 0x22ab, 0x0338}, +{0x22e0, 0x227c, 0x0338}, +{0x22e1, 0x227d, 0x0338}, +{0x22e2, 0x2291, 0x0338}, +{0x22e3, 0x2292, 0x0338}, +{0x22ea, 0x22b2, 0x0338}, +{0x22eb, 0x22b3, 0x0338}, +{0x22ec, 0x22b4, 0x0338}, +{0x22ed, 0x22b5, 0x0338}, +{0x2329, 0x3008, 0}, +{0x232a, 0x3009, 0}, +{0x2adc, 0x2add, 0x0338}, +{0x304c, 0x304b, 0x3099}, +{0x304e, 0x304d, 0x3099}, +{0x3050, 0x304f, 0x3099}, +{0x3052, 0x3051, 0x3099}, +{0x3054, 0x3053, 0x3099}, +{0x3056, 0x3055, 0x3099}, +{0x3058, 0x3057, 0x3099}, +{0x305a, 0x3059, 0x3099}, +{0x305c, 0x305b, 0x3099}, +{0x305e, 0x305d, 0x3099}, +{0x3060, 0x305f, 0x3099}, +{0x3062, 0x3061, 0x3099}, +{0x3065, 0x3064, 0x3099}, +{0x3067, 0x3066, 0x3099}, +{0x3069, 0x3068, 0x3099}, +{0x3070, 0x306f, 0x3099}, +{0x3071, 0x306f, 0x309a}, +{0x3073, 0x3072, 0x3099}, +{0x3074, 0x3072, 0x309a}, +{0x3076, 0x3075, 0x3099}, +{0x3077, 0x3075, 0x309a}, +{0x3079, 0x3078, 0x3099}, +{0x307a, 0x3078, 0x309a}, +{0x307c, 0x307b, 0x3099}, +{0x307d, 0x307b, 0x309a}, +{0x3094, 0x3046, 0x3099}, +{0x309e, 0x309d, 0x3099}, +{0x30ac, 0x30ab, 0x3099}, +{0x30ae, 0x30ad, 0x3099}, +{0x30b0, 0x30af, 0x3099}, +{0x30b2, 0x30b1, 0x3099}, +{0x30b4, 0x30b3, 0x3099}, +{0x30b6, 0x30b5, 0x3099}, +{0x30b8, 0x30b7, 0x3099}, +{0x30ba, 0x30b9, 0x3099}, +{0x30bc, 0x30bb, 0x3099}, +{0x30be, 0x30bd, 0x3099}, +{0x30c0, 0x30bf, 0x3099}, +{0x30c2, 0x30c1, 0x3099}, +{0x30c5, 0x30c4, 0x3099}, +{0x30c7, 0x30c6, 0x3099}, +{0x30c9, 0x30c8, 0x3099}, +{0x30d0, 0x30cf, 0x3099}, +{0x30d1, 0x30cf, 0x309a}, +{0x30d3, 0x30d2, 0x3099}, +{0x30d4, 0x30d2, 0x309a}, +{0x30d6, 0x30d5, 0x3099}, +{0x30d7, 0x30d5, 0x309a}, +{0x30d9, 0x30d8, 0x3099}, +{0x30da, 0x30d8, 0x309a}, +{0x30dc, 0x30db, 0x3099}, +{0x30dd, 0x30db, 0x309a}, +{0x30f4, 0x30a6, 0x3099}, +{0x30f7, 0x30ef, 0x3099}, +{0x30f8, 0x30f0, 0x3099}, +{0x30f9, 0x30f1, 0x3099}, +{0x30fa, 0x30f2, 0x3099}, +{0x30fe, 0x30fd, 0x3099}, +{0xf900, 0x8c48, 0}, +{0xf901, 0x66f4, 0}, +{0xf902, 0x8eca, 0}, +{0xf903, 0x8cc8, 0}, +{0xf904, 0x6ed1, 0}, +{0xf905, 0x4e32, 0}, +{0xf906, 0x53e5, 0}, +{0xf907, 0x9f9c, 0}, +{0xf908, 0x9f9c, 0}, +{0xf909, 0x5951, 0}, +{0xf90a, 0x91d1, 0}, +{0xf90b, 0x5587, 0}, +{0xf90c, 0x5948, 0}, +{0xf90d, 0x61f6, 0}, +{0xf90e, 0x7669, 0}, +{0xf90f, 0x7f85, 0}, +{0xf910, 0x863f, 0}, +{0xf911, 0x87ba, 0}, +{0xf912, 0x88f8, 0}, +{0xf913, 0x908f, 0}, +{0xf914, 0x6a02, 0}, +{0xf915, 0x6d1b, 0}, +{0xf916, 0x70d9, 0}, +{0xf917, 0x73de, 0}, +{0xf918, 0x843d, 0}, +{0xf919, 0x916a, 0}, +{0xf91a, 0x99f1, 0}, +{0xf91b, 0x4e82, 0}, +{0xf91c, 0x5375, 0}, +{0xf91d, 0x6b04, 0}, +{0xf91e, 0x721b, 0}, +{0xf91f, 0x862d, 0}, +{0xf920, 0x9e1e, 0}, +{0xf921, 0x5d50, 0}, +{0xf922, 0x6feb, 0}, +{0xf923, 0x85cd, 0}, +{0xf924, 0x8964, 0}, +{0xf925, 0x62c9, 0}, +{0xf926, 0x81d8, 0}, +{0xf927, 0x881f, 0}, +{0xf928, 0x5eca, 0}, +{0xf929, 0x6717, 0}, +{0xf92a, 0x6d6a, 0}, +{0xf92b, 0x72fc, 0}, +{0xf92c, 0x90ce, 0}, +{0xf92d, 0x4f86, 0}, +{0xf92e, 0x51b7, 0}, +{0xf92f, 0x52de, 0}, +{0xf930, 0x64c4, 0}, +{0xf931, 0x6ad3, 0}, +{0xf932, 0x7210, 0}, +{0xf933, 0x76e7, 0}, +{0xf934, 0x8001, 0}, +{0xf935, 0x8606, 0}, +{0xf936, 0x865c, 0}, +{0xf937, 0x8def, 0}, +{0xf938, 0x9732, 0}, +{0xf939, 0x9b6f, 0}, +{0xf93a, 0x9dfa, 0}, +{0xf93b, 0x788c, 0}, +{0xf93c, 0x797f, 0}, +{0xf93d, 0x7da0, 0}, +{0xf93e, 0x83c9, 0}, +{0xf93f, 0x9304, 0}, +{0xf940, 0x9e7f, 0}, +{0xf941, 0x8ad6, 0}, +{0xf942, 0x58df, 0}, +{0xf943, 0x5f04, 0}, +{0xf944, 0x7c60, 0}, +{0xf945, 0x807e, 0}, +{0xf946, 0x7262, 0}, +{0xf947, 0x78ca, 0}, +{0xf948, 0x8cc2, 0}, +{0xf949, 0x96f7, 0}, +{0xf94a, 0x58d8, 0}, +{0xf94b, 0x5c62, 0}, +{0xf94c, 0x6a13, 0}, +{0xf94d, 0x6dda, 0}, +{0xf94e, 0x6f0f, 0}, +{0xf94f, 0x7d2f, 0}, +{0xf950, 0x7e37, 0}, +{0xf951, 0x964b, 0}, +{0xf952, 0x52d2, 0}, +{0xf953, 0x808b, 0}, +{0xf954, 0x51dc, 0}, +{0xf955, 0x51cc, 0}, +{0xf956, 0x7a1c, 0}, +{0xf957, 0x7dbe, 0}, +{0xf958, 0x83f1, 0}, +{0xf959, 0x9675, 0}, +{0xf95a, 0x8b80, 0}, +{0xf95b, 0x62cf, 0}, +{0xf95c, 0x6a02, 0}, +{0xf95d, 0x8afe, 0}, +{0xf95e, 0x4e39, 0}, +{0xf95f, 0x5be7, 0}, +{0xf960, 0x6012, 0}, +{0xf961, 0x7387, 0}, +{0xf962, 0x7570, 0}, +{0xf963, 0x5317, 0}, +{0xf964, 0x78fb, 0}, +{0xf965, 0x4fbf, 0}, +{0xf966, 0x5fa9, 0}, +{0xf967, 0x4e0d, 0}, +{0xf968, 0x6ccc, 0}, +{0xf969, 0x6578, 0}, +{0xf96a, 0x7d22, 0}, +{0xf96b, 0x53c3, 0}, +{0xf96c, 0x585e, 0}, +{0xf96d, 0x7701, 0}, +{0xf96e, 0x8449, 0}, +{0xf96f, 0x8aaa, 0}, +{0xf970, 0x6bba, 0}, +{0xf971, 0x8fb0, 0}, +{0xf972, 0x6c88, 0}, +{0xf973, 0x62fe, 0}, +{0xf974, 0x82e5, 0}, +{0xf975, 0x63a0, 0}, +{0xf976, 0x7565, 0}, +{0xf977, 0x4eae, 0}, +{0xf978, 0x5169, 0}, +{0xf979, 0x51c9, 0}, +{0xf97a, 0x6881, 0}, +{0xf97b, 0x7ce7, 0}, +{0xf97c, 0x826f, 0}, +{0xf97d, 0x8ad2, 0}, +{0xf97e, 0x91cf, 0}, +{0xf97f, 0x52f5, 0}, +{0xf980, 0x5442, 0}, +{0xf981, 0x5973, 0}, +{0xf982, 0x5eec, 0}, +{0xf983, 0x65c5, 0}, +{0xf984, 0x6ffe, 0}, +{0xf985, 0x792a, 0}, +{0xf986, 0x95ad, 0}, +{0xf987, 0x9a6a, 0}, +{0xf988, 0x9e97, 0}, +{0xf989, 0x9ece, 0}, +{0xf98a, 0x529b, 0}, +{0xf98b, 0x66c6, 0}, +{0xf98c, 0x6b77, 0}, +{0xf98d, 0x8f62, 0}, +{0xf98e, 0x5e74, 0}, +{0xf98f, 0x6190, 0}, +{0xf990, 0x6200, 0}, +{0xf991, 0x649a, 0}, +{0xf992, 0x6f23, 0}, +{0xf993, 0x7149, 0}, +{0xf994, 0x7489, 0}, +{0xf995, 0x79ca, 0}, +{0xf996, 0x7df4, 0}, +{0xf997, 0x806f, 0}, +{0xf998, 0x8f26, 0}, +{0xf999, 0x84ee, 0}, +{0xf99a, 0x9023, 0}, +{0xf99b, 0x934a, 0}, +{0xf99c, 0x5217, 0}, +{0xf99d, 0x52a3, 0}, +{0xf99e, 0x54bd, 0}, +{0xf99f, 0x70c8, 0}, +{0xf9a0, 0x88c2, 0}, +{0xf9a1, 0x8aaa, 0}, +{0xf9a2, 0x5ec9, 0}, +{0xf9a3, 0x5ff5, 0}, +{0xf9a4, 0x637b, 0}, +{0xf9a5, 0x6bae, 0}, +{0xf9a6, 0x7c3e, 0}, +{0xf9a7, 0x7375, 0}, +{0xf9a8, 0x4ee4, 0}, +{0xf9a9, 0x56f9, 0}, +{0xf9aa, 0x5be7, 0}, +{0xf9ab, 0x5dba, 0}, +{0xf9ac, 0x601c, 0}, +{0xf9ad, 0x73b2, 0}, +{0xf9ae, 0x7469, 0}, +{0xf9af, 0x7f9a, 0}, +{0xf9b0, 0x8046, 0}, +{0xf9b1, 0x9234, 0}, +{0xf9b2, 0x96f6, 0}, +{0xf9b3, 0x9748, 0}, +{0xf9b4, 0x9818, 0}, +{0xf9b5, 0x4f8b, 0}, +{0xf9b6, 0x79ae, 0}, +{0xf9b7, 0x91b4, 0}, +{0xf9b8, 0x96b8, 0}, +{0xf9b9, 0x60e1, 0}, +{0xf9ba, 0x4e86, 0}, +{0xf9bb, 0x50da, 0}, +{0xf9bc, 0x5bee, 0}, +{0xf9bd, 0x5c3f, 0}, +{0xf9be, 0x6599, 0}, +{0xf9bf, 0x6a02, 0}, +{0xf9c0, 0x71ce, 0}, +{0xf9c1, 0x7642, 0}, +{0xf9c2, 0x84fc, 0}, +{0xf9c3, 0x907c, 0}, +{0xf9c4, 0x9f8d, 0}, +{0xf9c5, 0x6688, 0}, +{0xf9c6, 0x962e, 0}, +{0xf9c7, 0x5289, 0}, +{0xf9c8, 0x677b, 0}, +{0xf9c9, 0x67f3, 0}, +{0xf9ca, 0x6d41, 0}, +{0xf9cb, 0x6e9c, 0}, +{0xf9cc, 0x7409, 0}, +{0xf9cd, 0x7559, 0}, +{0xf9ce, 0x786b, 0}, +{0xf9cf, 0x7d10, 0}, +{0xf9d0, 0x985e, 0}, +{0xf9d1, 0x516d, 0}, +{0xf9d2, 0x622e, 0}, +{0xf9d3, 0x9678, 0}, +{0xf9d4, 0x502b, 0}, +{0xf9d5, 0x5d19, 0}, +{0xf9d6, 0x6dea, 0}, +{0xf9d7, 0x8f2a, 0}, +{0xf9d8, 0x5f8b, 0}, +{0xf9d9, 0x6144, 0}, +{0xf9da, 0x6817, 0}, +{0xf9db, 0x7387, 0}, +{0xf9dc, 0x9686, 0}, +{0xf9dd, 0x5229, 0}, +{0xf9de, 0x540f, 0}, +{0xf9df, 0x5c65, 0}, +{0xf9e0, 0x6613, 0}, +{0xf9e1, 0x674e, 0}, +{0xf9e2, 0x68a8, 0}, +{0xf9e3, 0x6ce5, 0}, +{0xf9e4, 0x7406, 0}, +{0xf9e5, 0x75e2, 0}, +{0xf9e6, 0x7f79, 0}, +{0xf9e7, 0x88cf, 0}, +{0xf9e8, 0x88e1, 0}, +{0xf9e9, 0x91cc, 0}, +{0xf9ea, 0x96e2, 0}, +{0xf9eb, 0x533f, 0}, +{0xf9ec, 0x6eba, 0}, +{0xf9ed, 0x541d, 0}, +{0xf9ee, 0x71d0, 0}, +{0xf9ef, 0x7498, 0}, +{0xf9f0, 0x85fa, 0}, +{0xf9f1, 0x96a3, 0}, +{0xf9f2, 0x9c57, 0}, +{0xf9f3, 0x9e9f, 0}, +{0xf9f4, 0x6797, 0}, +{0xf9f5, 0x6dcb, 0}, +{0xf9f6, 0x81e8, 0}, +{0xf9f7, 0x7acb, 0}, +{0xf9f8, 0x7b20, 0}, +{0xf9f9, 0x7c92, 0}, +{0xf9fa, 0x72c0, 0}, +{0xf9fb, 0x7099, 0}, +{0xf9fc, 0x8b58, 0}, +{0xf9fd, 0x4ec0, 0}, +{0xf9fe, 0x8336, 0}, +{0xf9ff, 0x523a, 0}, +{0xfa00, 0x5207, 0}, +{0xfa01, 0x5ea6, 0}, +{0xfa02, 0x62d3, 0}, +{0xfa03, 0x7cd6, 0}, +{0xfa04, 0x5b85, 0}, +{0xfa05, 0x6d1e, 0}, +{0xfa06, 0x66b4, 0}, +{0xfa07, 0x8f3b, 0}, +{0xfa08, 0x884c, 0}, +{0xfa09, 0x964d, 0}, +{0xfa0a, 0x898b, 0}, +{0xfa0b, 0x5ed3, 0}, +{0xfa0c, 0x5140, 0}, +{0xfa0d, 0x55c0, 0}, +{0xfa10, 0x585a, 0}, +{0xfa12, 0x6674, 0}, +{0xfa15, 0x51de, 0}, +{0xfa16, 0x732a, 0}, +{0xfa17, 0x76ca, 0}, +{0xfa18, 0x793c, 0}, +{0xfa19, 0x795e, 0}, +{0xfa1a, 0x7965, 0}, +{0xfa1b, 0x798f, 0}, +{0xfa1c, 0x9756, 0}, +{0xfa1d, 0x7cbe, 0}, +{0xfa1e, 0x7fbd, 0}, +{0xfa20, 0x8612, 0}, +{0xfa22, 0x8af8, 0}, +{0xfa25, 0x9038, 0}, +{0xfa26, 0x90fd, 0}, +{0xfa2a, 0x98ef, 0}, +{0xfa2b, 0x98fc, 0}, +{0xfa2c, 0x9928, 0}, +{0xfa2d, 0x9db4, 0}, +{0xfa2e, 0x90de, 0}, +{0xfa2f, 0x96b7, 0}, +{0xfa30, 0x4fae, 0}, +{0xfa31, 0x50e7, 0}, +{0xfa32, 0x514d, 0}, +{0xfa33, 0x52c9, 0}, +{0xfa34, 0x52e4, 0}, +{0xfa35, 0x5351, 0}, +{0xfa36, 0x559d, 0}, +{0xfa37, 0x5606, 0}, +{0xfa38, 0x5668, 0}, +{0xfa39, 0x5840, 0}, +{0xfa3a, 0x58a8, 0}, +{0xfa3b, 0x5c64, 0}, +{0xfa3c, 0x5c6e, 0}, +{0xfa3d, 0x6094, 0}, +{0xfa3e, 0x6168, 0}, +{0xfa3f, 0x618e, 0}, +{0xfa40, 0x61f2, 0}, +{0xfa41, 0x654f, 0}, +{0xfa42, 0x65e2, 0}, +{0xfa43, 0x6691, 0}, +{0xfa44, 0x6885, 0}, +{0xfa45, 0x6d77, 0}, +{0xfa46, 0x6e1a, 0}, +{0xfa47, 0x6f22, 0}, +{0xfa48, 0x716e, 0}, +{0xfa49, 0x722b, 0}, +{0xfa4a, 0x7422, 0}, +{0xfa4b, 0x7891, 0}, +{0xfa4c, 0x793e, 0}, +{0xfa4d, 0x7949, 0}, +{0xfa4e, 0x7948, 0}, +{0xfa4f, 0x7950, 0}, +{0xfa50, 0x7956, 0}, +{0xfa51, 0x795d, 0}, +{0xfa52, 0x798d, 0}, +{0xfa53, 0x798e, 0}, +{0xfa54, 0x7a40, 0}, +{0xfa55, 0x7a81, 0}, +{0xfa56, 0x7bc0, 0}, +{0xfa57, 0x7df4, 0}, +{0xfa58, 0x7e09, 0}, +{0xfa59, 0x7e41, 0}, +{0xfa5a, 0x7f72, 0}, +{0xfa5b, 0x8005, 0}, +{0xfa5c, 0x81ed, 0}, +{0xfa5d, 0x8279, 0}, +{0xfa5e, 0x8279, 0}, +{0xfa5f, 0x8457, 0}, +{0xfa60, 0x8910, 0}, +{0xfa61, 0x8996, 0}, +{0xfa62, 0x8b01, 0}, +{0xfa63, 0x8b39, 0}, +{0xfa64, 0x8cd3, 0}, +{0xfa65, 0x8d08, 0}, +{0xfa66, 0x8fb6, 0}, +{0xfa67, 0x9038, 0}, +{0xfa68, 0x96e3, 0}, +{0xfa69, 0x97ff, 0}, +{0xfa6a, 0x983b, 0}, +{0xfa6b, 0x6075, 0}, +{0xfa6c, 0x242ee, 0}, +{0xfa6d, 0x8218, 0}, +{0xfa70, 0x4e26, 0}, +{0xfa71, 0x51b5, 0}, +{0xfa72, 0x5168, 0}, +{0xfa73, 0x4f80, 0}, +{0xfa74, 0x5145, 0}, +{0xfa75, 0x5180, 0}, +{0xfa76, 0x52c7, 0}, +{0xfa77, 0x52fa, 0}, +{0xfa78, 0x559d, 0}, +{0xfa79, 0x5555, 0}, +{0xfa7a, 0x5599, 0}, +{0xfa7b, 0x55e2, 0}, +{0xfa7c, 0x585a, 0}, +{0xfa7d, 0x58b3, 0}, +{0xfa7e, 0x5944, 0}, +{0xfa7f, 0x5954, 0}, +{0xfa80, 0x5a62, 0}, +{0xfa81, 0x5b28, 0}, +{0xfa82, 0x5ed2, 0}, +{0xfa83, 0x5ed9, 0}, +{0xfa84, 0x5f69, 0}, +{0xfa85, 0x5fad, 0}, +{0xfa86, 0x60d8, 0}, +{0xfa87, 0x614e, 0}, +{0xfa88, 0x6108, 0}, +{0xfa89, 0x618e, 0}, +{0xfa8a, 0x6160, 0}, +{0xfa8b, 0x61f2, 0}, +{0xfa8c, 0x6234, 0}, +{0xfa8d, 0x63c4, 0}, +{0xfa8e, 0x641c, 0}, +{0xfa8f, 0x6452, 0}, +{0xfa90, 0x6556, 0}, +{0xfa91, 0x6674, 0}, +{0xfa92, 0x6717, 0}, +{0xfa93, 0x671b, 0}, +{0xfa94, 0x6756, 0}, +{0xfa95, 0x6b79, 0}, +{0xfa96, 0x6bba, 0}, +{0xfa97, 0x6d41, 0}, +{0xfa98, 0x6edb, 0}, +{0xfa99, 0x6ecb, 0}, +{0xfa9a, 0x6f22, 0}, +{0xfa9b, 0x701e, 0}, +{0xfa9c, 0x716e, 0}, +{0xfa9d, 0x77a7, 0}, +{0xfa9e, 0x7235, 0}, +{0xfa9f, 0x72af, 0}, +{0xfaa0, 0x732a, 0}, +{0xfaa1, 0x7471, 0}, +{0xfaa2, 0x7506, 0}, +{0xfaa3, 0x753b, 0}, +{0xfaa4, 0x761d, 0}, +{0xfaa5, 0x761f, 0}, +{0xfaa6, 0x76ca, 0}, +{0xfaa7, 0x76db, 0}, +{0xfaa8, 0x76f4, 0}, +{0xfaa9, 0x774a, 0}, +{0xfaaa, 0x7740, 0}, +{0xfaab, 0x78cc, 0}, +{0xfaac, 0x7ab1, 0}, +{0xfaad, 0x7bc0, 0}, +{0xfaae, 0x7c7b, 0}, +{0xfaaf, 0x7d5b, 0}, +{0xfab0, 0x7df4, 0}, +{0xfab1, 0x7f3e, 0}, +{0xfab2, 0x8005, 0}, +{0xfab3, 0x8352, 0}, +{0xfab4, 0x83ef, 0}, +{0xfab5, 0x8779, 0}, +{0xfab6, 0x8941, 0}, +{0xfab7, 0x8986, 0}, +{0xfab8, 0x8996, 0}, +{0xfab9, 0x8abf, 0}, +{0xfaba, 0x8af8, 0}, +{0xfabb, 0x8acb, 0}, +{0xfabc, 0x8b01, 0}, +{0xfabd, 0x8afe, 0}, +{0xfabe, 0x8aed, 0}, +{0xfabf, 0x8b39, 0}, +{0xfac0, 0x8b8a, 0}, +{0xfac1, 0x8d08, 0}, +{0xfac2, 0x8f38, 0}, +{0xfac3, 0x9072, 0}, +{0xfac4, 0x9199, 0}, +{0xfac5, 0x9276, 0}, +{0xfac6, 0x967c, 0}, +{0xfac7, 0x96e3, 0}, +{0xfac8, 0x9756, 0}, +{0xfac9, 0x97db, 0}, +{0xfaca, 0x97ff, 0}, +{0xfacb, 0x980b, 0}, +{0xfacc, 0x983b, 0}, +{0xfacd, 0x9b12, 0}, +{0xface, 0x9f9c, 0}, +{0xfacf, 0x2284a, 0}, +{0xfad0, 0x22844, 0}, +{0xfad1, 0x233d5, 0}, +{0xfad2, 0x3b9d, 0}, +{0xfad3, 0x4018, 0}, +{0xfad4, 0x4039, 0}, +{0xfad5, 0x25249, 0}, +{0xfad6, 0x25cd0, 0}, +{0xfad7, 0x27ed3, 0}, +{0xfad8, 0x9f43, 0}, +{0xfad9, 0x9f8e, 0}, +{0xfb1d, 0x05d9, 0x05b4}, +{0xfb1f, 0x05f2, 0x05b7}, +{0xfb2a, 0x05e9, 0x05c1}, +{0xfb2b, 0x05e9, 0x05c2}, +{0xfb2c, 0xfb49, 0x05c1}, +{0xfb2d, 0xfb49, 0x05c2}, +{0xfb2e, 0x05d0, 0x05b7}, +{0xfb2f, 0x05d0, 0x05b8}, +{0xfb30, 0x05d0, 0x05bc}, +{0xfb31, 0x05d1, 0x05bc}, +{0xfb32, 0x05d2, 0x05bc}, +{0xfb33, 0x05d3, 0x05bc}, +{0xfb34, 0x05d4, 0x05bc}, +{0xfb35, 0x05d5, 0x05bc}, +{0xfb36, 0x05d6, 0x05bc}, +{0xfb38, 0x05d8, 0x05bc}, +{0xfb39, 0x05d9, 0x05bc}, +{0xfb3a, 0x05da, 0x05bc}, +{0xfb3b, 0x05db, 0x05bc}, +{0xfb3c, 0x05dc, 0x05bc}, +{0xfb3e, 0x05de, 0x05bc}, +{0xfb40, 0x05e0, 0x05bc}, +{0xfb41, 0x05e1, 0x05bc}, +{0xfb43, 0x05e3, 0x05bc}, +{0xfb44, 0x05e4, 0x05bc}, +{0xfb46, 0x05e6, 0x05bc}, +{0xfb47, 0x05e7, 0x05bc}, +{0xfb48, 0x05e8, 0x05bc}, +{0xfb49, 0x05e9, 0x05bc}, +{0xfb4a, 0x05ea, 0x05bc}, +{0xfb4b, 0x05d5, 0x05b9}, +{0xfb4c, 0x05d1, 0x05bf}, +{0xfb4d, 0x05db, 0x05bf}, +{0xfb4e, 0x05e4, 0x05bf}, +{0x1109a, 0x11099, 0x110ba}, +{0x1109c, 0x1109b, 0x110ba}, +{0x110ab, 0x110a5, 0x110ba}, +{0x1112e, 0x11131, 0x11127}, +{0x1112f, 0x11132, 0x11127}, +{0x1134b, 0x11347, 0x1133e}, +{0x1134c, 0x11347, 0x11357}, +{0x114bb, 0x114b9, 0x114ba}, +{0x114bc, 0x114b9, 0x114b0}, +{0x114be, 0x114b9, 0x114bd}, +{0x115ba, 0x115b8, 0x115af}, +{0x115bb, 0x115b9, 0x115af}, +{0x11938, 0x11935, 0x11930}, +{0x1d15e, 0x1d157, 0x1d165}, +{0x1d15f, 0x1d158, 0x1d165}, +{0x1d160, 0x1d15f, 0x1d16e}, +{0x1d161, 0x1d15f, 0x1d16f}, +{0x1d162, 0x1d15f, 0x1d170}, +{0x1d163, 0x1d15f, 0x1d171}, +{0x1d164, 0x1d15f, 0x1d172}, +{0x1d1bb, 0x1d1b9, 0x1d165}, +{0x1d1bc, 0x1d1ba, 0x1d165}, +{0x1d1bd, 0x1d1bb, 0x1d16e}, +{0x1d1be, 0x1d1bc, 0x1d16e}, +{0x1d1bf, 0x1d1bb, 0x1d16f}, +{0x1d1c0, 0x1d1bc, 0x1d16f}, +{0x2f800, 0x4e3d, 0}, +{0x2f801, 0x4e38, 0}, +{0x2f802, 0x4e41, 0}, +{0x2f803, 0x20122, 0}, +{0x2f804, 0x4f60, 0}, +{0x2f805, 0x4fae, 0}, +{0x2f806, 0x4fbb, 0}, +{0x2f807, 0x5002, 0}, +{0x2f808, 0x507a, 0}, +{0x2f809, 0x5099, 0}, +{0x2f80a, 0x50e7, 0}, +{0x2f80b, 0x50cf, 0}, +{0x2f80c, 0x349e, 0}, +{0x2f80d, 0x2063a, 0}, +{0x2f80e, 0x514d, 0}, +{0x2f80f, 0x5154, 0}, +{0x2f810, 0x5164, 0}, +{0x2f811, 0x5177, 0}, +{0x2f812, 0x2051c, 0}, +{0x2f813, 0x34b9, 0}, +{0x2f814, 0x5167, 0}, +{0x2f815, 0x518d, 0}, +{0x2f816, 0x2054b, 0}, +{0x2f817, 0x5197, 0}, +{0x2f818, 0x51a4, 0}, +{0x2f819, 0x4ecc, 0}, +{0x2f81a, 0x51ac, 0}, +{0x2f81b, 0x51b5, 0}, +{0x2f81c, 0x291df, 0}, +{0x2f81d, 0x51f5, 0}, +{0x2f81e, 0x5203, 0}, +{0x2f81f, 0x34df, 0}, +{0x2f820, 0x523b, 0}, +{0x2f821, 0x5246, 0}, +{0x2f822, 0x5272, 0}, +{0x2f823, 0x5277, 0}, +{0x2f824, 0x3515, 0}, +{0x2f825, 0x52c7, 0}, +{0x2f826, 0x52c9, 0}, +{0x2f827, 0x52e4, 0}, +{0x2f828, 0x52fa, 0}, +{0x2f829, 0x5305, 0}, +{0x2f82a, 0x5306, 0}, +{0x2f82b, 0x5317, 0}, +{0x2f82c, 0x5349, 0}, +{0x2f82d, 0x5351, 0}, +{0x2f82e, 0x535a, 0}, +{0x2f82f, 0x5373, 0}, +{0x2f830, 0x537d, 0}, +{0x2f831, 0x537f, 0}, +{0x2f832, 0x537f, 0}, +{0x2f833, 0x537f, 0}, +{0x2f834, 0x20a2c, 0}, +{0x2f835, 0x7070, 0}, +{0x2f836, 0x53ca, 0}, +{0x2f837, 0x53df, 0}, +{0x2f838, 0x20b63, 0}, +{0x2f839, 0x53eb, 0}, +{0x2f83a, 0x53f1, 0}, +{0x2f83b, 0x5406, 0}, +{0x2f83c, 0x549e, 0}, +{0x2f83d, 0x5438, 0}, +{0x2f83e, 0x5448, 0}, +{0x2f83f, 0x5468, 0}, +{0x2f840, 0x54a2, 0}, +{0x2f841, 0x54f6, 0}, +{0x2f842, 0x5510, 0}, +{0x2f843, 0x5553, 0}, +{0x2f844, 0x5563, 0}, +{0x2f845, 0x5584, 0}, +{0x2f846, 0x5584, 0}, +{0x2f847, 0x5599, 0}, +{0x2f848, 0x55ab, 0}, +{0x2f849, 0x55b3, 0}, +{0x2f84a, 0x55c2, 0}, +{0x2f84b, 0x5716, 0}, +{0x2f84c, 0x5606, 0}, +{0x2f84d, 0x5717, 0}, +{0x2f84e, 0x5651, 0}, +{0x2f84f, 0x5674, 0}, +{0x2f850, 0x5207, 0}, +{0x2f851, 0x58ee, 0}, +{0x2f852, 0x57ce, 0}, +{0x2f853, 0x57f4, 0}, +{0x2f854, 0x580d, 0}, +{0x2f855, 0x578b, 0}, +{0x2f856, 0x5832, 0}, +{0x2f857, 0x5831, 0}, +{0x2f858, 0x58ac, 0}, +{0x2f859, 0x214e4, 0}, +{0x2f85a, 0x58f2, 0}, +{0x2f85b, 0x58f7, 0}, +{0x2f85c, 0x5906, 0}, +{0x2f85d, 0x591a, 0}, +{0x2f85e, 0x5922, 0}, +{0x2f85f, 0x5962, 0}, +{0x2f860, 0x216a8, 0}, +{0x2f861, 0x216ea, 0}, +{0x2f862, 0x59ec, 0}, +{0x2f863, 0x5a1b, 0}, +{0x2f864, 0x5a27, 0}, +{0x2f865, 0x59d8, 0}, +{0x2f866, 0x5a66, 0}, +{0x2f867, 0x36ee, 0}, +{0x2f868, 0x36fc, 0}, +{0x2f869, 0x5b08, 0}, +{0x2f86a, 0x5b3e, 0}, +{0x2f86b, 0x5b3e, 0}, +{0x2f86c, 0x219c8, 0}, +{0x2f86d, 0x5bc3, 0}, +{0x2f86e, 0x5bd8, 0}, +{0x2f86f, 0x5be7, 0}, +{0x2f870, 0x5bf3, 0}, +{0x2f871, 0x21b18, 0}, +{0x2f872, 0x5bff, 0}, +{0x2f873, 0x5c06, 0}, +{0x2f874, 0x5f53, 0}, +{0x2f875, 0x5c22, 0}, +{0x2f876, 0x3781, 0}, +{0x2f877, 0x5c60, 0}, +{0x2f878, 0x5c6e, 0}, +{0x2f879, 0x5cc0, 0}, +{0x2f87a, 0x5c8d, 0}, +{0x2f87b, 0x21de4, 0}, +{0x2f87c, 0x5d43, 0}, +{0x2f87d, 0x21de6, 0}, +{0x2f87e, 0x5d6e, 0}, +{0x2f87f, 0x5d6b, 0}, +{0x2f880, 0x5d7c, 0}, +{0x2f881, 0x5de1, 0}, +{0x2f882, 0x5de2, 0}, +{0x2f883, 0x382f, 0}, +{0x2f884, 0x5dfd, 0}, +{0x2f885, 0x5e28, 0}, +{0x2f886, 0x5e3d, 0}, +{0x2f887, 0x5e69, 0}, +{0x2f888, 0x3862, 0}, +{0x2f889, 0x22183, 0}, +{0x2f88a, 0x387c, 0}, +{0x2f88b, 0x5eb0, 0}, +{0x2f88c, 0x5eb3, 0}, +{0x2f88d, 0x5eb6, 0}, +{0x2f88e, 0x5eca, 0}, +{0x2f88f, 0x2a392, 0}, +{0x2f890, 0x5efe, 0}, +{0x2f891, 0x22331, 0}, +{0x2f892, 0x22331, 0}, +{0x2f893, 0x8201, 0}, +{0x2f894, 0x5f22, 0}, +{0x2f895, 0x5f22, 0}, +{0x2f896, 0x38c7, 0}, +{0x2f897, 0x232b8, 0}, +{0x2f898, 0x261da, 0}, +{0x2f899, 0x5f62, 0}, +{0x2f89a, 0x5f6b, 0}, +{0x2f89b, 0x38e3, 0}, +{0x2f89c, 0x5f9a, 0}, +{0x2f89d, 0x5fcd, 0}, +{0x2f89e, 0x5fd7, 0}, +{0x2f89f, 0x5ff9, 0}, +{0x2f8a0, 0x6081, 0}, +{0x2f8a1, 0x393a, 0}, +{0x2f8a2, 0x391c, 0}, +{0x2f8a3, 0x6094, 0}, +{0x2f8a4, 0x226d4, 0}, +{0x2f8a5, 0x60c7, 0}, +{0x2f8a6, 0x6148, 0}, +{0x2f8a7, 0x614c, 0}, +{0x2f8a8, 0x614e, 0}, +{0x2f8a9, 0x614c, 0}, +{0x2f8aa, 0x617a, 0}, +{0x2f8ab, 0x618e, 0}, +{0x2f8ac, 0x61b2, 0}, +{0x2f8ad, 0x61a4, 0}, +{0x2f8ae, 0x61af, 0}, +{0x2f8af, 0x61de, 0}, +{0x2f8b0, 0x61f2, 0}, +{0x2f8b1, 0x61f6, 0}, +{0x2f8b2, 0x6210, 0}, +{0x2f8b3, 0x621b, 0}, +{0x2f8b4, 0x625d, 0}, +{0x2f8b5, 0x62b1, 0}, +{0x2f8b6, 0x62d4, 0}, +{0x2f8b7, 0x6350, 0}, +{0x2f8b8, 0x22b0c, 0}, +{0x2f8b9, 0x633d, 0}, +{0x2f8ba, 0x62fc, 0}, +{0x2f8bb, 0x6368, 0}, +{0x2f8bc, 0x6383, 0}, +{0x2f8bd, 0x63e4, 0}, +{0x2f8be, 0x22bf1, 0}, +{0x2f8bf, 0x6422, 0}, +{0x2f8c0, 0x63c5, 0}, +{0x2f8c1, 0x63a9, 0}, +{0x2f8c2, 0x3a2e, 0}, +{0x2f8c3, 0x6469, 0}, +{0x2f8c4, 0x647e, 0}, +{0x2f8c5, 0x649d, 0}, +{0x2f8c6, 0x6477, 0}, +{0x2f8c7, 0x3a6c, 0}, +{0x2f8c8, 0x654f, 0}, +{0x2f8c9, 0x656c, 0}, +{0x2f8ca, 0x2300a, 0}, +{0x2f8cb, 0x65e3, 0}, +{0x2f8cc, 0x66f8, 0}, +{0x2f8cd, 0x6649, 0}, +{0x2f8ce, 0x3b19, 0}, +{0x2f8cf, 0x6691, 0}, +{0x2f8d0, 0x3b08, 0}, +{0x2f8d1, 0x3ae4, 0}, +{0x2f8d2, 0x5192, 0}, +{0x2f8d3, 0x5195, 0}, +{0x2f8d4, 0x6700, 0}, +{0x2f8d5, 0x669c, 0}, +{0x2f8d6, 0x80ad, 0}, +{0x2f8d7, 0x43d9, 0}, +{0x2f8d8, 0x6717, 0}, +{0x2f8d9, 0x671b, 0}, +{0x2f8da, 0x6721, 0}, +{0x2f8db, 0x675e, 0}, +{0x2f8dc, 0x6753, 0}, +{0x2f8dd, 0x233c3, 0}, +{0x2f8de, 0x3b49, 0}, +{0x2f8df, 0x67fa, 0}, +{0x2f8e0, 0x6785, 0}, +{0x2f8e1, 0x6852, 0}, +{0x2f8e2, 0x6885, 0}, +{0x2f8e3, 0x2346d, 0}, +{0x2f8e4, 0x688e, 0}, +{0x2f8e5, 0x681f, 0}, +{0x2f8e6, 0x6914, 0}, +{0x2f8e7, 0x3b9d, 0}, +{0x2f8e8, 0x6942, 0}, +{0x2f8e9, 0x69a3, 0}, +{0x2f8ea, 0x69ea, 0}, +{0x2f8eb, 0x6aa8, 0}, +{0x2f8ec, 0x236a3, 0}, +{0x2f8ed, 0x6adb, 0}, +{0x2f8ee, 0x3c18, 0}, +{0x2f8ef, 0x6b21, 0}, +{0x2f8f0, 0x238a7, 0}, +{0x2f8f1, 0x6b54, 0}, +{0x2f8f2, 0x3c4e, 0}, +{0x2f8f3, 0x6b72, 0}, +{0x2f8f4, 0x6b9f, 0}, +{0x2f8f5, 0x6bba, 0}, +{0x2f8f6, 0x6bbb, 0}, +{0x2f8f7, 0x23a8d, 0}, +{0x2f8f8, 0x21d0b, 0}, +{0x2f8f9, 0x23afa, 0}, +{0x2f8fa, 0x6c4e, 0}, +{0x2f8fb, 0x23cbc, 0}, +{0x2f8fc, 0x6cbf, 0}, +{0x2f8fd, 0x6ccd, 0}, +{0x2f8fe, 0x6c67, 0}, +{0x2f8ff, 0x6d16, 0}, +{0x2f900, 0x6d3e, 0}, +{0x2f901, 0x6d77, 0}, +{0x2f902, 0x6d41, 0}, +{0x2f903, 0x6d69, 0}, +{0x2f904, 0x6d78, 0}, +{0x2f905, 0x6d85, 0}, +{0x2f906, 0x23d1e, 0}, +{0x2f907, 0x6d34, 0}, +{0x2f908, 0x6e2f, 0}, +{0x2f909, 0x6e6e, 0}, +{0x2f90a, 0x3d33, 0}, +{0x2f90b, 0x6ecb, 0}, +{0x2f90c, 0x6ec7, 0}, +{0x2f90d, 0x23ed1, 0}, +{0x2f90e, 0x6df9, 0}, +{0x2f90f, 0x6f6e, 0}, +{0x2f910, 0x23f5e, 0}, +{0x2f911, 0x23f8e, 0}, +{0x2f912, 0x6fc6, 0}, +{0x2f913, 0x7039, 0}, +{0x2f914, 0x701e, 0}, +{0x2f915, 0x701b, 0}, +{0x2f916, 0x3d96, 0}, +{0x2f917, 0x704a, 0}, +{0x2f918, 0x707d, 0}, +{0x2f919, 0x7077, 0}, +{0x2f91a, 0x70ad, 0}, +{0x2f91b, 0x20525, 0}, +{0x2f91c, 0x7145, 0}, +{0x2f91d, 0x24263, 0}, +{0x2f91e, 0x719c, 0}, +{0x2f91f, 0x243ab, 0}, +{0x2f920, 0x7228, 0}, +{0x2f921, 0x7235, 0}, +{0x2f922, 0x7250, 0}, +{0x2f923, 0x24608, 0}, +{0x2f924, 0x7280, 0}, +{0x2f925, 0x7295, 0}, +{0x2f926, 0x24735, 0}, +{0x2f927, 0x24814, 0}, +{0x2f928, 0x737a, 0}, +{0x2f929, 0x738b, 0}, +{0x2f92a, 0x3eac, 0}, +{0x2f92b, 0x73a5, 0}, +{0x2f92c, 0x3eb8, 0}, +{0x2f92d, 0x3eb8, 0}, +{0x2f92e, 0x7447, 0}, +{0x2f92f, 0x745c, 0}, +{0x2f930, 0x7471, 0}, +{0x2f931, 0x7485, 0}, +{0x2f932, 0x74ca, 0}, +{0x2f933, 0x3f1b, 0}, +{0x2f934, 0x7524, 0}, +{0x2f935, 0x24c36, 0}, +{0x2f936, 0x753e, 0}, +{0x2f937, 0x24c92, 0}, +{0x2f938, 0x7570, 0}, +{0x2f939, 0x2219f, 0}, +{0x2f93a, 0x7610, 0}, +{0x2f93b, 0x24fa1, 0}, +{0x2f93c, 0x24fb8, 0}, +{0x2f93d, 0x25044, 0}, +{0x2f93e, 0x3ffc, 0}, +{0x2f93f, 0x4008, 0}, +{0x2f940, 0x76f4, 0}, +{0x2f941, 0x250f3, 0}, +{0x2f942, 0x250f2, 0}, +{0x2f943, 0x25119, 0}, +{0x2f944, 0x25133, 0}, +{0x2f945, 0x771e, 0}, +{0x2f946, 0x771f, 0}, +{0x2f947, 0x771f, 0}, +{0x2f948, 0x774a, 0}, +{0x2f949, 0x4039, 0}, +{0x2f94a, 0x778b, 0}, +{0x2f94b, 0x4046, 0}, +{0x2f94c, 0x4096, 0}, +{0x2f94d, 0x2541d, 0}, +{0x2f94e, 0x784e, 0}, +{0x2f94f, 0x788c, 0}, +{0x2f950, 0x78cc, 0}, +{0x2f951, 0x40e3, 0}, +{0x2f952, 0x25626, 0}, +{0x2f953, 0x7956, 0}, +{0x2f954, 0x2569a, 0}, +{0x2f955, 0x256c5, 0}, +{0x2f956, 0x798f, 0}, +{0x2f957, 0x79eb, 0}, +{0x2f958, 0x412f, 0}, +{0x2f959, 0x7a40, 0}, +{0x2f95a, 0x7a4a, 0}, +{0x2f95b, 0x7a4f, 0}, +{0x2f95c, 0x2597c, 0}, +{0x2f95d, 0x25aa7, 0}, +{0x2f95e, 0x25aa7, 0}, +{0x2f95f, 0x7aee, 0}, +{0x2f960, 0x4202, 0}, +{0x2f961, 0x25bab, 0}, +{0x2f962, 0x7bc6, 0}, +{0x2f963, 0x7bc9, 0}, +{0x2f964, 0x4227, 0}, +{0x2f965, 0x25c80, 0}, +{0x2f966, 0x7cd2, 0}, +{0x2f967, 0x42a0, 0}, +{0x2f968, 0x7ce8, 0}, +{0x2f969, 0x7ce3, 0}, +{0x2f96a, 0x7d00, 0}, +{0x2f96b, 0x25f86, 0}, +{0x2f96c, 0x7d63, 0}, +{0x2f96d, 0x4301, 0}, +{0x2f96e, 0x7dc7, 0}, +{0x2f96f, 0x7e02, 0}, +{0x2f970, 0x7e45, 0}, +{0x2f971, 0x4334, 0}, +{0x2f972, 0x26228, 0}, +{0x2f973, 0x26247, 0}, +{0x2f974, 0x4359, 0}, +{0x2f975, 0x262d9, 0}, +{0x2f976, 0x7f7a, 0}, +{0x2f977, 0x2633e, 0}, +{0x2f978, 0x7f95, 0}, +{0x2f979, 0x7ffa, 0}, +{0x2f97a, 0x8005, 0}, +{0x2f97b, 0x264da, 0}, +{0x2f97c, 0x26523, 0}, +{0x2f97d, 0x8060, 0}, +{0x2f97e, 0x265a8, 0}, +{0x2f97f, 0x8070, 0}, +{0x2f980, 0x2335f, 0}, +{0x2f981, 0x43d5, 0}, +{0x2f982, 0x80b2, 0}, +{0x2f983, 0x8103, 0}, +{0x2f984, 0x440b, 0}, +{0x2f985, 0x813e, 0}, +{0x2f986, 0x5ab5, 0}, +{0x2f987, 0x267a7, 0}, +{0x2f988, 0x267b5, 0}, +{0x2f989, 0x23393, 0}, +{0x2f98a, 0x2339c, 0}, +{0x2f98b, 0x8201, 0}, +{0x2f98c, 0x8204, 0}, +{0x2f98d, 0x8f9e, 0}, +{0x2f98e, 0x446b, 0}, +{0x2f98f, 0x8291, 0}, +{0x2f990, 0x828b, 0}, +{0x2f991, 0x829d, 0}, +{0x2f992, 0x52b3, 0}, +{0x2f993, 0x82b1, 0}, +{0x2f994, 0x82b3, 0}, +{0x2f995, 0x82bd, 0}, +{0x2f996, 0x82e6, 0}, +{0x2f997, 0x26b3c, 0}, +{0x2f998, 0x82e5, 0}, +{0x2f999, 0x831d, 0}, +{0x2f99a, 0x8363, 0}, +{0x2f99b, 0x83ad, 0}, +{0x2f99c, 0x8323, 0}, +{0x2f99d, 0x83bd, 0}, +{0x2f99e, 0x83e7, 0}, +{0x2f99f, 0x8457, 0}, +{0x2f9a0, 0x8353, 0}, +{0x2f9a1, 0x83ca, 0}, +{0x2f9a2, 0x83cc, 0}, +{0x2f9a3, 0x83dc, 0}, +{0x2f9a4, 0x26c36, 0}, +{0x2f9a5, 0x26d6b, 0}, +{0x2f9a6, 0x26cd5, 0}, +{0x2f9a7, 0x452b, 0}, +{0x2f9a8, 0x84f1, 0}, +{0x2f9a9, 0x84f3, 0}, +{0x2f9aa, 0x8516, 0}, +{0x2f9ab, 0x273ca, 0}, +{0x2f9ac, 0x8564, 0}, +{0x2f9ad, 0x26f2c, 0}, +{0x2f9ae, 0x455d, 0}, +{0x2f9af, 0x4561, 0}, +{0x2f9b0, 0x26fb1, 0}, +{0x2f9b1, 0x270d2, 0}, +{0x2f9b2, 0x456b, 0}, +{0x2f9b3, 0x8650, 0}, +{0x2f9b4, 0x865c, 0}, +{0x2f9b5, 0x8667, 0}, +{0x2f9b6, 0x8669, 0}, +{0x2f9b7, 0x86a9, 0}, +{0x2f9b8, 0x8688, 0}, +{0x2f9b9, 0x870e, 0}, +{0x2f9ba, 0x86e2, 0}, +{0x2f9bb, 0x8779, 0}, +{0x2f9bc, 0x8728, 0}, +{0x2f9bd, 0x876b, 0}, +{0x2f9be, 0x8786, 0}, +{0x2f9bf, 0x45d7, 0}, +{0x2f9c0, 0x87e1, 0}, +{0x2f9c1, 0x8801, 0}, +{0x2f9c2, 0x45f9, 0}, +{0x2f9c3, 0x8860, 0}, +{0x2f9c4, 0x8863, 0}, +{0x2f9c5, 0x27667, 0}, +{0x2f9c6, 0x88d7, 0}, +{0x2f9c7, 0x88de, 0}, +{0x2f9c8, 0x4635, 0}, +{0x2f9c9, 0x88fa, 0}, +{0x2f9ca, 0x34bb, 0}, +{0x2f9cb, 0x278ae, 0}, +{0x2f9cc, 0x27966, 0}, +{0x2f9cd, 0x46be, 0}, +{0x2f9ce, 0x46c7, 0}, +{0x2f9cf, 0x8aa0, 0}, +{0x2f9d0, 0x8aed, 0}, +{0x2f9d1, 0x8b8a, 0}, +{0x2f9d2, 0x8c55, 0}, +{0x2f9d3, 0x27ca8, 0}, +{0x2f9d4, 0x8cab, 0}, +{0x2f9d5, 0x8cc1, 0}, +{0x2f9d6, 0x8d1b, 0}, +{0x2f9d7, 0x8d77, 0}, +{0x2f9d8, 0x27f2f, 0}, +{0x2f9d9, 0x20804, 0}, +{0x2f9da, 0x8dcb, 0}, +{0x2f9db, 0x8dbc, 0}, +{0x2f9dc, 0x8df0, 0}, +{0x2f9dd, 0x208de, 0}, +{0x2f9de, 0x8ed4, 0}, +{0x2f9df, 0x8f38, 0}, +{0x2f9e0, 0x285d2, 0}, +{0x2f9e1, 0x285ed, 0}, +{0x2f9e2, 0x9094, 0}, +{0x2f9e3, 0x90f1, 0}, +{0x2f9e4, 0x9111, 0}, +{0x2f9e5, 0x2872e, 0}, +{0x2f9e6, 0x911b, 0}, +{0x2f9e7, 0x9238, 0}, +{0x2f9e8, 0x92d7, 0}, +{0x2f9e9, 0x92d8, 0}, +{0x2f9ea, 0x927c, 0}, +{0x2f9eb, 0x93f9, 0}, +{0x2f9ec, 0x9415, 0}, +{0x2f9ed, 0x28bfa, 0}, +{0x2f9ee, 0x958b, 0}, +{0x2f9ef, 0x4995, 0}, +{0x2f9f0, 0x95b7, 0}, +{0x2f9f1, 0x28d77, 0}, +{0x2f9f2, 0x49e6, 0}, +{0x2f9f3, 0x96c3, 0}, +{0x2f9f4, 0x5db2, 0}, +{0x2f9f5, 0x9723, 0}, +{0x2f9f6, 0x29145, 0}, +{0x2f9f7, 0x2921a, 0}, +{0x2f9f8, 0x4a6e, 0}, +{0x2f9f9, 0x4a76, 0}, +{0x2f9fa, 0x97e0, 0}, +{0x2f9fb, 0x2940a, 0}, +{0x2f9fc, 0x4ab2, 0}, +{0x2f9fd, 0x29496, 0}, +{0x2f9fe, 0x980b, 0}, +{0x2f9ff, 0x980b, 0}, +{0x2fa00, 0x9829, 0}, +{0x2fa01, 0x295b6, 0}, +{0x2fa02, 0x98e2, 0}, +{0x2fa03, 0x4b33, 0}, +{0x2fa04, 0x9929, 0}, +{0x2fa05, 0x99a7, 0}, +{0x2fa06, 0x99c2, 0}, +{0x2fa07, 0x99fe, 0}, +{0x2fa08, 0x4bce, 0}, +{0x2fa09, 0x29b30, 0}, +{0x2fa0a, 0x9b12, 0}, +{0x2fa0b, 0x9c40, 0}, +{0x2fa0c, 0x9cfd, 0}, +{0x2fa0d, 0x4cce, 0}, +{0x2fa0e, 0x4ced, 0}, +{0x2fa0f, 0x9d67, 0}, +{0x2fa10, 0x2a0ce, 0}, +{0x2fa11, 0x4cf8, 0}, +{0x2fa12, 0x2a105, 0}, +{0x2fa13, 0x2a20e, 0}, +{0x2fa14, 0x2a291, 0}, +{0x2fa15, 0x9ebb, 0}, +{0x2fa16, 0x4d56, 0}, +{0x2fa17, 0x9ef9, 0}, +{0x2fa18, 0x9efe, 0}, +{0x2fa19, 0x9f05, 0}, +{0x2fa1a, 0x9f0f, 0}, +{0x2fa1b, 0x9f16, 0}, +{0x2fa1c, 0x9f3b, 0}, +{0x2fa1d, 0x2a600, 0}, diff --git a/unicode/combining_classes.h b/unicode/combining_classes.h new file mode 100644 index 00000000..a2262bc3 --- /dev/null +++ b/unicode/combining_classes.h @@ -0,0 +1,398 @@ +/* + * Autogenerated by read_ucd.py from The Unicode Standard 15.0.0 + * + * List the canonical combining class of each Unicode character, if it is + * not zero. This controls how combining marks can be reordered by the + * Unicode normalisation algorithms. + * + * Used by utils/unicode-norm.c. + */ + +{0x0300, 0x0314, 230}, +{0x0315, 0x0315, 232}, +{0x0316, 0x0319, 220}, +{0x031a, 0x031a, 232}, +{0x031b, 0x031b, 216}, +{0x031c, 0x0320, 220}, +{0x0321, 0x0322, 202}, +{0x0323, 0x0326, 220}, +{0x0327, 0x0328, 202}, +{0x0329, 0x0333, 220}, +{0x0334, 0x0338, 1}, +{0x0339, 0x033c, 220}, +{0x033d, 0x0344, 230}, +{0x0345, 0x0345, 240}, +{0x0346, 0x0346, 230}, +{0x0347, 0x0349, 220}, +{0x034a, 0x034c, 230}, +{0x034d, 0x034e, 220}, +{0x0350, 0x0352, 230}, +{0x0353, 0x0356, 220}, +{0x0357, 0x0357, 230}, +{0x0358, 0x0358, 232}, +{0x0359, 0x035a, 220}, +{0x035b, 0x035b, 230}, +{0x035c, 0x035c, 233}, +{0x035d, 0x035e, 234}, +{0x035f, 0x035f, 233}, +{0x0360, 0x0361, 234}, +{0x0362, 0x0362, 233}, +{0x0363, 0x036f, 230}, +{0x0483, 0x0487, 230}, +{0x0591, 0x0591, 220}, +{0x0592, 0x0595, 230}, +{0x0596, 0x0596, 220}, +{0x0597, 0x0599, 230}, +{0x059a, 0x059a, 222}, +{0x059b, 0x059b, 220}, +{0x059c, 0x05a1, 230}, +{0x05a2, 0x05a7, 220}, +{0x05a8, 0x05a9, 230}, +{0x05aa, 0x05aa, 220}, +{0x05ab, 0x05ac, 230}, +{0x05ad, 0x05ad, 222}, +{0x05ae, 0x05ae, 228}, +{0x05af, 0x05af, 230}, +{0x05b0, 0x05b0, 10}, +{0x05b1, 0x05b1, 11}, +{0x05b2, 0x05b2, 12}, +{0x05b3, 0x05b3, 13}, +{0x05b4, 0x05b4, 14}, +{0x05b5, 0x05b5, 15}, +{0x05b6, 0x05b6, 16}, +{0x05b7, 0x05b7, 17}, +{0x05b8, 0x05b8, 18}, +{0x05b9, 0x05ba, 19}, +{0x05bb, 0x05bb, 20}, +{0x05bc, 0x05bc, 21}, +{0x05bd, 0x05bd, 22}, +{0x05bf, 0x05bf, 23}, +{0x05c1, 0x05c1, 24}, +{0x05c2, 0x05c2, 25}, +{0x05c4, 0x05c4, 230}, +{0x05c5, 0x05c5, 220}, +{0x05c7, 0x05c7, 18}, +{0x0610, 0x0617, 230}, +{0x0618, 0x0618, 30}, +{0x0619, 0x0619, 31}, +{0x061a, 0x061a, 32}, +{0x064b, 0x064b, 27}, +{0x064c, 0x064c, 28}, +{0x064d, 0x064d, 29}, +{0x064e, 0x064e, 30}, +{0x064f, 0x064f, 31}, +{0x0650, 0x0650, 32}, +{0x0651, 0x0651, 33}, +{0x0652, 0x0652, 34}, +{0x0653, 0x0654, 230}, +{0x0655, 0x0656, 220}, +{0x0657, 0x065b, 230}, +{0x065c, 0x065c, 220}, +{0x065d, 0x065e, 230}, +{0x065f, 0x065f, 220}, +{0x0670, 0x0670, 35}, +{0x06d6, 0x06dc, 230}, +{0x06df, 0x06e2, 230}, +{0x06e3, 0x06e3, 220}, +{0x06e4, 0x06e4, 230}, +{0x06e7, 0x06e8, 230}, +{0x06ea, 0x06ea, 220}, +{0x06eb, 0x06ec, 230}, +{0x06ed, 0x06ed, 220}, +{0x0711, 0x0711, 36}, +{0x0730, 0x0730, 230}, +{0x0731, 0x0731, 220}, +{0x0732, 0x0733, 230}, +{0x0734, 0x0734, 220}, +{0x0735, 0x0736, 230}, +{0x0737, 0x0739, 220}, +{0x073a, 0x073a, 230}, +{0x073b, 0x073c, 220}, +{0x073d, 0x073d, 230}, +{0x073e, 0x073e, 220}, +{0x073f, 0x0741, 230}, +{0x0742, 0x0742, 220}, +{0x0743, 0x0743, 230}, +{0x0744, 0x0744, 220}, +{0x0745, 0x0745, 230}, +{0x0746, 0x0746, 220}, +{0x0747, 0x0747, 230}, +{0x0748, 0x0748, 220}, +{0x0749, 0x074a, 230}, +{0x07eb, 0x07f1, 230}, +{0x07f2, 0x07f2, 220}, +{0x07f3, 0x07f3, 230}, +{0x07fd, 0x07fd, 220}, +{0x0816, 0x0819, 230}, +{0x081b, 0x0823, 230}, +{0x0825, 0x0827, 230}, +{0x0829, 0x082d, 230}, +{0x0859, 0x085b, 220}, +{0x0898, 0x0898, 230}, +{0x0899, 0x089b, 220}, +{0x089c, 0x089f, 230}, +{0x08ca, 0x08ce, 230}, +{0x08cf, 0x08d3, 220}, +{0x08d4, 0x08e1, 230}, +{0x08e3, 0x08e3, 220}, +{0x08e4, 0x08e5, 230}, +{0x08e6, 0x08e6, 220}, +{0x08e7, 0x08e8, 230}, +{0x08e9, 0x08e9, 220}, +{0x08ea, 0x08ec, 230}, +{0x08ed, 0x08ef, 220}, +{0x08f0, 0x08f0, 27}, +{0x08f1, 0x08f1, 28}, +{0x08f2, 0x08f2, 29}, +{0x08f3, 0x08f5, 230}, +{0x08f6, 0x08f6, 220}, +{0x08f7, 0x08f8, 230}, +{0x08f9, 0x08fa, 220}, +{0x08fb, 0x08ff, 230}, +{0x093c, 0x093c, 7}, +{0x094d, 0x094d, 9}, +{0x0951, 0x0951, 230}, +{0x0952, 0x0952, 220}, +{0x0953, 0x0954, 230}, +{0x09bc, 0x09bc, 7}, +{0x09cd, 0x09cd, 9}, +{0x09fe, 0x09fe, 230}, +{0x0a3c, 0x0a3c, 7}, +{0x0a4d, 0x0a4d, 9}, +{0x0abc, 0x0abc, 7}, +{0x0acd, 0x0acd, 9}, +{0x0b3c, 0x0b3c, 7}, +{0x0b4d, 0x0b4d, 9}, +{0x0bcd, 0x0bcd, 9}, +{0x0c3c, 0x0c3c, 7}, +{0x0c4d, 0x0c4d, 9}, +{0x0c55, 0x0c55, 84}, +{0x0c56, 0x0c56, 91}, +{0x0cbc, 0x0cbc, 7}, +{0x0ccd, 0x0ccd, 9}, +{0x0d3b, 0x0d3c, 9}, +{0x0d4d, 0x0d4d, 9}, +{0x0dca, 0x0dca, 9}, +{0x0e38, 0x0e39, 103}, +{0x0e3a, 0x0e3a, 9}, +{0x0e48, 0x0e4b, 107}, +{0x0eb8, 0x0eb9, 118}, +{0x0eba, 0x0eba, 9}, +{0x0ec8, 0x0ecb, 122}, +{0x0f18, 0x0f19, 220}, +{0x0f35, 0x0f35, 220}, +{0x0f37, 0x0f37, 220}, +{0x0f39, 0x0f39, 216}, +{0x0f71, 0x0f71, 129}, +{0x0f72, 0x0f72, 130}, +{0x0f74, 0x0f74, 132}, +{0x0f7a, 0x0f7d, 130}, +{0x0f80, 0x0f80, 130}, +{0x0f82, 0x0f83, 230}, +{0x0f84, 0x0f84, 9}, +{0x0f86, 0x0f87, 230}, +{0x0fc6, 0x0fc6, 220}, +{0x1037, 0x1037, 7}, +{0x1039, 0x103a, 9}, +{0x108d, 0x108d, 220}, +{0x135d, 0x135f, 230}, +{0x1714, 0x1715, 9}, +{0x1734, 0x1734, 9}, +{0x17d2, 0x17d2, 9}, +{0x17dd, 0x17dd, 230}, +{0x18a9, 0x18a9, 228}, +{0x1939, 0x1939, 222}, +{0x193a, 0x193a, 230}, +{0x193b, 0x193b, 220}, +{0x1a17, 0x1a17, 230}, +{0x1a18, 0x1a18, 220}, +{0x1a60, 0x1a60, 9}, +{0x1a75, 0x1a7c, 230}, +{0x1a7f, 0x1a7f, 220}, +{0x1ab0, 0x1ab4, 230}, +{0x1ab5, 0x1aba, 220}, +{0x1abb, 0x1abc, 230}, +{0x1abd, 0x1abd, 220}, +{0x1abf, 0x1ac0, 220}, +{0x1ac1, 0x1ac2, 230}, +{0x1ac3, 0x1ac4, 220}, +{0x1ac5, 0x1ac9, 230}, +{0x1aca, 0x1aca, 220}, +{0x1acb, 0x1ace, 230}, +{0x1b34, 0x1b34, 7}, +{0x1b44, 0x1b44, 9}, +{0x1b6b, 0x1b6b, 230}, +{0x1b6c, 0x1b6c, 220}, +{0x1b6d, 0x1b73, 230}, +{0x1baa, 0x1bab, 9}, +{0x1be6, 0x1be6, 7}, +{0x1bf2, 0x1bf3, 9}, +{0x1c37, 0x1c37, 7}, +{0x1cd0, 0x1cd2, 230}, +{0x1cd4, 0x1cd4, 1}, +{0x1cd5, 0x1cd9, 220}, +{0x1cda, 0x1cdb, 230}, +{0x1cdc, 0x1cdf, 220}, +{0x1ce0, 0x1ce0, 230}, +{0x1ce2, 0x1ce8, 1}, +{0x1ced, 0x1ced, 220}, +{0x1cf4, 0x1cf4, 230}, +{0x1cf8, 0x1cf9, 230}, +{0x1dc0, 0x1dc1, 230}, +{0x1dc2, 0x1dc2, 220}, +{0x1dc3, 0x1dc9, 230}, +{0x1dca, 0x1dca, 220}, +{0x1dcb, 0x1dcc, 230}, +{0x1dcd, 0x1dcd, 234}, +{0x1dce, 0x1dce, 214}, +{0x1dcf, 0x1dcf, 220}, +{0x1dd0, 0x1dd0, 202}, +{0x1dd1, 0x1df5, 230}, +{0x1df6, 0x1df6, 232}, +{0x1df7, 0x1df8, 228}, +{0x1df9, 0x1df9, 220}, +{0x1dfa, 0x1dfa, 218}, +{0x1dfb, 0x1dfb, 230}, +{0x1dfc, 0x1dfc, 233}, +{0x1dfd, 0x1dfd, 220}, +{0x1dfe, 0x1dfe, 230}, +{0x1dff, 0x1dff, 220}, +{0x20d0, 0x20d1, 230}, +{0x20d2, 0x20d3, 1}, +{0x20d4, 0x20d7, 230}, +{0x20d8, 0x20da, 1}, +{0x20db, 0x20dc, 230}, +{0x20e1, 0x20e1, 230}, +{0x20e5, 0x20e6, 1}, +{0x20e7, 0x20e7, 230}, +{0x20e8, 0x20e8, 220}, +{0x20e9, 0x20e9, 230}, +{0x20ea, 0x20eb, 1}, +{0x20ec, 0x20ef, 220}, +{0x20f0, 0x20f0, 230}, +{0x2cef, 0x2cf1, 230}, +{0x2d7f, 0x2d7f, 9}, +{0x2de0, 0x2dff, 230}, +{0x302a, 0x302a, 218}, +{0x302b, 0x302b, 228}, +{0x302c, 0x302c, 232}, +{0x302d, 0x302d, 222}, +{0x302e, 0x302f, 224}, +{0x3099, 0x309a, 8}, +{0xa66f, 0xa66f, 230}, +{0xa674, 0xa67d, 230}, +{0xa69e, 0xa69f, 230}, +{0xa6f0, 0xa6f1, 230}, +{0xa806, 0xa806, 9}, +{0xa82c, 0xa82c, 9}, +{0xa8c4, 0xa8c4, 9}, +{0xa8e0, 0xa8f1, 230}, +{0xa92b, 0xa92d, 220}, +{0xa953, 0xa953, 9}, +{0xa9b3, 0xa9b3, 7}, +{0xa9c0, 0xa9c0, 9}, +{0xaab0, 0xaab0, 230}, +{0xaab2, 0xaab3, 230}, +{0xaab4, 0xaab4, 220}, +{0xaab7, 0xaab8, 230}, +{0xaabe, 0xaabf, 230}, +{0xaac1, 0xaac1, 230}, +{0xaaf6, 0xaaf6, 9}, +{0xabed, 0xabed, 9}, +{0xfb1e, 0xfb1e, 26}, +{0xfe20, 0xfe26, 230}, +{0xfe27, 0xfe2d, 220}, +{0xfe2e, 0xfe2f, 230}, +{0x101fd, 0x101fd, 220}, +{0x102e0, 0x102e0, 220}, +{0x10376, 0x1037a, 230}, +{0x10a0d, 0x10a0d, 220}, +{0x10a0f, 0x10a0f, 230}, +{0x10a38, 0x10a38, 230}, +{0x10a39, 0x10a39, 1}, +{0x10a3a, 0x10a3a, 220}, +{0x10a3f, 0x10a3f, 9}, +{0x10ae5, 0x10ae5, 230}, +{0x10ae6, 0x10ae6, 220}, +{0x10d24, 0x10d27, 230}, +{0x10eab, 0x10eac, 230}, +{0x10efd, 0x10eff, 220}, +{0x10f46, 0x10f47, 220}, +{0x10f48, 0x10f4a, 230}, +{0x10f4b, 0x10f4b, 220}, +{0x10f4c, 0x10f4c, 230}, +{0x10f4d, 0x10f50, 220}, +{0x10f82, 0x10f82, 230}, +{0x10f83, 0x10f83, 220}, +{0x10f84, 0x10f84, 230}, +{0x10f85, 0x10f85, 220}, +{0x11046, 0x11046, 9}, +{0x11070, 0x11070, 9}, +{0x1107f, 0x1107f, 9}, +{0x110b9, 0x110b9, 9}, +{0x110ba, 0x110ba, 7}, +{0x11100, 0x11102, 230}, +{0x11133, 0x11134, 9}, +{0x11173, 0x11173, 7}, +{0x111c0, 0x111c0, 9}, +{0x111ca, 0x111ca, 7}, +{0x11235, 0x11235, 9}, +{0x11236, 0x11236, 7}, +{0x112e9, 0x112e9, 7}, +{0x112ea, 0x112ea, 9}, +{0x1133b, 0x1133c, 7}, +{0x1134d, 0x1134d, 9}, +{0x11366, 0x1136c, 230}, +{0x11370, 0x11374, 230}, +{0x11442, 0x11442, 9}, +{0x11446, 0x11446, 7}, +{0x1145e, 0x1145e, 230}, +{0x114c2, 0x114c2, 9}, +{0x114c3, 0x114c3, 7}, +{0x115bf, 0x115bf, 9}, +{0x115c0, 0x115c0, 7}, +{0x1163f, 0x1163f, 9}, +{0x116b6, 0x116b6, 9}, +{0x116b7, 0x116b7, 7}, +{0x1172b, 0x1172b, 9}, +{0x11839, 0x11839, 9}, +{0x1183a, 0x1183a, 7}, +{0x1193d, 0x1193e, 9}, +{0x11943, 0x11943, 7}, +{0x119e0, 0x119e0, 9}, +{0x11a34, 0x11a34, 9}, +{0x11a47, 0x11a47, 9}, +{0x11a99, 0x11a99, 9}, +{0x11c3f, 0x11c3f, 9}, +{0x11d42, 0x11d42, 7}, +{0x11d44, 0x11d45, 9}, +{0x11d97, 0x11d97, 9}, +{0x11f41, 0x11f42, 9}, +{0x16af0, 0x16af4, 1}, +{0x16b30, 0x16b36, 230}, +{0x16ff0, 0x16ff1, 6}, +{0x1bc9e, 0x1bc9e, 1}, +{0x1d165, 0x1d166, 216}, +{0x1d167, 0x1d169, 1}, +{0x1d16d, 0x1d16d, 226}, +{0x1d16e, 0x1d172, 216}, +{0x1d17b, 0x1d182, 220}, +{0x1d185, 0x1d189, 230}, +{0x1d18a, 0x1d18b, 220}, +{0x1d1aa, 0x1d1ad, 230}, +{0x1d242, 0x1d244, 230}, +{0x1e000, 0x1e006, 230}, +{0x1e008, 0x1e018, 230}, +{0x1e01b, 0x1e021, 230}, +{0x1e023, 0x1e024, 230}, +{0x1e026, 0x1e02a, 230}, +{0x1e08f, 0x1e08f, 230}, +{0x1e130, 0x1e136, 230}, +{0x1e2ae, 0x1e2ae, 230}, +{0x1e2ec, 0x1e2ef, 230}, +{0x1e4ec, 0x1e4ed, 232}, +{0x1e4ee, 0x1e4ee, 220}, +{0x1e4ef, 0x1e4ef, 230}, +{0x1e8d0, 0x1e8d6, 220}, +{0x1e944, 0x1e949, 230}, +{0x1e94a, 0x1e94a, 7}, diff --git a/unicode/read_ucd.py b/unicode/read_ucd.py index 050f6eb1..03bc5006 100755 --- a/unicode/read_ucd.py +++ b/unicode/read_ucd.py @@ -20,7 +20,9 @@ import zipfile UCDRecord = collections.namedtuple('UCDRecord', [ 'c', 'General_Category', + 'Canonical_Combining_Class', 'Bidi_Class', + 'Decomposition_Type', 'Decomposition_Mapping', ]) @@ -107,6 +109,12 @@ class Main: self.write_wide_chars_list(fh) with open("ambiguous_wide_chars.h", "w") as fh: self.write_ambiguous_wide_chars_list(fh) + with open("combining_classes.h", "w") as fh: + self.write_combining_class_table(fh) + with open("canonical_decomp.h", "w") as fh: + self.write_canonical_decomp_table(fh) + with open("canonical_comp.h", "w") as fh: + self.write_canonical_comp_table(fh) def find_unicode_version(self): """Find out the version of Unicode. @@ -166,14 +174,21 @@ class Main: # Decode some of the raw fields into more cooked # forms. + cclass = int(cclass) - # For the moment, we only care about decomposition - # mappings that consist of a single hex number (i.e. - # are singletons and not compatibility mappings) - try: - dm = [int(decomp, 16)] - except ValueError: - dm = [] + # Separate the decomposition field into decomposition + # type and mapping. + if decomp == "": + dtype = decomp = None + elif "<" not in decomp: + dtype = 'canonical' + else: + assert decomp.startswith("<") + dtype, decomp = decomp[1:].split(">", 1) + decomp = decomp.lstrip(" ") + # And decode the mapping part from hex strings to integers. + if decomp is not None: + decomp = [int(w, 16) for w in decomp.split(" ")] # And yield a UCDRecord for each code point in our # range. @@ -181,8 +196,10 @@ class Main: yield UCDRecord( c=codepoint, General_Category=category, + Canonical_Combining_Class=cclass, Bidi_Class=bidiclass, - Decomposition_Mapping=dm, + Decomposition_Type=dtype, + Decomposition_Mapping=decomp, ) @property @@ -231,6 +248,16 @@ class Main: for c in cs: yield c, fields[1] + @property + def CompositionExclusions(self): + """Composition exclusions from CompositionExclusions.txt. + + Each yielded item is just a code point. + """ + with self.open_ucd_file("CompositionExclusions.txt") as fh: + for line in lines(fh): + yield int(line, 16) + def write_file_header_comment(self, fh, description): print("/*", file=fh) print(" * Autogenerated by read_ucd.py from", @@ -311,7 +338,8 @@ Used by terminal/bidi.c. equivalents = {} for rec in self.UnicodeData: - if len(rec.Decomposition_Mapping) == 1: + if (rec.Decomposition_Type == 'canonical' and + len(rec.Decomposition_Mapping) == 1): c = rec.c c2 = rec.Decomposition_Mapping[0] equivalents[c] = c2 @@ -389,5 +417,78 @@ Used by utils/wcwidth.c. """) self.write_width_table(fh, {'A'}) + def write_combining_class_table(self, fh): + self.write_file_header_comment(fh, """ + +List the canonical combining class of each Unicode character, if it is +not zero. This controls how combining marks can be reordered by the +Unicode normalisation algorithms. + +Used by utils/unicode-norm.c. + +""") + cclasses = {} + + for rec in self.UnicodeData: + cc = rec.Canonical_Combining_Class + if cc != 0: + cclasses[rec.c] = cc + + for (start, end), cclass in map_to_ranges(cclasses): + print(f"{{0x{start:04x}, 0x{end:04x}, {cclass:d}}},", file=fh) + + def write_canonical_decomp_table(self, fh): + self.write_file_header_comment(fh, """ + +List the canonical decomposition of every Unicode character that has +one. This consists of up to two characters, but those may need +decomposition in turn. + +Used by utils/unicode-norm.c. + +""") + decomps = {} + + for rec in self.UnicodeData: + if rec.Decomposition_Type != 'canonical': + continue + # Fill in a zero code point as the second character, if + # it's only one character long + decomps[rec.c] = (rec.Decomposition_Mapping + [0])[:2] + + for c, (d1, d2) in sorted(decomps.items()): + d2s = f"0x{d2:04x}" if d2 else "0" + print(f"{{0x{c:04x}, 0x{d1:04x}, {d2s}}},", file=fh) + + def write_canonical_comp_table(self, fh): + self.write_file_header_comment(fh, """ + +List the pairs of Unicode characters that canonically recompose to a +single character in NFC. + +Used by utils/unicode-norm.c. + +""") + exclusions = set(self.CompositionExclusions) + nonstarters = set(rec.c for rec in self.UnicodeData + if rec.Canonical_Combining_Class != 0) + + decomps = {} + + for rec in self.UnicodeData: + if rec.Decomposition_Type != 'canonical': + continue # we don't want compatibility decompositions + if len(rec.Decomposition_Mapping) != 2: + continue # we don't want singletons either + if rec.c in exclusions: + continue # we don't want anything explicitly excluded + if (rec.c in nonstarters or + rec.Decomposition_Mapping[0] in nonstarters): + continue # we don't want non-starter decompositions + decomps[tuple(rec.Decomposition_Mapping)] = rec.c + + for (d0, d1), c in sorted(decomps.items()): + print(f"{{0x{d0:04x}, 0x{d1:04x}, 0x{c:04x}}},", file=fh) + if __name__ == '__main__': Main().run() diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index c09027f4..1f64225f 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -65,6 +65,7 @@ add_sources_from_current_dir(utils stripctrl.c tempseat.c tree234.c + unicode-norm.c validate_manual_hostkey.c version.c wcwidth.c diff --git a/utils/unicode-norm.c b/utils/unicode-norm.c new file mode 100644 index 00000000..24eb70f1 --- /dev/null +++ b/utils/unicode-norm.c @@ -0,0 +1,446 @@ +#include +#include +#include "misc.h" + +typedef uint32_t uchar; +typedef int cclass_t; + +/* A local uchar-oriented analogue of strbuf */ +typedef struct ucharbuf { + uchar *buf; + size_t len, size; +} ucharbuf; + +static ucharbuf *ucharbuf_new(void) +{ + ucharbuf *ub = snew(ucharbuf); + ub->buf = NULL; + ub->len = ub->size = 0; + return ub; +} + +static void ucharbuf_append(ucharbuf *ub, uchar c) +{ + /* Use the _nm variant because this is used for passphrases */ + sgrowarray_nm(ub->buf, ub->size, ub->len); + ub->buf[ub->len++] = c; +} + +static void ucharbuf_free(ucharbuf *ub) +{ + if (ub->buf) { + memset(ub->buf, 0, ub->size * sizeof(*ub->buf)); + sfree(ub->buf); + } + sfree(ub); +} + +/* + * Constants relating to the arithmetic decomposition mapping of + * Hangul to jamo, from section 3.12 of Unicode 15.0.0. The following + * constant names match those in the spec. + */ +static const uchar SBase = 0xAC00; +static const uchar LBase = 0x1100, VBase = 0x1161, TBase = 0x11A7; +static const uchar LCount = 19, VCount = 21, TCount = 28; +static const uchar NCount = VCount * TCount, SCount = LCount * NCount; + +static cclass_t combining_class(uchar c) +{ + struct range { + uchar start, end; + cclass_t cclass; + }; + static const struct range ranges[] = { + #include "unicode/combining_classes.h" + }; + + const struct range *start = ranges, *end = start + lenof(ranges); + + while (end > start) { + const struct range *curr = start + (end-start) / 2; + if (c < curr->start) + end = curr; + else if (c > curr->end) + start = curr + 1; + else + return curr->cclass; + } + + return 0; +}; + +static unsigned decompose_char(uchar c, uchar *out) +{ + struct decomp { + uchar composed, dec0, dec1; + }; + static const struct decomp decomps[] = { + #include "unicode/canonical_decomp.h" + }; + + if (c - SBase < SCount) { + /* Arithmetically decompose a Hangul character into jamo */ + uchar SIndex = c - SBase; + uchar LIndex = SIndex / NCount; + uchar VIndex = SIndex % NCount / TCount; + uchar TIndex = SIndex % TCount; + + unsigned n = 0; + out[n++] = LBase + LIndex; + out[n++] = VBase + VIndex; + if (TIndex) + out[n++] = TBase + TIndex; + return n; + } + + const struct decomp *start = decomps, *end = start + lenof(decomps); + + while (end > start) { + const struct decomp *curr = start + (end-start) / 2; + if (c < curr->composed) + end = curr; + else if (c > curr->composed) + start = curr + 1; + else { + out[0] = curr->dec0; + if (curr->dec1) { + out[1] = curr->dec1; + return 2; + } else { + return 1; + } + } + } + + return 0; +}; + +static uchar compose_chars(uchar S, uchar C) +{ + struct comp { + uchar dec0, dec1, composed; + }; + static const struct comp comps[] = { + #include "unicode/canonical_comp.h" + }; + + if (S - LBase < LCount && C - VBase < VCount) { + /* Arithmetically compose an L and V jamo into a Hangul LV + * character */ + return SBase + (S - LBase) * NCount + (C - VBase) * TCount; + } + + if (S - SBase < SCount && (S - SBase) % TCount == 0 && + C - TBase < TCount) { + /* Arithmetically compose an LV Hangul character and a T jamo + * into a Hangul LVT character */ + return S + C - TBase; + } + + const struct comp *start = comps, *end = start + lenof(comps); + + while (end > start) { + const struct comp *curr = start + (end-start) / 2; + if (S < curr->dec0) + end = curr; + else if (S > curr->dec0) + start = curr + 1; + else if (C < curr->dec1) + end = curr; + else if (C > curr->dec1) + start = curr + 1; + else + return curr->composed; + } + + return 0; +}; + +/* + * Recursively decompose a sequence of Unicode characters. The output + * is written to 'out', as a sequence of native-byte-order uchar. + */ +static void recursively_decompose(const uchar *str, size_t len, ucharbuf *out) +{ + uchar decomposed[3]; + + while (len-- > 0) { + uchar c = *str++; + unsigned n = decompose_char(c, decomposed); + if (n == 0) { + /* This character is indecomposable */ + ucharbuf_append(out, c); + } else { + /* This character has been decomposed into up to 3 + * characters, so we must now recursively decompose those */ + recursively_decompose(decomposed, n, out); + } + } +} + +/* + * Reorder combining marks according to the Canonical Ordering + * Algorithm (definition D109 in Unicode 15.0.0 section 3.11). + * + * The algorithm is phrased mechanistically, but the essence is: among + * any contiguous sequence of combining marks (that is, characters + * with cclass > 0), sort them by their cclass - but _stably_, i.e. + * breaking ties in cclass by preserving the original order of the + * characters in question. + */ +static void canonical_ordering(uchar *str, size_t len) +{ + for (size_t i = 1; i < len; i++) { + cclass_t cclass = combining_class(str[i]); + if (cclass == 0) + continue; + + size_t j = i; + while (j > 0 && combining_class(str[j-1]) > cclass) { + uchar tmp = str[j-1]; + str[j-1] = str[j]; + str[j] = tmp; + + j--; + } + } +} + +/* + * Canonically recompose characters according to the Canonical + * Composition Algorithm (definition D117 in Unicode 15.0.0 section + * 3.11). + */ +static size_t canonical_composition(uchar *str, size_t len) +{ + const uchar *in = str; + uchar *out = str; + uchar *last_starter = NULL; + cclass_t highest_cclass_between = -1; + + while (len > 0) { + len--; + uchar c = *in++; + cclass_t cclass = combining_class(c); + + if (last_starter && highest_cclass_between < cclass) { + uchar composed = compose_chars(*last_starter, c); + if (composed) { + *last_starter = composed; + continue; + } + } + + if (cclass == 0) { + last_starter = out; + highest_cclass_between = -1; + } else if (cclass > highest_cclass_between) { + highest_cclass_between = cclass; + } + + *out++ = c; + } + + return out - str; +} + +/* + * Render a string into NFD. + */ +static ucharbuf *nfd(ucharbuf *input) +{ + ucharbuf *output = ucharbuf_new(); + + /* + * Definition D118 in Unicode 15.0.0 section 3.11, referring to + * D68 in section 3.7: recursively decompose characters, then + * reorder combining marks. + */ + recursively_decompose(input->buf, input->len, output); + canonical_ordering(output->buf, output->len); + + return output; +} + +/* + * Render a string into NFC. + */ +static ucharbuf *nfc(ucharbuf *input) +{ + /* + * Definition D120 in Unicode 15.0.0 section 3.11: render the + * string into NFD, then apply the canonical composition algorithm. + */ + ucharbuf *output = nfd(input); + output->len = canonical_composition(output->buf, output->len); + + return output; +} + +/* + * Convert a UTF-8 string into NFC, returning it as UTF-8 again. + */ +strbuf *utf8_to_nfc(ptrlen input) +{ + BinarySource src[1]; + BinarySource_BARE_INIT_PL(src, input); + + ucharbuf *inbuf = ucharbuf_new(); + while (get_avail(src)) + ucharbuf_append(inbuf, decode_utf8(src)); + + ucharbuf *outbuf = nfc(inbuf); + + strbuf *output = strbuf_new_nm(); + for (size_t i = 0; i < outbuf->len; i++) + put_utf8_char(output, outbuf->buf[i]); + + ucharbuf_free(inbuf); + ucharbuf_free(outbuf); + + return output; +} + +#ifdef TEST +void out_of_memory(void) +{ + fprintf(stderr, "out of memory!\n"); + exit(2); +} + +static int pass, fail; + +static void subtest(const char *filename, int lineno, const char *subdesc, + char nftype, ucharbuf *input, ucharbuf *expected) +{ + /* + * Convert input into either NFC or NFD, and check it's equal to + * expected + */ + ucharbuf *nf; + switch (nftype) { + case 'C': + nf = nfc(input); + break; + case 'D': + nf = nfd(input); + break; + default: + unreachable("bad nftype"); + } + + if (nf->len == expected->len && !memcmp(nf->buf, expected->buf, nf->len)) { + pass++; + } else { + printf("%s:%d: failed %s: NF%c([", filename, lineno, subdesc, nftype); + for (size_t pos = 0; pos < input->len; pos += sizeof(uchar)) + printf("%s%04X", pos ? " " : "", (unsigned)input->buf[pos]); + printf("]) -> ["); + for (size_t pos = 0; pos < nf->len; pos += sizeof(uchar)) + printf("%s%04X", pos ? " " : "", (unsigned)nf->buf[pos]); + printf("] != ["); + for (size_t pos = 0; pos < expected->len; pos += sizeof(uchar)) + printf("%s%04X", pos ? " " : "", (unsigned)expected->buf[pos]); + printf("]\n"); + fail++; + } + + ucharbuf_free(nf); +} + +static void run_tests(const char *filename, FILE *fp) +{ + for (int lineno = 1;; lineno++) { + char *line = chomp(fgetline(fp)); + if (!line) + break; + + /* Strip section dividers which begin with @ */ + if (*line == '@') { + sfree(line); + continue; + } + + /* Strip comments, if any */ + ptrlen pl = ptrlen_from_asciz(line); + { + const char *p = memchr(pl.ptr, '#', pl.len); + if (p) + pl.len = p - (const char *)pl.ptr; + } + + /* Strip trailing space */ + while (pl.len > 0 && + (((char *)pl.ptr)[pl.len-1] == ' ' || + ((char *)pl.ptr)[pl.len-1] == '\t')) + pl.len--; + + /* Skip empty lines */ + if (!pl.len) { + sfree(line); + continue; + } + + /* Break up at semicolons, expecting five fields, each of + * which we decode into hex code points */ + ucharbuf *fields[5]; + for (size_t i = 0; i < lenof(fields); i++) { + ptrlen field = ptrlen_get_word(&pl, ";"); + fields[i] = ucharbuf_new(); + + ptrlen chr; + while ((chr = ptrlen_get_word(&field, " ")).len) { + char *chrstr = mkstr(chr); + uchar c = strtoul(chrstr, NULL, 16); + sfree(chrstr); + ucharbuf_append(fields[i], c); + } + } + + subtest(filename, lineno, "NFC(c1) = c2", 'C', fields[0], fields[1]); + subtest(filename, lineno, "NFC(c2) = c2", 'C', fields[1], fields[1]); + subtest(filename, lineno, "NFC(c3) = c2", 'C', fields[2], fields[1]); + subtest(filename, lineno, "NFC(c4) = c4", 'C', fields[3], fields[3]); + subtest(filename, lineno, "NFC(c5) = c4", 'C', fields[4], fields[3]); + subtest(filename, lineno, "NFD(c1) = c3", 'D', fields[0], fields[2]); + subtest(filename, lineno, "NFD(c2) = c3", 'D', fields[1], fields[2]); + subtest(filename, lineno, "NFD(c3) = c3", 'D', fields[2], fields[2]); + subtest(filename, lineno, "NFD(c4) = c5", 'D', fields[3], fields[4]); + subtest(filename, lineno, "NFD(c5) = c5", 'D', fields[4], fields[4]); + + for (size_t i = 0; i < lenof(fields); i++) + ucharbuf_free(fields[i]); + + sfree(line); + } +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "test_unicode_norm: give an input file " + "of tests or '-'\n"); + return 1; + } + + const char *filename = argv[1]; + + if (!strcmp(filename, "-")) { + run_tests("", stdin); + } else { + FILE *fp = fopen(filename, "r"); + if (!fp) { + fprintf(stderr, "test_unicode_norm: unable to open '%s'\n", + filename); + return 1; + } + run_tests(filename, fp); + fclose(fp); + } + + printf("pass %d fail %d total %d\n", pass, fail, pass + fail); + + return fail != 0; +} +#endif