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