Skip to main content

core/unicode/
unicode_data.rs

1//! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!
2// Alphabetic                  :  1723 bytes, 147369 codepoints in 759 ranges (U+0000AA - U+03347A) using skiplist
3// Case_Ignorable              :  1063 bytes,   2789 codepoints in 459 ranges (U+0000A8 - U+0E01F0) using skiplist
4// Cf                          :    87 bytes,    170 codepoints in  21 ranges (U+0000AD - U+0E0080) using skiplist
5// Cn_Planes_0_3               :  1677 bytes,  94165 codepoints in 730 ranges (U+000378 - U+03FFFE) using skiplist
6// Default_Ignorable_Code_Point:    83 bytes,   4174 codepoints in  17 ranges (U+0000AD - U+0E1000) using skiplist
7// Grapheme_Extend             :   899 bytes,   2232 codepoints in 383 ranges (U+000300 - U+0E01F0) using skiplist
8// Lowercase                   :   943 bytes,   2569 codepoints in 676 ranges (U+0000AA - U+01E944) using bitset
9// Lt                          :    33 bytes,     31 codepoints in  10 ranges (U+0001C5 - U+001FFD) using skiplist
10// N                           :   463 bytes,   1914 codepoints in 145 ranges (U+0000B2 - U+01FBFA) using skiplist
11// Uppercase                   :   799 bytes,   1980 codepoints in 659 ranges (U+0000C0 - U+01F18A) using bitset
12// White_Space                 :   256 bytes,     19 codepoints in   8 ranges (U+000085 - U+003001) using cascading
13// to_lower                    :  1112 bytes,   1462 codepoints in 185 ranges (U+0000C0 - U+01E921) using 2-level LUT
14// to_upper                    :  1998 bytes,   1554 codepoints in 299 ranges (U+0000B5 - U+01E943) using 2-level LUT
15// to_title                    :   340 bytes,    135 codepoints in  49 ranges (U+0000DF - U+00FB17) using 2-level LUT
16// to_casefold                 :    32 bytes,    174 codepoints in   5 ranges (U+000131 - U+00ABBF) using 2-level LUT
17// Total                       : 11508 bytes
18
19#[inline(always)]
20const fn bitset_search<
21    const N: usize,
22    const CHUNK_SIZE: usize,
23    const N1: usize,
24    const CANONICAL: usize,
25    const CANONICALIZED: usize,
26>(
27    needle: u32,
28    chunk_idx_map: &[u8; N],
29    bitset_chunk_idx: &[[u8; CHUNK_SIZE]; N1],
30    bitset_canonical: &[u64; CANONICAL],
31    bitset_canonicalized: &[(u8, u8); CANONICALIZED],
32) -> bool {
33    let bucket_idx = (needle / 64) as usize;
34    let chunk_map_idx = bucket_idx / CHUNK_SIZE;
35    let chunk_piece = bucket_idx % CHUNK_SIZE;
36    // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const.
37    let chunk_idx = if chunk_map_idx < chunk_idx_map.len() {
38        chunk_idx_map[chunk_map_idx]
39    } else {
40        return false;
41    };
42    let idx = bitset_chunk_idx[chunk_idx as usize][chunk_piece] as usize;
43    // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const.
44    let word = if idx < bitset_canonical.len() {
45        bitset_canonical[idx]
46    } else {
47        let (real_idx, mapping) = bitset_canonicalized[idx - bitset_canonical.len()];
48        let mut word = bitset_canonical[real_idx as usize];
49        let should_invert = mapping & (1 << 6) != 0;
50        if should_invert {
51            word = !word;
52        }
53        // Lower 6 bits
54        let quantity = mapping & ((1 << 6) - 1);
55        if mapping & (1 << 7) != 0 {
56            // shift
57            word >>= quantity as u64;
58        } else {
59            word = word.rotate_left(quantity as u32);
60        }
61        word
62    };
63    (word & (1 << (needle % 64) as u64)) != 0
64}
65
66#[repr(transparent)]
67struct ShortOffsetRunHeader(u32);
68
69impl ShortOffsetRunHeader {
70    const fn new(start_index: usize, prefix_sum: u32) -> Self {
71        assert!(start_index < (1 << 11));
72        assert!(prefix_sum < (1 << 21));
73
74        Self((start_index as u32) << 21 | prefix_sum)
75    }
76
77    #[inline]
78    const fn start_index(&self) -> usize {
79        (self.0 >> 21) as usize
80    }
81
82    #[inline]
83    const fn prefix_sum(&self) -> u32 {
84        self.0 & ((1 << 21) - 1)
85    }
86}
87
88/// # Safety
89///
90/// - The last element of `short_offset_runs` must be greater than `std::char::MAX`.
91/// - The start indices of all elements in `short_offset_runs` must be less than `OFFSETS`.
92#[inline(always)]
93unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
94    needle: char,
95    short_offset_runs: &[ShortOffsetRunHeader; SOR],
96    offsets: &[u8; OFFSETS],
97) -> bool {
98    let needle = needle as u32;
99
100    let last_idx =
101        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) {
102            Ok(idx) => idx + 1,
103            Err(idx) => idx,
104        };
105    // SAFETY: `last_idx` *cannot* be past the end of the array, as the last
106    // element is greater than `std::char::MAX` (the largest possible needle)
107    // as guaranteed by the caller.
108    //
109    // So, we cannot have found it (i.e. `Ok(idx) => idx + 1 != length`) and the
110    // correct location cannot be past it, so `Err(idx) => idx != length` either.
111    //
112    // This means that we can avoid bounds checking for the accesses below, too.
113    //
114    // We need to use `intrinsics::assume` since the `panic_nounwind` contained
115    // in `hint::assert_unchecked` may not be optimized out.
116    unsafe { crate::intrinsics::assume(last_idx < SOR) };
117
118    let mut offset_idx = short_offset_runs[last_idx].start_index();
119    let length = if let Some(next) = short_offset_runs.get(last_idx + 1) {
120        (*next).start_index() - offset_idx
121    } else {
122        offsets.len() - offset_idx
123    };
124
125    let prev =
126        last_idx.checked_sub(1).map(|prev| short_offset_runs[prev].prefix_sum()).unwrap_or(0);
127
128    let total = needle - prev;
129    let mut prefix_sum = 0;
130    for _ in 0..(length - 1) {
131        // SAFETY: It is guaranteed that `length <= OFFSETS - offset_idx`,
132        // so it follows that `length - 1 + offset_idx < OFFSETS`, therefore
133        // `offset_idx < OFFSETS` is always true in this loop.
134        //
135        // We need to use `intrinsics::assume` since the `panic_nounwind` contained
136        // in `hint::assert_unchecked` may not be optimized out.
137        unsafe { crate::intrinsics::assume(offset_idx < OFFSETS) };
138        let offset = offsets[offset_idx];
139        prefix_sum += offset as u32;
140        if prefix_sum > total {
141            break;
142        }
143        offset_idx += 1;
144    }
145    offset_idx % 2 == 1
146}
147
148pub const UNICODE_VERSION: (u8, u8, u8) = (17, 0, 0);
149
150#[rustfmt::skip]
151pub mod alphabetic {
152    use super::ShortOffsetRunHeader;
153
154    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 51] = [
155        ShortOffsetRunHeader::new(0, 706), ShortOffsetRunHeader::new(12, 4681),
156        ShortOffsetRunHeader::new(414, 5741), ShortOffsetRunHeader::new(452, 7958),
157        ShortOffsetRunHeader::new(552, 9398), ShortOffsetRunHeader::new(623, 11264),
158        ShortOffsetRunHeader::new(625, 12293), ShortOffsetRunHeader::new(663, 13312),
159        ShortOffsetRunHeader::new(687, 19904), ShortOffsetRunHeader::new(688, 42125),
160        ShortOffsetRunHeader::new(690, 42509), ShortOffsetRunHeader::new(694, 55204),
161        ShortOffsetRunHeader::new(778, 63744), ShortOffsetRunHeader::new(783, 64110),
162        ShortOffsetRunHeader::new(784, 64830), ShortOffsetRunHeader::new(806, 66176),
163        ShortOffsetRunHeader::new(847, 67383), ShortOffsetRunHeader::new(894, 73440),
164        ShortOffsetRunHeader::new(1217, 74650), ShortOffsetRunHeader::new(1228, 77712),
165        ShortOffsetRunHeader::new(1233, 78896), ShortOffsetRunHeader::new(1236, 82939),
166        ShortOffsetRunHeader::new(1240, 83527), ShortOffsetRunHeader::new(1242, 90368),
167        ShortOffsetRunHeader::new(1243, 92160), ShortOffsetRunHeader::new(1245, 92729),
168        ShortOffsetRunHeader::new(1246, 93504), ShortOffsetRunHeader::new(1261, 101590),
169        ShortOffsetRunHeader::new(1282, 110576), ShortOffsetRunHeader::new(1287, 110883),
170        ShortOffsetRunHeader::new(1294, 111356), ShortOffsetRunHeader::new(1304, 113664),
171        ShortOffsetRunHeader::new(1305, 119808), ShortOffsetRunHeader::new(1315, 120486),
172        ShortOffsetRunHeader::new(1352, 122624), ShortOffsetRunHeader::new(1375, 123536),
173        ShortOffsetRunHeader::new(1399, 124112), ShortOffsetRunHeader::new(1403, 126464),
174        ShortOffsetRunHeader::new(1431, 127280), ShortOffsetRunHeader::new(1497, 131072),
175        ShortOffsetRunHeader::new(1503, 173792), ShortOffsetRunHeader::new(1504, 178206),
176        ShortOffsetRunHeader::new(1506, 183982), ShortOffsetRunHeader::new(1508, 191457),
177        ShortOffsetRunHeader::new(1510, 192094), ShortOffsetRunHeader::new(1512, 194560),
178        ShortOffsetRunHeader::new(1513, 195102), ShortOffsetRunHeader::new(1514, 196608),
179        ShortOffsetRunHeader::new(1515, 201547), ShortOffsetRunHeader::new(1516, 210042),
180        ShortOffsetRunHeader::new(1518, 1324154),
181    ];
182    static OFFSETS: [u8; 1519] = [
183        170, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 0, 4, 12, 14, 5, 7, 1, 1, 1, 86, 1, 29, 18, 1, 2, 2,
184        4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 2, 1, 6, 41, 39, 14, 1, 1,
185        1, 2, 1, 2, 1, 1, 8, 27, 4, 4, 29, 11, 5, 56, 1, 7, 14, 102, 1, 8, 4, 8, 4, 3, 10, 3, 2, 1,
186        16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 5, 24, 1, 7, 7, 1, 8, 42,
187        10, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3, 4, 3, 8,
188        2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1, 2,
189        1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, 1, 5,
190        3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2,
191        2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, 3, 3, 12,
192        4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 13, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2, 1, 3, 1,
193        2, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 5, 3, 1, 4, 13, 3,
194        12, 13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, 24, 1, 9, 1,
195        1, 2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, 1, 1, 1, 19,
196        1, 3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 19, 4, 16, 1, 36, 67, 55, 1, 1, 2, 5,
197        16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1, 4, 2, 33,
198        1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, 0, 2, 17, 1, 26,
199        5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, 1, 4, 1, 67, 89,
200        7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, 63, 2, 20, 50, 1,
201        23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, 11, 14, 55, 22, 3, 10, 36, 2,
202        11, 5, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 19, 34, 11, 0, 2, 6, 2, 38, 2, 6, 2, 8, 1,
203        1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, 7, 116, 1,
204        13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 11, 2, 4, 5, 5,
205        4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1, 16, 23, 9, 7, 1,
206        7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2, 5, 4, 86, 6, 3,
207        1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, 46, 2, 0, 3, 16, 10, 2, 20, 47,
208        5, 8, 3, 113, 39, 9, 2, 103, 2, 82, 20, 21, 1, 33, 24, 52, 12, 68, 1, 1, 44, 6, 3, 1, 1, 3,
209        10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, 1, 55, 9, 14, 18, 23, 3, 69, 1,
210        1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1, 43, 1, 14, 6, 123, 21, 0, 12,
211        23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, 1, 1, 1, 2, 1, 2, 1, 108, 33, 0,
212        18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, 89, 3, 6, 2, 6, 2, 6, 2, 3, 35,
213        12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, 29, 3, 49, 47, 32, 13, 30, 5, 43,
214        5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, 8, 52, 12, 11, 1, 15, 1, 7, 1, 2,
215        1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, 6, 1, 42, 1, 9, 69, 6, 2, 1, 1,
216        44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, 10, 26, 6, 26, 38, 56, 6, 2, 64,
217        4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, 27, 54, 10, 22, 10, 19, 13, 18,
218        110, 73, 55, 51, 13, 51, 13, 40, 34, 28, 3, 1, 5, 23, 250, 42, 1, 2, 3, 2, 16, 6, 50, 3, 3,
219        29, 10, 1, 8, 22, 42, 18, 46, 21, 27, 23, 9, 70, 43, 5, 10, 57, 9, 1, 13, 25, 23, 51, 17, 4,
220        8, 35, 3, 1, 9, 64, 1, 4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 4, 62, 7, 1, 1, 1, 4,
221        1, 15, 1, 10, 7, 57, 23, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, 3, 1, 6,
222        1, 5, 7, 28, 10, 1, 1, 2, 1, 1, 38, 1, 10, 1, 1, 2, 1, 1, 4, 1, 2, 3, 1, 1, 1, 44, 66, 1, 3,
223        1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, 2, 1, 71,
224        27, 2, 14, 21, 7, 185, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, 4, 93, 8,
225        2, 46, 2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 18, 73, 103, 8, 88, 33, 31, 9, 1, 45,
226        1, 7, 1, 1, 49, 30, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, 6,
227        1, 2, 1, 37, 1, 2, 1, 4, 1, 1, 23, 44, 0, 23, 9, 17, 1, 41, 3, 3, 111, 1, 79, 0, 102, 111,
228        17, 196, 0, 97, 15, 0, 17, 6, 25, 0, 5, 0, 0, 47, 0, 0, 7, 31, 17, 79, 17, 30, 18, 48, 16,
229        4, 31, 21, 5, 19, 0, 45, 211, 64, 32, 25, 2, 25, 44, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 7,
230        9, 0, 41, 32, 97, 115, 0, 4, 1, 7, 1, 2, 1, 0, 15, 1, 29, 3, 2, 1, 14, 4, 8, 0, 0, 107, 5,
231        13, 3, 9, 7, 10, 4, 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4,
232        2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25,
233        1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 31, 6, 6, 213, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33,
234        1, 112, 45, 10, 7, 16, 1, 0, 30, 18, 44, 0, 28, 228, 30, 2, 1, 207, 31, 1, 22, 8, 2, 224, 7,
235        1, 4, 1, 2, 1, 15, 1, 197, 59, 68, 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4,
236        1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
237        1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0, 26, 6, 26, 6, 26, 0, 0,
238        32, 0, 2, 0, 2, 0, 15, 0, 0, 0, 0, 0, 5, 0, 0,
239    ];
240    #[inline]
241    pub fn lookup(c: char) -> bool {
242        debug_assert!(!c.is_ascii());
243        (c as u32) >= 0xaa && lookup_slow(c)
244    }
245
246    #[inline(never)]
247    fn lookup_slow(c: char) -> bool {
248        const {
249            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
250            let mut i = 0;
251            while i < SHORT_OFFSET_RUNS.len() {
252                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
253                i += 1;
254            }
255        }
256        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
257        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
258        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
259    }
260}
261
262#[rustfmt::skip]
263pub mod case_ignorable {
264    use super::ShortOffsetRunHeader;
265
266    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 36] = [
267        ShortOffsetRunHeader::new(0, 688), ShortOffsetRunHeader::new(11, 4957),
268        ShortOffsetRunHeader::new(263, 5906), ShortOffsetRunHeader::new(265, 8125),
269        ShortOffsetRunHeader::new(377, 11388), ShortOffsetRunHeader::new(411, 12293),
270        ShortOffsetRunHeader::new(423, 40981), ShortOffsetRunHeader::new(435, 42232),
271        ShortOffsetRunHeader::new(437, 42508), ShortOffsetRunHeader::new(439, 64286),
272        ShortOffsetRunHeader::new(535, 65024), ShortOffsetRunHeader::new(539, 66045),
273        ShortOffsetRunHeader::new(569, 67456), ShortOffsetRunHeader::new(575, 68097),
274        ShortOffsetRunHeader::new(581, 68900), ShortOffsetRunHeader::new(593, 69291),
275        ShortOffsetRunHeader::new(601, 71727), ShortOffsetRunHeader::new(727, 71995),
276        ShortOffsetRunHeader::new(731, 73459), ShortOffsetRunHeader::new(797, 78896),
277        ShortOffsetRunHeader::new(809, 90398), ShortOffsetRunHeader::new(813, 92912),
278        ShortOffsetRunHeader::new(817, 93504), ShortOffsetRunHeader::new(823, 94031),
279        ShortOffsetRunHeader::new(827, 110576), ShortOffsetRunHeader::new(837, 113821),
280        ShortOffsetRunHeader::new(843, 118528), ShortOffsetRunHeader::new(847, 119143),
281        ShortOffsetRunHeader::new(851, 121344), ShortOffsetRunHeader::new(861, 122880),
282        ShortOffsetRunHeader::new(873, 123566), ShortOffsetRunHeader::new(889, 124139),
283        ShortOffsetRunHeader::new(893, 125136), ShortOffsetRunHeader::new(907, 127995),
284        ShortOffsetRunHeader::new(911, 917505), ShortOffsetRunHeader::new(913, 2032112),
285    ];
286    static OFFSETS: [u8; 919] = [
287        168, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2, 1, 1, 251, 7, 207, 1, 5, 1, 49,
288        45, 1, 1, 1, 2, 1, 2, 1, 1, 44, 1, 11, 6, 10, 11, 1, 1, 35, 1, 10, 21, 16, 1, 101, 8, 1, 10,
289        1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24, 24, 43, 3, 44, 1, 7, 2, 5, 9, 41,
290        58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, 58, 1, 4, 4, 8, 1, 20, 2, 26, 1, 2,
291        2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6,
292        1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1, 61, 1, 12, 1, 50, 1, 3, 1, 55, 1, 1, 3,
293        5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, 5, 2, 20, 2, 28, 2, 57, 2, 4, 4, 8, 1,
294        20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, 98, 1, 2, 9, 9, 1, 1, 7, 73, 2, 27, 1,
295        1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3,
296        16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3, 29, 2, 30, 2, 30, 2, 64, 2, 1, 7, 8, 1,
297        2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, 219, 2, 2, 1, 58,
298        1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 46, 2, 12, 20, 4, 48, 1, 1, 5, 1, 1, 5, 1,
299        40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 64, 6, 82, 3, 1, 13,
300        1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1, 3, 11, 3, 13, 3, 13, 3, 13, 2, 12,
301        5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, 16, 13, 51, 33, 0, 2, 113, 3, 125, 1,
302        15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, 93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10,
303        1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 102, 4, 3, 2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151,
304        2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, 2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2,
305        12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5,
306        9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3, 1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6,
307        1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, 0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 9,
308        0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 38, 1, 26, 5, 1, 1, 0, 2, 24, 1, 52, 6, 70, 11,
309        49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, 1, 4, 1, 10, 1, 50, 3, 36, 5, 1,
310        8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57,
311        2, 3, 1, 37, 7, 3, 5, 70, 6, 13, 1, 1, 1, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1,
312        1, 4, 2, 1, 2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101,
313        1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4,
314        8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, 3, 1, 1, 201, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2,
315        1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 65, 1, 0, 2, 11, 2, 52, 5, 5, 1, 1,
316        1, 23, 1, 0, 17, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 9, 4, 0, 3, 40, 2, 0, 1, 63, 17, 64, 2, 1,
317        2, 13, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, 0, 46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3, 0,
318        55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 5, 62, 33, 1, 160, 14,
319        0, 1, 61, 4, 0, 5, 254, 2, 243, 1, 2, 1, 7, 2, 5, 1, 9, 1, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96,
320        128, 240, 0,
321    ];
322    #[inline]
323    pub fn lookup(c: char) -> bool {
324        debug_assert!(!c.is_ascii());
325        (c as u32) >= 0xa8 && lookup_slow(c)
326    }
327
328    #[inline(never)]
329    fn lookup_slow(c: char) -> bool {
330        const {
331            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
332            let mut i = 0;
333            while i < SHORT_OFFSET_RUNS.len() {
334                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
335                i += 1;
336            }
337        }
338        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
339        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
340        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
341    }
342}
343
344#[rustfmt::skip]
345pub mod cf {
346    use super::ShortOffsetRunHeader;
347
348    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 11] = [
349        ShortOffsetRunHeader::new(0, 1536), ShortOffsetRunHeader::new(3, 2192),
350        ShortOffsetRunHeader::new(11, 6158), ShortOffsetRunHeader::new(15, 8203),
351        ShortOffsetRunHeader::new(17, 65279), ShortOffsetRunHeader::new(25, 69821),
352        ShortOffsetRunHeader::new(29, 78896), ShortOffsetRunHeader::new(33, 113824),
353        ShortOffsetRunHeader::new(35, 119155), ShortOffsetRunHeader::new(37, 917505),
354        ShortOffsetRunHeader::new(39, 2031744),
355    ];
356    static OFFSETS: [u8; 43] = [
357        173, 1, 0, 6, 22, 1, 192, 1, 49, 1, 0, 2, 80, 1, 0, 1, 0, 5, 26, 5, 49, 5, 1, 10, 0, 1,
358        249, 3, 0, 1, 15, 1, 0, 16, 0, 4, 0, 8, 0, 1, 30, 96, 0,
359    ];
360    #[inline]
361    pub fn lookup(c: char) -> bool {
362        debug_assert!(!c.is_ascii());
363        (c as u32) >= 0xad && lookup_slow(c)
364    }
365
366    #[inline(never)]
367    fn lookup_slow(c: char) -> bool {
368        const {
369            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
370            let mut i = 0;
371            while i < SHORT_OFFSET_RUNS.len() {
372                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
373                i += 1;
374            }
375        }
376        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
377        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
378        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
379    }
380}
381
382#[rustfmt::skip]
383pub mod cn_planes_0_3 {
384    use super::ShortOffsetRunHeader;
385
386    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 54] = [
387        ShortOffsetRunHeader::new(0, 888), ShortOffsetRunHeader::new(1, 1328),
388        ShortOffsetRunHeader::new(11, 1806), ShortOffsetRunHeader::new(25, 4681),
389        ShortOffsetRunHeader::new(325, 5789), ShortOffsetRunHeader::new(365, 7958),
390        ShortOffsetRunHeader::new(445, 9258), ShortOffsetRunHeader::new(491, 11124),
391        ShortOffsetRunHeader::new(495, 11508), ShortOffsetRunHeader::new(497, 42125),
392        ShortOffsetRunHeader::new(549, 42540), ShortOffsetRunHeader::new(553, 55204),
393        ShortOffsetRunHeader::new(605, 64110), ShortOffsetRunHeader::new(611, 64976),
394        ShortOffsetRunHeader::new(629, 67383), ShortOffsetRunHeader::new(735, 74650),
395        ShortOffsetRunHeader::new(1067, 77712), ShortOffsetRunHeader::new(1074, 78934),
396        ShortOffsetRunHeader::new(1077, 82939), ShortOffsetRunHeader::new(1079, 83527),
397        ShortOffsetRunHeader::new(1081, 90368), ShortOffsetRunHeader::new(1082, 92160),
398        ShortOffsetRunHeader::new(1084, 92729), ShortOffsetRunHeader::new(1085, 93504),
399        ShortOffsetRunHeader::new(1108, 101590), ShortOffsetRunHeader::new(1127, 110576),
400        ShortOffsetRunHeader::new(1132, 110883), ShortOffsetRunHeader::new(1139, 111356),
401        ShortOffsetRunHeader::new(1149, 113664), ShortOffsetRunHeader::new(1150, 117760),
402        ShortOffsetRunHeader::new(1160, 118452), ShortOffsetRunHeader::new(1163, 120486),
403        ShortOffsetRunHeader::new(1227, 120780), ShortOffsetRunHeader::new(1229, 121484),
404        ShortOffsetRunHeader::new(1231, 122624), ShortOffsetRunHeader::new(1236, 123536),
405        ShortOffsetRunHeader::new(1262, 124112), ShortOffsetRunHeader::new(1268, 126065),
406        ShortOffsetRunHeader::new(1298, 126976), ShortOffsetRunHeader::new(1370, 128729),
407        ShortOffsetRunHeader::new(1395, 129624), ShortOffsetRunHeader::new(1423, 131072),
408        ShortOffsetRunHeader::new(1444, 173792), ShortOffsetRunHeader::new(1445, 178206),
409        ShortOffsetRunHeader::new(1447, 183982), ShortOffsetRunHeader::new(1449, 191457),
410        ShortOffsetRunHeader::new(1451, 192094), ShortOffsetRunHeader::new(1453, 194560),
411        ShortOffsetRunHeader::new(1454, 195102), ShortOffsetRunHeader::new(1455, 196608),
412        ShortOffsetRunHeader::new(1456, 201547), ShortOffsetRunHeader::new(1457, 210042),
413        ShortOffsetRunHeader::new(1459, 262142), ShortOffsetRunHeader::new(1460, 1376254),
414    ];
415    static OFFSETS: [u8; 1461] = [
416        0, 2, 6, 4, 7, 1, 1, 1, 20, 1, 0, 1, 38, 2, 50, 2, 3, 1, 55, 8, 27, 4, 6, 11, 0, 1, 60, 2,
417        101, 14, 59, 2, 49, 2, 15, 1, 28, 2, 1, 1, 11, 5, 34, 5, 237, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1,
418        3, 4, 2, 9, 2, 2, 2, 4, 8, 1, 4, 2, 1, 5, 2, 25, 2, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1, 2,
419        1, 2, 2, 1, 1, 5, 4, 2, 2, 3, 3, 1, 7, 4, 1, 1, 7, 17, 10, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2,
420        1, 5, 2, 10, 1, 3, 1, 3, 2, 1, 15, 4, 2, 12, 7, 7, 1, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1,
421        5, 2, 9, 2, 2, 2, 3, 7, 3, 4, 2, 1, 5, 2, 18, 10, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3,
422        2, 3, 3, 3, 12, 4, 5, 3, 3, 1, 4, 2, 1, 6, 1, 14, 21, 5, 13, 1, 3, 1, 23, 1, 16, 2, 9, 1, 3,
423        1, 4, 7, 2, 1, 3, 1, 2, 2, 4, 2, 10, 7, 22, 1, 3, 1, 23, 1, 10, 1, 5, 2, 9, 1, 3, 1, 4, 7,
424        2, 5, 3, 1, 4, 2, 10, 1, 3, 12, 13, 1, 3, 1, 51, 1, 3, 1, 6, 4, 16, 2, 26, 1, 3, 1, 18, 3,
425        24, 1, 9, 1, 1, 2, 7, 3, 1, 4, 6, 1, 1, 1, 8, 6, 10, 2, 3, 12, 58, 4, 29, 37, 2, 1, 1, 1, 5,
426        1, 24, 1, 1, 1, 23, 2, 5, 1, 1, 1, 7, 1, 10, 2, 4, 32, 72, 1, 36, 4, 39, 1, 36, 1, 15, 1,
427        13, 37, 198, 1, 1, 5, 1, 2, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1, 4, 2, 33, 1, 4, 2, 7, 1, 1,
428        1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 2, 32, 3, 26, 6, 86, 2, 6, 2, 0, 3, 89, 7, 22, 9, 24, 9,
429        20, 12, 13, 1, 3, 1, 2, 12, 94, 2, 10, 6, 10, 6, 26, 6, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4,
430        12, 4, 1, 3, 42, 2, 5, 11, 44, 4, 26, 6, 11, 3, 62, 2, 65, 1, 29, 2, 11, 6, 10, 6, 14, 2,
431        46, 2, 12, 20, 77, 1, 166, 8, 60, 3, 15, 3, 62, 5, 43, 2, 11, 8, 43, 5, 0, 2, 6, 2, 38, 2,
432        6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 15, 1, 14, 2, 6, 1, 19, 2, 3, 1, 9, 1, 101, 1,
433        12, 2, 27, 1, 13, 3, 34, 14, 33, 15, 140, 4, 0, 22, 11, 21, 0, 2, 0, 5, 45, 1, 1, 5, 1, 2,
434        56, 7, 2, 14, 24, 9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 126, 34, 26, 1, 89, 12,
435        214, 26, 80, 1, 86, 2, 103, 5, 43, 1, 94, 1, 86, 9, 48, 1, 0, 3, 55, 9, 0, 20, 184, 8, 221,
436        20, 60, 3, 10, 6, 56, 8, 70, 8, 12, 6, 116, 11, 30, 3, 78, 1, 11, 4, 33, 1, 55, 9, 14, 2,
437        10, 2, 103, 24, 28, 10, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1, 60, 4, 126, 2, 10, 6, 0, 12, 23, 4,
438        49, 4, 0, 2, 106, 38, 7, 12, 5, 5, 26, 1, 5, 1, 1, 1, 2, 1, 2, 1, 0, 32, 42, 6, 51, 1, 19,
439        1, 4, 4, 5, 1, 135, 2, 1, 1, 190, 3, 6, 2, 6, 2, 6, 2, 3, 3, 7, 1, 7, 10, 5, 2, 12, 1, 26,
440        1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 5, 3, 4, 45, 3, 88, 1, 13, 3, 1, 47, 46, 130, 29, 3, 49,
441        15, 28, 4, 36, 9, 30, 5, 43, 5, 30, 1, 37, 4, 14, 42, 158, 2, 10, 6, 36, 4, 36, 4, 40, 8,
442        52, 11, 12, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 3, 52, 12, 0, 9, 22, 10, 8, 24, 6,
443        1, 42, 1, 9, 69, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 1, 72, 8, 9, 48, 19, 1, 2, 5, 33, 3, 27,
444        5, 27, 38, 56, 4, 20, 2, 50, 1, 2, 5, 8, 1, 3, 1, 29, 2, 3, 4, 10, 7, 9, 7, 64, 32, 39, 4,
445        12, 9, 54, 3, 29, 2, 27, 5, 26, 7, 4, 12, 7, 80, 73, 55, 51, 13, 51, 7, 46, 8, 10, 6, 38, 3,
446        29, 8, 2, 208, 31, 1, 42, 1, 3, 2, 2, 16, 6, 8, 9, 33, 46, 8, 42, 22, 26, 38, 28, 20, 23, 9,
447        78, 4, 36, 9, 68, 10, 1, 2, 25, 7, 10, 6, 53, 1, 18, 8, 39, 9, 96, 1, 20, 11, 18, 1, 47, 62,
448        7, 1, 1, 1, 4, 1, 15, 1, 11, 6, 59, 5, 10, 6, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 1, 10,
449        2, 2, 2, 3, 2, 1, 6, 1, 5, 7, 2, 7, 3, 5, 11, 10, 1, 1, 2, 1, 1, 38, 1, 10, 1, 1, 2, 1, 1,
450        4, 1, 10, 1, 2, 8, 2, 29, 92, 1, 5, 30, 72, 8, 10, 166, 54, 2, 38, 34, 69, 11, 10, 6, 13,
451        19, 58, 6, 10, 6, 20, 28, 27, 2, 15, 4, 23, 185, 60, 100, 83, 12, 8, 2, 1, 2, 8, 1, 2, 1,
452        30, 1, 2, 2, 12, 9, 10, 70, 8, 2, 46, 2, 11, 27, 72, 8, 83, 13, 73, 7, 10, 86, 8, 88, 34,
453        14, 10, 6, 9, 1, 45, 1, 14, 10, 29, 3, 32, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1,
454        9, 8, 10, 6, 6, 1, 2, 1, 37, 1, 2, 1, 6, 7, 10, 6, 44, 4, 10, 246, 25, 7, 17, 1, 41, 3, 29,
455        85, 1, 15, 50, 13, 0, 102, 111, 1, 5, 11, 196, 0, 99, 13, 0, 10, 0, 5, 0, 0, 58, 0, 0, 7,
456        31, 1, 10, 4, 81, 1, 10, 6, 30, 2, 6, 10, 70, 10, 10, 1, 7, 1, 21, 5, 19, 0, 58, 198, 91, 5,
457        25, 2, 25, 44, 75, 4, 57, 7, 17, 64, 5, 11, 7, 9, 0, 41, 32, 97, 115, 0, 4, 1, 7, 1, 2, 1,
458        0, 15, 1, 29, 3, 2, 1, 14, 4, 8, 0, 0, 107, 5, 13, 3, 9, 7, 10, 2, 8, 0, 253, 3, 0, 6, 23,
459        15, 17, 15, 46, 2, 23, 9, 116, 60, 246, 10, 39, 2, 194, 21, 70, 122, 20, 12, 20, 12, 87, 9,
460        25, 135, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1,
461        28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 0, 2, 0, 15, 5, 1, 15, 0, 31, 6, 6, 213, 7, 1, 17, 2,
462        7, 1, 2, 1, 5, 5, 62, 33, 1, 112, 45, 3, 14, 2, 10, 4, 2, 0, 31, 17, 58, 5, 1, 0, 42, 214,
463        43, 4, 1, 192, 31, 1, 22, 8, 2, 224, 7, 1, 4, 1, 2, 1, 15, 1, 197, 2, 16, 41, 76, 4, 10, 4,
464        2, 0, 68, 76, 61, 194, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4, 1, 1,
465        1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4, 1, 4,
466        1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 52, 2, 0, 44, 4, 100, 12, 15, 2, 15, 1, 15, 1, 37,
467        10, 174, 56, 29, 13, 44, 4, 9, 7, 2, 14, 6, 154, 0, 3, 17, 3, 13, 3, 218, 6, 12, 4, 1, 15,
468        12, 4, 56, 8, 10, 6, 40, 8, 30, 2, 12, 4, 2, 14, 9, 39, 0, 8, 14, 2, 13, 3, 11, 3, 57, 1, 1,
469        4, 16, 2, 12, 4, 10, 7, 147, 1, 103, 0, 0, 32, 0, 2, 0, 2, 0, 15, 0, 0, 0, 0, 0, 5, 0, 0, 0,
470    ];
471    #[inline]
472    pub fn lookup(c: char) -> bool {
473        debug_assert!(!c.is_ascii());
474        (c as u32) >= 0x378 && lookup_slow(c)
475    }
476
477    #[inline(never)]
478    fn lookup_slow(c: char) -> bool {
479        const {
480            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
481            let mut i = 0;
482            while i < SHORT_OFFSET_RUNS.len() {
483                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
484                i += 1;
485            }
486        }
487        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
488        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
489        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
490    }
491}
492
493#[rustfmt::skip]
494pub mod default_ignorable_code_point {
495    use super::ShortOffsetRunHeader;
496
497    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 12] = [
498        ShortOffsetRunHeader::new(0, 847), ShortOffsetRunHeader::new(3, 1564),
499        ShortOffsetRunHeader::new(5, 4447), ShortOffsetRunHeader::new(7, 6068),
500        ShortOffsetRunHeader::new(9, 8203), ShortOffsetRunHeader::new(13, 12644),
501        ShortOffsetRunHeader::new(19, 65024), ShortOffsetRunHeader::new(21, 113824),
502        ShortOffsetRunHeader::new(29, 119155), ShortOffsetRunHeader::new(31, 917504),
503        ShortOffsetRunHeader::new(33, 921600), ShortOffsetRunHeader::new(34, 2035712),
504    ];
505    static OFFSETS: [u8; 35] = [
506        173, 1, 0, 1, 0, 1, 0, 2, 0, 2, 85, 5, 0, 5, 26, 5, 49, 16, 0, 1, 0, 16, 239, 1, 160, 1,
507        79, 9, 0, 4, 0, 8, 0, 0, 0,
508    ];
509    #[inline]
510    pub fn lookup(c: char) -> bool {
511        debug_assert!(!c.is_ascii());
512        (c as u32) >= 0xad && lookup_slow(c)
513    }
514
515    #[inline(never)]
516    fn lookup_slow(c: char) -> bool {
517        const {
518            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
519            let mut i = 0;
520            while i < SHORT_OFFSET_RUNS.len() {
521                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
522                i += 1;
523            }
524        }
525        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
526        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
527        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
528    }
529}
530
531#[rustfmt::skip]
532pub mod grapheme_extend {
533    use super::ShortOffsetRunHeader;
534
535    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 33] = [
536        ShortOffsetRunHeader::new(0, 768), ShortOffsetRunHeader::new(1, 1155),
537        ShortOffsetRunHeader::new(3, 1425), ShortOffsetRunHeader::new(5, 4957),
538        ShortOffsetRunHeader::new(249, 5906), ShortOffsetRunHeader::new(251, 8204),
539        ShortOffsetRunHeader::new(347, 11503), ShortOffsetRunHeader::new(351, 12330),
540        ShortOffsetRunHeader::new(357, 42607), ShortOffsetRunHeader::new(361, 43010),
541        ShortOffsetRunHeader::new(369, 64286), ShortOffsetRunHeader::new(435, 65024),
542        ShortOffsetRunHeader::new(437, 65438), ShortOffsetRunHeader::new(441, 66045),
543        ShortOffsetRunHeader::new(443, 68097), ShortOffsetRunHeader::new(449, 68900),
544        ShortOffsetRunHeader::new(461, 69291), ShortOffsetRunHeader::new(465, 71727),
545        ShortOffsetRunHeader::new(601, 73459), ShortOffsetRunHeader::new(669, 78912),
546        ShortOffsetRunHeader::new(679, 90398), ShortOffsetRunHeader::new(683, 92912),
547        ShortOffsetRunHeader::new(687, 94031), ShortOffsetRunHeader::new(691, 113821),
548        ShortOffsetRunHeader::new(699, 118528), ShortOffsetRunHeader::new(701, 119141),
549        ShortOffsetRunHeader::new(705, 121344), ShortOffsetRunHeader::new(717, 122880),
550        ShortOffsetRunHeader::new(729, 123566), ShortOffsetRunHeader::new(743, 124140),
551        ShortOffsetRunHeader::new(747, 125136), ShortOffsetRunHeader::new(759, 917536),
552        ShortOffsetRunHeader::new(763, 2032112),
553    ];
554    static OFFSETS: [u8; 767] = [
555        0, 112, 0, 7, 0, 45, 1, 1, 1, 2, 1, 2, 1, 1, 72, 11, 48, 21, 16, 1, 101, 7, 2, 6, 2, 2, 1,
556        4, 35, 1, 30, 27, 91, 11, 58, 9, 9, 1, 24, 4, 1, 9, 1, 3, 1, 5, 43, 3, 59, 9, 42, 24, 1, 32,
557        55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 29, 1, 58, 1, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 26, 1, 2,
558        2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6,
559        1, 1, 58, 1, 1, 2, 1, 4, 8, 1, 7, 3, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, 3, 1,
560        55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 2, 1, 1, 3, 3, 1, 4, 7, 2, 11, 2, 28,
561        2, 57, 2, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, 1, 2, 7,
562        12, 8, 98, 1, 2, 9, 11, 7, 73, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1,
563        102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 0, 3, 0, 4, 28, 3,
564        29, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 9, 1, 45, 3, 1, 1, 117, 2, 34, 1, 118, 3, 4, 2, 9,
565        1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 46, 2, 12, 20, 4, 48,
566        10, 4, 3, 38, 9, 12, 2, 32, 4, 2, 6, 56, 1, 1, 2, 3, 1, 1, 5, 56, 8, 2, 2, 152, 3, 1, 13, 1,
567        7, 4, 1, 6, 1, 3, 2, 198, 64, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, 2, 0, 4, 1,
568        10, 32, 2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 1, 1,
569        44, 3, 48, 1, 2, 4, 2, 2, 2, 1, 36, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, 51, 1, 1, 3,
570        2, 2, 5, 2, 1, 1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, 0, 1, 226, 1,
571        149, 5, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 65, 5, 0, 2, 77, 6, 70, 11, 49, 4, 123,
572        1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 7, 1, 61, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9,
573        1, 1, 8, 4, 2, 1, 95, 3, 2, 4, 6, 1, 2, 1, 157, 1, 3, 8, 21, 2, 57, 2, 1, 1, 1, 1, 12, 1, 9,
574        1, 14, 7, 3, 5, 67, 1, 2, 6, 1, 1, 2, 1, 1, 3, 4, 3, 1, 1, 14, 2, 85, 8, 2, 3, 1, 1, 23, 1,
575        81, 1, 2, 6, 1, 1, 2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2,
576        106, 1, 1, 1, 2, 8, 101, 1, 1, 1, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 4, 4, 1, 144, 4, 2, 2,
577        4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 198, 1, 1, 3, 1, 1, 201, 7, 1, 6,
578        1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 11,
579        2, 52, 5, 5, 3, 23, 1, 0, 1, 6, 15, 0, 12, 3, 3, 0, 5, 59, 7, 0, 1, 63, 4, 81, 1, 11, 2, 0,
580        2, 0, 46, 2, 23, 0, 5, 3, 6, 8, 8, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1,
581        15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 100, 1, 160, 7, 0, 1, 61, 4, 0, 4, 254, 2, 243, 1, 2, 1,
582        7, 2, 5, 1, 0, 7, 109, 7, 0, 96, 128, 240, 0,
583    ];
584    #[inline]
585    pub fn lookup(c: char) -> bool {
586        debug_assert!(!c.is_ascii());
587        (c as u32) >= 0x300 && lookup_slow(c)
588    }
589
590    #[inline(never)]
591    fn lookup_slow(c: char) -> bool {
592        const {
593            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
594            let mut i = 0;
595            while i < SHORT_OFFSET_RUNS.len() {
596                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
597                i += 1;
598            }
599        }
600        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
601        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
602        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
603    }
604}
605
606#[rustfmt::skip]
607pub mod lowercase {
608    static BITSET_CHUNKS_MAP: [u8; 123] = [
609        12, 17, 0, 0, 9, 0, 0, 13, 14, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
610        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
611        0, 0, 0, 4, 1, 0, 15, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
612        0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0,
613        3, 18, 0, 7,
614    ];
615    static BITSET_INDEX_CHUNKS: [[u8; 16]; 20] = [
616        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
617        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0],
618        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 57, 0],
619        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0],
620        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, 0],
621        [0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 19, 62, 0, 0, 0, 0],
622        [0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 44, 0, 53, 49, 51, 34],
623        [0, 0, 0, 0, 9, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
624        [0, 0, 0, 3, 0, 16, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0],
625        [0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28],
626        [0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
627        [0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
628        [0, 0, 35, 17, 24, 54, 55, 50, 48, 7, 36, 43, 0, 29, 12, 32],
629        [0, 0, 47, 0, 57, 57, 57, 0, 23, 23, 71, 23, 37, 26, 25, 38],
630        [0, 5, 72, 0, 30, 15, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0],
631        [10, 61, 0, 6, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 33, 0],
632        [16, 27, 23, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
633        [16, 52, 2, 22, 70, 8, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0],
634        [16, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
635        [67, 42, 56, 11, 68, 65, 18, 13, 1, 66, 78, 21, 75, 76, 4, 46],
636    ];
637    static BITSET_CANONICAL: [u64; 57] = [
638        0b0000000000000000000000000000000000000000000000000000000000000000,
639        0b0000111111111111111111111111110000000000000000000000000011111111,
640        0b1010101010101010101010101010101010101010101010101010100000000010,
641        0b0000000000000111111111111111111111111111111111111111111111111111,
642        0b1111111111111111111111000000000000000000000000001111110111111111,
643        0b1000000000000010000000000000000000000000000000000000000000000000,
644        0b0000111111111111111111111111111111111111000000000000000000000000,
645        0b1111111111111111111111111111111111111111111111111010101010000101,
646        0b1111111111111111111111111111111100000000000000000000000000000000,
647        0b1111111111111111111111111111110000000000000000000000000000000000,
648        0b1111111111111111111111110000000000000000000000000000000000000000,
649        0b1111111111111111111111000000000000000000000000001111111111101111,
650        0b1111111111111111111100000000000000000000000000010000000000000000,
651        0b1111111111111111110000000000000000000000000011111111111111111111,
652        0b1111111111111111000000111111111111110111111111111111111111111111,
653        0b1111111111111111000000000000000000000000000000000100001111000000,
654        0b1111111111111111000000000000000000000000000000000000000000000000,
655        0b1111111101111111111111111111111110000000000000000000000000000000,
656        0b1111110000000000000000000000000011111111111111111111111111000000,
657        0b1111100000000000000000000000000000000000000000000000000000000000,
658        0b1111011111111111111111111111111111111111111111110000000000000000,
659        0b1111000000000000000000000000001111110111111111111111111111111100,
660        0b1010101010101010101010101010101010101010101010101101010101010100,
661        0b1010101010101010101010101010101010101010101010101010101010101010,
662        0b0101010110101010101010101010101010101010101010101010101010101010,
663        0b0100000011011111000000001111111100000000111111110000000011111111,
664        0b0011111111111111000000001111111100000000111111110000000000111111,
665        0b0011111111011010000101010110001011111111111111111111111111111111,
666        0b0011111100000000000000000000000000000000000000000000000000000000,
667        0b0011110010001010000000000000000000000000000000000000000000100000,
668        0b0011001000010000100000000000000000000000000010001100010000000000,
669        0b0001101111111011111111111111101111111111100000000000000000000000,
670        0b0001100100101111101010101010101010101010111000110111111111111111,
671        0b0000011111111101111111111111111111111111111111111111111110111001,
672        0b0000011101011110000000000000000000001010101010101010010100001010,
673        0b0000010000100000000001000000000000000000000000000000000000000000,
674        0b0000000111111111111111111111111111111111110011111111111111111111,
675        0b0000000011111111000000001111111100000000001111110000000011111111,
676        0b0000000011011100000000001111111100000000110011110000000011011100,
677        0b0000000000001000010100000001101010101010101010101010101010101010,
678        0b0000000000000000001000001011111111111111111111111111111111111111,
679        0b0000000000000000000001111110000001111111111111111111101111111111,
680        0b0000000000000000000000001111111111111111110111111100000000000000,
681        0b0000000000000000000000000001111100000000000000000000000000000011,
682        0b0000000000000000000000000000000000111010101010101010101010101010,
683        0b0000000000000000000000000000000000000000111110000000000001111111,
684        0b0000000000000000000000000000000000000000000000000000101111110111,
685        0b0000000000000000000000000000000000000000000000000000010111111111,
686        0b1001001111111010101010101010101010101010101010101010101010101010,
687        0b1001010111111111101010101010101010101010101010101010101010101010,
688        0b1010101000101001101010101010101010110101010101010101001001000000,
689        0b1010101010100000100000101010101010101010101110100101000010101010,
690        0b1010101010101010101010101010101011111111111111111111111111111111,
691        0b1010101010101011101010101010100000000000000000000000000000000000,
692        0b1101010010101010101010101010101010101010101010101010101101010101,
693        0b1110011001010001001011010010101001001110001001000011000100101001,
694        0b1110101111000000000000000000000000001111111111111111111111111100,
695    ];
696    static BITSET_MAPPING: [(u8, u8); 22] = [
697        (0, 64), (1, 184), (1, 182), (1, 179), (1, 172), (1, 168), (1, 161), (1, 146), (1, 144),
698        (1, 140), (1, 136), (1, 132), (2, 146), (2, 144), (2, 83), (3, 93), (3, 147), (3, 133),
699        (4, 12), (4, 6), (5, 187), (6, 78),
700    ];
701
702    pub const fn lookup(c: char) -> bool {
703        debug_assert!(!c.is_ascii());
704        (c as u32) >= 0xaa &&
705        super::bitset_search(
706            c as u32,
707            &BITSET_CHUNKS_MAP,
708            &BITSET_INDEX_CHUNKS,
709            &BITSET_CANONICAL,
710            &BITSET_MAPPING,
711        )
712    }
713}
714
715#[rustfmt::skip]
716pub mod lt {
717    use super::ShortOffsetRunHeader;
718
719    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 3] = [
720        ShortOffsetRunHeader::new(0, 453), ShortOffsetRunHeader::new(1, 8072),
721        ShortOffsetRunHeader::new(9, 1122301),
722    ];
723    static OFFSETS: [u8; 21] = [
724        0, 1, 2, 1, 2, 1, 38, 1, 0, 8, 8, 8, 8, 8, 12, 1, 15, 1, 47, 1, 0,
725    ];
726    #[inline]
727    pub fn lookup(c: char) -> bool {
728        debug_assert!(!c.is_ascii());
729        (c as u32) >= 0x1c5 && lookup_slow(c)
730    }
731
732    #[inline(never)]
733    fn lookup_slow(c: char) -> bool {
734        const {
735            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
736            let mut i = 0;
737            while i < SHORT_OFFSET_RUNS.len() {
738                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
739                i += 1;
740            }
741        }
742        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
743        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
744        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
745    }
746}
747
748#[rustfmt::skip]
749pub mod n {
750    use super::ShortOffsetRunHeader;
751
752    static SHORT_OFFSET_RUNS: [ShortOffsetRunHeader; 43] = [
753        ShortOffsetRunHeader::new(0, 1632), ShortOffsetRunHeader::new(7, 2406),
754        ShortOffsetRunHeader::new(13, 4160), ShortOffsetRunHeader::new(47, 4969),
755        ShortOffsetRunHeader::new(51, 5870), ShortOffsetRunHeader::new(53, 6470),
756        ShortOffsetRunHeader::new(61, 8304), ShortOffsetRunHeader::new(77, 9312),
757        ShortOffsetRunHeader::new(87, 10102), ShortOffsetRunHeader::new(91, 11517),
758        ShortOffsetRunHeader::new(93, 12295), ShortOffsetRunHeader::new(95, 12690),
759        ShortOffsetRunHeader::new(101, 42528), ShortOffsetRunHeader::new(113, 43056),
760        ShortOffsetRunHeader::new(117, 44016), ShortOffsetRunHeader::new(129, 65296),
761        ShortOffsetRunHeader::new(131, 65799), ShortOffsetRunHeader::new(133, 66273),
762        ShortOffsetRunHeader::new(139, 67672), ShortOffsetRunHeader::new(151, 68858),
763        ShortOffsetRunHeader::new(181, 69216), ShortOffsetRunHeader::new(187, 70736),
764        ShortOffsetRunHeader::new(207, 71248), ShortOffsetRunHeader::new(211, 71904),
765        ShortOffsetRunHeader::new(219, 72688), ShortOffsetRunHeader::new(223, 73552),
766        ShortOffsetRunHeader::new(233, 74752), ShortOffsetRunHeader::new(237, 90416),
767        ShortOffsetRunHeader::new(239, 92768), ShortOffsetRunHeader::new(241, 93552),
768        ShortOffsetRunHeader::new(249, 93824), ShortOffsetRunHeader::new(251, 94196),
769        ShortOffsetRunHeader::new(253, 118000), ShortOffsetRunHeader::new(255, 119488),
770        ShortOffsetRunHeader::new(257, 120782), ShortOffsetRunHeader::new(263, 123200),
771        ShortOffsetRunHeader::new(265, 123632), ShortOffsetRunHeader::new(267, 124144),
772        ShortOffsetRunHeader::new(269, 125127), ShortOffsetRunHeader::new(273, 126065),
773        ShortOffsetRunHeader::new(277, 127232), ShortOffsetRunHeader::new(287, 130032),
774        ShortOffsetRunHeader::new(289, 1244154),
775    ];
776    static OFFSETS: [u8; 291] = [
777        178, 2, 5, 1, 2, 3, 0, 10, 134, 10, 198, 10, 0, 10, 118, 10, 4, 6, 108, 10, 118, 10, 118,
778        10, 2, 6, 110, 13, 115, 10, 8, 7, 103, 10, 104, 7, 7, 19, 109, 10, 96, 10, 118, 10, 70, 20,
779        0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10, 182, 10,
780        86, 10, 134, 10, 6, 10, 0, 1, 3, 6, 6, 10, 198, 51, 2, 5, 0, 60, 78, 22, 0, 30, 0, 1, 0, 1,
781        25, 9, 14, 3, 0, 4, 138, 10, 30, 8, 1, 15, 32, 10, 39, 15, 0, 10, 188, 10, 0, 6, 154, 10,
782        38, 10, 198, 10, 22, 10, 86, 10, 0, 10, 0, 10, 0, 45, 12, 57, 17, 2, 0, 27, 36, 4, 29, 1, 8,
783        1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9, 52, 2,
784        30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 6, 10, 0, 31, 158, 10, 42, 4, 112, 7, 134,
785        30, 128, 10, 60, 10, 144, 10, 7, 20, 251, 10, 0, 10, 118, 10, 0, 10, 102, 10, 6, 20, 76, 12,
786        0, 19, 93, 10, 0, 10, 86, 29, 227, 10, 70, 10, 54, 10, 0, 10, 102, 21, 0, 111, 0, 10, 0, 10,
787        86, 10, 134, 10, 1, 7, 0, 10, 0, 23, 0, 3, 0, 10, 0, 20, 12, 20, 108, 25, 0, 50, 0, 10, 0,
788        10, 0, 10, 247, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0, 10, 0,
789    ];
790    #[inline]
791    pub fn lookup(c: char) -> bool {
792        debug_assert!(!c.is_ascii());
793        (c as u32) >= 0xb2 && lookup_slow(c)
794    }
795
796    #[inline(never)]
797    fn lookup_slow(c: char) -> bool {
798        const {
799            assert!(SHORT_OFFSET_RUNS.last().unwrap().0 > char::MAX as u32);
800            let mut i = 0;
801            while i < SHORT_OFFSET_RUNS.len() {
802                assert!(SHORT_OFFSET_RUNS[i].start_index() < OFFSETS.len());
803                i += 1;
804            }
805        }
806        // SAFETY: We just ensured the last element of `SHORT_OFFSET_RUNS` is greater than `std::char::MAX`
807        // and the start indices of all elements in `SHORT_OFFSET_RUNS` are smaller than `OFFSETS.len()`.
808        unsafe { super::skip_search(c, &SHORT_OFFSET_RUNS, &OFFSETS) }
809    }
810}
811
812#[rustfmt::skip]
813pub mod uppercase {
814    static BITSET_CHUNKS_MAP: [u8; 125] = [
815        3, 14, 6, 6, 0, 6, 6, 2, 5, 12, 6, 15, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
816        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
817        6, 6, 6, 7, 6, 13, 6, 11, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
818        6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 16, 6, 6,
819        6, 6, 10, 6, 4,
820    ];
821    static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [
822        [44, 44, 5, 35, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 5, 0],
823        [44, 44, 5, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
824        [44, 44, 40, 44, 44, 44, 44, 44, 17, 17, 66, 17, 43, 29, 24, 23],
825        [44, 44, 44, 32, 36, 21, 22, 15, 13, 34, 44, 44, 44, 11, 30, 39],
826        [44, 44, 44, 44, 9, 8, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44],
827        [44, 44, 44, 44, 37, 28, 67, 44, 44, 44, 44, 44, 44, 44, 44, 44],
828        [44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
829        [44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 57, 44, 44, 44],
830        [44, 44, 44, 44, 44, 44, 44, 44, 44, 49, 63, 44, 44, 44, 44, 44],
831        [44, 44, 44, 44, 44, 44, 44, 44, 44, 65, 64, 44, 20, 14, 16, 4],
832        [44, 44, 44, 44, 50, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
833        [44, 44, 53, 44, 44, 31, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
834        [44, 44, 54, 46, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
835        [51, 44, 9, 47, 44, 42, 33, 44, 44, 44, 44, 44, 44, 44, 44, 44],
836        [52, 19, 3, 18, 10, 48, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
837        [52, 38, 17, 27, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44],
838        [58, 1, 26, 55, 12, 7, 25, 56, 41, 59, 6, 2, 62, 61, 60, 68],
839    ];
840    static BITSET_CANONICAL: [u64; 44] = [
841        0b0000000000111111111111111111111111111111111111111111111111111111,
842        0b1111111111111111111111110000000000000000000000000011111111111111,
843        0b0000011111111111111111111111110000000000000000000000000000000001,
844        0b0101010101010101010101010101010101010101010101010101010000000001,
845        0b0000000000100000000000000000000000010101010101010101101011110101,
846        0b1111111111111111111111111111111100000000000000000000000000000000,
847        0b1111111111111111111111110000000000000000000000000000001111111111,
848        0b1111111111111111111100000000000000000000000000011111110001011111,
849        0b1111111111111111000000111111111111111111111111110000001111111111,
850        0b1111111111111111000000000000000000000000000000000000000000000000,
851        0b1111111111111110010101010101010101010101010101010101010101010101,
852        0b1000000001000101000000000000000000000000000000000000000000000000,
853        0b0111101100000000000000000000000000011111110111111110011110110000,
854        0b0110110000000101010101010101010101010101010101010101010101010101,
855        0b0110101000000000010101010101010101010101010101010101010101010101,
856        0b0101010111010010010101010101010101001010101010101010010010010000,
857        0b0101010101011111011111010101010101010101010001010010100001010101,
858        0b0101010101010101010101010101010101010101010101010101010101010101,
859        0b0101010101010101010101010101010101010101010101010010101010101011,
860        0b0101010101010101010101010101010100000000000000000000000000000000,
861        0b0101010101010100010101010101010000000000000000000000000000000000,
862        0b0010101101010101010101010101010101010101010101010101010010101010,
863        0b0001000110101110110100101101010110110001110110111100111011010110,
864        0b0000111100000000000111110000000000001111000000000000111100000000,
865        0b0000111100000000000000000000000000000000000000000000000000000000,
866        0b0000001111111111111111111111111100000000000000000000000000111111,
867        0b0000000000111111110111100110010011010000000000000000000000000011,
868        0b0000000000000100001010000000010101010101010101010101010101010101,
869        0b0000000000000000111111111111111100000000000000000000000000100000,
870        0b0000000000000000111111110000000010101010000000000011111100000000,
871        0b0000000000000000000011111111101111111111111111101101011101000000,
872        0b0000000000000000000000000011111111111111111111110000000000000000,
873        0b0000000000000000000000000000000001111111011111111111111111111111,
874        0b0000000000000000000000000000000000000000001101111111011111111111,
875        0b0000000000000000000000000000000000000000000000000101010101111010,
876        0b0000000000000000000000000000000000000000000000000010000010111111,
877        0b1010101001010101010101010101010101010101010101010101010101010101,
878        0b1100000000001111001111010101000000111110001001110011100010000100,
879        0b1100000000100101111010101001110100000000000000000000000000000000,
880        0b1110011010010000010101010101010101010101000111001000000000000000,
881        0b1110011111111111111111111111111111111111111111110000001000000000,
882        0b1111000000000000000000000000001111111111111111111111111100000000,
883        0b1111011111111111000000000000000000000000000000000000000000000000,
884        0b1111111100000000111111110000000000111111000000001111111100000000,
885    ];
886    static BITSET_MAPPING: [(u8, u8); 25] = [
887        (0, 182), (0, 74), (0, 166), (0, 162), (0, 159), (0, 150), (0, 148), (0, 142), (0, 134),
888        (0, 131), (0, 64), (1, 66), (1, 70), (1, 83), (1, 12), (1, 8), (2, 146), (2, 140), (2, 134),
889        (2, 130), (3, 164), (3, 146), (3, 20), (4, 178), (4, 171),
890    ];
891
892    pub const fn lookup(c: char) -> bool {
893        debug_assert!(!c.is_ascii());
894        (c as u32) >= 0xc0 &&
895        super::bitset_search(
896            c as u32,
897            &BITSET_CHUNKS_MAP,
898            &BITSET_INDEX_CHUNKS,
899            &BITSET_CANONICAL,
900            &BITSET_MAPPING,
901        )
902    }
903}
904
905#[rustfmt::skip]
906pub mod white_space {
907    static WHITESPACE_MAP: [u8; 256] = [
908        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
909        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
910        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
911        0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
912        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
913        0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
914        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
915        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
916        0, 0, 0, 0, 0, 0, 0, 0, 0,
917    ];
918    #[inline]
919    pub const fn lookup(c: char) -> bool {
920        debug_assert!(!c.is_ascii());
921        match c as u32 >> 8 {
922            0 => WHITESPACE_MAP[c as usize & 0xff] & 1 != 0,
923            22 => c as u32 == 0x1680,
924            32 => WHITESPACE_MAP[c as usize & 0xff] & 2 != 0,
925            48 => c as u32 == 0x3000,
926            _ => false,
927        }
928    }
929}
930
931#[rustfmt::skip]
932pub mod conversions {
933
934
935    use crate::ops::RangeInclusive;
936
937    struct L1Lut {
938        l2_luts: [L2Lut; 2],
939    }
940
941    struct L2Lut {
942        singles: &'static [(Range, i16)],
943        multis: &'static [(u16, [u16; 3])],
944    }
945
946    #[derive(Copy, Clone)]
947    struct Range {
948        start: u16,
949        len: u8,
950        parity: bool,
951    }
952
953    impl Range {
954        const fn new(range: RangeInclusive<u16>, parity: bool) -> Self {
955            let start = *range.start();
956            let end = *range.end();
957            assert!(start <= end);
958
959            let len = end - start;
960            assert!(len <= 255);
961
962            Self { start, len: len as u8, parity }
963        }
964
965        const fn singleton(start: u16) -> Self {
966            Self::new(start..=start, false)
967        }
968
969        const fn step_by_1(range: RangeInclusive<u16>) -> Self {
970            Self::new(range, false)
971        }
972
973        const fn step_by_2(range: RangeInclusive<u16>) -> Self {
974            Self::new(range, true)
975        }
976
977        const fn start(&self) -> u16 {
978            self.start
979        }
980
981        const fn end(&self) -> u16 {
982            self.start + self.len as u16
983        }
984    }
985
986    fn deconstruct(c: char) -> (u16, u16) {
987        let c = c as u32;
988        let plane = (c >> 16) as u16;
989        let low = c as u16;
990        (plane, low)
991    }
992
993    unsafe fn reconstruct(plane: u16, low: u16) -> char {
994        // SAFETY: The caller must ensure that the result is a valid `char`.
995        unsafe { char::from_u32_unchecked(((plane as u32) << 16) | (low as u32)) }
996    }
997
998    fn lookup(input: char, l1_lut: &L1Lut) -> Option<[char; 3]> {
999        let (input_high, input_low) = deconstruct(input);
1000        let Some(l2_lut) = l1_lut.l2_luts.get(input_high as usize) else {
1001            return None;
1002        };
1003
1004        let idx = l2_lut.singles.binary_search_by(|(range, _)| {
1005            use crate::cmp::Ordering;
1006
1007            if input_low < range.start() {
1008                Ordering::Greater
1009            } else if input_low > range.end() {
1010                Ordering::Less
1011            } else {
1012                Ordering::Equal
1013            }
1014        });
1015
1016        if let Ok(idx) = idx {
1017            // SAFETY: binary search guarantees that the index is in bounds.
1018            let &(range, output_delta) = unsafe { l2_lut.singles.get_unchecked(idx) };
1019            let mask = range.parity as u16;
1020            if input_low & mask == range.start() & mask {
1021                let output_low = input_low.wrapping_add_signed(output_delta);
1022                // SAFETY: Table data are guaranteed to be valid Unicode.
1023                let output = unsafe { reconstruct(input_high, output_low) };
1024                return Some([output, '\0', '\0']);
1025            }
1026        };
1027
1028        if let Ok(idx) = l2_lut.multis.binary_search_by_key(&input_low, |&(p, _)| p) {
1029            // SAFETY: binary search guarantees that the index is in bounds.
1030            let &(_, output_lows) = unsafe { l2_lut.multis.get_unchecked(idx) };
1031            // SAFETY: Table data are guaranteed to be valid Unicode.
1032            let output = output_lows.map(|output_low| unsafe { reconstruct(input_high, output_low) });
1033            return Some(output);
1034        };
1035
1036        None
1037    }
1038
1039    pub fn to_lower(c: char) -> [char; 3] {
1040        // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=[:Changes_When_Lowercased:]-[:ASCII:]&abb=on
1041        if c < '\u{C0}' {
1042            return [c.to_ascii_lowercase(), '\0', '\0'];
1043        }
1044
1045        lookup(c, &LOWERCASE_LUT).unwrap_or([c, '\0', '\0'])
1046    }
1047
1048    pub fn to_upper(c: char) -> [char; 3] {
1049        // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=[:Changes_When_Uppercased:]-[:ASCII:]&abb=on
1050        if c < '\u{B5}' {
1051            return [c.to_ascii_uppercase(), '\0', '\0'];
1052        }
1053
1054        lookup(c, &UPPERCASE_LUT).unwrap_or([c, '\0', '\0'])
1055    }
1056
1057    pub fn to_title(c: char) -> [char; 3] {
1058        // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=[:Changes_When_Titlecased:]-[:ASCII:]&abb=on
1059        if c < '\u{B5}' {
1060            return [c.to_ascii_uppercase(), '\0', '\0'];
1061        }
1062
1063        lookup(c, &TITLECASE_LUT).or_else(|| lookup(c, &UPPERCASE_LUT)).unwrap_or([c, '\0', '\0'])
1064    }
1065
1066    pub fn to_casefold(c: char) -> [char; 3] {
1067        // https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=[:Changes_When_Casefolded:]-[:ASCII:]&abb=on
1068        if c < '\u{B5}' {
1069            return [c.to_ascii_lowercase(), '\0', '\0'];
1070        }
1071
1072
1073        lookup(c, &CASEFOLD_LUT).unwrap_or_else(|| {
1074            // Fall back to lowercase of uppercase
1075
1076            let uppercase = lookup(c, &UPPERCASE_LUT).unwrap_or([c, '\0', '\0']);
1077
1078            // We need to take the lowercase of each character in `uppercase`,
1079            // and then concatenate them together.
1080
1081            // Lowercase the first uppercased char
1082            let mut final_result = to_lower(uppercase[0]);
1083
1084            if uppercase[1] != '\0' {
1085                // There's a 2nd uppercase char, lowercase it as well
1086                let lowercase_1 = to_lower(uppercase[1]);
1087
1088                // The lowercase of the second uppercase character
1089                // can't be 3 chars long;
1090                // that would bring the total case-folding length
1091                // above 3 characters, which would violate
1092                // a Unicode stability guarantee.
1093                debug_assert_eq!(lowercase_1[2], '\0');
1094
1095                // Currently, in every case where there
1096                // are multiple uppercased characters,
1097                // the lowercase of the first uppercase
1098                // has length 1. However, Unicode doesn't
1099                // guarantee this.
1100                // If, after updating the Unicode data
1101                // to a new Unicode version, the below
1102                // assertion starts to fail in
1103                // `coretests/tests/unicode.rs` `to_casefold()`,
1104                // delete it, and uncomment the
1105                // `if` condition and corresponding
1106                // `else` block below it.
1107                debug_assert_eq!(final_result[1], '\0');
1108                //if final_result[1] == '\0' {
1109
1110                final_result[1] = lowercase_1[0];
1111
1112                if uppercase[2] != '\0' {
1113                    // There's a 3rd uppercased char, lowercase it as well.
1114                    // Because of the Unicode stability guarantee that case-folding
1115                    // does not expand a string more than 3x in length,
1116                    // we know this lowercase must be 1 char long.
1117
1118                    debug_assert_eq!(lowercase_1[1], '\0');
1119                    let lowercase_2 = to_lower(uppercase[2]);
1120                    debug_assert_eq!(lowercase_2[1], '\0');
1121                    debug_assert_eq!(lowercase_2[2], '\0');
1122                    final_result[2] = lowercase_2[0];
1123                } else {
1124                    // Currently, the lowercase of
1125                    // the second uppercase character
1126                    // can't be 2 chars long either,
1127                    // but Unicode doesn't guarantee this.
1128                    // If, after updating the Unicode data
1129                    // to a new Unicode version, the below
1130                    // assertion starts to fail in
1131                    // `coretests/tests/unicode.rs` `to_casefold()`,
1132                    // delete it and uncomment the line
1133                    // below it.
1134                    debug_assert_eq!(lowercase_1[1], '\0');
1135                    //final_result[2] = lowercase_1[1];
1136                }
1137
1138                /*} else {
1139                    final_result[2] = lowercase_1[0];
1140                    debug_assert_eq!(lowercase_1[1], '\0');
1141                    debug_assert_eq!(uppercase[2], '\0')
1142                }*/
1143            }
1144            final_result
1145        })
1146    }
1147
1148    static LOWERCASE_LUT: L1Lut = L1Lut {
1149        l2_luts: [
1150            L2Lut {
1151                singles: &[ // 172 entries, 1032 bytes
1152                    (Range::step_by_1(0x00c0..=0x00d6), 32), (Range::step_by_1(0x00d8..=0x00de), 32),
1153                    (Range::step_by_2(0x0100..=0x012e), 1), (Range::step_by_2(0x0132..=0x0136), 1),
1154                    (Range::step_by_2(0x0139..=0x0147), 1), (Range::step_by_2(0x014a..=0x0176), 1),
1155                    (Range::singleton(0x0178), -121), (Range::step_by_2(0x0179..=0x017d), 1),
1156                    (Range::singleton(0x0181), 210), (Range::step_by_2(0x0182..=0x0184), 1),
1157                    (Range::singleton(0x0186), 206), (Range::singleton(0x0187), 1),
1158                    (Range::step_by_1(0x0189..=0x018a), 205), (Range::singleton(0x018b), 1),
1159                    (Range::singleton(0x018e), 79), (Range::singleton(0x018f), 202),
1160                    (Range::singleton(0x0190), 203), (Range::singleton(0x0191), 1),
1161                    (Range::singleton(0x0193), 205), (Range::singleton(0x0194), 207),
1162                    (Range::singleton(0x0196), 211), (Range::singleton(0x0197), 209),
1163                    (Range::singleton(0x0198), 1), (Range::singleton(0x019c), 211),
1164                    (Range::singleton(0x019d), 213), (Range::singleton(0x019f), 214),
1165                    (Range::step_by_2(0x01a0..=0x01a4), 1), (Range::singleton(0x01a6), 218),
1166                    (Range::singleton(0x01a7), 1), (Range::singleton(0x01a9), 218),
1167                    (Range::singleton(0x01ac), 1), (Range::singleton(0x01ae), 218),
1168                    (Range::singleton(0x01af), 1), (Range::step_by_1(0x01b1..=0x01b2), 217),
1169                    (Range::step_by_2(0x01b3..=0x01b5), 1), (Range::singleton(0x01b7), 219),
1170                    (Range::singleton(0x01b8), 1), (Range::singleton(0x01bc), 1), (Range::singleton(0x01c4), 2),
1171                    (Range::singleton(0x01c5), 1), (Range::singleton(0x01c7), 2), (Range::singleton(0x01c8), 1),
1172                    (Range::singleton(0x01ca), 2), (Range::step_by_2(0x01cb..=0x01db), 1),
1173                    (Range::step_by_2(0x01de..=0x01ee), 1), (Range::singleton(0x01f1), 2),
1174                    (Range::step_by_2(0x01f2..=0x01f4), 1), (Range::singleton(0x01f6), -97),
1175                    (Range::singleton(0x01f7), -56), (Range::step_by_2(0x01f8..=0x021e), 1),
1176                    (Range::singleton(0x0220), -130), (Range::step_by_2(0x0222..=0x0232), 1),
1177                    (Range::singleton(0x023a), 10795), (Range::singleton(0x023b), 1),
1178                    (Range::singleton(0x023d), -163), (Range::singleton(0x023e), 10792),
1179                    (Range::singleton(0x0241), 1), (Range::singleton(0x0243), -195),
1180                    (Range::singleton(0x0244), 69), (Range::singleton(0x0245), 71),
1181                    (Range::step_by_2(0x0246..=0x024e), 1), (Range::step_by_2(0x0370..=0x0372), 1),
1182                    (Range::singleton(0x0376), 1), (Range::singleton(0x037f), 116),
1183                    (Range::singleton(0x0386), 38), (Range::step_by_1(0x0388..=0x038a), 37),
1184                    (Range::singleton(0x038c), 64), (Range::step_by_1(0x038e..=0x038f), 63),
1185                    (Range::step_by_1(0x0391..=0x03a1), 32), (Range::step_by_1(0x03a3..=0x03ab), 32),
1186                    (Range::singleton(0x03cf), 8), (Range::step_by_2(0x03d8..=0x03ee), 1),
1187                    (Range::singleton(0x03f4), -60), (Range::singleton(0x03f7), 1),
1188                    (Range::singleton(0x03f9), -7), (Range::singleton(0x03fa), 1),
1189                    (Range::step_by_1(0x03fd..=0x03ff), -130), (Range::step_by_1(0x0400..=0x040f), 80),
1190                    (Range::step_by_1(0x0410..=0x042f), 32), (Range::step_by_2(0x0460..=0x0480), 1),
1191                    (Range::step_by_2(0x048a..=0x04be), 1), (Range::singleton(0x04c0), 15),
1192                    (Range::step_by_2(0x04c1..=0x04cd), 1), (Range::step_by_2(0x04d0..=0x052e), 1),
1193                    (Range::step_by_1(0x0531..=0x0556), 48), (Range::step_by_1(0x10a0..=0x10c5), 7264),
1194                    (Range::singleton(0x10c7), 7264), (Range::singleton(0x10cd), 7264),
1195                    (Range::step_by_1(0x13a0..=0x13ef), -26672), (Range::step_by_1(0x13f0..=0x13f5), 8),
1196                    (Range::singleton(0x1c89), 1), (Range::step_by_1(0x1c90..=0x1cba), -3008),
1197                    (Range::step_by_1(0x1cbd..=0x1cbf), -3008), (Range::step_by_2(0x1e00..=0x1e94), 1),
1198                    (Range::singleton(0x1e9e), -7615), (Range::step_by_2(0x1ea0..=0x1efe), 1),
1199                    (Range::step_by_1(0x1f08..=0x1f0f), -8), (Range::step_by_1(0x1f18..=0x1f1d), -8),
1200                    (Range::step_by_1(0x1f28..=0x1f2f), -8), (Range::step_by_1(0x1f38..=0x1f3f), -8),
1201                    (Range::step_by_1(0x1f48..=0x1f4d), -8), (Range::step_by_2(0x1f59..=0x1f5f), -8),
1202                    (Range::step_by_1(0x1f68..=0x1f6f), -8), (Range::step_by_1(0x1f88..=0x1f8f), -8),
1203                    (Range::step_by_1(0x1f98..=0x1f9f), -8), (Range::step_by_1(0x1fa8..=0x1faf), -8),
1204                    (Range::step_by_1(0x1fb8..=0x1fb9), -8), (Range::step_by_1(0x1fba..=0x1fbb), -74),
1205                    (Range::singleton(0x1fbc), -9), (Range::step_by_1(0x1fc8..=0x1fcb), -86),
1206                    (Range::singleton(0x1fcc), -9), (Range::step_by_1(0x1fd8..=0x1fd9), -8),
1207                    (Range::step_by_1(0x1fda..=0x1fdb), -100), (Range::step_by_1(0x1fe8..=0x1fe9), -8),
1208                    (Range::step_by_1(0x1fea..=0x1feb), -112), (Range::singleton(0x1fec), -7),
1209                    (Range::step_by_1(0x1ff8..=0x1ff9), -128), (Range::step_by_1(0x1ffa..=0x1ffb), -126),
1210                    (Range::singleton(0x1ffc), -9), (Range::singleton(0x2126), -7517),
1211                    (Range::singleton(0x212a), -8383), (Range::singleton(0x212b), -8262),
1212                    (Range::singleton(0x2132), 28), (Range::step_by_1(0x2160..=0x216f), 16),
1213                    (Range::singleton(0x2183), 1), (Range::step_by_1(0x24b6..=0x24cf), 26),
1214                    (Range::step_by_1(0x2c00..=0x2c2f), 48), (Range::singleton(0x2c60), 1),
1215                    (Range::singleton(0x2c62), -10743), (Range::singleton(0x2c63), -3814),
1216                    (Range::singleton(0x2c64), -10727), (Range::step_by_2(0x2c67..=0x2c6b), 1),
1217                    (Range::singleton(0x2c6d), -10780), (Range::singleton(0x2c6e), -10749),
1218                    (Range::singleton(0x2c6f), -10783), (Range::singleton(0x2c70), -10782),
1219                    (Range::singleton(0x2c72), 1), (Range::singleton(0x2c75), 1),
1220                    (Range::step_by_1(0x2c7e..=0x2c7f), -10815), (Range::step_by_2(0x2c80..=0x2ce2), 1),
1221                    (Range::step_by_2(0x2ceb..=0x2ced), 1), (Range::singleton(0x2cf2), 1),
1222                    (Range::step_by_2(0xa640..=0xa66c), 1), (Range::step_by_2(0xa680..=0xa69a), 1),
1223                    (Range::step_by_2(0xa722..=0xa72e), 1), (Range::step_by_2(0xa732..=0xa76e), 1),
1224                    (Range::step_by_2(0xa779..=0xa77b), 1), (Range::singleton(0xa77d), 30204),
1225                    (Range::step_by_2(0xa77e..=0xa786), 1), (Range::singleton(0xa78b), 1),
1226                    (Range::singleton(0xa78d), 23256), (Range::step_by_2(0xa790..=0xa792), 1),
1227                    (Range::step_by_2(0xa796..=0xa7a8), 1), (Range::singleton(0xa7aa), 23228),
1228                    (Range::singleton(0xa7ab), 23217), (Range::singleton(0xa7ac), 23221),
1229                    (Range::singleton(0xa7ad), 23231), (Range::singleton(0xa7ae), 23228),
1230                    (Range::singleton(0xa7b0), 23278), (Range::singleton(0xa7b1), 23254),
1231                    (Range::singleton(0xa7b2), 23275), (Range::singleton(0xa7b3), 928),
1232                    (Range::step_by_2(0xa7b4..=0xa7c2), 1), (Range::singleton(0xa7c4), -48),
1233                    (Range::singleton(0xa7c5), 23229), (Range::singleton(0xa7c6), 30152),
1234                    (Range::step_by_2(0xa7c7..=0xa7c9), 1), (Range::singleton(0xa7cb), 23193),
1235                    (Range::step_by_2(0xa7cc..=0xa7da), 1), (Range::singleton(0xa7dc), 22975),
1236                    (Range::singleton(0xa7f5), 1), (Range::step_by_1(0xff21..=0xff3a), 32),
1237                ],
1238                multis: &[ // 1 entries, 8 bytes
1239                    (0x0130, [0x0069, 0x0307, 0x0000]),
1240                ],
1241            },
1242            L2Lut {
1243                singles: &[ // 12 entries, 72 bytes
1244                    (Range::step_by_1(0x0400..=0x0427), 40), (Range::step_by_1(0x04b0..=0x04d3), 40),
1245                    (Range::step_by_1(0x0570..=0x057a), 39), (Range::step_by_1(0x057c..=0x058a), 39),
1246                    (Range::step_by_1(0x058c..=0x0592), 39), (Range::step_by_1(0x0594..=0x0595), 39),
1247                    (Range::step_by_1(0x0c80..=0x0cb2), 64), (Range::step_by_1(0x0d50..=0x0d65), 32),
1248                    (Range::step_by_1(0x18a0..=0x18bf), 32), (Range::step_by_1(0x6e40..=0x6e5f), 32),
1249                    (Range::step_by_1(0x6ea0..=0x6eb8), 27), (Range::step_by_1(0xe900..=0xe921), 34),
1250                ],
1251                multis: &[ // 0 entries, 0 bytes
1252                ],
1253            },
1254        ],
1255    };
1256
1257    static UPPERCASE_LUT: L1Lut = L1Lut {
1258        l2_luts: [
1259            L2Lut {
1260                singles: &[ // 185 entries, 1110 bytes
1261                    (Range::singleton(0x00b5), 743), (Range::step_by_1(0x00e0..=0x00f6), -32),
1262                    (Range::step_by_1(0x00f8..=0x00fe), -32), (Range::singleton(0x00ff), 121),
1263                    (Range::step_by_2(0x0101..=0x012f), -1), (Range::singleton(0x0131), -232),
1264                    (Range::step_by_2(0x0133..=0x0137), -1), (Range::step_by_2(0x013a..=0x0148), -1),
1265                    (Range::step_by_2(0x014b..=0x0177), -1), (Range::step_by_2(0x017a..=0x017e), -1),
1266                    (Range::singleton(0x017f), -300), (Range::singleton(0x0180), 195),
1267                    (Range::step_by_2(0x0183..=0x0185), -1), (Range::singleton(0x0188), -1),
1268                    (Range::singleton(0x018c), -1), (Range::singleton(0x0192), -1),
1269                    (Range::singleton(0x0195), 97), (Range::singleton(0x0199), -1),
1270                    (Range::singleton(0x019a), 163), (Range::singleton(0x019b), -22975),
1271                    (Range::singleton(0x019e), 130), (Range::step_by_2(0x01a1..=0x01a5), -1),
1272                    (Range::singleton(0x01a8), -1), (Range::singleton(0x01ad), -1),
1273                    (Range::singleton(0x01b0), -1), (Range::step_by_2(0x01b4..=0x01b6), -1),
1274                    (Range::singleton(0x01b9), -1), (Range::singleton(0x01bd), -1),
1275                    (Range::singleton(0x01bf), 56), (Range::singleton(0x01c5), -1),
1276                    (Range::singleton(0x01c6), -2), (Range::singleton(0x01c8), -1),
1277                    (Range::singleton(0x01c9), -2), (Range::singleton(0x01cb), -1),
1278                    (Range::singleton(0x01cc), -2), (Range::step_by_2(0x01ce..=0x01dc), -1),
1279                    (Range::singleton(0x01dd), -79), (Range::step_by_2(0x01df..=0x01ef), -1),
1280                    (Range::singleton(0x01f2), -1), (Range::singleton(0x01f3), -2),
1281                    (Range::singleton(0x01f5), -1), (Range::step_by_2(0x01f9..=0x021f), -1),
1282                    (Range::step_by_2(0x0223..=0x0233), -1), (Range::singleton(0x023c), -1),
1283                    (Range::step_by_1(0x023f..=0x0240), 10815), (Range::singleton(0x0242), -1),
1284                    (Range::step_by_2(0x0247..=0x024f), -1), (Range::singleton(0x0250), 10783),
1285                    (Range::singleton(0x0251), 10780), (Range::singleton(0x0252), 10782),
1286                    (Range::singleton(0x0253), -210), (Range::singleton(0x0254), -206),
1287                    (Range::step_by_1(0x0256..=0x0257), -205), (Range::singleton(0x0259), -202),
1288                    (Range::singleton(0x025b), -203), (Range::singleton(0x025c), -23217),
1289                    (Range::singleton(0x0260), -205), (Range::singleton(0x0261), -23221),
1290                    (Range::singleton(0x0263), -207), (Range::singleton(0x0264), -23193),
1291                    (Range::singleton(0x0265), -23256), (Range::singleton(0x0266), -23228),
1292                    (Range::singleton(0x0268), -209), (Range::singleton(0x0269), -211),
1293                    (Range::singleton(0x026a), -23228), (Range::singleton(0x026b), 10743),
1294                    (Range::singleton(0x026c), -23231), (Range::singleton(0x026f), -211),
1295                    (Range::singleton(0x0271), 10749), (Range::singleton(0x0272), -213),
1296                    (Range::singleton(0x0275), -214), (Range::singleton(0x027d), 10727),
1297                    (Range::singleton(0x0280), -218), (Range::singleton(0x0282), -23229),
1298                    (Range::singleton(0x0283), -218), (Range::singleton(0x0287), -23254),
1299                    (Range::singleton(0x0288), -218), (Range::singleton(0x0289), -69),
1300                    (Range::step_by_1(0x028a..=0x028b), -217), (Range::singleton(0x028c), -71),
1301                    (Range::singleton(0x0292), -219), (Range::singleton(0x029d), -23275),
1302                    (Range::singleton(0x029e), -23278), (Range::singleton(0x0345), 84),
1303                    (Range::step_by_2(0x0371..=0x0373), -1), (Range::singleton(0x0377), -1),
1304                    (Range::step_by_1(0x037b..=0x037d), 130), (Range::singleton(0x03ac), -38),
1305                    (Range::step_by_1(0x03ad..=0x03af), -37), (Range::step_by_1(0x03b1..=0x03c1), -32),
1306                    (Range::singleton(0x03c2), -31), (Range::step_by_1(0x03c3..=0x03cb), -32),
1307                    (Range::singleton(0x03cc), -64), (Range::step_by_1(0x03cd..=0x03ce), -63),
1308                    (Range::singleton(0x03d0), -62), (Range::singleton(0x03d1), -57),
1309                    (Range::singleton(0x03d5), -47), (Range::singleton(0x03d6), -54),
1310                    (Range::singleton(0x03d7), -8), (Range::step_by_2(0x03d9..=0x03ef), -1),
1311                    (Range::singleton(0x03f0), -86), (Range::singleton(0x03f1), -80),
1312                    (Range::singleton(0x03f2), 7), (Range::singleton(0x03f3), -116),
1313                    (Range::singleton(0x03f5), -96), (Range::singleton(0x03f8), -1),
1314                    (Range::singleton(0x03fb), -1), (Range::step_by_1(0x0430..=0x044f), -32),
1315                    (Range::step_by_1(0x0450..=0x045f), -80), (Range::step_by_2(0x0461..=0x0481), -1),
1316                    (Range::step_by_2(0x048b..=0x04bf), -1), (Range::step_by_2(0x04c2..=0x04ce), -1),
1317                    (Range::singleton(0x04cf), -15), (Range::step_by_2(0x04d1..=0x052f), -1),
1318                    (Range::step_by_1(0x0561..=0x0586), -48), (Range::step_by_1(0x10d0..=0x10fa), 3008),
1319                    (Range::step_by_1(0x10fd..=0x10ff), 3008), (Range::step_by_1(0x13f8..=0x13fd), -8),
1320                    (Range::singleton(0x1c80), -6254), (Range::singleton(0x1c81), -6253),
1321                    (Range::singleton(0x1c82), -6244), (Range::step_by_1(0x1c83..=0x1c84), -6242),
1322                    (Range::singleton(0x1c85), -6243), (Range::singleton(0x1c86), -6236),
1323                    (Range::singleton(0x1c87), -6181), (Range::singleton(0x1c88), -30270),
1324                    (Range::singleton(0x1c8a), -1), (Range::singleton(0x1d79), -30204),
1325                    (Range::singleton(0x1d7d), 3814), (Range::singleton(0x1d8e), -30152),
1326                    (Range::step_by_2(0x1e01..=0x1e95), -1), (Range::singleton(0x1e9b), -59),
1327                    (Range::step_by_2(0x1ea1..=0x1eff), -1), (Range::step_by_1(0x1f00..=0x1f07), 8),
1328                    (Range::step_by_1(0x1f10..=0x1f15), 8), (Range::step_by_1(0x1f20..=0x1f27), 8),
1329                    (Range::step_by_1(0x1f30..=0x1f37), 8), (Range::step_by_1(0x1f40..=0x1f45), 8),
1330                    (Range::step_by_2(0x1f51..=0x1f57), 8), (Range::step_by_1(0x1f60..=0x1f67), 8),
1331                    (Range::step_by_1(0x1f70..=0x1f71), 74), (Range::step_by_1(0x1f72..=0x1f75), 86),
1332                    (Range::step_by_1(0x1f76..=0x1f77), 100), (Range::step_by_1(0x1f78..=0x1f79), 128),
1333                    (Range::step_by_1(0x1f7a..=0x1f7b), 112), (Range::step_by_1(0x1f7c..=0x1f7d), 126),
1334                    (Range::step_by_1(0x1fb0..=0x1fb1), 8), (Range::singleton(0x1fbe), -7205),
1335                    (Range::step_by_1(0x1fd0..=0x1fd1), 8), (Range::step_by_1(0x1fe0..=0x1fe1), 8),
1336                    (Range::singleton(0x1fe5), 7), (Range::singleton(0x214e), -28),
1337                    (Range::step_by_1(0x2170..=0x217f), -16), (Range::singleton(0x2184), -1),
1338                    (Range::step_by_1(0x24d0..=0x24e9), -26), (Range::step_by_1(0x2c30..=0x2c5f), -48),
1339                    (Range::singleton(0x2c61), -1), (Range::singleton(0x2c65), -10795),
1340                    (Range::singleton(0x2c66), -10792), (Range::step_by_2(0x2c68..=0x2c6c), -1),
1341                    (Range::singleton(0x2c73), -1), (Range::singleton(0x2c76), -1),
1342                    (Range::step_by_2(0x2c81..=0x2ce3), -1), (Range::step_by_2(0x2cec..=0x2cee), -1),
1343                    (Range::singleton(0x2cf3), -1), (Range::step_by_1(0x2d00..=0x2d25), -7264),
1344                    (Range::singleton(0x2d27), -7264), (Range::singleton(0x2d2d), -7264),
1345                    (Range::step_by_2(0xa641..=0xa66d), -1), (Range::step_by_2(0xa681..=0xa69b), -1),
1346                    (Range::step_by_2(0xa723..=0xa72f), -1), (Range::step_by_2(0xa733..=0xa76f), -1),
1347                    (Range::step_by_2(0xa77a..=0xa77c), -1), (Range::step_by_2(0xa77f..=0xa787), -1),
1348                    (Range::singleton(0xa78c), -1), (Range::step_by_2(0xa791..=0xa793), -1),
1349                    (Range::singleton(0xa794), 48), (Range::step_by_2(0xa797..=0xa7a9), -1),
1350                    (Range::step_by_2(0xa7b5..=0xa7c3), -1), (Range::step_by_2(0xa7c8..=0xa7ca), -1),
1351                    (Range::step_by_2(0xa7cd..=0xa7db), -1), (Range::singleton(0xa7f6), -1),
1352                    (Range::singleton(0xab53), -928), (Range::step_by_1(0xab70..=0xabbf), 26672),
1353                    (Range::step_by_1(0xff41..=0xff5a), -32),
1354                ],
1355                multis: &[ // 102 entries, 816 bytes
1356                    (0x00df, [0x0053, 0x0053, 0x0000]), (0x0149, [0x02bc, 0x004e, 0x0000]),
1357                    (0x01f0, [0x004a, 0x030c, 0x0000]), (0x0390, [0x0399, 0x0308, 0x0301]),
1358                    (0x03b0, [0x03a5, 0x0308, 0x0301]), (0x0587, [0x0535, 0x0552, 0x0000]),
1359                    (0x1e96, [0x0048, 0x0331, 0x0000]), (0x1e97, [0x0054, 0x0308, 0x0000]),
1360                    (0x1e98, [0x0057, 0x030a, 0x0000]), (0x1e99, [0x0059, 0x030a, 0x0000]),
1361                    (0x1e9a, [0x0041, 0x02be, 0x0000]), (0x1f50, [0x03a5, 0x0313, 0x0000]),
1362                    (0x1f52, [0x03a5, 0x0313, 0x0300]), (0x1f54, [0x03a5, 0x0313, 0x0301]),
1363                    (0x1f56, [0x03a5, 0x0313, 0x0342]), (0x1f80, [0x1f08, 0x0399, 0x0000]),
1364                    (0x1f81, [0x1f09, 0x0399, 0x0000]), (0x1f82, [0x1f0a, 0x0399, 0x0000]),
1365                    (0x1f83, [0x1f0b, 0x0399, 0x0000]), (0x1f84, [0x1f0c, 0x0399, 0x0000]),
1366                    (0x1f85, [0x1f0d, 0x0399, 0x0000]), (0x1f86, [0x1f0e, 0x0399, 0x0000]),
1367                    (0x1f87, [0x1f0f, 0x0399, 0x0000]), (0x1f88, [0x1f08, 0x0399, 0x0000]),
1368                    (0x1f89, [0x1f09, 0x0399, 0x0000]), (0x1f8a, [0x1f0a, 0x0399, 0x0000]),
1369                    (0x1f8b, [0x1f0b, 0x0399, 0x0000]), (0x1f8c, [0x1f0c, 0x0399, 0x0000]),
1370                    (0x1f8d, [0x1f0d, 0x0399, 0x0000]), (0x1f8e, [0x1f0e, 0x0399, 0x0000]),
1371                    (0x1f8f, [0x1f0f, 0x0399, 0x0000]), (0x1f90, [0x1f28, 0x0399, 0x0000]),
1372                    (0x1f91, [0x1f29, 0x0399, 0x0000]), (0x1f92, [0x1f2a, 0x0399, 0x0000]),
1373                    (0x1f93, [0x1f2b, 0x0399, 0x0000]), (0x1f94, [0x1f2c, 0x0399, 0x0000]),
1374                    (0x1f95, [0x1f2d, 0x0399, 0x0000]), (0x1f96, [0x1f2e, 0x0399, 0x0000]),
1375                    (0x1f97, [0x1f2f, 0x0399, 0x0000]), (0x1f98, [0x1f28, 0x0399, 0x0000]),
1376                    (0x1f99, [0x1f29, 0x0399, 0x0000]), (0x1f9a, [0x1f2a, 0x0399, 0x0000]),
1377                    (0x1f9b, [0x1f2b, 0x0399, 0x0000]), (0x1f9c, [0x1f2c, 0x0399, 0x0000]),
1378                    (0x1f9d, [0x1f2d, 0x0399, 0x0000]), (0x1f9e, [0x1f2e, 0x0399, 0x0000]),
1379                    (0x1f9f, [0x1f2f, 0x0399, 0x0000]), (0x1fa0, [0x1f68, 0x0399, 0x0000]),
1380                    (0x1fa1, [0x1f69, 0x0399, 0x0000]), (0x1fa2, [0x1f6a, 0x0399, 0x0000]),
1381                    (0x1fa3, [0x1f6b, 0x0399, 0x0000]), (0x1fa4, [0x1f6c, 0x0399, 0x0000]),
1382                    (0x1fa5, [0x1f6d, 0x0399, 0x0000]), (0x1fa6, [0x1f6e, 0x0399, 0x0000]),
1383                    (0x1fa7, [0x1f6f, 0x0399, 0x0000]), (0x1fa8, [0x1f68, 0x0399, 0x0000]),
1384                    (0x1fa9, [0x1f69, 0x0399, 0x0000]), (0x1faa, [0x1f6a, 0x0399, 0x0000]),
1385                    (0x1fab, [0x1f6b, 0x0399, 0x0000]), (0x1fac, [0x1f6c, 0x0399, 0x0000]),
1386                    (0x1fad, [0x1f6d, 0x0399, 0x0000]), (0x1fae, [0x1f6e, 0x0399, 0x0000]),
1387                    (0x1faf, [0x1f6f, 0x0399, 0x0000]), (0x1fb2, [0x1fba, 0x0399, 0x0000]),
1388                    (0x1fb3, [0x0391, 0x0399, 0x0000]), (0x1fb4, [0x0386, 0x0399, 0x0000]),
1389                    (0x1fb6, [0x0391, 0x0342, 0x0000]), (0x1fb7, [0x0391, 0x0342, 0x0399]),
1390                    (0x1fbc, [0x0391, 0x0399, 0x0000]), (0x1fc2, [0x1fca, 0x0399, 0x0000]),
1391                    (0x1fc3, [0x0397, 0x0399, 0x0000]), (0x1fc4, [0x0389, 0x0399, 0x0000]),
1392                    (0x1fc6, [0x0397, 0x0342, 0x0000]), (0x1fc7, [0x0397, 0x0342, 0x0399]),
1393                    (0x1fcc, [0x0397, 0x0399, 0x0000]), (0x1fd2, [0x0399, 0x0308, 0x0300]),
1394                    (0x1fd3, [0x0399, 0x0308, 0x0301]), (0x1fd6, [0x0399, 0x0342, 0x0000]),
1395                    (0x1fd7, [0x0399, 0x0308, 0x0342]), (0x1fe2, [0x03a5, 0x0308, 0x0300]),
1396                    (0x1fe3, [0x03a5, 0x0308, 0x0301]), (0x1fe4, [0x03a1, 0x0313, 0x0000]),
1397                    (0x1fe6, [0x03a5, 0x0342, 0x0000]), (0x1fe7, [0x03a5, 0x0308, 0x0342]),
1398                    (0x1ff2, [0x1ffa, 0x0399, 0x0000]), (0x1ff3, [0x03a9, 0x0399, 0x0000]),
1399                    (0x1ff4, [0x038f, 0x0399, 0x0000]), (0x1ff6, [0x03a9, 0x0342, 0x0000]),
1400                    (0x1ff7, [0x03a9, 0x0342, 0x0399]), (0x1ffc, [0x03a9, 0x0399, 0x0000]),
1401                    (0xfb00, [0x0046, 0x0046, 0x0000]), (0xfb01, [0x0046, 0x0049, 0x0000]),
1402                    (0xfb02, [0x0046, 0x004c, 0x0000]), (0xfb03, [0x0046, 0x0046, 0x0049]),
1403                    (0xfb04, [0x0046, 0x0046, 0x004c]), (0xfb05, [0x0053, 0x0054, 0x0000]),
1404                    (0xfb06, [0x0053, 0x0054, 0x0000]), (0xfb13, [0x0544, 0x0546, 0x0000]),
1405                    (0xfb14, [0x0544, 0x0535, 0x0000]), (0xfb15, [0x0544, 0x053b, 0x0000]),
1406                    (0xfb16, [0x054e, 0x0546, 0x0000]), (0xfb17, [0x0544, 0x053d, 0x0000]),
1407                ],
1408            },
1409            L2Lut {
1410                singles: &[ // 12 entries, 72 bytes
1411                    (Range::step_by_1(0x0428..=0x044f), -40), (Range::step_by_1(0x04d8..=0x04fb), -40),
1412                    (Range::step_by_1(0x0597..=0x05a1), -39), (Range::step_by_1(0x05a3..=0x05b1), -39),
1413                    (Range::step_by_1(0x05b3..=0x05b9), -39), (Range::step_by_1(0x05bb..=0x05bc), -39),
1414                    (Range::step_by_1(0x0cc0..=0x0cf2), -64), (Range::step_by_1(0x0d70..=0x0d85), -32),
1415                    (Range::step_by_1(0x18c0..=0x18df), -32), (Range::step_by_1(0x6e60..=0x6e7f), -32),
1416                    (Range::step_by_1(0x6ebb..=0x6ed3), -27), (Range::step_by_1(0xe922..=0xe943), -34),
1417                ],
1418                multis: &[ // 0 entries, 0 bytes
1419                ],
1420            },
1421        ],
1422    };
1423
1424    static TITLECASE_LUT: L1Lut = L1Lut {
1425        l2_luts: [
1426            L2Lut {
1427                singles: &[ // 26 entries, 156 bytes
1428                    (Range::singleton(0x01c4), 1), (Range::singleton(0x01c5), 0),
1429                    (Range::singleton(0x01c6), -1), (Range::singleton(0x01c7), 1),
1430                    (Range::singleton(0x01c8), 0), (Range::singleton(0x01c9), -1),
1431                    (Range::singleton(0x01ca), 1), (Range::singleton(0x01cb), 0),
1432                    (Range::singleton(0x01cc), -1), (Range::singleton(0x01f1), 1),
1433                    (Range::singleton(0x01f2), 0), (Range::singleton(0x01f3), -1),
1434                    (Range::step_by_1(0x10d0..=0x10fa), 0), (Range::step_by_1(0x10fd..=0x10ff), 0),
1435                    (Range::step_by_1(0x1f80..=0x1f87), 8), (Range::step_by_1(0x1f88..=0x1f8f), 0),
1436                    (Range::step_by_1(0x1f90..=0x1f97), 8), (Range::step_by_1(0x1f98..=0x1f9f), 0),
1437                    (Range::step_by_1(0x1fa0..=0x1fa7), 8), (Range::step_by_1(0x1fa8..=0x1faf), 0),
1438                    (Range::singleton(0x1fb3), 9), (Range::singleton(0x1fbc), 0), (Range::singleton(0x1fc3), 9),
1439                    (Range::singleton(0x1fcc), 0), (Range::singleton(0x1ff3), 9), (Range::singleton(0x1ffc), 0),
1440                ],
1441                multis: &[ // 23 entries, 184 bytes
1442                    (0x00df, [0x0053, 0x0073, 0x0000]), (0x0587, [0x0535, 0x0582, 0x0000]),
1443                    (0x1fb2, [0x1fba, 0x0345, 0x0000]), (0x1fb4, [0x0386, 0x0345, 0x0000]),
1444                    (0x1fb7, [0x0391, 0x0342, 0x0345]), (0x1fc2, [0x1fca, 0x0345, 0x0000]),
1445                    (0x1fc4, [0x0389, 0x0345, 0x0000]), (0x1fc7, [0x0397, 0x0342, 0x0345]),
1446                    (0x1ff2, [0x1ffa, 0x0345, 0x0000]), (0x1ff4, [0x038f, 0x0345, 0x0000]),
1447                    (0x1ff7, [0x03a9, 0x0342, 0x0345]), (0xfb00, [0x0046, 0x0066, 0x0000]),
1448                    (0xfb01, [0x0046, 0x0069, 0x0000]), (0xfb02, [0x0046, 0x006c, 0x0000]),
1449                    (0xfb03, [0x0046, 0x0066, 0x0069]), (0xfb04, [0x0046, 0x0066, 0x006c]),
1450                    (0xfb05, [0x0053, 0x0074, 0x0000]), (0xfb06, [0x0053, 0x0074, 0x0000]),
1451                    (0xfb13, [0x0544, 0x0576, 0x0000]), (0xfb14, [0x0544, 0x0565, 0x0000]),
1452                    (0xfb15, [0x0544, 0x056b, 0x0000]), (0xfb16, [0x054e, 0x0576, 0x0000]),
1453                    (0xfb17, [0x0544, 0x056d, 0x0000]),
1454                ],
1455            },
1456            L2Lut {
1457                singles: &[ // 0 entries, 0 bytes
1458                ],
1459                multis: &[ // 0 entries, 0 bytes
1460                ],
1461            },
1462        ],
1463    };
1464
1465    static CASEFOLD_LUT: L1Lut = L1Lut {
1466        l2_luts: [
1467            L2Lut {
1468                singles: &[ // 4 entries, 24 bytes
1469                    (Range::singleton(0x0131), 0), (Range::step_by_1(0x13a0..=0x13f5), 0),
1470                    (Range::step_by_1(0x13f8..=0x13fd), -8), (Range::step_by_1(0xab70..=0xabbf), 26672),
1471                ],
1472                multis: &[ // 1 entries, 8 bytes
1473                    (0x1e9e, [0x0073, 0x0073, 0x0000]),
1474                ],
1475            },
1476            L2Lut {
1477                singles: &[ // 0 entries, 0 bytes
1478                ],
1479                multis: &[ // 0 entries, 0 bytes
1480                ],
1481            },
1482        ],
1483    };
1484}