diff --git a/scripts/unicode.py b/scripts/unicode.py index 7786dc1..52f97c5 100644 --- a/scripts/unicode.py +++ b/scripts/unicode.py @@ -14,9 +14,10 @@ # - DerivedNormalizationProps.txt # - NormalizationTest.txt # - UnicodeData.txt +# - StandardizedVariants.txt # # Since this should not require frequent updates, we just store this -# out-of-line and check the unicode.rs file into git. +# out-of-line and check the tables.rs and normalization_tests.rs files into git. import collections import urllib.request @@ -57,6 +58,11 @@ expanded_categories = { 'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'], } +# Constants from Unicode 9.0.0 Section 3.12 Conjoining Jamo Behavior +# http://www.unicode.org/versions/Unicode9.0.0/ch03.pdf#M9.32468.Heading.310.Combining.Jamo.Behavior +S_BASE, L_COUNT, V_COUNT, T_COUNT = 0xAC00, 19, 21, 28 +S_COUNT = L_COUNT * V_COUNT * T_COUNT + class UnicodeData(object): def __init__(self): self._load_unicode_data() @@ -66,14 +72,20 @@ class UnicodeData(object): self.canon_comp = self._compute_canonical_comp() self.canon_fully_decomp, self.compat_fully_decomp = self._compute_fully_decomposed() + self.ext_decomp = {} + self.ext_fully_decomp = {} + self._load_standardized_variants() + def stats(name, table): count = sum(len(v) for v in table.values()) print("%s: %d chars => %d decomposed chars" % (name, len(table), count)) print("Decomposition table stats:") stats("Canonical decomp", self.canon_decomp) + stats("Canonical decomp with extensions", self.ext_decomp) stats("Compatible decomp", self.compat_decomp) stats("Canonical fully decomp", self.canon_fully_decomp) + stats("Canonical fully decomp with extensions", self.ext_fully_decomp) stats("Compatible fully decomp", self.compat_fully_decomp) self.ss_leading, self.ss_trailing = self._compute_stream_safe_tables() @@ -83,6 +95,7 @@ class UnicodeData(object): return resp.read().decode('utf-8') def _load_unicode_data(self): + self.name_to_char_int = {} self.combining_classes = {} self.compat_decomp = {} self.canon_decomp = {} @@ -95,6 +108,9 @@ class UnicodeData(object): char, category, cc, decomp = pieces[0], pieces[2], pieces[3], pieces[5] char_int = int(char, 16) + name = pieces[1].strip() + self.name_to_char_int[name] = char_int + if cc != '0': self.combining_classes[char_int] = cc @@ -106,6 +122,39 @@ class UnicodeData(object): if category == 'M' or 'M' in expanded_categories.get(category, []): self.general_category_mark.append(char_int) + def _load_standardized_variants(self): + for line in self._fetch("StandardizedVariants.txt").splitlines(): + strip_comments = line.split('#', 1)[0].strip() + if not strip_comments: + continue + + pieces = strip_comments.split(';') + assert len(pieces) == 3 + + variation_sequence, description, differences = pieces[0], pieces[1].strip(), pieces[2] + + # Don't use variations that only apply in particular shaping environments. + if differences: + continue + + # Look for entries where the description field is a codepoint name. + if description in self.name_to_char_int: + char_int = self.name_to_char_int[description] + + assert not char_int in self.combining_classes, "Unexpected: standardized variant with a combining class" + assert not char_int in self.compat_decomp, "Unexpected: standardized variant and compatibility decomposition" + assert len(self.canon_decomp[char_int]) == 1, "Unexpected: standardized variant and non-singleton canonical decomposition" + # If we ever need to handle Hangul here, we'll need to handle it separately. + assert not (S_BASE <= char_int < S_BASE + S_COUNT) + + standardized_variant_parts = [int(c, 16) for c in variation_sequence.split()] + for c in standardized_variant_parts: + #assert not never_composes(c) TODO: Re-enable this once #67 lands. + assert not c in self.canon_decomp, "Unexpected: standardized variant is unnormalized (canon)" + assert not c in self.compat_decomp, "Unexpected: standardized variant is unnormalized (compat)" + self.ext_decomp[char_int] = standardized_variant_parts + self.ext_fully_decomp[char_int] = standardized_variant_parts + def _load_norm_props(self): props = collections.defaultdict(list) @@ -178,11 +227,6 @@ class UnicodeData(object): The upshot is that decomposition code is very simple and easy to inline at mild code size cost. """ - # Constants from Unicode 9.0.0 Section 3.12 Conjoining Jamo Behavior - # http://www.unicode.org/versions/Unicode9.0.0/ch03.pdf#M9.32468.Heading.310.Combining.Jamo.Behavior - S_BASE, L_COUNT, V_COUNT, T_COUNT = 0xAC00, 19, 21, 28 - S_COUNT = L_COUNT * V_COUNT * T_COUNT - def _decompose(char_int, compatible): # 7-bit ASCII never decomposes if char_int <= 0x7f: @@ -320,8 +364,8 @@ def gen_composition_table(canon_comp, out): out.write(" }\n") out.write("}\n") -def gen_decomposition_tables(canon_decomp, compat_decomp, out): - tables = [(canon_decomp, 'canonical'), (compat_decomp, 'compatibility')] +def gen_decomposition_tables(canon_decomp, ext_decomp, compat_decomp, out): + tables = [(canon_decomp, 'canonical'), (ext_decomp, 'ext'), (compat_decomp, 'compatibility')] for table, name in tables: gen_mph_data(name + '_decomposed', table, "(u32, &'static [char])", lambda k: "(0x{:x}, &[{}])".format(k, @@ -491,7 +535,7 @@ if __name__ == '__main__': gen_composition_table(data.canon_comp, out) out.write("\n") - gen_decomposition_tables(data.canon_fully_decomp, data.compat_fully_decomp, out) + gen_decomposition_tables(data.canon_fully_decomp, data.ext_fully_decomp, data.compat_fully_decomp, out) gen_combining_mark(data.general_category_mark, out) out.write("\n") diff --git a/src/decompose.rs b/src/decompose.rs index 23cdb1a..9248d54 100644 --- a/src/decompose.rs +++ b/src/decompose.rs @@ -16,6 +16,8 @@ use tinyvec::TinyVec; enum DecompositionType { Canonical, Compatible, + CanonicalExt, + CompatibleExt, } /// External iterator for a string decomposition's characters. @@ -56,6 +58,26 @@ pub fn new_compatible>(iter: I) -> Decompositions { } } +#[inline] +pub fn new_canonical_ext>(iter: I) -> Decompositions { + Decompositions { + kind: self::DecompositionType::CanonicalExt, + iter: iter.fuse(), + buffer: TinyVec::new(), + ready: 0..0, + } +} + +#[inline] +pub fn new_compatible_ext>(iter: I) -> Decompositions { + Decompositions { + kind: self::DecompositionType::CompatibleExt, + iter: iter.fuse(), + buffer: TinyVec::new(), + ready: 0..0, + } +} + impl Decompositions { #[inline] fn push_back(&mut self, ch: char) { @@ -113,6 +135,12 @@ impl> Iterator for Decompositions { (Some(ch), &DecompositionType::Compatible) => { super::char::decompose_compatible(ch, |d| self.push_back(d)); } + (Some(ch), &DecompositionType::CanonicalExt) => { + super::char::decompose_canonical_ext(ch, |d| self.push_back(d)); + } + (Some(ch), &DecompositionType::CompatibleExt) => { + super::char::decompose_compatible_ext(ch, |d| self.push_back(d)); + } (None, _) => { if self.buffer.is_empty() { return None; diff --git a/src/lib.rs b/src/lib.rs index 6749adc..3b0dd0a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,7 +83,10 @@ mod test; /// Methods for composing and decomposing characters. pub mod char { - pub use crate::normalize::{compose, decompose_canonical, decompose_compatible}; + pub use crate::normalize::{ + compose, decompose_canonical, decompose_canonical_ext, decompose_compatible, + decompose_compatible_ext, + }; pub use crate::lookups::{canonical_combining_class, is_combining_mark}; } @@ -108,6 +111,42 @@ pub trait UnicodeNormalization> { /// (compatibility decomposition followed by canonical composition). fn nfkc(self) -> Recompositions; + /// Similar to `nfd`, but with extensions which differ from the standard + /// decomposition algorithm and which don't have a stability guarantee, + /// but which still produce valid NFD and provide better results: + /// - Standardized Variation Seqeuences are used to avoid losing + /// information when normalizing "CJK Compatibility Ideographs" + /// codepoints. Note that many systemes today ignore variation + /// selectors, but the information is at least preserved in a + /// standardized form. + /// + /// Additional extensions may be added in future versions. + /// + /// If you need to match the standard `toNFD` algorithm exactly, or you + /// need a stability guarantee, use `nfd` instead. + fn nfd_ext(self) -> Decompositions; + + /// Similar to `nfkd`, and the result is valid NFKD, but with the same + /// extensions as `nfd`. + /// + /// If you need to match the standard `toNFKD` algorithm exactly, or you + /// need a stability guarantee, use `nfd` instead. + fn nfkd_ext(self) -> Decompositions; + + /// Similar to `nfc`, and the result is valid NFC, but with the same + /// extensions as `nfd`. + /// + /// If you need to match the standard `toNFC` algorithm exactly, or you + /// need a stability guarantee, use `nfd` instead. + fn nfc_ext(self) -> Recompositions; + + /// Similar to `nfkc`, and the result is valid NFKC, but with the same + /// extensions as `nfd`. + /// + /// If you need to match the standard `toNFKC` algorithm exactly, or you + /// need a stability guarantee, use `nfd` instead. + fn nfkc_ext(self) -> Recompositions; + /// An Iterator over the string with Conjoining Grapheme Joiner characters /// inserted according to the Stream-Safe Text Process (UAX15-D4) fn stream_safe(self) -> StreamSafe; @@ -134,6 +173,26 @@ impl<'a> UnicodeNormalization> for &'a str { recompose::new_compatible(self.chars()) } + #[inline] + fn nfd_ext(self) -> Decompositions> { + decompose::new_canonical_ext(self.chars()) + } + + #[inline] + fn nfkd_ext(self) -> Decompositions> { + decompose::new_compatible_ext(self.chars()) + } + + #[inline] + fn nfc_ext(self) -> Recompositions> { + recompose::new_canonical_ext(self.chars()) + } + + #[inline] + fn nfkc_ext(self) -> Recompositions> { + recompose::new_compatible_ext(self.chars()) + } + #[inline] fn stream_safe(self) -> StreamSafe> { StreamSafe::new(self.chars()) @@ -161,6 +220,26 @@ impl> UnicodeNormalization for I { recompose::new_compatible(self) } + #[inline] + fn nfd_ext(self) -> Decompositions { + decompose::new_canonical_ext(self) + } + + #[inline] + fn nfkd_ext(self) -> Decompositions { + decompose::new_compatible_ext(self) + } + + #[inline] + fn nfc_ext(self) -> Recompositions { + recompose::new_canonical_ext(self) + } + + #[inline] + fn nfkc_ext(self) -> Recompositions { + recompose::new_compatible_ext(self) + } + #[inline] fn stream_safe(self) -> StreamSafe { StreamSafe::new(self) diff --git a/src/lookups.rs b/src/lookups.rs index 5bf5090..28c7483 100644 --- a/src/lookups.rs +++ b/src/lookups.rs @@ -53,6 +53,17 @@ pub(crate) fn canonical_fully_decomposed(c: char) -> Option<&'static [char]> { ) } +pub(crate) fn ext_fully_decomposed(c: char) -> Option<&'static [char]> { + mph_lookup( + c.into(), + EXT_DECOMPOSED_SALT, + EXT_DECOMPOSED_KV, + pair_lookup_fk, + pair_lookup_fv_opt, + None, + ) +} + pub(crate) fn compatibility_fully_decomposed(c: char) -> Option<&'static [char]> { mph_lookup( c.into(), diff --git a/src/normalize.rs b/src/normalize.rs index 1097c42..1774a5d 100644 --- a/src/normalize.rs +++ b/src/normalize.rs @@ -11,6 +11,7 @@ //! Functions for computing canonical and compatible decompositions for Unicode characters. use crate::lookups::{ canonical_fully_decomposed, compatibility_fully_decomposed, composition_table, + ext_fully_decomposed, }; use core::{char, ops::FnMut}; @@ -36,6 +37,37 @@ pub fn decompose_compatible(c: char, emit_char: F) { decompose(c, decompose_char, emit_char) } +/// Compute "extended" canonical Unicode decomposition for character. +/// +/// This is `decompose_canonical` plus extensions, which currently consist of: +/// - [Standardized Variation Sequences] are used instead of the standard canonical +/// decompositions for CJK codepoints with singleton canonical decompositions, to +/// avoid losing information. See the +/// [Unicode Variation Sequence FAQ](http://unicode.org/faq/vs.html) and the +/// "Other Enhancements" section of the +/// [Unicode 6.3 Release Summary](https://www.unicode.org/versions/Unicode6.3.0/#Summary) +/// for more information. +#[inline] +pub fn decompose_canonical_ext(c: char, emit_char: F) +where + F: FnMut(char), +{ + let decompose_char = |c| ext_fully_decomposed(c).or_else(|| canonical_fully_decomposed(c)); + decompose(c, decompose_char, emit_char) +} + +/// Compute "extended" compatible Unicode decomposition for character. +/// +/// This is `decompose_compatible` plus the same extensions as `decompose_canonical_ext`. +#[inline] +pub fn decompose_compatible_ext(c: char, emit_char: F) { + let decompose_char = |c| { + ext_fully_decomposed(c) + .or_else(|| compatibility_fully_decomposed(c).or_else(|| canonical_fully_decomposed(c))) + }; + decompose(c, decompose_char, emit_char) +} + #[inline] fn decompose(c: char, decompose_char: D, mut emit_char: F) where diff --git a/src/recompose.rs b/src/recompose.rs index 2a1960a..35084d4 100644 --- a/src/recompose.rs +++ b/src/recompose.rs @@ -51,6 +51,28 @@ pub fn new_compatible>(iter: I) -> Recompositions { } } +#[inline] +pub fn new_canonical_ext>(iter: I) -> Recompositions { + Recompositions { + iter: super::decompose::new_canonical_ext(iter), + state: self::RecompositionState::Composing, + buffer: TinyVec::new(), + composee: None, + last_ccc: None, + } +} + +#[inline] +pub fn new_compatible_ext>(iter: I) -> Recompositions { + Recompositions { + iter: super::decompose::new_compatible_ext(iter), + state: self::RecompositionState::Composing, + buffer: TinyVec::new(), + composee: None, + last_ccc: None, + } +} + impl> Iterator for Recompositions { type Item = char; diff --git a/src/tables.rs b/src/tables.rs index f90dedd..ce0ec51 100644 --- a/src/tables.rs +++ b/src/tables.rs @@ -7774,6 +7774,2015 @@ pub(crate) const CANONICAL_DECOMPOSED_KV: &[(u32, &'static [char])] = &[ (0xf9d7, &['\u{8F2A}']), ]; +pub(crate) const EXT_DECOMPOSED_SALT: &[u16] = &[ + 0x5, + 0x0, + 0x0, + 0x0, + 0x162, + 0x14, + 0xb6, + 0x0, + 0x183, + 0xd, + 0x0, + 0x0, + 0x35, + 0x11, + 0x7, + 0x0, + 0x1c, + 0x0, + 0x1, + 0x0, + 0xd3, + 0xb, + 0xa, + 0xe1, + 0x0, + 0x0, + 0x0, + 0x48, + 0x72, + 0xc7, + 0x2, + 0x21, + 0x15, + 0x2c, + 0x0, + 0x0, + 0x0, + 0x5, + 0x1f, + 0x8, + 0x7, + 0x0, + 0x4, + 0x0, + 0x7, + 0x10, + 0x0, + 0x0, + 0x0, + 0x4e, + 0x0, + 0x6, + 0x0, + 0x11, + 0x14, + 0x4, + 0x1a, + 0x2, + 0x58, + 0x0, + 0x17, + 0x0, + 0x0, + 0x0, + 0x4, + 0x0, + 0x1, + 0x0, + 0x1, + 0x0, + 0x4, + 0x6, + 0x16, + 0x20, + 0x4, + 0x0, + 0x1e, + 0x30, + 0x0, + 0x24, + 0x1a, + 0x17, + 0x0, + 0xa0, + 0x29, + 0x34, + 0x2, + 0x0, + 0x4, + 0x0, + 0x23, + 0x29, + 0x21, + 0x0, + 0x0, + 0xb, + 0x0, + 0x20, + 0x1, + 0x7, + 0x8, + 0x9, + 0x8, + 0x0, + 0x1, + 0x0, + 0x1, + 0x4, + 0x3, + 0x1d, + 0x0, + 0x0, + 0x0, + 0x1, + 0x29, + 0xd, + 0x7, + 0x0, + 0x0, + 0x2, + 0xe, + 0x9, + 0x4, + 0xc, + 0x1, + 0x13, + 0x5, + 0x6, + 0x5, + 0x1, + 0x9, + 0x1, + 0xa, + 0x2, + 0x0, + 0x8, + 0x29, + 0x0, + 0x8, + 0x2, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0xd, + 0x0, + 0x9, + 0x10, + 0xf, + 0x0, + 0x11, + 0xf, + 0x0, + 0x8, + 0x1, + 0x1, + 0x5, + 0x0, + 0x1, + 0x26, + 0x5, + 0x39, + 0x8, + 0x1, + 0x17, + 0xd, + 0x4, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0xe, + 0x0, + 0x5, + 0x0, + 0x0, + 0x0, + 0x0, + 0x4, + 0x0, + 0x1, + 0x2, + 0x4, + 0x3, + 0x35, + 0x1, + 0x2, + 0x1, + 0x7, + 0x0, + 0x0, + 0x3, + 0x2, + 0x11, + 0x0, + 0xd, + 0x3, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x4, + 0x5, + 0x0, + 0xe, + 0x0, + 0x0, + 0x3, + 0x6, + 0x2, + 0xb, + 0x2, + 0x1, + 0x3, + 0x12, + 0xb, + 0x0, + 0x0, + 0x0, + 0x2, + 0xb, + 0x1, + 0x4, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x2f, + 0x1, + 0x13, + 0xb, + 0x4, + 0x2, + 0x4, + 0x4, + 0x0, + 0xb, + 0x4, + 0x0, + 0xb, + 0x4, + 0xd, + 0xc, + 0x0, + 0x1e, + 0x0, + 0x21, + 0xd, + 0x2, + 0x7, + 0x0, + 0x0, + 0x0, + 0x1, + 0x2, + 0x0, + 0x20, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x1f, + 0x1, + 0x2, + 0x0, + 0x0, + 0x5, + 0x0, + 0x0, + 0x4, + 0x0, + 0x11, + 0x2, + 0x8, + 0x7, + 0x0, + 0x0, + 0xc, + 0x3, + 0x0, + 0x4, + 0xe, + 0x23, + 0x4, + 0x1, + 0x0, + 0x2, + 0x0, + 0x4, + 0x8, + 0x10, + 0x2, + 0x0, + 0x13, + 0xd, + 0x0, + 0xb, + 0x9, + 0x6, + 0x0, + 0x0, + 0x9, + 0xc, + 0xa, + 0x4, + 0x1a, + 0x3, + 0x1, + 0x3, + 0x0, + 0x1, + 0x0, + 0x6, + 0x3, + 0xa, + 0x0, + 0xa, + 0x6, + 0x8, + 0x8, + 0x3, + 0x19, + 0x0, + 0x0, + 0x0, + 0x0, + 0xc, + 0x5, + 0x0, + 0x5, + 0x1, + 0x0, + 0x2, + 0x0, + 0x8, + 0x0, + 0xc, + 0x0, + 0x2, + 0x0, + 0x1, + 0x0, + 0x0, + 0x0, + 0x0, + 0x4, + 0x2, + 0x15, + 0x0, + 0x4, + 0x1, + 0x12, + 0x4, + 0x3, + 0xc, + 0x4, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x3, + 0x0, + 0x5, + 0x2, + 0x0, + 0x1, + 0x2, + 0x1, + 0x10, + 0x4, + 0x0, + 0x5, + 0x2, + 0x1, + 0x6, + 0x0, + 0x0, + 0x0, + 0x0, + 0xa, + 0x8, + 0x2, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x4, + 0x4, + 0xc, + 0x2, + 0x0, + 0x6, + 0x3, + 0x3, + 0xf, + 0x0, + 0x3, + 0x5, + 0x1, + 0x0, + 0x0, + 0x8, + 0x0, + 0x2, + 0x4, + 0x2, + 0x13, + 0x0, + 0x0, + 0x0, + 0xa, + 0x6, + 0x1, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0xa, + 0x0, + 0x5, + 0x0, + 0x5, + 0x0, + 0x6, + 0x0, + 0x1, + 0x1, + 0x5, + 0x1, + 0xa, + 0x9, + 0x5, + 0x1, + 0x0, + 0x7, + 0x1, + 0x1, + 0x7, + 0x1, + 0x1f, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x2, + 0x11, + 0x5, + 0x3, + 0x5, + 0x3, + 0x1, + 0x1, + 0x0, + 0x4, + 0x1, + 0x4, + 0x1, + 0x8, + 0x0, + 0x19, + 0x0, + 0x4, + 0x3, + 0x5, + 0x6, + 0x0, + 0x11, + 0xe, + 0x5, + 0x1, + 0x0, + 0x1a, + 0x4, + 0x0, + 0x3, + 0x0, + 0x0, + 0x5, + 0x0, + 0x0, + 0x1, + 0x17, + 0x0, + 0x6, + 0x3, + 0xf, + 0x1, + 0x6, + 0x9, + 0x0, + 0x5, + 0x0, + 0x3, + 0x1, + 0x17, + 0x7, + 0x0, + 0x2, + 0x5, + 0x3, + 0x2, + 0x0, + 0x7, + 0x1, + 0x0, + 0x4, + 0x0, + 0x0, + 0x5, + 0x15, + 0x4, + 0x0, + 0x3, + 0x1, + 0x3, + 0x7, + 0x0, + 0x0, + 0x1, + 0x0, + 0x0, + 0x0, + 0x0, + 0x9, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x9, + 0x0, + 0x0, + 0x0, + 0x1, + 0x3, + 0x0, + 0x0, + 0x3, + 0x1, + 0x0, + 0x0, + 0x0, + 0x1, + 0x0, + 0x0, + 0x0, + 0x3, + 0x8, + 0x0, + 0x2, + 0x2, + 0x3, + 0x5, + 0x0, + 0x0, + 0x0, + 0x8, + 0x3, + 0x2, + 0x0, + 0x9, + 0x4, + 0x0, + 0x6, + 0xf, + 0x1, + 0x0, + 0x0, + 0x4, + 0x2, + 0x2, + 0x4, + 0x4, + 0xd, + 0x0, + 0x0, + 0x0, + 0x1, + 0x0, + 0x2, + 0x5, + 0x0, + 0x0, + 0xc, + 0x4, + 0x9, + 0x2, + 0x8, + 0x1, + 0x0, + 0x5, + 0x4, + 0x1, + 0x2, + 0x1, + 0x5, + 0x2, + 0xb, + 0x4, + 0xd, + 0x4, + 0x0, + 0x1, + 0x18, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x3, + 0x0, + 0x2, + 0xa, + 0x2, + 0x4, + 0x4, + 0x0, + 0x0, + 0x0, + 0x1, + 0x0, + 0xc, + 0x1, + 0xc, + 0x1, + 0x9, + 0xb, + 0x0, + 0x1, + 0x0, + 0x2, + 0x0, + 0x5, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x7, + 0x2, + 0x0, + 0x6, + 0x4, + 0xa, + 0x1, + 0x1, + 0x5, + 0x2, + 0x6, + 0x4, + 0x3, + 0xd, + 0x2, + 0x2, + 0x0, + 0x1, + 0x2, + 0x3, + 0x2, + 0x0, + 0x1, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x2, + 0x0, + 0x1, + 0x0, + 0x0, + 0x3, + 0x2, + 0x0, + 0x5, + 0x2, + 0x5, + 0x2, + 0x1, + 0x4, + 0x1, + 0x1, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x7, + 0x2, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x1, + 0x0, + 0x2, + 0x0, + 0x0, + 0x4, + 0x8, + 0x0, + 0x3, + 0x2, + 0x2, + 0x2, + 0x2, + 0x4, + 0x1, + 0x4, + 0x2, + 0x0, + 0x1, + 0x4, + 0x1, + 0x1, + 0x2, + 0x0, + 0x0, + 0xc, + 0x0, + 0x1, + 0x2, + 0x0, + 0x6, + 0x2, + 0x0, + 0x0, + 0x8, + 0x1, + 0x9, + 0x1, + 0x3, + 0x0, + 0x4, + 0x1, + 0x0, + 0x6, + 0x0, + 0x3, + 0x7, + 0x0, + 0x0, + 0x2, + 0x1, + 0x0, + 0x3, + 0x2, + 0x0, + 0x2, + 0x7, + 0x0, + 0x0, + 0x0, + 0x0, + 0x5, + 0x3, + 0x1, + 0x3, + 0x0, + 0x5, + 0x0, + 0x1, + 0x0, + 0x3, + 0x1, + 0x1, + 0x2, + 0x3, + 0x0, + 0x2, + 0x3, + 0x0, + 0x0, + 0x1, + 0x0, + 0x0, + 0x0, + 0x0, + 0x1, + 0x0, + 0x4, + 0x3, + 0x2, + 0x4, + 0x3, + 0x5, + 0x2, + 0x0, + 0x0, + 0x1, + 0x3, + 0x2, + 0x0, + 0x0, + 0x4, + 0x3, + 0x0, + 0x1, + 0x6, + 0x1, + 0x4, + 0x0, + 0x2, + 0x2, + 0x1, + 0x0, + 0xd, + 0x1, + 0x0, + 0x0, + 0x1, + 0x0, + 0x2, + 0x3, + 0x8, + 0x5, + 0x7, + 0x6, + 0x0, + 0x1, + 0x6, + 0x1, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x2, + 0x0, + 0x1, + 0x0, + 0x0, + 0x1, + 0x1, + 0x2, + 0x4, + 0x2, + 0x1, + 0x1, + 0x2, + 0x0, + 0x0, + 0x0, + 0x1, + 0x5, + 0x1, + 0x0, + 0x2, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x1, + 0x4, + 0x0, + 0x2, + 0x0, + 0x1, + 0x3, + 0x3, + 0x1, + 0x0, + 0x4, + 0x0, + 0x1, + 0x1, + 0x1, + 0x1, + 0x1, + 0x4, + 0x0, + 0x0, + 0x3, + 0x1, + 0x3, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x1, + 0x2, + 0x0, + 0x0, + 0x1, + 0x3, + 0x2, + 0x1, + 0x2, + 0x1, + 0x9, + 0x1, + 0x0, + 0x1, + 0x3, + 0x4, + 0x0, + 0x0, + 0x0, + 0x2, + 0x0, + 0x3, + 0x1, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x2, + 0x1, + 0x4, + 0x1, + 0x1, + 0x1, + 0x2, + 0x1, + 0x6, + 0x1, + 0x1, + 0x2, + 0x1, + 0x0, + 0x0, + 0x0, + 0x3, + 0x1, + 0x0, + 0x5, + 0x1, +]; +pub(crate) const EXT_DECOMPOSED_KV: &[(u32, &'static [char])] = &[ + (0xfa08, &['\u{884C}', '\u{FE00}']), + (0x2f825, &['\u{52C7}', '\u{FE01}']), + (0x2f838, &['\u{20B63}', '\u{FE00}']), + (0x2f95b, &['\u{7A4F}', '\u{FE00}']), + (0x2f8fb, &['\u{23CBC}', '\u{FE00}']), + (0x2f83a, &['\u{53F1}', '\u{FE00}']), + (0x2f8a7, &['\u{614C}', '\u{FE00}']), + (0x2f856, &['\u{5832}', '\u{FE00}']), + (0x2f810, &['\u{5164}', '\u{FE00}']), + (0xfa8b, &['\u{61F2}', '\u{FE01}']), + (0xfa7a, &['\u{5599}', '\u{FE00}']), + (0x2f9ef, &['\u{4995}', '\u{FE00}']), + (0x2f959, &['\u{7A40}', '\u{FE01}']), + (0xf9c8, &['\u{677B}', '\u{FE00}']), + (0xf9c4, &['\u{9F8D}', '\u{FE00}']), + (0x2f833, &['\u{537F}', '\u{FE02}']), + (0xf96c, &['\u{585E}', '\u{FE00}']), + (0xf9a1, &['\u{8AAA}', '\u{FE01}']), + (0xf906, &['\u{53E5}', '\u{FE00}']), + (0x2fa01, &['\u{295B6}', '\u{FE00}']), + (0xf94c, &['\u{6A13}', '\u{FE00}']), + (0xf90f, &['\u{7F85}', '\u{FE00}']), + (0x2f8dd, &['\u{233C3}', '\u{FE00}']), + (0xfa55, &['\u{7A81}', '\u{FE00}']), + (0x2f860, &['\u{216A8}', '\u{FE00}']), + (0x2f999, &['\u{831D}', '\u{FE00}']), + (0xfabc, &['\u{8B01}', '\u{FE01}']), + (0x2f9b9, &['\u{870E}', '\u{FE00}']), + (0xf943, &['\u{5F04}', '\u{FE00}']), + (0x2f952, &['\u{25626}', '\u{FE00}']), + (0x2f8f1, &['\u{6B54}', '\u{FE00}']), + (0xf99c, &['\u{5217}', '\u{FE00}']), + (0xf969, &['\u{6578}', '\u{FE00}']), + (0xf98d, &['\u{8F62}', '\u{FE00}']), + (0xfa7f, &['\u{5954}', '\u{FE00}']), + (0x2f9d6, &['\u{8D1B}', '\u{FE00}']), + (0x2f81b, &['\u{51B5}', '\u{FE01}']), + (0xfa9d, &['\u{77A7}', '\u{FE00}']), + (0x2f8e4, &['\u{688E}', '\u{FE00}']), + (0xfa94, &['\u{6756}', '\u{FE00}']), + (0x2f890, &['\u{5EFE}', '\u{FE00}']), + (0xf93d, &['\u{7DA0}', '\u{FE00}']), + (0x2f924, &['\u{7280}', '\u{FE00}']), + (0x2f983, &['\u{8103}', '\u{FE00}']), + (0xfa2f, &['\u{96B7}', '\u{FE00}']), + (0x2f891, &['\u{22331}', '\u{FE00}']), + (0x2f934, &['\u{7524}', '\u{FE00}']), + (0x2f835, &['\u{7070}', '\u{FE00}']), + (0x2f899, &['\u{5F62}', '\u{FE00}']), + (0x2f8ae, &['\u{61AF}', '\u{FE00}']), + (0xf9d6, &['\u{6DEA}', '\u{FE00}']), + (0x2f9a0, &['\u{8353}', '\u{FE00}']), + (0xfac2, &['\u{8F38}', '\u{FE00}']), + (0x2f851, &['\u{58EE}', '\u{FE00}']), + (0x2f804, &['\u{4F60}', '\u{FE00}']), + (0x2f90d, &['\u{23ED1}', '\u{FE00}']), + (0xf95e, &['\u{4E39}', '\u{FE00}']), + (0x2f8da, &['\u{6721}', '\u{FE00}']), + (0x2f885, &['\u{5E28}', '\u{FE00}']), + (0x2f96a, &['\u{7D00}', '\u{FE00}']), + (0xf907, &['\u{9F9C}', '\u{FE00}']), + (0xf9f9, &['\u{7C92}', '\u{FE00}']), + (0xf94b, &['\u{5C62}', '\u{FE00}']), + (0x2f915, &['\u{701B}', '\u{FE00}']), + (0xf9f1, &['\u{96A3}', '\u{FE00}']), + (0x2f86d, &['\u{5BC3}', '\u{FE00}']), + (0x2f921, &['\u{7235}', '\u{FE01}']), + (0xfa96, &['\u{6BBA}', '\u{FE01}']), + (0xf9e0, &['\u{6613}', '\u{FE00}']), + (0xf921, &['\u{5D50}', '\u{FE00}']), + (0x2f99f, &['\u{8457}', '\u{FE01}']), + (0x2f8b2, &['\u{6210}', '\u{FE00}']), + (0xfab1, &['\u{7F3E}', '\u{FE00}']), + (0xfa6c, &['\u{242EE}', '\u{FE00}']), + (0x2f819, &['\u{4ECC}', '\u{FE00}']), + (0x2f910, &['\u{23F5E}', '\u{FE00}']), + (0x2f8dc, &['\u{6753}', '\u{FE00}']), + (0x2f9d3, &['\u{27CA8}', '\u{FE00}']), + (0x2f8a3, &['\u{6094}', '\u{FE01}']), + (0xf915, &['\u{6D1B}', '\u{FE00}']), + (0x2f88a, &['\u{387C}', '\u{FE00}']), + (0xf9f6, &['\u{81E8}', '\u{FE00}']), + (0x2f9f1, &['\u{28D77}', '\u{FE00}']), + (0xf98e, &['\u{5E74}', '\u{FE00}']), + (0xfad5, &['\u{25249}', '\u{FE00}']), + (0xf93b, &['\u{788C}', '\u{FE00}']), + (0x2f91e, &['\u{719C}', '\u{FE00}']), + (0xf9eb, &['\u{533F}', '\u{FE00}']), + (0xfa42, &['\u{65E2}', '\u{FE00}']), + (0x2f958, &['\u{412F}', '\u{FE00}']), + (0xfa19, &['\u{795E}', '\u{FE00}']), + (0xfaaa, &['\u{7740}', '\u{FE00}']), + (0x2f949, &['\u{4039}', '\u{FE01}']), + (0x2f978, &['\u{7F95}', '\u{FE00}']), + (0x2f8a9, &['\u{614C}', '\u{FE01}']), + (0x2f90a, &['\u{3D33}', '\u{FE00}']), + (0x2f89a, &['\u{5F6B}', '\u{FE00}']), + (0x2f8b5, &['\u{62B1}', '\u{FE00}']), + (0x2f94c, &['\u{4096}', '\u{FE00}']), + (0xfa43, &['\u{6691}', '\u{FE00}']), + (0xf997, &['\u{806F}', '\u{FE00}']), + (0x2f8ba, &['\u{62FC}', '\u{FE00}']), + (0xfa00, &['\u{5207}', '\u{FE00}']), + (0xfac3, &['\u{9072}', '\u{FE00}']), + (0x2f948, &['\u{774A}', '\u{FE01}']), + (0x2f9f4, &['\u{5DB2}', '\u{FE00}']), + (0xfa99, &['\u{6ECB}', '\u{FE00}']), + (0x2f976, &['\u{7F7A}', '\u{FE00}']), + (0xf978, &['\u{5169}', '\u{FE00}']), + (0x2f8fe, &['\u{6C67}', '\u{FE00}']), + (0x2f8e3, &['\u{2346D}', '\u{FE00}']), + (0xf919, &['\u{916A}', '\u{FE00}']), + (0x2f8ef, &['\u{6B21}', '\u{FE00}']), + (0xf939, &['\u{9B6F}', '\u{FE00}']), + (0x2f8c9, &['\u{656C}', '\u{FE00}']), + (0x2f844, &['\u{5563}', '\u{FE00}']), + (0xfabb, &['\u{8ACB}', '\u{FE00}']), + (0x2f9c4, &['\u{8863}', '\u{FE00}']), + (0x2f984, &['\u{440B}', '\u{FE00}']), + (0x2f802, &['\u{4E41}', '\u{FE00}']), + (0xfa15, &['\u{51DE}', '\u{FE00}']), + (0xf9be, &['\u{6599}', '\u{FE00}']), + (0xf942, &['\u{58DF}', '\u{FE00}']), + (0x2f852, &['\u{57CE}', '\u{FE00}']), + (0xfaae, &['\u{7C7B}', '\u{FE00}']), + (0x2fa17, &['\u{9EF9}', '\u{FE00}']), + (0x2f92d, &['\u{3EB8}', '\u{FE01}']), + (0x2f83f, &['\u{5468}', '\u{FE00}']), + (0xf90c, &['\u{5948}', '\u{FE00}']), + (0xf931, &['\u{6AD3}', '\u{FE00}']), + (0xf9c1, &['\u{7642}', '\u{FE00}']), + (0x2f873, &['\u{5C06}', '\u{FE00}']), + (0x2f965, &['\u{25C80}', '\u{FE00}']), + (0xf902, &['\u{8ECA}', '\u{FE00}']), + (0x2f805, &['\u{4FAE}', '\u{FE01}']), + (0x2f8ca, &['\u{2300A}', '\u{FE00}']), + (0xf9c7, &['\u{5289}', '\u{FE00}']), + (0x2f8f4, &['\u{6B9F}', '\u{FE00}']), + (0xfa0d, &['\u{55C0}', '\u{FE00}']), + (0xfa5c, &['\u{81ED}', '\u{FE00}']), + (0xfa4c, &['\u{793E}', '\u{FE00}']), + (0x2f865, &['\u{59D8}', '\u{FE00}']), + (0x2f876, &['\u{3781}', '\u{FE00}']), + (0x2f9d7, &['\u{8D77}', '\u{FE00}']), + (0xf975, &['\u{63A0}', '\u{FE00}']), + (0x2f9bb, &['\u{8779}', '\u{FE01}']), + (0x2f9d2, &['\u{8C55}', '\u{FE00}']), + (0xf9ed, &['\u{541D}', '\u{FE00}']), + (0x2f9b4, &['\u{865C}', '\u{FE01}']), + (0xfa6d, &['\u{8218}', '\u{FE00}']), + (0xf9e5, &['\u{75E2}', '\u{FE00}']), + (0x2f8d8, &['\u{6717}', '\u{FE02}']), + (0x2f93d, &['\u{25044}', '\u{FE00}']), + (0xfa03, &['\u{7CD6}', '\u{FE00}']), + (0xf9a0, &['\u{88C2}', '\u{FE00}']), + (0x2fa12, &['\u{2A105}', '\u{FE00}']), + (0xfa63, &['\u{8B39}', '\u{FE00}']), + (0xf920, &['\u{9E1E}', '\u{FE00}']), + (0xf91f, &['\u{862D}', '\u{FE00}']), + (0x2f97d, &['\u{8060}', '\u{FE00}']), + (0xf990, &['\u{6200}', '\u{FE00}']), + (0xfa57, &['\u{7DF4}', '\u{FE01}']), + (0x2f975, &['\u{262D9}', '\u{FE00}']), + (0xfad8, &['\u{9F43}', '\u{FE00}']), + (0xfab3, &['\u{8352}', '\u{FE00}']), + (0x2f9f3, &['\u{96C3}', '\u{FE00}']), + (0xf9fb, &['\u{7099}', '\u{FE00}']), + (0xf918, &['\u{843D}', '\u{FE00}']), + (0x2f8c3, &['\u{6469}', '\u{FE00}']), + (0xf9ca, &['\u{6D41}', '\u{FE00}']), + (0xf952, &['\u{52D2}', '\u{FE00}']), + (0x2fa0b, &['\u{9C40}', '\u{FE00}']), + (0x2f941, &['\u{250F3}', '\u{FE00}']), + (0x2f862, &['\u{59EC}', '\u{FE00}']), + (0x2f8ff, &['\u{6D16}', '\u{FE00}']), + (0x2f85d, &['\u{591A}', '\u{FE00}']), + (0xf9d9, &['\u{6144}', '\u{FE00}']), + (0x2f855, &['\u{578B}', '\u{FE00}']), + (0x2f98f, &['\u{8291}', '\u{FE00}']), + (0xf9d4, &['\u{502B}', '\u{FE00}']), + (0xf99e, &['\u{54BD}', '\u{FE00}']), + (0x2f850, &['\u{5207}', '\u{FE01}']), + (0xfa22, &['\u{8AF8}', '\u{FE00}']), + (0x2f94f, &['\u{788C}', '\u{FE01}']), + (0xfaa9, &['\u{774A}', '\u{FE00}']), + (0xfa71, &['\u{51B5}', '\u{FE00}']), + (0xf95d, &['\u{8AFE}', '\u{FE00}']), + (0x2f8bd, &['\u{63E4}', '\u{FE00}']), + (0x2fa02, &['\u{98E2}', '\u{FE00}']), + (0x2f93f, &['\u{4008}', '\u{FE00}']), + (0x2f808, &['\u{507A}', '\u{FE00}']), + (0x2f950, &['\u{78CC}', '\u{FE01}']), + (0x2f933, &['\u{3F1B}', '\u{FE00}']), + (0x2f853, &['\u{57F4}', '\u{FE00}']), + (0x2f8f0, &['\u{238A7}', '\u{FE00}']), + (0xf967, &['\u{4E0D}', '\u{FE00}']), + (0xfa16, &['\u{732A}', '\u{FE00}']), + (0xfaa6, &['\u{76CA}', '\u{FE01}']), + (0x2f8b3, &['\u{621B}', '\u{FE00}']), + (0x2f9f7, &['\u{2921A}', '\u{FE00}']), + (0xf986, &['\u{95AD}', '\u{FE00}']), + (0x2f99d, &['\u{83BD}', '\u{FE00}']), + (0x2f9b8, &['\u{8688}', '\u{FE00}']), + (0xf998, &['\u{8F26}', '\u{FE00}']), + (0x2f82b, &['\u{5317}', '\u{FE01}']), + (0x2f872, &['\u{5BFF}', '\u{FE00}']), + (0xfab9, &['\u{8ABF}', '\u{FE00}']), + (0xfa9b, &['\u{701E}', '\u{FE00}']), + (0xf9b0, &['\u{8046}', '\u{FE00}']), + (0xf98b, &['\u{66C6}', '\u{FE00}']), + (0xfad1, &['\u{233D5}', '\u{FE00}']), + (0xf917, &['\u{73DE}', '\u{FE00}']), + (0x2f989, &['\u{23393}', '\u{FE00}']), + (0x2f866, &['\u{5A66}', '\u{FE00}']), + (0xf932, &['\u{7210}', '\u{FE00}']), + (0x2fa0e, &['\u{4CED}', '\u{FE00}']), + (0xfa07, &['\u{8F3B}', '\u{FE00}']), + (0xf9bd, &['\u{5C3F}', '\u{FE00}']), + (0x2f88c, &['\u{5EB3}', '\u{FE00}']), + (0xfa56, &['\u{7BC0}', '\u{FE00}']), + (0xfa64, &['\u{8CD3}', '\u{FE00}']), + (0xfa04, &['\u{5B85}', '\u{FE00}']), + (0xfa9e, &['\u{7235}', '\u{FE00}']), + (0x2f9e0, &['\u{285D2}', '\u{FE00}']), + (0x2f89d, &['\u{5FCD}', '\u{FE00}']), + (0x2f9ee, &['\u{958B}', '\u{FE00}']), + (0xf9db, &['\u{7387}', '\u{FE01}']), + (0xf923, &['\u{85CD}', '\u{FE00}']), + (0x2f841, &['\u{54F6}', '\u{FE00}']), + (0x2f81a, &['\u{51AC}', '\u{FE00}']), + (0xf911, &['\u{87BA}', '\u{FE00}']), + (0xfaad, &['\u{7BC0}', '\u{FE01}']), + (0xfac1, &['\u{8D08}', '\u{FE01}']), + (0x2f928, &['\u{737A}', '\u{FE00}']), + (0x2f935, &['\u{24C36}', '\u{FE00}']), + (0x2f8d5, &['\u{669C}', '\u{FE00}']), + (0xf92e, &['\u{51B7}', '\u{FE00}']), + (0xfa59, &['\u{7E41}', '\u{FE00}']), + (0x2f96b, &['\u{25F86}', '\u{FE00}']), + (0x2f8b9, &['\u{633D}', '\u{FE00}']), + (0x2f877, &['\u{5C60}', '\u{FE00}']), + (0x2fa00, &['\u{9829}', '\u{FE00}']), + (0xfa05, &['\u{6D1E}', '\u{FE00}']), + (0xf9e8, &['\u{88E1}', '\u{FE00}']), + (0x2f8c6, &['\u{6477}', '\u{FE00}']), + (0xf97a, &['\u{6881}', '\u{FE00}']), + (0x2f9ea, &['\u{927C}', '\u{FE00}']), + (0xf944, &['\u{7C60}', '\u{FE00}']), + (0x2f8c4, &['\u{647E}', '\u{FE00}']), + (0x2f9cd, &['\u{46BE}', '\u{FE00}']), + (0x2f8e5, &['\u{681F}', '\u{FE00}']), + (0x2f9d9, &['\u{20804}', '\u{FE00}']), + (0x2f980, &['\u{2335F}', '\u{FE00}']), + (0x2f9a8, &['\u{84F1}', '\u{FE00}']), + (0x2f92f, &['\u{745C}', '\u{FE00}']), + (0x2f951, &['\u{40E3}', '\u{FE00}']), + (0x2f9f9, &['\u{4A76}', '\u{FE00}']), + (0xfab4, &['\u{83EF}', '\u{FE00}']), + (0xf985, &['\u{792A}', '\u{FE00}']), + (0x2f829, &['\u{5305}', '\u{FE00}']), + (0x2f8a2, &['\u{391C}', '\u{FE00}']), + (0x2f9c3, &['\u{8860}', '\u{FE00}']), + (0x2f936, &['\u{753E}', '\u{FE00}']), + (0x2f9af, &['\u{4561}', '\u{FE00}']), + (0xfa77, &['\u{52FA}', '\u{FE00}']), + (0xf956, &['\u{7A1C}', '\u{FE00}']), + (0xfa5f, &['\u{8457}', '\u{FE00}']), + (0x2f93b, &['\u{24FA1}', '\u{FE00}']), + (0xf914, &['\u{6A02}', '\u{FE00}']), + (0x2f994, &['\u{82B3}', '\u{FE00}']), + (0x2f91b, &['\u{20525}', '\u{FE00}']), + (0x2f880, &['\u{5D7C}', '\u{FE00}']), + (0x2f956, &['\u{798F}', '\u{FE01}']), + (0xf958, &['\u{83F1}', '\u{FE00}']), + (0x2f99b, &['\u{83AD}', '\u{FE00}']), + (0x2fa06, &['\u{99C2}', '\u{FE00}']), + (0xfabf, &['\u{8B39}', '\u{FE01}']), + (0x2f8b6, &['\u{62D4}', '\u{FE00}']), + (0x2f8a0, &['\u{6081}', '\u{FE00}']), + (0xfa87, &['\u{614E}', '\u{FE00}']), + (0x2f8ea, &['\u{69EA}', '\u{FE00}']), + (0x2f867, &['\u{36EE}', '\u{FE00}']), + (0xf97d, &['\u{8AD2}', '\u{FE00}']), + (0xf968, &['\u{6CCC}', '\u{FE00}']), + (0xfa5a, &['\u{7F72}', '\u{FE00}']), + (0xf97b, &['\u{7CE7}', '\u{FE00}']), + (0x2fa10, &['\u{2A0CE}', '\u{FE00}']), + (0xfa2b, &['\u{98FC}', '\u{FE00}']), + (0xfa75, &['\u{5180}', '\u{FE00}']), + (0xf94d, &['\u{6DDA}', '\u{FE00}']), + (0xfad4, &['\u{4039}', '\u{FE00}']), + (0x2f8cc, &['\u{66F8}', '\u{FE00}']), + (0xfa8a, &['\u{6160}', '\u{FE00}']), + (0xf9f4, &['\u{6797}', '\u{FE00}']), + (0xfac6, &['\u{967C}', '\u{FE00}']), + (0xfa9c, &['\u{716E}', '\u{FE01}']), + (0xfa10, &['\u{585A}', '\u{FE00}']), + (0xf9e2, &['\u{68A8}', '\u{FE00}']), + (0xf947, &['\u{78CA}', '\u{FE00}']), + (0xf941, &['\u{8AD6}', '\u{FE00}']), + (0xfa4e, &['\u{7948}', '\u{FE00}']), + (0x2f9da, &['\u{8DCB}', '\u{FE00}']), + (0x2f893, &['\u{8201}', '\u{FE00}']), + (0xf96f, &['\u{8AAA}', '\u{FE00}']), + (0xf983, &['\u{65C5}', '\u{FE00}']), + (0xf9f5, &['\u{6DCB}', '\u{FE00}']), + (0xf962, &['\u{7570}', '\u{FE00}']), + (0x2f968, &['\u{7CE8}', '\u{FE00}']), + (0x2f923, &['\u{24608}', '\u{FE00}']), + (0x2fa18, &['\u{9EFE}', '\u{FE00}']), + (0x2f930, &['\u{7471}', '\u{FE01}']), + (0xfa90, &['\u{6556}', '\u{FE00}']), + (0xfa54, &['\u{7A40}', '\u{FE00}']), + (0xf9d8, &['\u{5F8B}', '\u{FE00}']), + (0x2f9e4, &['\u{9111}', '\u{FE00}']), + (0x2fa05, &['\u{99A7}', '\u{FE00}']), + (0x2f964, &['\u{4227}', '\u{FE00}']), + (0xf99f, &['\u{70C8}', '\u{FE00}']), + (0x2f94b, &['\u{4046}', '\u{FE00}']), + (0x2f9a9, &['\u{84F3}', '\u{FE00}']), + (0xfa0c, &['\u{5140}', '\u{FE00}']), + (0x2f986, &['\u{5AB5}', '\u{FE00}']), + (0xfa85, &['\u{5FAD}', '\u{FE00}']), + (0x2f95f, &['\u{7AEE}', '\u{FE00}']), + (0xf9f8, &['\u{7B20}', '\u{FE00}']), + (0xf9b4, &['\u{9818}', '\u{FE00}']), + (0x2f82e, &['\u{535A}', '\u{FE00}']), + (0xfad9, &['\u{9F8E}', '\u{FE00}']), + (0x2f937, &['\u{24C92}', '\u{FE00}']), + (0xf9cf, &['\u{7D10}', '\u{FE00}']), + (0xfaa1, &['\u{7471}', '\u{FE00}']), + (0x2f917, &['\u{704A}', '\u{FE00}']), + (0xfaa5, &['\u{761F}', '\u{FE00}']), + (0xfa3b, &['\u{5C64}', '\u{FE00}']), + (0x2f88d, &['\u{5EB6}', '\u{FE00}']), + (0x2f906, &['\u{23D1E}', '\u{FE00}']), + (0x2f901, &['\u{6D77}', '\u{FE01}']), + (0x2f97a, &['\u{8005}', '\u{FE02}']), + (0xfa60, &['\u{8910}', '\u{FE00}']), + (0x2f92c, &['\u{3EB8}', '\u{FE00}']), + (0x2f80a, &['\u{50E7}', '\u{FE01}']), + (0x2f99a, &['\u{8363}', '\u{FE00}']), + (0x2fa13, &['\u{2A20E}', '\u{FE00}']), + (0x2f938, &['\u{7570}', '\u{FE01}']), + (0x2f813, &['\u{34B9}', '\u{FE00}']), + (0x2f831, &['\u{537F}', '\u{FE00}']), + (0xfa1c, &['\u{9756}', '\u{FE00}']), + (0xfacc, &['\u{983B}', '\u{FE01}']), + (0xfa5e, &['\u{8279}', '\u{FE01}']), + (0x2f995, &['\u{82BD}', '\u{FE00}']), + (0x2f8d3, &['\u{5195}', '\u{FE00}']), + (0xfacd, &['\u{9B12}', '\u{FE00}']), + (0x2f81d, &['\u{51F5}', '\u{FE00}']), + (0x2f97b, &['\u{264DA}', '\u{FE00}']), + (0xfa3a, &['\u{58A8}', '\u{FE00}']), + (0xf9c6, &['\u{962E}', '\u{FE00}']), + (0xfabd, &['\u{8AFE}', '\u{FE01}']), + (0xf92d, &['\u{4F86}', '\u{FE00}']), + (0xf99b, &['\u{934A}', '\u{FE00}']), + (0xf91d, &['\u{6B04}', '\u{FE00}']), + (0x2f84d, &['\u{5717}', '\u{FE00}']), + (0x2f8ad, &['\u{61A4}', '\u{FE00}']), + (0xf9d3, &['\u{9678}', '\u{FE00}']), + (0x2f843, &['\u{5553}', '\u{FE00}']), + (0xf97c, &['\u{826F}', '\u{FE00}']), + (0xfa30, &['\u{4FAE}', '\u{FE00}']), + (0x2f858, &['\u{58AC}', '\u{FE00}']), + (0x2f8a5, &['\u{60C7}', '\u{FE00}']), + (0x2f988, &['\u{267B5}', '\u{FE00}']), + (0x2f9e1, &['\u{285ED}', '\u{FE00}']), + (0xfa74, &['\u{5145}', '\u{FE00}']), + (0x2f882, &['\u{5DE2}', '\u{FE00}']), + (0x2f879, &['\u{5CC0}', '\u{FE00}']), + (0x2f8b7, &['\u{6350}', '\u{FE00}']), + (0xf940, &['\u{9E7F}', '\u{FE00}']), + (0x2f9e5, &['\u{2872E}', '\u{FE00}']), + (0x2f9cf, &['\u{8AA0}', '\u{FE00}']), + (0xfa8e, &['\u{641C}', '\u{FE00}']), + (0x2f90c, &['\u{6EC7}', '\u{FE00}']), + (0x2f985, &['\u{813E}', '\u{FE00}']), + (0x2f849, &['\u{55B3}', '\u{FE00}']), + (0x2f960, &['\u{4202}', '\u{FE00}']), + (0x2f8c2, &['\u{3A2E}', '\u{FE00}']), + (0x2f85f, &['\u{5962}', '\u{FE00}']), + (0x2f916, &['\u{3D96}', '\u{FE00}']), + (0xf9fa, &['\u{72C0}', '\u{FE00}']), + (0x2f824, &['\u{3515}', '\u{FE00}']), + (0xf936, &['\u{865C}', '\u{FE00}']), + (0x2f94a, &['\u{778B}', '\u{FE00}']), + (0x2f80e, &['\u{514D}', '\u{FE01}']), + (0x2f913, &['\u{7039}', '\u{FE00}']), + (0x2f94d, &['\u{2541D}', '\u{FE00}']), + (0xf999, &['\u{84EE}', '\u{FE00}']), + (0x2f979, &['\u{7FFA}', '\u{FE00}']), + (0x2f926, &['\u{24735}', '\u{FE00}']), + (0xf9ea, &['\u{96E2}', '\u{FE00}']), + (0xfa3f, &['\u{618E}', '\u{FE00}']), + (0x2f83b, &['\u{5406}', '\u{FE00}']), + (0xfa5b, &['\u{8005}', '\u{FE00}']), + (0xfa93, &['\u{671B}', '\u{FE00}']), + (0xf913, &['\u{908F}', '\u{FE00}']), + (0xf98c, &['\u{6B77}', '\u{FE00}']), + (0x2f8c0, &['\u{63C5}', '\u{FE00}']), + (0xfad7, &['\u{27ED3}', '\u{FE00}']), + (0xf98a, &['\u{529B}', '\u{FE00}']), + (0xfa26, &['\u{90FD}', '\u{FE00}']), + (0xfabe, &['\u{8AED}', '\u{FE00}']), + (0x2f977, &['\u{2633E}', '\u{FE00}']), + (0xf954, &['\u{51DC}', '\u{FE00}']), + (0xf91a, &['\u{99F1}', '\u{FE00}']), + (0x2f8cd, &['\u{6649}', '\u{FE00}']), + (0x2f8a4, &['\u{226D4}', '\u{FE00}']), + (0xfa84, &['\u{5F69}', '\u{FE00}']), + (0x2f85e, &['\u{5922}', '\u{FE00}']), + (0xfa9f, &['\u{72AF}', '\u{FE00}']), + (0xf9b1, &['\u{9234}', '\u{FE00}']), + (0x2f9ca, &['\u{34BB}', '\u{FE00}']), + (0xfac4, &['\u{9199}', '\u{FE00}']), + (0xf927, &['\u{881F}', '\u{FE00}']), + (0xfa01, &['\u{5EA6}', '\u{FE00}']), + (0xf929, &['\u{6717}', '\u{FE00}']), + (0xf9f3, &['\u{9E9F}', '\u{FE00}']), + (0x2f9e6, &['\u{911B}', '\u{FE00}']), + (0xfa70, &['\u{4E26}', '\u{FE00}']), + (0x2f820, &['\u{523B}', '\u{FE00}']), + (0xf9a9, &['\u{56F9}', '\u{FE00}']), + (0x2f9bf, &['\u{45D7}', '\u{FE00}']), + (0x2f922, &['\u{7250}', '\u{FE00}']), + (0x2f9de, &['\u{8ED4}', '\u{FE00}']), + (0x2f8ec, &['\u{236A3}', '\u{FE00}']), + (0xf9b5, &['\u{4F8B}', '\u{FE00}']), + (0x2f9b7, &['\u{86A9}', '\u{FE00}']), + (0x2f981, &['\u{43D5}', '\u{FE00}']), + (0xfa31, &['\u{50E7}', '\u{FE00}']), + (0x2f9c1, &['\u{8801}', '\u{FE00}']), + (0x2f874, &['\u{5F53}', '\u{FE00}']), + (0xf9d0, &['\u{985E}', '\u{FE00}']), + (0xf94a, &['\u{58D8}', '\u{FE00}']), + (0x2f998, &['\u{82E5}', '\u{FE01}']), + (0x2f91c, &['\u{7145}', '\u{FE00}']), + (0x2f9df, &['\u{8F38}', '\u{FE01}']), + (0x2f859, &['\u{214E4}', '\u{FE00}']), + (0x2f883, &['\u{382F}', '\u{FE00}']), + (0xf9cc, &['\u{7409}', '\u{FE00}']), + (0x2f9b5, &['\u{8667}', '\u{FE00}']), + (0x2f970, &['\u{7E45}', '\u{FE00}']), + (0x2f814, &['\u{5167}', '\u{FE00}']), + (0x2f9ff, &['\u{980B}', '\u{FE02}']), + (0x2f84c, &['\u{5606}', '\u{FE01}']), + (0x2f9a4, &['\u{26C36}', '\u{FE00}']), + (0x2f966, &['\u{7CD2}', '\u{FE00}']), + (0xfa1e, &['\u{7FBD}', '\u{FE00}']), + (0x2fa0c, &['\u{9CFD}', '\u{FE00}']), + (0x2f863, &['\u{5A1B}', '\u{FE00}']), + (0xfaa2, &['\u{7506}', '\u{FE00}']), + (0x2f91a, &['\u{70AD}', '\u{FE00}']), + (0x2f8f8, &['\u{21D0B}', '\u{FE00}']), + (0x2f8a6, &['\u{6148}', '\u{FE00}']), + (0x2f895, &['\u{5F22}', '\u{FE01}']), + (0xf90b, &['\u{5587}', '\u{FE00}']), + (0x2f993, &['\u{82B1}', '\u{FE00}']), + (0x2f8be, &['\u{22BF1}', '\u{FE00}']), + (0xf948, &['\u{8CC2}', '\u{FE00}']), + (0x2f80d, &['\u{2063A}', '\u{FE00}']), + (0x2f81f, &['\u{34DF}', '\u{FE00}']), + (0xf9e4, &['\u{7406}', '\u{FE00}']), + (0x2f823, &['\u{5277}', '\u{FE00}']), + (0x2f9fa, &['\u{97E0}', '\u{FE00}']), + (0x2f8fa, &['\u{6C4E}', '\u{FE00}']), + (0xfa6a, &['\u{983B}', '\u{FE00}']), + (0x2f9f0, &['\u{95B7}', '\u{FE00}']), + (0x2f967, &['\u{42A0}', '\u{FE00}']), + (0xfa8f, &['\u{6452}', '\u{FE00}']), + (0xfa06, &['\u{66B4}', '\u{FE00}']), + (0xf982, &['\u{5EEC}', '\u{FE00}']), + (0xf989, &['\u{9ECE}', '\u{FE00}']), + (0x2f990, &['\u{828B}', '\u{FE00}']), + (0xfac9, &['\u{97DB}', '\u{FE00}']), + (0x2f8ed, &['\u{6ADB}', '\u{FE00}']), + (0x2f822, &['\u{5272}', '\u{FE00}']), + (0xf9cb, &['\u{6E9C}', '\u{FE00}']), + (0xfa4d, &['\u{7949}', '\u{FE00}']), + (0x2f944, &['\u{25133}', '\u{FE00}']), + (0x2f9e8, &['\u{92D7}', '\u{FE00}']), + (0x2f8d2, &['\u{5192}', '\u{FE00}']), + (0x2f97c, &['\u{26523}', '\u{FE00}']), + (0xfa68, &['\u{96E3}', '\u{FE00}']), + (0xfa53, &['\u{798E}', '\u{FE00}']), + (0x2f8f5, &['\u{6BBA}', '\u{FE02}']), + (0x2f945, &['\u{771E}', '\u{FE00}']), + (0xfa95, &['\u{6B79}', '\u{FE00}']), + (0xfa2e, &['\u{90DE}', '\u{FE00}']), + (0xf91b, &['\u{4E82}', '\u{FE00}']), + (0x2f837, &['\u{53DF}', '\u{FE00}']), + (0x2f894, &['\u{5F22}', '\u{FE00}']), + (0x2fa09, &['\u{29B30}', '\u{FE00}']), + (0x2f974, &['\u{4359}', '\u{FE00}']), + (0xf9ba, &['\u{4E86}', '\u{FE00}']), + (0x2f80b, &['\u{50CF}', '\u{FE00}']), + (0xfaca, &['\u{97FF}', '\u{FE01}']), + (0x2f969, &['\u{7CE3}', '\u{FE00}']), + (0x2f8b1, &['\u{61F6}', '\u{FE01}']), + (0x2f8d1, &['\u{3AE4}', '\u{FE00}']), + (0x2f91d, &['\u{24263}', '\u{FE00}']), + (0x2f9d4, &['\u{8CAB}', '\u{FE00}']), + (0x2fa15, &['\u{9EBB}', '\u{FE00}']), + (0x2f954, &['\u{2569A}', '\u{FE00}']), + (0xfa81, &['\u{5B28}', '\u{FE00}']), + (0x2f9a5, &['\u{26D6B}', '\u{FE00}']), + (0x2f90f, &['\u{6F6E}', '\u{FE00}']), + (0xf92a, &['\u{6D6A}', '\u{FE00}']), + (0x2fa19, &['\u{9F05}', '\u{FE00}']), + (0x2f943, &['\u{25119}', '\u{FE00}']), + (0x2f947, &['\u{771F}', '\u{FE01}']), + (0x2fa0a, &['\u{9B12}', '\u{FE01}']), + (0x2f963, &['\u{7BC9}', '\u{FE00}']), + (0xf9bb, &['\u{50DA}', '\u{FE00}']), + (0x2f8ac, &['\u{61B2}', '\u{FE00}']), + (0xf9c5, &['\u{6688}', '\u{FE00}']), + (0x2f97e, &['\u{265A8}', '\u{FE00}']), + (0x2f889, &['\u{22183}', '\u{FE00}']), + (0x2f8e9, &['\u{69A3}', '\u{FE00}']), + (0xf9da, &['\u{6817}', '\u{FE00}']), + (0xface, &['\u{9F9C}', '\u{FE02}']), + (0x2f920, &['\u{7228}', '\u{FE00}']), + (0xf951, &['\u{964B}', '\u{FE00}']), + (0xf9bc, &['\u{5BEE}', '\u{FE00}']), + (0x2f940, &['\u{76F4}', '\u{FE01}']), + (0x2f84e, &['\u{5651}', '\u{FE00}']), + (0xfa48, &['\u{716E}', '\u{FE00}']), + (0x2fa08, &['\u{4BCE}', '\u{FE00}']), + (0xf9e6, &['\u{7F79}', '\u{FE00}']), + (0x2f8c8, &['\u{654F}', '\u{FE01}']), + (0xf912, &['\u{88F8}', '\u{FE00}']), + (0x2f8f7, &['\u{23A8D}', '\u{FE00}']), + (0x2f904, &['\u{6D78}', '\u{FE00}']), + (0xfa76, &['\u{52C7}', '\u{FE00}']), + (0x2f8e8, &['\u{6942}', '\u{FE00}']), + (0x2f9e2, &['\u{9094}', '\u{FE00}']), + (0xf903, &['\u{8CC8}', '\u{FE00}']), + (0xfa9a, &['\u{6F22}', '\u{FE01}']), + (0xf996, &['\u{7DF4}', '\u{FE00}']), + (0x2f8db, &['\u{675E}', '\u{FE00}']), + (0xfa4a, &['\u{7422}', '\u{FE00}']), + (0xfa6b, &['\u{6075}', '\u{FE00}']), + (0x2f8fd, &['\u{6CCD}', '\u{FE00}']), + (0xfa79, &['\u{5555}', '\u{FE00}']), + (0xf987, &['\u{9A6A}', '\u{FE00}']), + (0x2f8f2, &['\u{3C4E}', '\u{FE00}']), + (0xf90d, &['\u{61F6}', '\u{FE00}']), + (0xf922, &['\u{6FEB}', '\u{FE00}']), + (0xfa88, &['\u{6108}', '\u{FE00}']), + (0xf91c, &['\u{5375}', '\u{FE00}']), + (0x2f870, &['\u{5BF3}', '\u{FE00}']), + (0x2f9ac, &['\u{8564}', '\u{FE00}']), + (0x2f839, &['\u{53EB}', '\u{FE00}']), + (0x2fa03, &['\u{4B33}', '\u{FE00}']), + (0x2f854, &['\u{580D}', '\u{FE00}']), + (0x2f92a, &['\u{3EAC}', '\u{FE00}']), + (0xfa35, &['\u{5351}', '\u{FE00}']), + (0x2f9e7, &['\u{9238}', '\u{FE00}']), + (0x2f9a6, &['\u{26CD5}', '\u{FE00}']), + (0xfaaf, &['\u{7D5B}', '\u{FE00}']), + (0x2f911, &['\u{23F8E}', '\u{FE00}']), + (0x2f95d, &['\u{25AA7}', '\u{FE00}']), + (0x2f89c, &['\u{5F9A}', '\u{FE00}']), + (0xfa45, &['\u{6D77}', '\u{FE00}']), + (0xfa1b, &['\u{798F}', '\u{FE00}']), + (0xfa3d, &['\u{6094}', '\u{FE00}']), + (0xf980, &['\u{5442}', '\u{FE00}']), + (0xfa8c, &['\u{6234}', '\u{FE00}']), + (0x2f9e9, &['\u{92D8}', '\u{FE00}']), + (0x2f9f8, &['\u{4A6E}', '\u{FE00}']), + (0x2f902, &['\u{6D41}', '\u{FE02}']), + (0x2fa1d, &['\u{2A600}', '\u{FE00}']), + (0xfab6, &['\u{8941}', '\u{FE00}']), + (0xf995, &['\u{79CA}', '\u{FE00}']), + (0x2f832, &['\u{537F}', '\u{FE01}']), + (0x2f955, &['\u{256C5}', '\u{FE00}']), + (0x2f8fc, &['\u{6CBF}', '\u{FE00}']), + (0x2f875, &['\u{5C22}', '\u{FE00}']), + (0x2f82a, &['\u{5306}', '\u{FE00}']), + (0x2f811, &['\u{5177}', '\u{FE00}']), + (0x2f868, &['\u{36FC}', '\u{FE00}']), + (0x2f925, &['\u{7295}', '\u{FE00}']), + (0xfa20, &['\u{8612}', '\u{FE00}']), + (0x2f83e, &['\u{5448}', '\u{FE00}']), + (0xf9af, &['\u{7F9A}', '\u{FE00}']), + (0x2f997, &['\u{26B3C}', '\u{FE00}']), + (0x2f9ec, &['\u{9415}', '\u{FE00}']), + (0xf9ab, &['\u{5DBA}', '\u{FE00}']), + (0xf935, &['\u{8606}', '\u{FE00}']), + (0xfa80, &['\u{5A62}', '\u{FE00}']), + (0x2f95c, &['\u{2597C}', '\u{FE00}']), + (0xfa92, &['\u{6717}', '\u{FE01}']), + (0xf95b, &['\u{62CF}', '\u{FE00}']), + (0xf93e, &['\u{83C9}', '\u{FE00}']), + (0xf9de, &['\u{540F}', '\u{FE00}']), + (0xf9f0, &['\u{85FA}', '\u{FE00}']), + (0x2f847, &['\u{5599}', '\u{FE01}']), + (0xfa98, &['\u{6EDB}', '\u{FE00}']), + (0xf90e, &['\u{7669}', '\u{FE00}']), + (0xfa4f, &['\u{7950}', '\u{FE00}']), + (0xfaa4, &['\u{761D}', '\u{FE00}']), + (0x2f9c0, &['\u{87E1}', '\u{FE00}']), + (0x2f8bf, &['\u{6422}', '\u{FE00}']), + (0xfa62, &['\u{8B01}', '\u{FE00}']), + (0xf9b6, &['\u{79AE}', '\u{FE00}']), + (0x2f826, &['\u{52C9}', '\u{FE01}']), + (0xf9c9, &['\u{67F3}', '\u{FE00}']), + (0x2f992, &['\u{52B3}', '\u{FE00}']), + (0x2f8e1, &['\u{6852}', '\u{FE00}']), + (0xf959, &['\u{9675}', '\u{FE00}']), + (0x2f892, &['\u{22331}', '\u{FE01}']), + (0xfa18, &['\u{793C}', '\u{FE00}']), + (0x2f87d, &['\u{21DE6}', '\u{FE00}']), + (0xf970, &['\u{6BBA}', '\u{FE00}']), + (0x2f92b, &['\u{73A5}', '\u{FE00}']), + (0x2fa04, &['\u{9929}', '\u{FE00}']), + (0xfa89, &['\u{618E}', '\u{FE01}']), + (0x2f9e3, &['\u{90F1}', '\u{FE00}']), + (0x2f9c2, &['\u{45F9}', '\u{FE00}']), + (0xfacb, &['\u{980B}', '\u{FE00}']), + (0x2f9c8, &['\u{4635}', '\u{FE00}']), + (0x2f908, &['\u{6E2F}', '\u{FE00}']), + (0x2f86f, &['\u{5BE7}', '\u{FE02}']), + (0x2f98a, &['\u{2339C}', '\u{FE00}']), + (0xf9a8, &['\u{4EE4}', '\u{FE00}']), + (0x2f8c7, &['\u{3A6C}', '\u{FE00}']), + (0x2fa16, &['\u{4D56}', '\u{FE00}']), + (0xfa4b, &['\u{7891}', '\u{FE00}']), + (0x2f878, &['\u{5C6E}', '\u{FE01}']), + (0x2f8bb, &['\u{6368}', '\u{FE00}']), + (0x2f816, &['\u{2054B}', '\u{FE00}']), + (0x2f86a, &['\u{5B3E}', '\u{FE00}']), + (0xf9c3, &['\u{907C}', '\u{FE00}']), + (0xf945, &['\u{807E}', '\u{FE00}']), + (0x2f9fe, &['\u{980B}', '\u{FE01}']), + (0xfa86, &['\u{60D8}', '\u{FE00}']), + (0x2f82c, &['\u{5349}', '\u{FE00}']), + (0xf988, &['\u{9E97}', '\u{FE00}']), + (0xfac5, &['\u{9276}', '\u{FE00}']), + (0xfa66, &['\u{8FB6}', '\u{FE00}']), + (0x2f840, &['\u{54A2}', '\u{FE00}']), + (0xf9ee, &['\u{71D0}', '\u{FE00}']), + (0x2f830, &['\u{537D}', '\u{FE00}']), + (0x2f914, &['\u{701E}', '\u{FE01}']), + (0x2f942, &['\u{250F2}', '\u{FE00}']), + (0xfaa3, &['\u{753B}', '\u{FE00}']), + (0xf974, &['\u{82E5}', '\u{FE00}']), + (0x2f807, &['\u{5002}', '\u{FE00}']), + (0x2f905, &['\u{6D85}', '\u{FE00}']), + (0x2f9b2, &['\u{456B}', '\u{FE00}']), + (0x2f887, &['\u{5E69}', '\u{FE00}']), + (0x2f912, &['\u{6FC6}', '\u{FE00}']), + (0xf9ae, &['\u{7469}', '\u{FE00}']), + (0xf96a, &['\u{7D22}', '\u{FE00}']), + (0xf9b7, &['\u{91B4}', '\u{FE00}']), + (0x2f932, &['\u{74CA}', '\u{FE00}']), + (0x2f98d, &['\u{8F9E}', '\u{FE00}']), + (0xfa25, &['\u{9038}', '\u{FE00}']), + (0xf993, &['\u{7149}', '\u{FE00}']), + (0x2f9f5, &['\u{9723}', '\u{FE00}']), + (0xf9df, &['\u{5C65}', '\u{FE00}']), + (0x2f9c7, &['\u{88DE}', '\u{FE00}']), + (0x2f996, &['\u{82E6}', '\u{FE00}']), + (0x2f842, &['\u{5510}', '\u{FE00}']), + (0x2f869, &['\u{5B08}', '\u{FE00}']), + (0x2f861, &['\u{216EA}', '\u{FE00}']), + (0x2f8af, &['\u{61DE}', '\u{FE00}']), + (0x2f8c5, &['\u{649D}', '\u{FE00}']), + (0x2f962, &['\u{7BC6}', '\u{FE00}']), + (0x2f98b, &['\u{8201}', '\u{FE01}']), + (0x2f9a1, &['\u{83CA}', '\u{FE00}']), + (0xfad2, &['\u{3B9D}', '\u{FE00}']), + (0x2f9ae, &['\u{455D}', '\u{FE00}']), + (0x2f8bc, &['\u{6383}', '\u{FE00}']), + (0xf9b3, &['\u{9748}', '\u{FE00}']), + (0x2f88f, &['\u{2A392}', '\u{FE00}']), + (0xf965, &['\u{4FBF}', '\u{FE00}']), + (0x2f953, &['\u{7956}', '\u{FE01}']), + (0x2f84b, &['\u{5716}', '\u{FE00}']), + (0x2f90b, &['\u{6ECB}', '\u{FE01}']), + (0x2f834, &['\u{20A2C}', '\u{FE00}']), + (0xfa2d, &['\u{9DB4}', '\u{FE00}']), + (0x2f8e6, &['\u{6914}', '\u{FE00}']), + (0xf971, &['\u{8FB0}', '\u{FE00}']), + (0x2fa1c, &['\u{9F3B}', '\u{FE00}']), + (0xfa61, &['\u{8996}', '\u{FE00}']), + (0x2f98e, &['\u{446B}', '\u{FE00}']), + (0x2f9c9, &['\u{88FA}', '\u{FE00}']), + (0xfa0b, &['\u{5ED3}', '\u{FE00}']), + (0x2f86b, &['\u{5B3E}', '\u{FE01}']), + (0xf949, &['\u{96F7}', '\u{FE00}']), + (0xfac7, &['\u{96E3}', '\u{FE01}']), + (0xf96e, &['\u{8449}', '\u{FE00}']), + (0xf966, &['\u{5FA9}', '\u{FE00}']), + (0xf955, &['\u{51CC}', '\u{FE00}']), + (0x2f8d0, &['\u{3B08}', '\u{FE00}']), + (0x2f93a, &['\u{7610}', '\u{FE00}']), + (0xf9ff, &['\u{523A}', '\u{FE00}']), + (0xfac8, &['\u{9756}', '\u{FE01}']), + (0xf93c, &['\u{797F}', '\u{FE00}']), + (0x2f845, &['\u{5584}', '\u{FE00}']), + (0x2f9ce, &['\u{46C7}', '\u{FE00}']), + (0xfad6, &['\u{25CD0}', '\u{FE00}']), + (0x2f95a, &['\u{7A4A}', '\u{FE00}']), + (0xf9e9, &['\u{91CC}', '\u{FE00}']), + (0x2f91f, &['\u{243AB}', '\u{FE00}']), + (0xf950, &['\u{7E37}', '\u{FE00}']), + (0x2f8c1, &['\u{63A9}', '\u{FE00}']), + (0x2f9ad, &['\u{26F2C}', '\u{FE00}']), + (0x2f97f, &['\u{8070}', '\u{FE00}']), + (0xfa83, &['\u{5ED9}', '\u{FE00}']), + (0x2f82d, &['\u{5351}', '\u{FE01}']), + (0x2f8df, &['\u{67FA}', '\u{FE00}']), + (0x2f87c, &['\u{5D43}', '\u{FE00}']), + (0xfa58, &['\u{7E09}', '\u{FE00}']), + (0x2f846, &['\u{5584}', '\u{FE01}']), + (0xfa37, &['\u{5606}', '\u{FE00}']), + (0xfa78, &['\u{559D}', '\u{FE01}']), + (0x2f9f6, &['\u{29145}', '\u{FE00}']), + (0x2f99e, &['\u{83E7}', '\u{FE00}']), + (0xfad3, &['\u{4018}', '\u{FE00}']), + (0xfad0, &['\u{22844}', '\u{FE00}']), + (0xf9d5, &['\u{5D19}', '\u{FE00}']), + (0xfab7, &['\u{8986}', '\u{FE00}']), + (0xfa09, &['\u{964D}', '\u{FE00}']), + (0x2f8ce, &['\u{3B19}', '\u{FE00}']), + (0xf957, &['\u{7DBE}', '\u{FE00}']), + (0xf991, &['\u{649A}', '\u{FE00}']), + (0xfab8, &['\u{8996}', '\u{FE01}']), + (0x2f8eb, &['\u{6AA8}', '\u{FE00}']), + (0x2f9b1, &['\u{270D2}', '\u{FE00}']), + (0xfa2a, &['\u{98EF}', '\u{FE00}']), + (0x2f93c, &['\u{24FB8}', '\u{FE00}']), + (0xfa72, &['\u{5168}', '\u{FE00}']), + (0x2f96f, &['\u{7E02}', '\u{FE00}']), + (0x2f8d6, &['\u{80AD}', '\u{FE00}']), + (0x2f886, &['\u{5E3D}', '\u{FE00}']), + (0xf9fd, &['\u{4EC0}', '\u{FE00}']), + (0xf9c0, &['\u{71CE}', '\u{FE00}']), + (0x2f9be, &['\u{8786}', '\u{FE00}']), + (0xf9b8, &['\u{96B8}', '\u{FE00}']), + (0x2f81e, &['\u{5203}', '\u{FE00}']), + (0xf900, &['\u{8C48}', '\u{FE00}']), + (0x2f98c, &['\u{8204}', '\u{FE00}']), + (0x2f93e, &['\u{3FFC}', '\u{FE00}']), + (0xfaa0, &['\u{732A}', '\u{FE01}']), + (0x2f8f3, &['\u{6B72}', '\u{FE00}']), + (0xf961, &['\u{7387}', '\u{FE00}']), + (0x2f83d, &['\u{5438}', '\u{FE00}']), + (0x2f8f6, &['\u{6BBB}', '\u{FE00}']), + (0xf9d2, &['\u{622E}', '\u{FE00}']), + (0x2f84a, &['\u{55C2}', '\u{FE00}']), + (0xf9e1, &['\u{674E}', '\u{FE00}']), + (0xfa7c, &['\u{585A}', '\u{FE01}']), + (0x2f9aa, &['\u{8516}', '\u{FE00}']), + (0xfa51, &['\u{795D}', '\u{FE00}']), + (0x2f8b8, &['\u{22B0C}', '\u{FE00}']), + (0x2f931, &['\u{7485}', '\u{FE00}']), + (0xfa7e, &['\u{5944}', '\u{FE00}']), + (0xf9a6, &['\u{7C3E}', '\u{FE00}']), + (0xf976, &['\u{7565}', '\u{FE00}']), + (0xfa97, &['\u{6D41}', '\u{FE01}']), + (0x2f8e7, &['\u{3B9D}', '\u{FE01}']), + (0x2f88b, &['\u{5EB0}', '\u{FE00}']), + (0x2f9c6, &['\u{88D7}', '\u{FE00}']), + (0x2f8d9, &['\u{671B}', '\u{FE01}']), + (0xfa52, &['\u{798D}', '\u{FE00}']), + (0x2fa0d, &['\u{4CCE}', '\u{FE00}']), + (0x2f900, &['\u{6D3E}', '\u{FE00}']), + (0x2f836, &['\u{53CA}', '\u{FE00}']), + (0xf9ad, &['\u{73B2}', '\u{FE00}']), + (0xf934, &['\u{8001}', '\u{FE00}']), + (0xfab0, &['\u{7DF4}', '\u{FE02}']), + (0x2f809, &['\u{5099}', '\u{FE00}']), + (0x2f9f2, &['\u{49E6}', '\u{FE00}']), + (0x2f86c, &['\u{219C8}', '\u{FE00}']), + (0xf9fc, &['\u{8B58}', '\u{FE00}']), + (0x2f95e, &['\u{25AA7}', '\u{FE01}']), + (0xf9a3, &['\u{5FF5}', '\u{FE00}']), + (0x2f971, &['\u{4334}', '\u{FE00}']), + (0x2f89b, &['\u{38E3}', '\u{FE00}']), + (0xf977, &['\u{4EAE}', '\u{FE00}']), + (0xfa1a, &['\u{7965}', '\u{FE00}']), + (0xfa3c, &['\u{5C6E}', '\u{FE00}']), + (0x2f9bd, &['\u{876B}', '\u{FE00}']), + (0xf928, &['\u{5ECA}', '\u{FE00}']), + (0x2f864, &['\u{5A27}', '\u{FE00}']), + (0x2f9d1, &['\u{8B8A}', '\u{FE01}']), + (0x2f982, &['\u{80B2}', '\u{FE00}']), + (0xf9dc, &['\u{9686}', '\u{FE00}']), + (0x2f972, &['\u{26228}', '\u{FE00}']), + (0x2f8cb, &['\u{65E3}', '\u{FE00}']), + (0xf960, &['\u{6012}', '\u{FE00}']), + (0xf992, &['\u{6F23}', '\u{FE00}']), + (0x2f8b4, &['\u{625D}', '\u{FE00}']), + (0x2f803, &['\u{20122}', '\u{FE00}']), + (0x2f818, &['\u{51A4}', '\u{FE00}']), + (0xf9f7, &['\u{7ACB}', '\u{FE00}']), + (0x2f827, &['\u{52E4}', '\u{FE01}']), + (0x2f9fb, &['\u{2940A}', '\u{FE00}']), + (0x2f987, &['\u{267A7}', '\u{FE00}']), + (0xfaab, &['\u{78CC}', '\u{FE00}']), + (0xfa39, &['\u{5840}', '\u{FE00}']), + (0x2fa07, &['\u{99FE}', '\u{FE00}']), + (0xf9b9, &['\u{60E1}', '\u{FE00}']), + (0x2f86e, &['\u{5BD8}', '\u{FE00}']), + (0x2f8e0, &['\u{6785}', '\u{FE00}']), + (0xfaa7, &['\u{76DB}', '\u{FE00}']), + (0x2f8a8, &['\u{614E}', '\u{FE01}']), + (0xfa0a, &['\u{898B}', '\u{FE00}']), + (0x2fa14, &['\u{2A291}', '\u{FE00}']), + (0x2f888, &['\u{3862}', '\u{FE00}']), + (0x2f9a2, &['\u{83CC}', '\u{FE00}']), + (0x2f848, &['\u{55AB}', '\u{FE00}']), + (0xfaa8, &['\u{76F4}', '\u{FE00}']), + (0xfa67, &['\u{9038}', '\u{FE01}']), + (0xf946, &['\u{7262}', '\u{FE00}']), + (0x2f946, &['\u{771F}', '\u{FE00}']), + (0xfa7d, &['\u{58B3}', '\u{FE00}']), + (0xfa1d, &['\u{7CBE}', '\u{FE00}']), + (0x2fa11, &['\u{4CF8}', '\u{FE00}']), + (0xfa2c, &['\u{9928}', '\u{FE00}']), + (0xf924, &['\u{8964}', '\u{FE00}']), + (0x2f96e, &['\u{7DC7}', '\u{FE00}']), + (0xf96d, &['\u{7701}', '\u{FE00}']), + (0xf95a, &['\u{8B80}', '\u{FE00}']), + (0x2f85c, &['\u{5906}', '\u{FE00}']), + (0xf92b, &['\u{72FC}', '\u{FE00}']), + (0xfac0, &['\u{8B8A}', '\u{FE00}']), + (0xfa8d, &['\u{63C4}', '\u{FE00}']), + (0x2f9d8, &['\u{27F2F}', '\u{FE00}']), + (0xf938, &['\u{9732}', '\u{FE00}']), + (0x2f821, &['\u{5246}', '\u{FE00}']), + (0xf9aa, &['\u{5BE7}', '\u{FE01}']), + (0xf9ce, &['\u{786B}', '\u{FE00}']), + (0xfa47, &['\u{6F22}', '\u{FE00}']), + (0x2f8aa, &['\u{617A}', '\u{FE00}']), + (0x2f918, &['\u{707D}', '\u{FE00}']), + (0x2f8ee, &['\u{3C18}', '\u{FE00}']), + (0xf96b, &['\u{53C3}', '\u{FE00}']), + (0xf909, &['\u{5951}', '\u{FE00}']), + (0x2f87f, &['\u{5D6B}', '\u{FE00}']), + (0xf908, &['\u{9F9C}', '\u{FE01}']), + (0xfa5d, &['\u{8279}', '\u{FE00}']), + (0xf9ac, &['\u{601C}', '\u{FE00}']), + (0x2f896, &['\u{38C7}', '\u{FE00}']), + (0x2f9b0, &['\u{26FB1}', '\u{FE00}']), + (0xf9a7, &['\u{7375}', '\u{FE00}']), + (0xf99d, &['\u{52A3}', '\u{FE00}']), + (0x2f957, &['\u{79EB}', '\u{FE00}']), + (0xf905, &['\u{4E32}', '\u{FE00}']), + (0x2f9bc, &['\u{8728}', '\u{FE00}']), + (0x2f8f9, &['\u{23AFA}', '\u{FE00}']), + (0x2f8b0, &['\u{61F2}', '\u{FE02}']), + (0x2f881, &['\u{5DE1}', '\u{FE00}']), + (0x2fa1b, &['\u{9F16}', '\u{FE00}']), + (0x2f9dd, &['\u{208DE}', '\u{FE00}']), + (0x2f9ed, &['\u{28BFA}', '\u{FE00}']), + (0x2f871, &['\u{21B18}', '\u{FE00}']), + (0x2f8ab, &['\u{618E}', '\u{FE02}']), + (0x2f812, &['\u{2051C}', '\u{FE00}']), + (0xf933, &['\u{76E7}', '\u{FE00}']), + (0xf9f2, &['\u{9C57}', '\u{FE00}']), + (0xf984, &['\u{6FFE}', '\u{FE00}']), + (0x2f90e, &['\u{6DF9}', '\u{FE00}']), + (0xfab2, &['\u{8005}', '\u{FE01}']), + (0xfa32, &['\u{514D}', '\u{FE00}']), + (0x2f96d, &['\u{4301}', '\u{FE00}']), + (0x2f9a7, &['\u{452B}', '\u{FE00}']), + (0xf94f, &['\u{7D2F}', '\u{FE00}']), + (0x2fa0f, &['\u{9D67}', '\u{FE00}']), + (0xf925, &['\u{62C9}', '\u{FE00}']), + (0xfa91, &['\u{6674}', '\u{FE01}']), + (0xf972, &['\u{6C88}', '\u{FE00}']), + (0xf90a, &['\u{91D1}', '\u{FE00}']), + (0xfa02, &['\u{62D3}', '\u{FE00}']), + (0xf92f, &['\u{52DE}', '\u{FE00}']), + (0xf9dd, &['\u{5229}', '\u{FE00}']), + (0xfa17, &['\u{76CA}', '\u{FE00}']), + (0xf93f, &['\u{9304}', '\u{FE00}']), + (0x2f898, &['\u{261DA}', '\u{FE00}']), + (0x2f907, &['\u{6D34}', '\u{FE00}']), + (0xf9ec, &['\u{6EBA}', '\u{FE00}']), + (0xf9e3, &['\u{6CE5}', '\u{FE00}']), + (0xfab5, &['\u{8779}', '\u{FE00}']), + (0xfa40, &['\u{61F2}', '\u{FE00}']), + (0x2f815, &['\u{518D}', '\u{FE00}']), + (0x2f9db, &['\u{8DBC}', '\u{FE00}']), + (0xf91e, &['\u{721B}', '\u{FE00}']), + (0xf92c, &['\u{90CE}', '\u{FE00}']), + (0x2f884, &['\u{5DFD}', '\u{FE00}']), + (0xfa46, &['\u{6E1A}', '\u{FE00}']), + (0x2f9b3, &['\u{8650}', '\u{FE00}']), + (0x2f85b, &['\u{58F7}', '\u{FE00}']), + (0xf9cd, &['\u{7559}', '\u{FE00}']), + (0xf93a, &['\u{9DFA}', '\u{FE00}']), + (0xf97e, &['\u{91CF}', '\u{FE00}']), + (0xfa3e, &['\u{6168}', '\u{FE00}']), + (0x2f9eb, &['\u{93F9}', '\u{FE00}']), + (0x2f8e2, &['\u{6885}', '\u{FE01}']), + (0x2f9b6, &['\u{8669}', '\u{FE00}']), + (0xf916, &['\u{70D9}', '\u{FE00}']), + (0x2f8de, &['\u{3B49}', '\u{FE00}']), + (0xf98f, &['\u{6190}', '\u{FE00}']), + (0xfa12, &['\u{6674}', '\u{FE00}']), + (0xfa44, &['\u{6885}', '\u{FE00}']), + (0xf981, &['\u{5973}', '\u{FE00}']), + (0x2f9dc, &['\u{8DF0}', '\u{FE00}']), + (0xf95c, &['\u{6A02}', '\u{FE01}']), + (0xf937, &['\u{8DEF}', '\u{FE00}']), + (0x2f87a, &['\u{5C8D}', '\u{FE00}']), + (0x2f903, &['\u{6D69}', '\u{FE00}']), + (0x2f9c5, &['\u{27667}', '\u{FE00}']), + (0x2f8cf, &['\u{6691}', '\u{FE01}']), + (0x2f909, &['\u{6E6E}', '\u{FE00}']), + (0x2f991, &['\u{829D}', '\u{FE00}']), + (0xfa65, &['\u{8D08}', '\u{FE00}']), + (0xfa73, &['\u{4F80}', '\u{FE00}']), + (0x2f88e, &['\u{5ECA}', '\u{FE01}']), + (0xf9ef, &['\u{7498}', '\u{FE00}']), + (0x2f9cb, &['\u{278AE}', '\u{FE00}']), + (0x2f9a3, &['\u{83DC}', '\u{FE00}']), + (0x2f99c, &['\u{8323}', '\u{FE00}']), + (0x2f919, &['\u{7077}', '\u{FE00}']), + (0x2f857, &['\u{5831}', '\u{FE00}']), + (0x2f96c, &['\u{7D63}', '\u{FE00}']), + (0x2f800, &['\u{4E3D}', '\u{FE00}']), + (0x2fa1a, &['\u{9F0F}', '\u{FE00}']), + (0xf97f, &['\u{52F5}', '\u{FE00}']), + (0xfaba, &['\u{8AF8}', '\u{FE01}']), + (0xfa82, &['\u{5ED2}', '\u{FE00}']), + (0x2f92e, &['\u{7447}', '\u{FE00}']), + (0xf9fe, &['\u{8336}', '\u{FE00}']), + (0xf994, &['\u{7489}', '\u{FE00}']), + (0x2f83c, &['\u{549E}', '\u{FE00}']), + (0xfa50, &['\u{7956}', '\u{FE00}']), + (0x2f817, &['\u{5197}', '\u{FE00}']), + (0xfa38, &['\u{5668}', '\u{FE00}']), + (0xfa69, &['\u{97FF}', '\u{FE00}']), + (0xfaac, &['\u{7AB1}', '\u{FE00}']), + (0xf901, &['\u{66F4}', '\u{FE00}']), + (0xfa33, &['\u{52C9}', '\u{FE00}']), + (0xf9bf, &['\u{6A02}', '\u{FE02}']), + (0xf9d1, &['\u{516D}', '\u{FE00}']), + (0xf95f, &['\u{5BE7}', '\u{FE00}']), + (0x2f82f, &['\u{5373}', '\u{FE00}']), + (0xf9a4, &['\u{637B}', '\u{FE00}']), + (0x2f89e, &['\u{5FD7}', '\u{FE00}']), + (0x2f801, &['\u{4E38}', '\u{FE00}']), + (0x2f84f, &['\u{5674}', '\u{FE00}']), + (0x2f961, &['\u{25BAB}', '\u{FE00}']), + (0x2f87e, &['\u{5D6E}', '\u{FE00}']), + (0x2f9d5, &['\u{8CC1}', '\u{FE00}']), + (0xf9e7, &['\u{88CF}', '\u{FE00}']), + (0xf973, &['\u{62FE}', '\u{FE00}']), + (0xf9c2, &['\u{84FC}', '\u{FE00}']), + (0x2f9d0, &['\u{8AED}', '\u{FE01}']), + (0xf9a5, &['\u{6BAE}', '\u{FE00}']), + (0x2f80c, &['\u{349E}', '\u{FE00}']), + (0xf930, &['\u{64C4}', '\u{FE00}']), + (0x2f8a1, &['\u{393A}', '\u{FE00}']), + (0x2f828, &['\u{52FA}', '\u{FE01}']), + (0x2f89f, &['\u{5FF9}', '\u{FE00}']), + (0xf964, &['\u{78FB}', '\u{FE00}']), + (0xf94e, &['\u{6F0F}', '\u{FE00}']), + (0x2f8d7, &['\u{43D9}', '\u{FE00}']), + (0x2f806, &['\u{4FBB}', '\u{FE00}']), + (0x2f9cc, &['\u{27966}', '\u{FE00}']), + (0x2f94e, &['\u{784E}', '\u{FE00}']), + (0x2f929, &['\u{738B}', '\u{FE00}']), + (0xfa34, &['\u{52E4}', '\u{FE00}']), + (0x2f939, &['\u{2219F}', '\u{FE00}']), + (0xf910, &['\u{863F}', '\u{FE00}']), + (0xf926, &['\u{81D8}', '\u{FE00}']), + (0xf9a2, &['\u{5EC9}', '\u{FE00}']), + (0xfa49, &['\u{722B}', '\u{FE00}']), + (0xf953, &['\u{808B}', '\u{FE00}']), + (0x2f80f, &['\u{5154}', '\u{FE00}']), + (0xf963, &['\u{5317}', '\u{FE00}']), + (0x2f8d4, &['\u{6700}', '\u{FE00}']), + (0xf9b2, &['\u{96F6}', '\u{FE00}']), + (0x2f973, &['\u{26247}', '\u{FE00}']), + (0x2f897, &['\u{232B8}', '\u{FE00}']), + (0x2f9fc, &['\u{4AB2}', '\u{FE00}']), + (0xf99a, &['\u{9023}', '\u{FE00}']), + (0x2f85a, &['\u{58F2}', '\u{FE00}']), + (0xfacf, &['\u{2284A}', '\u{FE00}']), + (0x2f9ab, &['\u{273CA}', '\u{FE00}']), + (0x2f927, &['\u{24814}', '\u{FE00}']), + (0x2f9fd, &['\u{29496}', '\u{FE00}']), + (0xfa36, &['\u{559D}', '\u{FE00}']), + (0xf904, &['\u{6ED1}', '\u{FE00}']), + (0x2f81c, &['\u{291DF}', '\u{FE00}']), + (0xfa7b, &['\u{55E2}', '\u{FE00}']), + (0xfa41, &['\u{654F}', '\u{FE00}']), + (0x2f87b, &['\u{21DE4}', '\u{FE00}']), + (0x2f9ba, &['\u{86E2}', '\u{FE00}']), + (0xf979, &['\u{51C9}', '\u{FE00}']), + (0xf9d7, &['\u{8F2A}', '\u{FE00}']), +]; + pub(crate) const COMPATIBILITY_DECOMPOSED_SALT: &[u16] = &[ 0x0, 0x0, diff --git a/tests/ext.rs b/tests/ext.rs new file mode 100644 index 0000000..8060aee --- /dev/null +++ b/tests/ext.rs @@ -0,0 +1,119 @@ +//! Test the extended versions of `nfd`, `nfc`, `nfkc`, and `nfkd`. + +use unicode_normalization::UnicodeNormalization; + +#[test] +fn test_standardized_variations_for_cjk_singleton_decompositions() { + // These codepoints have singleton decompositions in the canonical + // decomposition, and can use standardized variations in the extended + // decomposition. + let s = "\u{2f999}\u{2f8a6}"; + + let mut nfd_iter = s.chars().nfd(); + assert_eq!(nfd_iter.next(), Some('\u{831d}')); + assert_eq!(nfd_iter.next(), Some('\u{6148}')); + assert_eq!(nfd_iter.next(), None); + + let mut nfd_ext_iter = s.chars().nfd_ext(); + assert_eq!(nfd_ext_iter.next(), Some('\u{831d}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{fe00}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{6148}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{fe00}')); + assert_eq!(nfd_ext_iter.next(), None); + + let mut nfkd_iter = s.chars().nfkd(); + assert_eq!(nfkd_iter.next(), Some('\u{831d}')); + assert_eq!(nfkd_iter.next(), Some('\u{6148}')); + assert_eq!(nfkd_iter.next(), None); + + let mut nfkd_ext_iter = s.chars().nfkd_ext(); + assert_eq!(nfkd_ext_iter.next(), Some('\u{831d}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{fe00}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{6148}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{fe00}')); + assert_eq!(nfkd_ext_iter.next(), None); + + let mut nfc_iter = s.chars().nfc(); + assert_eq!(nfc_iter.next(), Some('\u{831d}')); + assert_eq!(nfc_iter.next(), Some('\u{6148}')); + assert_eq!(nfc_iter.next(), None); + + let mut nfc_ext_iter = s.chars().nfc_ext(); + assert_eq!(nfc_ext_iter.next(), Some('\u{831d}')); + assert_eq!(nfc_ext_iter.next(), Some('\u{fe00}')); + assert_eq!(nfc_ext_iter.next(), Some('\u{6148}')); + assert_eq!(nfc_ext_iter.next(), Some('\u{fe00}')); + assert_eq!(nfc_ext_iter.next(), None); + + let mut nfkc_iter = s.chars().nfkc(); + assert_eq!(nfkc_iter.next(), Some('\u{831d}')); + assert_eq!(nfkc_iter.next(), Some('\u{6148}')); + assert_eq!(nfkc_iter.next(), None); + + let mut nfkc_ext_iter = s.chars().nfkc_ext(); + assert_eq!(nfkc_ext_iter.next(), Some('\u{831d}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{fe00}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{6148}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{fe00}')); + assert_eq!(nfkc_ext_iter.next(), None); +} + +/// Test that the ext iterators incude the usual NFC/NFD/NFKC/NKFD normalizations. +#[test] +fn test_underlying_nfd_nfc_nfkd_nfkc() { + let s = "hi\u{212b}\u{4d}\u{3a9}\u{2156}\u{31}\u{2044}\u{33}"; + + let mut nfd_ext_iter = s.chars().nfd_ext(); + assert_eq!(nfd_ext_iter.next(), Some('h')); + assert_eq!(nfd_ext_iter.next(), Some('i')); + assert_eq!(nfd_ext_iter.next(), Some('\u{41}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{30a}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{4d}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{3a9}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{2156}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{31}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{2044}')); + assert_eq!(nfd_ext_iter.next(), Some('\u{33}')); + assert_eq!(nfd_ext_iter.next(), None); + + let mut nfkd_ext_iter = s.chars().nfkd_ext(); + assert_eq!(nfkd_ext_iter.next(), Some('h')); + assert_eq!(nfkd_ext_iter.next(), Some('i')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{41}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{30a}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{4d}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{3a9}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{32}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{2044}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{35}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{31}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{2044}')); + assert_eq!(nfkd_ext_iter.next(), Some('\u{33}')); + assert_eq!(nfkd_ext_iter.next(), None); + + let mut nfc_ext_iter = s.chars().nfc_ext(); + assert_eq!(nfc_ext_iter.next(), Some('h')); + assert_eq!(nfc_ext_iter.next(), Some('i')); + assert_eq!(nfc_ext_iter.next(), Some('\u{c5}')); + assert_eq!(nfc_ext_iter.next(), Some('\u{4d}')); + assert_eq!(nfc_ext_iter.next(), Some('\u{3a9}')); + assert_eq!(nfc_ext_iter.next(), Some('\u{2156}')); + assert_eq!(nfc_ext_iter.next(), Some('\u{31}')); + assert_eq!(nfc_ext_iter.next(), Some('\u{2044}')); + assert_eq!(nfc_ext_iter.next(), Some('\u{33}')); + assert_eq!(nfc_ext_iter.next(), None); + + let mut nfkc_ext_iter = s.chars().nfkc_ext(); + assert_eq!(nfkc_ext_iter.next(), Some('h')); + assert_eq!(nfkc_ext_iter.next(), Some('i')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{c5}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{4d}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{3a9}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{32}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{2044}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{35}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{31}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{2044}')); + assert_eq!(nfkc_ext_iter.next(), Some('\u{33}')); + assert_eq!(nfkc_ext_iter.next(), None); +}