// unescape_html: decode HTML character references like Python's
// html.unescape, except that references to control characters and
// noncharacters decode to that code point (as the WHATWG tokenizer does)
// instead of being deleted.
//
// Design
// - One buffer holds both output and input. The input sits IN_OFF bytes in,
// and output is written from the start. Every reference expands by at most
// 1.2x (≪⃒ is 5 bytes in, 6 out), so the write cursor stays at least
// IN_OFF - 0.2 * 1 MiB (about 51 KiB) behind the read cursor: decoding in
// place is safe and memory stays near 1.25 MiB.
// - A sentinel '&' after the input stops every scan, so the inner loops need
// no bounds checks. The fast path copies 64 bytes at a time with Zig's
// @Vector(16, u8) (Wasm SIMD128) and stops only at '&'.
// - Named references use a minimal perfect hash of the 2125 names in
// html.entities.html5, generated offline. Vector compares find the name's
// length, the name (zero-padded to 32 bytes) is hashed as four 64-bit
// words, and every hit is verified against the stored name with one
// pair of vector compares. Legacy names without ';' (&, ©, ...) use
// the longest legacy prefix of the name, as html.unescape does.
//
// Tables generated from Python 3.14's html.entities.html5.
// Build (zig 0.15.2): zig build-exe unescape_html.zig -target wasm32-freestanding
// -mcpu=generic+simd128 -O ReleaseFast -fstrip -fno-entry -rdynamic
// --stack 4096 --max-memory=1376256
const V = @Vector(16, u8);
const OUT_CAP: u32 = 1310720;
const IN_CAP: u32 = 1048576;
const IN_OFF: u32 = OUT_CAP - IN_CAP;
var buf: [OUT_CAP + 64]u8 align(16) = undefined;
export fn input_ptr() u32 {
return @intFromPtr(&buf) + IN_OFF;
}
export fn input_utf8_cap() u32 {
return IN_CAP;
}
export fn output_utf8_cap() u32 {
return OUT_CAP;
}
const N: u32 = 2125;
const B: u32 = 600;
const DISP = [B]u16{
13,1,9,9,33,6,15,2,9,60,6,105,2,59,91,8,
1,11,62,9,13,5,61,3,4,0,3,12,6,1,150,25,
42,18,17,10,32,155,5,138,2,4,38,6,3,47,1,30,
56,3,7,2,7,37,1,9,8,11,11,5,35,56,1,24,
7,25,2,70,1,41,36,1,84,19,15,1,21,28,16,37,
1,8,0,13,7,26,4,25,5,93,101,34,19,10,86,1,
23,56,20,3,1,1,7,1,148,0,196,14,6,5,120,31,
3,28,1,16,2,114,1,1,101,25,47,5,138,52,12,2,
110,14,77,6,2,1,26,92,25,32,12,17,19,27,1,18,
6,52,0,128,4,3,27,84,14,6,82,0,190,0,11,35,
153,26,5,1,1,3,70,249,2,11,4,1,7,0,30,70,
75,58,38,185,21,1,60,2,26,28,1,2,6,66,0,105,
27,32,3,79,112,7,6,12,13,4,0,1,34,160,248,98,
0,2,2,9,6,1,95,135,3,9,64,82,17,16,9,307,
131,245,16,17,0,25,4,17,9,1,0,6,70,2,3,158,
2,222,8,6,159,63,266,13,144,61,3,36,5,2,8,150,
99,12,1,46,57,1,1,3,155,7,3,46,23,234,9,106,
0,0,118,73,20,10,94,21,129,7,899,48,6,52,102,2,
5,202,776,317,15,16,0,14,12,145,49,15,129,51,31,61,
15,319,72,6,355,19,0,64,29,10,0,1,2,34,176,28,
19,154,618,9,426,101,69,65,2,213,1,4,3,1,1,1,
36,109,1,530,22,6,6,8,10,0,58,140,539,6,119,28,
61,13,19,72,17,9,102,12,27,1,84,24,14,43,14,213,
6,129,243,252,338,1,2,4,83,3,26,14,35,53,1,25,
194,2,180,27,66,72,267,12,14,1,18,1,79,133,0,64,
13,1,27,2,161,25,173,102,101,3,16,20,3,25,139,2,
139,1,8,157,64,110,53,24,5,157,94,263,3,530,686,2,
214,159,40,13,135,2,2,59,4,114,7,380,0,5,29,319,
20,6,147,120,327,326,10,170,1,315,0,1,143,60,76,0,
49,3,336,16,34,327,8,333,5,221,1,53,16,31,249,962,
326,27,78,448,0,133,617,6,65,1,32,53,5,6,41,4,
88,232,279,1,854,237,59,2,12,33,169,137,1,36,420,407,
906,230,109,48,133,731,3,290,480,70,118,222,70,92,392,57,
0,209,8,86,265,389,19,1,88,1,341,817,371,0,22,2,
111,22,45,71,682,2,397,954,161,8,683,100,1183,543,1,1221,
2,8,264,1154,667,1872,72,0,53,496,35,694,78,4,253,553,
332,8,248,44,50,566,672,869,82,33,331,7,21,128,523,421,
844,1,126,1,7,4,641,384
};
// Per slot, in byte planes so the tables compress well: name length, the
// first code point's low and high bytes, and META: bit 0 is the code point's
// bit 16, bits 1-4 are index+1 into SECOND (0 if none), and bit 5 marks a
// legacy name that is also valid without ';'.
const LENS align(16) = [_]u8{
14,6,6,6,7,18,3,15,5,5,4,16,18,6,11,4,5,5,6,5,9,4,4,8,4,5,4,4,6,6,6,2,
17,3,4,5,6,10,13,5,6,5,4,5,6,13,6,5,5,4,14,11,6,7,10,7,12,6,4,5,5,4,5,6,
5,10,6,4,4,4,2,6,7,12,6,6,18,5,12,7,6,4,2,6,6,3,5,4,4,20,5,11,6,6,7,5,
17,8,8,5,14,5,5,4,4,7,12,5,4,3,5,5,14,4,13,4,4,6,6,4,4,2,3,5,3,9,4,5,
18,4,4,7,5,6,6,4,7,6,3,5,7,7,5,4,4,6,6,3,6,5,5,5,5,12,4,14,5,7,5,3,
5,6,6,5,5,16,6,21,2,3,10,6,5,3,7,14,5,5,8,17,11,6,5,6,5,8,6,5,6,4,4,4,
8,11,4,3,6,9,5,6,3,6,6,16,12,4,5,4,6,15,8,6,5,13,7,7,6,7,6,7,6,6,9,6,
2,3,6,2,9,8,6,4,5,6,8,5,5,8,6,5,13,5,6,5,5,3,5,4,5,6,6,18,10,5,4,6,
3,6,3,6,15,4,3,4,3,4,10,2,5,11,5,6,4,9,5,6,10,16,6,4,3,15,10,13,4,4,4,6,
4,7,14,6,4,3,5,7,8,6,3,9,14,13,3,5,15,4,5,3,22,6,4,3,5,8,31,14,3,7,6,10,
6,4,3,6,3,5,6,6,3,3,8,5,6,5,6,4,7,4,7,10,4,6,5,4,4,10,9,5,10,8,4,4,
15,8,6,4,11,19,6,5,6,4,4,16,6,9,5,5,6,4,2,8,6,3,17,3,9,9,5,3,3,14,4,5,
6,4,4,5,12,4,16,4,4,4,3,7,3,5,6,3,4,8,8,7,16,6,4,13,5,4,3,6,6,3,6,6,
7,9,5,7,6,3,16,6,14,6,6,8,11,5,2,4,12,7,5,3,4,5,3,6,5,3,6,6,5,3,17,6,
5,15,10,6,11,6,3,3,14,4,16,7,10,6,12,4,5,3,13,4,7,3,6,5,4,20,4,8,5,19,6,7,
14,5,5,7,19,8,6,8,6,5,5,4,4,14,6,3,6,4,8,3,4,3,6,5,4,18,8,15,6,6,5,5,
4,13,5,4,11,4,5,5,4,9,5,19,5,3,3,5,7,6,8,4,3,7,3,7,3,6,5,7,3,9,10,5,
6,6,5,3,6,6,16,4,4,6,4,4,15,8,14,5,10,5,5,14,6,6,13,4,6,5,5,5,8,4,4,8,
9,7,7,17,4,5,3,3,3,6,5,4,6,5,4,7,2,9,4,5,7,22,7,6,8,5,3,5,5,5,4,14,
5,7,5,13,5,10,17,6,4,7,18,5,13,4,10,8,11,10,15,4,7,6,4,6,14,12,6,5,8,2,7,14,
2,4,11,5,4,15,7,3,5,5,4,5,6,6,5,6,5,6,2,5,3,3,10,11,4,4,6,3,6,5,20,15,
8,7,5,5,4,6,9,4,14,4,6,6,18,13,6,13,4,3,4,4,5,4,14,4,7,21,5,2,6,4,6,3,
7,19,11,9,7,4,5,4,4,4,4,6,10,5,8,17,6,4,6,6,6,5,8,2,7,6,6,3,4,5,5,3,
8,15,4,20,3,6,8,7,6,4,11,11,3,5,4,9,10,16,5,9,15,7,3,7,6,9,8,12,19,4,8,3,
4,8,5,11,9,3,6,5,4,4,6,5,11,16,2,8,4,17,6,9,6,21,6,3,5,10,7,4,6,5,6,6,
5,7,3,5,6,13,4,5,6,4,5,17,11,6,4,20,4,6,4,6,15,4,7,6,3,7,3,8,6,6,3,4,
6,5,4,4,3,6,4,18,6,5,4,9,5,2,10,5,6,3,5,6,6,6,5,8,5,14,6,3,5,5,4,4,
3,6,7,5,8,7,3,6,8,5,6,4,4,14,3,8,3,3,8,6,7,9,5,6,3,6,8,6,3,6,5,14,
15,4,5,5,3,5,3,5,3,6,7,6,11,4,6,6,6,6,18,4,10,5,4,5,7,6,4,6,6,6,2,5,
6,9,5,4,6,4,4,5,6,3,3,6,4,6,5,4,3,5,4,7,8,6,4,4,2,5,6,6,3,5,5,4,
4,6,6,6,6,4,4,6,3,4,3,2,4,4,12,6,6,13,3,4,6,2,4,4,6,6,4,5,3,13,3,6,
5,5,6,10,4,2,4,6,8,5,5,4,4,4,6,5,13,3,5,15,14,6,5,4,3,4,6,4,8,3,4,5,
5,3,5,10,2,11,4,6,6,7,5,5,3,5,16,8,4,4,6,2,6,3,5,4,5,6,10,2,7,16,6,5,
3,7,5,6,5,16,9,7,9,7,14,3,2,4,17,5,7,7,4,6,6,4,7,2,5,6,8,3,3,2,4,3,
3,24,5,8,6,6,13,5,5,4,6,8,2,2,6,8,7,6,6,3,9,6,6,10,3,6,4,21,6,6,6,5,
3,5,5,4,4,3,7,6,8,13,5,4,4,5,4,3,6,10,6,3,14,2,14,5,4,9,16,16,5,5,6,11,
3,3,4,3,6,8,6,7,5,4,6,6,5,6,4,5,5,6,3,4,5,3,3,5,6,15,3,9,6,5,5,4,
4,5,6,6,7,3,7,5,8,5,3,4,5,4,9,11,5,3,6,6,5,5,8,9,4,6,3,8,3,6,5,4,
5,13,14,5,6,15,5,6,5,4,6,5,8,3,5,4,5,3,3,5,16,6,6,4,14,3,9,16,4,8,6,4,
4,6,7,7,9,6,5,3,4,6,4,6,5,6,3,6,4,5,6,6,5,4,5,13,7,3,5,12,6,5,13,5,
15,6,4,6,5,5,8,6,3,5,7,5,16,6,3,4,6,4,5,6,5,4,5,7,7,6,6,10,17,2,7,11,
9,5,14,4,13,4,4,7,4,7,16,7,2,10,20,5,4,6,4,3,5,4,4,6,5,5,6,5,8,9,6,18,
4,17,5,4,6,4,10,12,5,6,5,6,4,12,5,4,13,7,3,7,6,6,6,4,5,6,5,5,6,7,6,3,
13,2,3,5,17,8,3,3,12,8,7,5,4,13,4,6,4,5,8,5,7,7,7,11,5,5,19,11,5,3,7,5,
7,2,6,4,5,5,4,5,17,6,6,11,3,6,6,3,2,4,6,9,13,8,6,5,5,5,5,6,9,4,4,16,
11,4,4,5,4,8,4,6,3,5,6,2,4,5,6,4,7,5,17,6,6,3,6,17,8,3,6,8,4,4,3,7,
7,5,4,6,6,6,4,5,6,8,4,10,5,7,2,7,5,6,5,3,4,15,19,13,8,3,6,6,5,5,3,4,
5,3,8,5,5,6,3,5,6,7,2,6,8,2,12,16,6,7,5,13,3,20,6,12,14,4,10,5,6,8,6,6,
8,7,4,23,6,5,6,5,12,8,5,5,4,7,4,6,14,10,3,3,5,6,5,4,7,6,5,13,6,6,4,13,
5,6,5,15,7,3,6,5,8,5,9,5,6,12,11,4,4,4,6,5,4,15,5,11,5,7,4,7,3,4,5,17,
5,4,5,3,12,8,9,3,4,4,4,5,4,5,5,17,8,5,4,4,2,4,5,5,9,8,7,4,4,3,12,3,
4,5,14,15,5,3,5,5,2,18,8,6,4,4,7,6,3,4,16,6,4,3,8,4,4,5,9,5,5,3,5,4,
8,7,4,5,5,11,7,14,6,4,18,3,7,13,5,5,3,4,8,6,9,21,7,5,5,5,16,6,5,11,2,15,
17,6,13,6,5,8,11,9,4,14,5,4,3,6,6,12,5,5,7,6,3,5,5,15,15,21,6,13,11,5,9,5,
3,5,2,7,4,14,3,13,4,5,16,13,4,4,3,24,9,6,4,6,6,9,8,5,11,6,5,4,8,2,4,7,
7,11,4,4,5,5,15,4,6,12,4,5,5,3,3,7,7,5,5,4,5,4,10,12,5,6,3,5,7,6,6,12,
6,3,5,5,14,5,8,20,3,4,6,6,5,5,12,9,8,8,10,6,6,9,10,14,3,12,4,18,10,3,2,6,
4,5,5,5,4,7,6,7,10,4,2,17,3,6,5,4,5,4,5,20,5,11,5,8,5,5,6,6,14,6,2,7,
4,4,3,6,6,4,4,16,5,9,8,5,4,6,13,7,4,6,7,16,5,8,10,4,6,7,3,4,5,17,4,4,
5,3,5,3,3,5,8,5,6,6,4,5,4,7,4,4,11,4,14,4,3,4,7,6,5,4,3,9,6,8,7,18,
5,3,13,6,4,5,17,6,4,5,6,3,17,8,6,4,3,4,6,18,4,4,3,4,8,16,5,6,3,2,3,5,
7,12,15,6,9,5,7,5,14,4,10,6,9,8,6,4,8,7,8,15,4,4,3,6,15,14,13,6,5,6,5,4,
9,4,6,12,4,4,7,3,5,8,4,4,8,4,6,5,6,5,4,13,3,5,5,6,3,6,7,6,15,6,4,6,
6,5,3,4,3,7,5,10,3,5,5,6,4,6,5,8,4,4,3,11,3,3,11,10,3,5,5,5,3,5,3,4,
17,5,3,6,5,5,7,4,4,5,8,4,8,4,4,3,2,4,5,20,6,7,8,5,5,3,3,4,17,9,6,6,
6,5,19,5,8,4,5,6,4,4,4,5,6,3,6,8,4,2,6,5,6,5,6,3,3,5,15,5,5,4,21,6,
20,15,6,4,4,14,5,6,10,6,4,6,5
} ++ [_]u8{0} ** 16;
const LO = [N]u8{
36,9,170,212,221,181,20,189,60,200,214,84,93,195,8,78,44,75,237,45,147,172,187,134,
26,70,83,195,37,182,12,70,233,94,161,206,182,95,73,222,233,82,153,1,6,33,243,230,
186,166,121,125,221,176,188,62,101,165,56,51,114,206,254,211,130,154,201,115,181,78,187,215,
53,164,146,84,207,206,194,222,208,125,123,89,139,35,108,191,67,28,92,102,175,233,194,90,
11,6,36,28,98,145,108,38,146,39,228,197,90,34,185,147,24,79,245,28,195,185,45,220,
93,84,217,125,125,97,195,82,247,106,158,216,180,88,55,178,127,40,171,79,52,195,148,213,
237,88,177,37,68,63,47,7,217,191,235,162,12,53,121,23,107,60,22,55,14,92,111,11,
106,174,145,209,96,55,114,190,158,194,161,126,150,42,144,36,93,37,237,99,249,69,210,53,
209,129,252,60,220,142,77,189,50,141,106,221,145,54,34,56,155,117,73,53,117,68,221,145,
8,193,5,126,183,2,9,89,72,5,109,72,139,16,176,64,115,98,81,179,80,226,21,233,
135,105,23,193,214,101,24,7,20,7,236,147,204,4,92,214,236,199,106,12,178,104,170,38,
39,160,223,156,1,223,136,24,62,219,138,58,139,193,31,66,47,204,183,82,196,105,107,115,
89,167,235,107,135,18,128,190,51,172,129,144,202,180,208,186,186,213,231,218,227,159,193,7,
174,17,51,203,30,192,147,150,79,155,17,26,176,102,241,67,176,91,56,144,33,72,211,103,
164,178,61,133,40,232,88,172,15,11,125,239,252,181,167,171,245,11,94,33,246,196,233,31,
100,37,65,194,84,17,147,206,11,156,62,19,151,37,145,13,10,126,5,103,110,249,146,169,
71,100,181,199,143,39,245,146,95,39,53,144,73,152,37,48,123,171,131,87,127,26,170,234,
17,162,9,193,213,74,42,3,124,96,85,191,236,44,232,64,147,187,62,74,95,180,71,178,
29,253,202,216,122,143,11,152,103,61,192,243,146,200,107,113,214,208,198,239,128,194,166,176,
148,138,81,110,167,48,11,3,36,42,179,60,130,22,156,76,10,212,191,35,132,173,128,9,
38,223,126,0,198,180,227,138,167,255,155,255,23,172,33,15,38,112,21,65,21,40,164,16,
2,125,228,143,253,10,73,192,98,209,254,235,119,207,72,175,12,109,80,146,236,100,212,55,
31,93,18,169,217,154,26,80,42,240,231,15,175,197,67,9,54,96,201,111,10,85,187,184,
124,173,8,175,198,21,11,18,44,104,49,180,218,204,90,32,157,9,12,140,88,193,91,200,
2,143,159,125,134,97,169,75,55,46,194,22,213,184,85,175,102,79,169,102,227,221,184,161,
19,154,66,60,157,207,97,144,49,178,238,248,84,149,252,131,162,97,203,173,199,201,1,95,
148,210,189,2,103,138,13,232,148,98,6,246,13,160,196,212,103,246,186,244,66,151,60,35,
248,18,154,23,57,68,148,123,3,2,177,229,173,247,9,13,57,203,49,58,64,154,226,206,
65,33,238,84,74,80,38,173,144,81,52,52,250,190,64,188,218,32,61,183,185,41,91,182,
197,225,116,216,149,114,4,44,115,11,48,168,180,92,203,233,164,170,200,199,165,62,168,12,
242,205,101,68,16,218,122,189,120,188,99,63,106,215,228,47,206,194,213,236,23,166,46,57,
96,94,151,157,240,187,157,208,207,220,107,218,78,118,172,141,87,147,186,195,208,167,179,104,
67,175,247,72,211,145,194,102,235,111,40,122,149,179,97,109,10,37,94,4,253,170,41,61,
234,197,105,40,126,68,61,53,14,119,83,38,0,97,165,174,13,36,201,213,213,8,41,249,
86,175,148,34,234,106,226,87,168,49,202,174,27,13,219,22,161,199,6,15,167,18,87,11,
177,28,0,19,199,107,205,169,34,208,116,56,16,210,137,123,83,0,187,35,65,92,112,183,
62,150,245,7,2,77,56,14,58,187,203,190,185,11,33,23,27,25,182,30,158,198,111,29,
52,202,172,236,139,17,113,192,78,48,168,215,10,106,150,51,146,95,38,78,154,107,122,42,
3,220,184,175,55,151,102,79,72,55,182,90,171,41,188,117,120,144,124,66,127,113,1,223,
160,63,165,76,211,89,53,175,34,52,46,121,209,225,100,178,24,69,93,174,19,98,163,99,
35,118,147,71,176,77,149,70,210,85,19,8,153,195,83,11,125,191,60,88,72,158,219,212,
216,90,72,83,40,204,38,31,165,25,57,72,38,62,189,147,182,129,80,49,159,204,186,77,
229,161,142,25,246,40,76,46,43,252,22,136,232,168,207,58,41,40,8,146,217,149,45,54,
34,109,29,242,177,237,158,99,103,125,35,40,102,68,230,181,22,189,203,69,8,103,109,52,
43,142,30,231,210,237,26,177,183,22,163,39,122,91,79,60,246,131,2,72,44,90,53,60,
143,201,157,128,36,60,76,54,31,50,86,169,59,41,126,17,169,2,51,144,106,100,174,233,
119,116,95,42,92,44,3,49,164,200,123,29,60,112,32,150,211,214,2,173,59,183,12,126,
30,102,215,92,185,205,219,180,57,140,35,28,125,190,69,195,192,52,175,96,157,0,150,213,
165,192,55,77,243,221,22,20,134,196,121,205,103,5,181,203,111,91,67,34,226,57,107,161,
245,96,193,138,27,168,234,197,165,52,249,148,181,164,163,142,75,171,135,12,139,185,52,170,
110,113,21,97,145,250,173,183,34,70,102,192,168,25,128,70,145,176,136,15,245,196,180,241,
239,174,29,67,131,52,118,96,2,16,49,235,160,1,4,232,195,136,105,180,186,1,190,92,
52,46,10,151,114,227,101,51,42,84,75,166,198,56,209,169,208,246,213,170,253,87,163,175,
95,193,114,78,62,111,70,190,146,85,158,59,194,160,181,30,93,102,85,83,219,69,50,95,
91,59,32,204,179,179,5,210,247,56,198,72,190,188,42,192,177,36,120,172,245,239,9,4,
232,150,210,254,99,18,69,197,71,4,67,48,63,48,99,15,58,53,4,192,28,136,217,85,
92,204,36,2,250,235,176,112,39,148,163,30,124,71,6,21,203,96,140,149,247,3,75,54,
178,127,16,110,39,124,58,35,185,157,38,51,230,43,14,27,181,4,52,91,208,127,203,67,
184,245,96,153,5,130,32,118,42,172,80,185,162,105,14,60,181,28,151,61,82,24,132,210,
88,104,209,35,14,15,106,46,200,209,28,22,228,60,24,136,89,222,86,91,16,16,159,235,
24,44,43,149,93,159,183,45,38,207,194,30,26,204,103,137,53,12,86,240,241,36,81,71,
37,28,34,206,100,176,41,60,194,104,180,61,86,85,133,180,77,135,51,164,26,45,101,166,
50,26,221,32,150,88,248,66,240,17,69,48,204,249,151,10,93,9,28,248,9,98,29,251,
248,239,96,125,5,119,115,201,85,59,141,12,19,126,29,116,99,182,245,253,108,49,22,4,
76,209,15,162,22,147,92,76,124,31,190,20,105,110,251,25,153,200,133,179,54,183,196,180,
114,170,110,37,95,64,123,22,197,221,191,181,187,30,203,66,125,250,134,179,79,138,131,47,
86,84,108,189,33,183,173,106,217,73,121,123,176,90,94,97,61,18,96,131,9,72,19,126,
75,183,36,228,87,35,205,180,143,8,158,199,107,145,97,113,2,74,196,54,82,41,191,199,
16,14,83,195,184,20,37,191,62,95,160,0,69,40,108,15,26,61,208,86,1,149,229,37,
147,11,137,181,19,31,115,246,255,102,65,219,177,134,153,246,46,66,247,8,152,82,47,242,
64,197,22,224,222,237,123,114,66,110,197,200,34,207,98,157,89,209,166,105,25,137,219,29,
219,170,188,22,13,36,193,178,229,119,15,190,75,106,5,193,236,47,204,171,204,19,205,249,
45,105,19,56,82,150,24,110,198,0,218,179,170,68,17,250,153,95,144,225,51,53,174,195,
222,124,28,11,18,11,182,61,48,124,25,135,24,44,113,81,14,167,126,30,205,32,165,191,
20,13,78,210,131,194,155,235,50,74,112,0,201,110,130,71,145,198,91,177,6,197,132,107,
17,101,66,38,171,161,19,130,35,165,66,200,87,101,5,182,203,139,179,124,218,5,153,201,
98,191,195,35,101,176,232,145,146,176,17,160,4,63,139,81,152,185,190,111,34,180,71,5,
197,90,16,63,168,192,192,104,62,102,74,199,83,194,241,137,94,212,80,181,120,5,162,116,
54,15,27,251,249,194,18,34,23,214,28,189,117,94,109,80,216,45,46,193,168,230,126,29,
87,41,234,8,29,36,5,177,149,83,106,198,43,197,165,224,119,197,164,161,37,162,32,87,
165,51,64,30,250,216,194,162,41,55,220,161,161,245,125,101,59,27,86,231,181,70,134,202,
231,176,159,176,196,118,15,133,202,112,220,88,36,26,129,29,199,182,111,148,104,16,51,115,
73,215,16,207,219,12,25,188,174,217,169,195,127,29,212,228,219,47,65,79,120,89,34,112,
216,50,169,212,184,79,172,102,73,241,104,10,12,99,189,5,17,238,196,64,152,6,198,15,
163,245,18,11,166,84,198,146,16,4,95,191,86,230,219,54,16,37,24,244,7,174,155,184,
217,202,19,181,45,68,252,32,144,29,62,38,186,209,53,152,77,245,200,231,17,218,60,130,
154,80,144,171,189,218,29,244,146,33,49,166,203,51,13,2,19,43,103,181,38,196,198,117,
32,207,179,184,47,177,74,170,198,64,39,181,84,240,124,214,39,220,46,184,100,78,224,28,
38,211,25,29,3,189,146,101,177,20,160,12,87
};
const HI = [N]u8{
34,32,33,42,33,34,4,37,42,33,0,41,41,34,35,4,0,34,34,34,33,42,212,34,
33,34,4,41,42,34,35,33,39,0,33,33,33,32,34,34,39,37,3,251,42,34,34,0,
33,212,34,34,0,41,33,32,34,34,42,41,1,212,33,42,34,33,41,42,3,34,42,34,
34,33,34,33,41,0,34,41,34,42,34,1,34,4,37,37,42,32,37,38,42,34,42,37,
32,42,33,37,32,41,34,4,3,42,33,41,42,213,42,37,32,213,39,33,34,34,42,0,
213,42,2,34,42,34,212,34,39,34,42,42,0,1,1,33,34,1,42,34,42,42,3,34,
42,33,35,213,34,42,1,34,33,37,39,42,34,41,42,213,1,1,32,33,38,41,42,32,
34,0,34,0,0,4,41,33,34,37,42,42,34,41,33,0,1,41,0,38,0,4,3,4,
3,34,0,4,32,34,1,0,4,34,42,35,33,4,33,213,3,34,41,32,1,34,3,33,
32,42,32,34,33,1,32,33,34,213,1,33,34,33,35,213,39,34,34,34,34,35,35,42,
34,37,34,33,34,34,1,4,32,1,0,34,42,4,0,42,42,0,34,1,34,34,42,32,
213,0,35,3,1,34,34,33,213,32,34,1,42,33,35,42,213,34,42,41,0,34,213,34,
4,41,34,41,34,213,34,34,34,34,34,33,33,37,0,42,33,3,39,34,34,34,212,34,
33,33,34,34,4,42,42,42,34,34,33,32,42,42,0,1,33,42,34,42,34,34,0,34,
34,3,34,42,41,0,37,212,34,35,42,37,39,42,0,212,3,34,33,1,3,33,0,34,
1,34,34,33,1,3,34,34,35,212,0,35,34,34,34,213,35,42,34,34,34,39,1,42,
1,213,212,33,34,0,33,33,213,4,213,41,34,33,0,213,34,41,42,42,34,1,37,34,
42,0,0,34,3,34,4,34,42,38,37,3,34,34,39,1,33,3,1,41,32,34,33,212,
34,34,0,34,34,34,34,42,37,0,0,0,33,3,34,1,3,33,42,42,34,34,33,0,
33,42,41,34,33,32,33,32,1,0,37,213,42,213,41,42,1,33,212,42,37,33,42,34,
34,0,34,42,33,41,41,42,34,33,33,0,1,33,32,32,1,34,42,4,4,33,0,37,
33,34,41,34,0,32,1,34,41,33,0,0,34,212,34,0,4,34,34,34,39,34,33,34,
41,0,42,0,34,41,4,42,213,3,34,41,42,42,34,1,35,38,3,34,35,1,33,212,
0,34,34,212,33,33,32,1,33,34,34,34,0,42,41,39,33,34,41,41,42,34,0,39,
33,41,3,42,34,37,3,4,213,0,33,32,42,34,213,42,34,34,212,37,34,2,0,37,
42,33,4,34,33,33,213,33,1,41,42,39,4,34,37,34,212,34,33,42,34,212,34,0,
34,33,33,37,41,34,33,39,33,34,35,3,42,3,42,33,34,41,42,34,34,33,41,0,
37,34,34,39,32,42,34,0,34,42,0,0,0,0,34,33,213,212,1,4,0,3,34,33,
34,32,0,37,213,1,34,37,34,37,32,34,39,33,38,33,34,4,213,212,41,41,41,42,
3,34,34,34,41,34,32,213,41,32,33,0,34,34,33,39,41,212,212,42,33,32,41,34,
0,212,38,1,1,33,34,3,42,0,1,34,213,34,42,0,41,33,33,34,4,0,35,42,
1,213,34,34,0,33,42,33,34,2,37,34,34,34,0,41,1,33,34,37,41,42,41,34,
213,41,39,34,33,42,3,0,42,34,33,42,33,34,32,42,33,34,1,34,42,37,1,4,
0,42,41,4,41,34,0,34,4,34,42,34,34,32,34,42,41,34,33,33,33,4,34,39,
42,34,33,1,34,38,34,33,3,32,37,41,41,1,34,4,37,2,38,4,3,33,4,32,
0,32,37,39,2,34,33,34,34,34,1,1,32,0,34,34,37,37,34,34,32,1,42,34,
4,41,34,32,34,34,4,1,42,0,42,212,37,34,213,42,213,4,35,32,34,42,41,41,
213,34,41,37,42,1,42,33,41,1,34,33,213,1,42,1,42,42,42,34,34,34,1,0,
41,3,37,0,34,33,34,32,41,42,3,1,33,41,3,42,41,33,34,213,41,34,4,34,
34,4,0,4,33,34,1,42,4,37,4,41,3,0,34,0,33,42,33,37,4,37,3,41,
34,41,41,42,34,213,33,1,34,4,33,34,34,37,34,33,41,33,34,213,1,3,32,34,
0,33,4,34,213,42,0,1,34,32,41,33,34,0,0,34,42,34,34,33,33,212,34,42,
33,37,42,32,39,41,1,34,4,39,35,42,34,0,0,0,33,34,1,33,34,42,34,1,
32,42,32,42,33,39,33,38,213,0,41,34,1,4,34,42,34,34,42,33,34,34,41,33,
213,41,32,0,3,34,33,41,0,42,33,34,34,213,41,37,34,34,34,34,33,213,34,0,
42,0,41,34,4,0,213,213,4,34,37,41,34,42,34,33,3,32,33,34,34,34,34,34,
42,42,0,34,34,4,1,33,3,42,0,32,34,1,32,33,34,33,34,42,213,3,34,1,
35,34,0,213,0,41,42,42,1,42,35,213,42,3,34,34,212,34,42,0,34,42,34,3,
42,41,41,4,42,41,34,42,41,41,1,0,34,35,37,42,38,33,4,32,0,4,34,0,
0,41,34,34,1,42,34,3,212,1,34,42,34,42,34,34,41,34,42,32,34,212,34,37,
34,34,32,1,3,39,41,0,0,42,34,34,0,33,37,4,37,42,34,41,1,33,3,42,
34,212,34,34,34,4,1,213,251,4,213,34,0,42,42,42,33,42,34,0,0,42,42,4,
33,34,0,33,34,0,37,213,34,34,34,33,33,33,34,33,42,39,0,37,33,34,0,42,
34,41,42,34,34,1,33,41,33,33,212,1,0,42,37,1,42,38,34,1,34,41,213,4,
0,0,34,34,3,33,38,33,34,34,34,34,37,42,42,33,0,34,34,32,39,0,4,34,
39,33,33,34,32,41,33,33,4,41,34,4,0,33,213,35,34,33,34,33,33,34,0,41,
42,33,37,4,0,41,35,41,34,34,34,41,1,33,4,33,42,32,42,3,0,251,42,33,
34,42,41,41,1,35,32,213,37,3,0,32,39,34,213,4,35,42,33,37,33,34,0,32,
42,3,34,33,38,34,39,34,1,42,41,42,34,34,33,34,3,33,42,34,1,32,34,42,
39,1,34,34,32,33,41,213,36,33,41,34,42,34,34,37,37,0,4,1,34,33,212,34,
34,33,0,34,0,34,42,35,213,34,3,33,34,33,1,42,33,37,41,42,3,213,1,34,
34,33,35,34,41,212,34,42,41,37,35,1,1,34,34,37,34,34,33,33,34,33,34,41,
32,41,2,213,3,41,39,34,3,34,1,42,42,37,3,4,37,213,35,39,35,1,4,0,
0,37,34,0,34,34,34,33,42,42,42,33,213,42,32,34,32,212,3,42,41,42,33,251,
34,33,33,42,41,3,33,34,0,35,33,37,213,38,34,41,33,33,42,42,34,0,33,212,
34,34,1,34,1,42,1,34,0,3,34,34,41,213,34,34,42,37,42,37,34,34,34,33,
34,213,1,37,0,33,33,34,42,34,34,42,33,4,4,41,35,33,37,34,35,42,34,42,
213,41,33,33,213,35,33,34,34,34,33,212,34,33,34,41,42,34,34,41,4,213,33,3,
35,41,41,33,0,213,1,33,34,41,34,34,34,0,34,33,213,34,41,34,34,42,41,32,
33,4,34,1,32,213,1,0,39,41,213,0,37,34,33,39,42,38,39,213,33,34,42,34,
4,34,34,34,35,34,41,39,34,38,33,0,33,33,32,33,41,3,33,1,1,42,33,34,
2,33,33,1,32,41,0,34,33,1,34,0,1,37,1,33,34,34,0,33,33,1,34,39,
33,34,34,41,213,33,213,41,212,251,34,34,0,213,213,39,34,34,33,34,42,32,0,3,
34,0,1,1,35,34,0,41,34,34,33,42,37,37,34,4,35,33,42,34,34,34,34,42,
34,41,34,33,34,34,34,41,1,42,34,1,39,42,34,33,34,3,4,3,35,0,42,34,
34,41,1,32,0,34,41,34,34,33,34,34,32,38,34,33,37,34,212,34,33,41,42,34,
213,41,33,36,34,42,34,33,34,42,33,33,213,35,41,34,3,3,37,41,35,35,34,35,
42,34,34,1,34,34,3,41,0,213,1,34,33,212,3,34,37,34,34,41,34,34,33,41,
39,33,33,37,34,3,33,0,33,34,4,212,34,41,38,37,2,4,1,3,0,39,42,34,
34,4,39,35,33,42,4,212,33,213,34,42,34,42,3,0,42,212,34,34,41,34,41,41,
41,4,34,35,34,33,37,33,0,2,41,3,42,34,1,213,4,33,33,39,35,213,42,212,
35,42,42,42,3,34,213,41,37,34,35,4,34,32,42,1,33,41,34,41,34,42,41,34,
42,42,41,41,34,42,213,41,33,2,33,0,34,35,0,0,34,4,1,34,1,213,42,42,
2,34,0,33,34,4,33,34,4,34,213,32,33,37,33,33,4,34,34,34,33,1,2,1,
33,33,4,33,3,34,0,33,213,1,37,0,213,42,33,42,32,4,4,41,213,0,33,42,
34,33,39,33,213,32,34,1,34,33,34,41,3,42,42,34,34,39,36,42,41,2,0,34,
42,213,34,37,42,42,35,0,37,4,4,42,33,33,35,41,34,1,34,0,41,34,42,41,
34,42,0,3,34,33,4,41,34,34,41,34,34,34,41,3,33,2,34,37,37,213,34,35,
34,33,32,34,4,33,41,1,35,34,33,42,37
};
const META = [N]u8{
0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,8,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,32,0,1,0,0,32,0,0,0,0,0,0,0,0,1,0,0,
12,0,0,0,0,0,0,0,0,0,0,0,8,32,0,0,0,8,0,0,16,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,32,1,0,0,0,0,0,1,0,
0,8,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,
0,0,0,0,0,0,0,0,0,32,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,32,0,0,0,
0,0,32,0,0,0,0,32,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,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,
0,32,12,0,0,16,0,0,1,32,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,32,16,1,0,
0,0,0,0,0,1,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,32,0,0,0,0,0,0,0,32,0,0,0,0,0,0,32,0,1,0,0,8,0,0,0,32,1,
0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,1,32,0,0,0,0,1,0,8,0,8,0,0,0,0,
0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,8,0,0,0,0,32,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,32,8,0,0,0,0,0,14,32,32,0,0,8,0,
0,0,8,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,
0,32,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,8,32,0,0,0,
0,0,32,32,0,1,0,0,0,0,8,0,0,0,0,0,0,0,0,32,8,0,0,0,1,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,32,16,0,0,8,0,0,0,0,0,0,0,
0,0,0,8,0,0,0,0,1,0,0,0,0,0,1,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,0,0,0,0,0,0,0,1,14,0,16,0,1,0,0,0,0,0,0,0,16,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,32,32,0,0,0,1,1,0,0,0,0,0,0,
0,0,32,0,1,0,0,0,0,0,0,0,0,0,0,0,16,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,
0,0,0,0,12,0,0,0,0,1,1,0,0,0,0,0,32,1,0,0,0,0,0,0,0,32,0,0,1,0,0,0,
0,0,0,0,0,32,0,0,0,1,0,0,32,0,0,0,0,0,0,0,8,0,32,0,0,0,0,0,8,0,0,0,
1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,8,0,0,0,0,14,0,0,0,32,8,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,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,32,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,8,0,
0,0,0,0,0,0,0,0,0,32,16,1,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
0,0,0,0,1,0,0,0,0,0,0,0,0,8,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,1,0,0,0,0,0,0,32,0,0,0,0,8,0,0,0,0,0,32,12,32,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,32,0,0,0,1,16,32,0,
0,0,0,0,0,32,0,16,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,
0,0,0,0,0,0,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,
1,0,0,32,0,0,0,0,0,0,0,0,0,1,0,0,0,12,0,0,0,1,0,32,0,32,0,0,0,32,1,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,0,0,0,0,0,0,0,0,
0,0,8,0,1,0,0,0,0,0,32,1,32,0,0,0,0,0,0,1,0,0,0,0,1,0,8,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,0,32,0,12,32,32,0,0,0,0,0,0,0,
1,0,8,0,12,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,32,0,8,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,16,0,32,0,0,0,
0,0,0,0,0,32,0,1,16,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0,0,0,0,0,0,0,0,0,
0,0,1,0,32,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,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,32,0,
0,0,0,0,32,0,0,0,0,16,0,0,0,0,0,0,16,0,0,0,32,0,0,0,0,0,0,0,0,0,0,1,
0,0,32,0,0,0,1,0,0,0,0,0,0,0,32,0,0,0,0,0,0,12,0,0,0,16,0,0,0,0,0,12,
0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,32,0,0,0,0,1,0,
0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,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,0,1,0,0,0,8,0,0,0,0,0,0,0,0,
0,1,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,1,8,0,0,0,1,0,0,0,0,0,0,
0,0,0,8,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,32,0,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,0,0,0,0,0,0,8,16,12,0,0,1,0,0,0,0,0,8,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,
0,0,0,0,32,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,32,
0,0,1,32,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,32,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,32,0,0,0,0,0,0,32,0,0,0,0,0,
0,0,0,0,1,0,1,0,1,0,0,0,32,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,
0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,8,0,12,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,32,0,0,0,0,0,0,32,0,0,12,0,0,0,0,0,0,0,0,0,16,1,0,0,0,0,0,
1,0,0,0,12,8,0,0,0,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,
12,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,1,0,0,0,0,
0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,32,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,8,8,0,1,0,0,0,0,0,1,0,1,0,8,0,0,0,0,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,16,0,8,0,0,0,0,0,16,0,1,0,0,0,0,32,0,0,32,32,
0,0,0,8,0,1,0,0,0,0,32,0,0,0,0,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,32,0,1,0,0,32,1,0,0,0,0,0,0,0,1,32,0,0,0,0,0,0,1,0,0,0,
8,0,6,0,0,0,0,0,12,0,0,0,0,0,12,0,0,1,0,0,0,0,0,32,0,0,0,0,0,0,0,0,
0,0,8,32,0,0,8,0,12,0,32,0,0,0,0,0,0,0,0,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
};
// BLOB offset of every sixteenth slot's name.
const BASE = [_]u16{
0,144,227,340,451,565,665,776,866,964,1059,1179,1284,1392,1512,1600,
1706,1796,1915,2026,2172,2251,2352,2481,2582,2672,2777,2892,2988,3120,3239,3358,
3464,3568,3661,3773,3881,3976,4087,4224,4355,4448,4556,4684,4780,4904,4986,5110,
5251,5358,5479,5600,5692,5788,5879,5976,6074,6168,6268,6348,6425,6505,6593,6676,
6778,6879,6970,7089,7166,7277,7387,7470,7602,7683,7770,7862,7948,8057,8169,8256,
8360,8464,8572,8703,8801,8910,9005,9118,9232,9328,9435,9516,9626,9718,9828,9927,
10058,10173,10283,10395,10501,10598,10685,10796,10884,11006,11134,11263,11399,11523,11623,11723,
11825,11941,12070,12164,12278,12382,12492,12569,12682,12794,12888,13015,13138,13231,13331,13416,
13498,13590,13700,13798,13899
};
// Names in slot order, padded so 32-byte loads stay inside.
const BLOB: *const [14004 + 32]u8 = "NotVerticalBarthinsprarrhksupsubzigrarrRightTriangleEqualDcybigtriangledowniproduuarrOumlRightUp" ++
"VectorBarRightDownTeeVectorbigcupLeftCeilingyucycommanapidnrtrieiiintDownArrowsmtefscrsubseteqQo" ++
"pfsimnegjcycirEplusduorigofdrcropddRightAngleBracketHatDarrnhArrcularrThickSpaceNotTildeTildecue" ++
"prrangleboxdRIotafiligxsqcupmeasuredangleisinsvaeligolarrKscrNotGreaterLesssucccurlyeqYacutebemp" ++
"tyvLeftVectorOverBarGreaterEqualbottomodivrarrcUogonyscrroarrsubsupvnsubnleftarrowboxboxEsimepsi" ++
"bumpPrgtrdotbecauseLeftTeeArrowsqsupefrac23NotLeftTriangleBarIcircIntersectionnvinfinSubsetnless" ++
"crcaronvsupneUcyboxVHdtrincapOpenCurlyDoubleQuoteboxUldiamondsuitpreceqscnsimsupmultboxURNegativ" ++
"eThinSpacebigsqcupintegersboxvrInvisibleTimeslangdtwixtTScyBetaplustwoLeftArrowBarbsolbandvefrpr" ++
"napblk34OpenCurlyQuoteXopflongleftarrowrealxcupherconloplusUumllopfOrdotsccuelesCongruentnscrefD" ++
"otlongleftrightarrownLtvsimgsupdsubacuteRcaronkcedilldshsuccsimItildelatbumpelotimessubedotDelta" ++
"eparbNotfrac45rmousthfrnsimeqamalgiogonnablaswArrtriangledownRangGreaterGreaternotnicudarrrltcir" ++
"TfrumacrlcedilVerbargimelphoneRightUpTeeVectorapacirNegativeVeryThinSpaceLtregsqsubseteqNtildegr" ++
"avezcysimrarrupharpoonrightplusbltrifLessLessGreaterSlantEqualCircleMinusswnwarslarrdollarscirch" ++
"ksearowiacuteclubsugravekhcyUpsiiecyvarthetaNotSucceedsuumlmcyDotDotUnionPlusomacrfrac12vcycupdo" ++
"tsimdotUnderParenthesisShortUpArrowzhcyTRADEAopfLambdaNotGreaterTildeUarrocirbprimewcircNotTilde" ++
"Equaldigammauparrowpuncspsubmultemsp14precsimcurarrAbreveThinSpacefrac16apBfrubreveiisupsetneqim" ++
"aglinelmoustIopfrbbrknequivdoteqdotvrtridoteqtrpeziumtelrecvBarvSupersetEqualboxHUlowastrhardltd" ++
"otgeqEogonYIcymdashcacuteigraveSquareIntersectionsupsetneqqJukcybsolsupsupNotCcedilnLtCcaronvart" ++
"riangleleftlvnEsmtmldrjfrnbspUnderBraceMuamacrcurlyeqsuccnsubeweierpGopfTripleDotsubnelacuteless" ++
"eqqgtrrightharpoondowndrcornncuprfrrightthreetimesprecapproxLeftVectorBarAumlgvnEzopfgtrsimljcyu" ++
"wanglentrianglerightllhardsupeOfrnprecangrtvbawconintnvdashnscleftarrowdowndownarrowsblacktriang" ++
"leETHscnapcirclearrowleftphivrobrklegNotSquareSupersetEqualminusblscrDelnharrimagpartCounterCloc" ++
"kwiseContourIntegralleftthreetimesOcysuppluslesgeseqslantgtrbumpeqoastIfrlsquorscesdotentildeNac" ++
"utelshorvdotminusgsimlangmsdthkapOacutegeqqDownTeebetabacksimlessapproxtoeaegraveboxuRQscrprodRi" ++
"ghtFloornleqslantxcirclongmapstoprecneqqsectPscrstraightepsilonSuchThatfrac78gdotbackepsilonRigh" ++
"tArrowLeftArroweacuteangrtTcaronsparnsimdownharpoonrightRacuteDownBrevesqcapcuveerfloorAscrGTpro" ++
"fsurfotimesparSquareSubsetEqualJfrLeftFloorngeqslantemptyngEnltLongrightarrowfnofgesccNcaronsopf" ++
"ZscrllarrSquareSubsetaposDownArrowUpArrowrarrnopfCHcyxfrrbrkslunapsearrpercntsfrsuccangmsdadlesd" ++
"otororslopeNotSucceedsTildeEcaronsqufntriangleleftawintcentTabbigveevarphiapeHARDcyExistsgtquest" ++
"spadesuitboxdLomicronnltrieIntLeftAngleBracketlmidotShortDownArrowlambdalcaronlurdsharMediumSpac" ++
"eltrieeeWscrProportionalnotnivcEcircnLlprecsqsubnivegsdotboxHubneAgraveoacutesrarrpsiNotGreaterG" ++
"reaterudblacvarpiDoubleLeftArrownsupseteqqcirmidNotPrecedesbigcapmapdegleftrightarrowgnapLeftUpD" ++
"ownVectorNotLessmapstodownpermilHilbertSpaceemspHcircastbigtriangleupEopfgesdotoSfrvangrtccupsCd" ++
"otDoubleLeftRightArrowjscrplusacirlhblkleftrightsquigarrowgesdotnotinvanshortparallelszligprsimb" ++
"igodotLeftArrowRightArrowlaemptyveparslgnapproxmodelshoarrnrarryumledotlooparrowrightDaggerrlmHs" ++
"troknleqpointintscyIEcyZfrcurrenboxdlCopfSucceedsSlantEqualsmeparslNotSquareSubsetyacutehairspna" ++
"posWedgelHarDoubleUpArrowthorneumlGreaterLesszscrasympstrnsKJcyNotCupCapnedotSquareSupersetEqual" ++
"loangleqiffColonlarrbfsrbrackrppolintcopynGgvzigzagKcyccupssmmfrkappavgnsimdbkarowpresubseteqqTi" ++
"ldeEqualccirctopbotspadesomegangtlfloorracutecirclearrowrightcscrvertnvDashisinTscrleftrightarro" ++
"wsnaturalsZeroWidthSpaceEmacrBernoullislneqqcwinttrianglelefteqUacutevsupnELeftTeeVectormaltnrar" ++
"rwnotinlbarrrbrkeandslopexveelsqbbsolhsubcomplexeslbrksldOmicronNotLessSlantEqualsubeboxvLohmycy" ++
"zfrperioddharrVertsubsubmumapdopfnpreceqlEHumpEqualNscrboxHDnsqsupeDiacriticalDoubleAcuteCedilla" ++
"SquarescpolintnlarrtcyTilderarrwnrArrpopfShortLeftArrowimathcemptyvrnmidLongleftarrowjukcyCircle" ++
"PlusFilledSmallSquaresupsetGscrbnequivReverseEquilibriumlatesdivideontimestscrcomplementUnderBar" ++
"SquareUnionRightarrowleftharpoondownboxvldrdharvsubneHopflangleLeftRightArrowNotCongruentBarwedb" ++
"epsifpartintPisupedotLeftrightarrowgEdsolsuccnapproxisinsesimUpperRightArrowcurarrmnumultriminus" ++
"ocircrosslsaquocapandsqcuplbraceexistxotimepmaringshydivNotElementquaternionsBopfvscrinodotkcyco" ++
"mmatKappaNotSquareSubsetEqualnLeftrightarrowNotTildeddaggericircboxDRSopfOdblacnparallelrectSqua" ++
"reSupersetboxVtprimethere4LongleftrightarrowRightUpVectorfemaleleftharpoonuplesgRcyFopfbscroperp" ++
"tosaRightTeeVectorscnEupsilonNotSucceedsSlantEqualnlsimLlgtlParlsimemsp13ofrlarrsimNegativeMediu" ++
"mSpaceexpectationDoubleDotnvltrietrielrharrangangeOscrsscrsubsimUpTeeArrowolineangmsdaaNotRevers" ++
"eElementogravexscrheartsnacuteDstroklAarrPrecedesnuequivDDfrac14tcedilacdyopfgtdotDashvsolrtrilt" ++
"riRightDownVectorvArrNotLeftTriangleEqualZcybrvbarprofalartriplusScaronmopfCircleTimescircleddas" ++
"hethorarrsimlLeftarrowcurlywedgeDiacriticalTildeboxVhlesseqgtrNotHumpDownHumplessgtrnotlbrkslurc" ++
"edildownarrowintercaltriangleleftNotRightTriangleBargtccraemptyvlnELopfangmsdahxharrthickapproxD" ++
"ownarrowlgEsigmaffjligVbarngtrzeetrfgtcirupdownarrowvartrianglerightafncongdotgscrDoubleVertical" ++
"BarScedilNotExistsnparslFilledVerySmallSquareitildencyecircnsubseteqqrdldharSHcyufishtnsimeequal" ++
"sbecausUbrcygtrlessAndnsparForAllApplyFunctionperpbumpEbkarownmidrrarrDoubleUpDownArrowUpdownarr" ++
"owJsercycapsDoubleLongRightArroworornVDashharrGcedilNotLeftTrianglesungnsqsubefrac35Psipertenklo" ++
"zangmsdaglAtailccarongelZHcysquarecaronstarDZcyChilagranyicyNegativeThickSpaceplusmnldquoboxhche" ++
"ckmarkHacekggnLeftarrowVdashangsphSubWcirckgreenhyphenOgravensupeSucceedsboxDrHorizontalLineveeb" ++
"armidcaretScircnapEimofocyltrParisindotnumspPartialDasympeqicyDcarontriminusraquovsubnEiscrrtriR" ++
"everseElementdfrintlarhkXfrJcybbrktbrkldquorboxplussupseteqqduharlarrfswfrrtimesangmsdaetridotlE" ++
"gdstrokeplusrightharpoonupLeftRightVectorIdotvDashneArrGfrUmacregsijligglEwedbarplussimBumpeqcir" ++
"cledcircnGtvzacutemidastnvrArrGammadblacktrianglerightmacrProportionnearrleqqbsemiharrcirOtimesz" ++
"etaSacutelarrlpseswarmuEqualgtrarrLeftArrowprcueKopfdfishtngeqIOcycuesctimesbpcyyensoftcydArrwed" ++
"geqjcircnpreTcyboxhuYUcysubrarrthetasymaacutenvlesup2wpcuporfrac58markerGcyboxVlSigmauHarsmidltl" ++
"arrlparltcapcupprurelVopfvarrncedilCapdscyellinodotltririsingdotseqhamiltrfishtupharpoonleftsimg" ++
"opfncaronXitdotforkOslashfrac56shcyerDotkfrvarsupsetneqqAMPgbreveUpTeersquolarrplImaginaryInparg" ++
"thalfsqcapssuccneqqnsuccesdotFscrUarrwscrintcalccapsRightArrowBarsqugsimeCloseCurlyQuotelongrigh" ++
"tarrownesearOmacrointYcyxmaptargetgneqprecnsimDotIumlcoloniiotaveeCcircRightArrowGgeqslantlessti" ++
"ntKcedilbulletcongdotrdquonhparRshroangtwoheadleftarrowclubsuitvopfrcubnwarhkorTstrokfcylnsimprn" ++
"EsetmnbarveesubsetneqqDDElementGreaterFullEquallrhardordernfrrbrksldbdquoccedilupsihntrianglerig" ++
"hteqrationalsdemptyvCenterDotquatintrightarrowtailandprjopfRightUpDownVectorboxvhnotinvcnsupsetp" ++
"artapproxbernouiopfBecauseltlsimgEacuteangrtvbdnprFcyLTUopfyfrPcyClockwiseContourIntegralboxDlan" ++
"gmsdabhomthtmcommaPrecedesTildeimageOmegaenspphmmatsqsupsetlllenVdashsuccnsimddotseqColonelowbar" ++
"cuptriangleqSOFTcyabreveFouriertrfTausupsimlcubCloseCurlyDoubleQuotethksimUdblacdaggernwarrCupnw" ++
"ArrnpartlateDopfetanotnivazcaronllcornerLessFullEqualtimeskopfsup1trisbmlcpscELacutegtreqqlessss" ++
"mileYfrLessSlantEqualxiTildeFullEqualUnionkscrthereforeNotPrecedesEqualDiacriticalGraveodashxodo" ++
"tominusstraightphiglaoltrdcaecyparsiminfintiessetmnnpolintroparsolbZacuteIacutengeqqbarwedutrisu" ++
"bnEsharpfrac18ucybullacircjcynGtiexclotildeLeftUpTeeVectorVeesubsetneqecaronlesccnltriupsiJscrJc" ++
"ircnotinEgeslesnvrtriegljLeftTeeuplusldrusharVDashlnezwnjsupnedscrThereforeblacksquarenlessngeho" ++
"rbarscaronAlphaxhArrangmsdafcenterdotquotcupcapnlEbigwedgedieprimesuhblktscyblk14SucceedsEqualNo" ++
"tSubsetEqualrBarrgacuterightleftarrowsdeltatopcirctdotSscrproptosimeqSupersetdcyYcircoopfflligAc" ++
"ytfrnrtriNonBreakingSpacexoplusxuplusvBarLeftDownVectorgnegvertneqqDiacriticalAcuteordmbigopluss" ++
"updotkjcyoscrconintNewLinenearrowLessTildeatildeboxhDvfrcupscoloneapidmapstolrarrdalethSuplarrhk" ++
"csupxrarrOtildesquarfloarrcirepoundPrecedesEqualquesteqogtpluseHumpDownHumpmstposuringDifferenti" ++
"alDolcirShortRightArrowfrac15CscrLcedilAcircsimgEtriangleGbreveorddiamseqcolonoeligGreaterEqualL" ++
"essrarrplufrdzcylbracksemianglerthreegammardshstarfImpliesnotinvbminusdsstarfTildeTildeblacktria" ++
"ngledownScminusduRightVectorPlusMinusnsmidNotLessGreatereuroLongLeftArrowiumlLJcynexistslangnwar" ++
"rowDoubleRightArrownotnivbicUpArrowBarCapitalDifferentialDudarrchcynvHarrsimeacyquestEscrropfulc" ++
"ropmDDotalephnexistrharurealpartnsubseteqUgraveRightDownVectorBaranddrightleftharpoonsboxvlDJcyu" ++
"acutelozflmoustacheRoundImplieswedgesqcupsdashvrarrfszdotExponentialEIukcyNopfvarsubsetneqqNoBre" ++
"akgElEpsilondivideffiligcapcapbethvltrilesdotRBarrudharhstrokangzarrrsaquoffrtrianglerightNuampP" ++
"rimeLeftDoubleBracketIntegralKfrLcyUnderBracketbiguplusorderofboxuLlArrSucceedsTildeEumlhybullsc" ++
"apepsivNotEqualswarrbigstarnsubsetmalteseLessGreaterImacrsmtesDownLeftRightVectorprecnapproxvdas" ++
"hgnEplanckhnvsimepsilonReelsdotraceOEliglsquonsubcsupeVerticalSeparatorUtildeSupsetVerticalBarlr" ++
"mhslashlharulqfroSuArrrAtailBackslashDoubleLeftTeethicksimcompfnblockboxUrTHORNiukcysacuteCoprod" ++
"uctIscrDscrNotRightTriangleSmallCircleBscrplusoplusrsqbboxminusprapcylctyifrcuwedsigmavrxSqrtrlh" ++
"artstroklnapalefsymboxdrDownLeftVectorBarmidcirvarrhogfrodblacNotTildeFullEqualparallelRfrsfrown" ++
"curlyveerHarUscrcapintprodcirscirboxhUtbrkLcaronRcedilecolonnsuputrifCupCapsupseteqMscrmapstolef" ++
"tradicCayleysgedwangleprimerataildblaccfrZetaLeftUpVectorBarDoubleLongLeftArrowNotEqualTildevark" ++
"appaSumNcediltimesdsupnEurtriEtaNJcyboxULFfrulcornerxlArrrceilTcedilNcyucircoslashbigcircnerbrac" ++
"eemptysetglGreaterTilderightrightarrowsandandtritimelsimePoincareplanePfrNotGreaterSlantEqualrdq" ++
"uorNotLessTildeInvisibleCommaascrvarepsilonparslrharultimesbarnumerofflligbackcongUparrowhbarNot" ++
"NestedGreaterGreaterRarrtlGammafrac38bcongVerticalLinelrcorneruharrboxurxopfnaturalxnislatailLow" ++
"erLeftArrowupuparrowslapprEratiomiddotrlarrYscrlesssimVvdashUringshortparallelscedilcapdotZdotsm" ++
"allsetminusangstgammadlrtritrianglerighteqolcrossafrlthreeeqsimleqslantlltrigtrapproxxutrinbumpe" ++
"varsubsetneqNotSupersetescrecircopfUbrevexdtriexclcurvearrowrightharrwNotLessLessforkvnapproxntg" ++
"lltquestLshnjcyubrcyLeftDownTeeVectorovbarLscrboxVRsupRightCeilingcupbrcapMinusPlusgesTopfoparZo" ++
"pflarrbfopfsmilenlArrLeftTriangleEqualsqsubsetisinvLarrrscrGtuarrequiverarrbigotimesapproxeqdiam" ++
"ondldcadjcylfrLeftUpVectorchibnotlBarrRightVectorBardownharpoonleftcedilQfrhcircuharlacDownRight" ++
"TeeVectorboxtimesforallconglparbetweenplanckWfrbsimRightTriangleBareqcirccompelseqvparslnldrdarr" ++
"TSHcynsupseteqimpedndashbfruogonoumldzigrarrluruharJopfUcircfltnsSubsetEqualswarrowLongRightArro" ++
"wroplusmaleLongLeftRightArrowEfrsearrowfallingdotseqCrossdisinrcysdotsetminusnprcueOverBraceNotR" ++
"ightTriangleEqualsuplarrlbbrknesimnaturUpArrowDownArrowEgravetradenRightarrowitrightsquigarrowLe" ++
"ftDownVectorBarthetavRightTeeArrowutildeeogonlnapproxRrightarrowvarproptoogonhookrightarrowlharu" ++
"EdotzwjnearhkAacuteLeftTrianglerarrbycircProductfrac34engboxvHaogonDownRightVectorntrianglelefte" ++
"qDoubleContourIntegralIgravelooparrowleftEquilibriumemacrbacksimeqxrArrCfrgneqqmpcudarrlaopfUppe" ++
"rLeftArrowUfrUpEquilibriumqscrffligLessEqualGreaterRightTriangleordfMopfNfrDoubleLongLeftRightAr" ++
"rowCircleDotequestlarrnsccuesmashpbackprimecircledRsigmacurlyeqprecverbarGcirccdotproflinenipara" ++
"cularrpCconintpreccurlyeqPopflneqboxulboxhdNotGreaterEqualiocyurcropDownTeeArrowngesinfinbsimean" ++
"gbotsubplusdotplusrbarrnbumprArrvnsupxcapcircledastblacklozengeIJligcupcupnleAmacrsuphsoleasters" ++
"ubsetexponentialesqsubephitshcyalphadoublebarwedgeAringgesdotolNestedGreaterGreatersumdHarlstrok" ++
"helliplaquosdotbDownArrowBarNotSubsetshortmidmapstoupEqualTildebowtieqprimeheartsuitvarnothingcu" ++
"rvearrowleftcirvarsupsetneqXscrPrecedesSlantEqualLleftarrowMapelltimesqopfofcirdharlblanknvgensu" ++
"cceqprnsimUpArrowsqsupseteqnsceImtwoheadrightarrowAfrsolbarlbrkeeDotThetaiotadtrifReverseUpEquil" ++
"ibriumfrownOverBracketncongbarwedgensubEveeeqcoprodLmidotDoubleRightTeexwedgepiruluharnvgtuopfEN" ++
"Gdivonxfrac13mscrrhovNotSupersetEqualboxvRpitchforkDotEqualohbarntlgemptyvleftarrowtailrarrsimse" ++
"xtplankvrealineEmptySmallSquareisinEvarsigmaLaplacetrfQUOTcopysrlessdotMcyhscrngsimDownLeftTeeVe" ++
"ctorflatboxHBreveEcyIogonrhoumllobrkgeqslantvpropcirceqSHCHcyLanglceilRopfsimplusDScyVscrUpDownA" ++
"rrowbopfNestedLessLesssupEintsubEUpsilonagraveeDDotpscrtopdotsquaresearhkRightTeerarrbfsDownRigh" ++
"tVectorBarrangegcyVerticalTildedlcornnisdseArrblacktriangleleftlarrtlrparjmathiinfinRhoNotNested" ++
"LessLessnotindotZcarontopflcyRscrfrac25RightDoubleBracketbbrkOopfgapuscrelintersNotSucceedsEqual" ++
"simlEsucceqtaulgLfrloparlozengeNotLessEqualOverParenthesisjsercynshortmidsbquolesdotogcircleftle" ++
"ftarrowsomidNotGreaterrpargtlvertneqqcirfnintnrarrcgsimcapbrcupsuphsubdrbkarowLeftTriangleBarges" ++
"lqintVfrodsoldnleftrightarrowDiacriticalDothookleftarrowAtildescsimurcornOcircaumlgtreqlessYAcyL" ++
"strokNotHumpEqualYumlhopfpluscirapEbrevecwconintCOPYhArrmultimapyacyrarrlpnleqqshchcydtdotwopfVe" ++
"ryThinSpaceHfrboxVLlhardincareBcyvellipDiamondwreathLowerRightArrowCacutecircdcaronrarrtlduarrVc" ++
"yHscrPhicoloneqAEligrightarrowMfrAogonboxVriquesteopfVdashlrAarrotimesasdashKHcyIcyRuleDelayedDf" ++
"rREGnrightarrowsuccapproxgggddarrcheckcrarrpfrfraslnisGdotNotSquareSupersetrealsacEswarhkkappacs" ++
"uberotimesosolnvapxlarrcircledSBarvDDotrahdringnvltsubegYopfsqsupEmptyVerySmallSquaresubdottopfo" ++
"rkurcornerocircblk12ScybcyltccleftrightharpoonsMellintrfdlcropnvlArrmnplusimacrNotGreaterFullEqu" ++
"almicrohkswarowdiamnsupErarrapnangcsubsup3thetaConintrshhardcyangmsdacStarwrnwnearrtrieAssignutd" ++
"otlfishtpivmhotildeContourIntegralrtrifboxHdWopfNotPrecedesSlantEqualulcornNotDoubleVerticalBarD" ++
"oubleDownArrowrsquorpropGJcyDownLeftVectorrangdtcaronrmoustacheplusdoRarriiiintboxDL" ++ [_]u8{0} ** 32;
const SECOND = [_]u32{ 106,817,819,824,8202,8402,8421,65024 };
const CP1252 = [32]u16{
8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,
144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376
};
const IOTA0: V = .{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
const IOTA1: V = IOTA0 + @as(V, @splat(16));
const ZERO: V = @splat(0);
inline fn splat(x: u32) V {
return @splat(@as(u8, @truncate(x)));
}
// Lane i is 0xFF where i < len (shifted by base), else 0.
inline fn prefixMask(iota: V, len: u32) V {
return @select(u8, iota < splat(len), @as(V, @splat(0xFF)), ZERO);
}
inline fn bitmask(b: @Vector(16, bool)) u32 {
return @as(u16, @bitCast(b));
}
inline fn mix(x0: u32) u32 {
var x = x0;
x ^= x >> 16;
x *%= 0x7FEB352D;
x ^= x >> 15;
x *%= 0x846CA68B;
x ^= x >> 16;
return x;
}
// Hash of a name zero-padded to 32 bytes in k0 and k1.
inline fn nameHash(k0: V, k1: V, len: u32) u32 {
const a: @Vector(2, u64) = @bitCast(k0);
const b: @Vector(2, u64) = @bitCast(k1);
const h = (a[0] *% 0x9E3779B97F4A7C15) ^ (a[1] *% 0xC2B2AE3D27D4EB4F) ^
(b[0] *% 0x165667B19E3779F9) ^ (b[1] *% 0xD6E8FEB86659FD93) ^ len;
return mix(@as(u32, @truncate(h >> 32)) ^ @as(u32, @truncate(h)));
}
// Returns the slot whose name is the first len bytes of k0:k1, or null.
// m0 and m1 mask the first len bytes; k0 and k1 are zero beyond them.
inline fn lookup(k0: V, k1: V, m0: V, m1: V, len: u32) ?u32 {
const h = nameHash(k0, k1, len);
const b: u32 = @truncate((@as(u64, h) * B) >> 32);
const slot: u32 = @truncate((@as(u64, mix(h ^ DISP[b])) * N) >> 32);
if (LENS[slot] != len) return null;
// Add the lengths of the names before this one in its group of 16.
const group: V = LENS[slot & ~@as(u32, 15) ..][0..16].*;
const ls: @Vector(2, u64) = @bitCast(group & prefixMask(IOTA0, slot & 15));
// Each 8-byte half sums to at most 8 * 31 < 256, so one multiply adds
// its bytes.
const ones: u64 = 0x0101010101010101;
const off = @as(u32, BASE[slot >> 4]) + @as(u32, @truncate((ls[0] *% ones) >> 56)) +
@as(u32, @truncate((ls[1] *% ones) >> 56));
const n0: V = BLOB[off..][0..16].*;
const n1: V = BLOB[off + 16 ..][0..16].*;
const diff = ((n0 & m0) ^ k0) | ((n1 & m1) ^ k1);
return if (@reduce(.And, diff == ZERO)) slot else null;
}
// Bit i is set where byte i of w is an ASCII letter or digit.
inline fn alnumBits(w: V) u32 {
const l = (w | splat(0x20)) -% splat('a');
const d = w -% splat('0');
return bitmask(l < splat(26)) | bitmask(d < splat(10));
}
// Writes c as UTF-8. Always stores 4 bytes (the buffer has room) and
// selects the encoding without branches.
inline fn putUtf8(o: [*]u8, c: u32) [*]u8 {
const n: u32 = 1 + @as(u32, @intFromBool(c >= 0x80)) + @intFromBool(c >= 0x800) + @intFromBool(c >= 0x10000);
const t1 = 0x80 | (c & 63);
const t2 = 0x80 | (c >> 6 & 63);
const t3 = 0x80 | (c >> 12 & 63);
const w2 = (0xC0 | c >> 6) | t1 << 8;
const w3 = (0xE0 | c >> 12) | t2 << 8 | t1 << 16;
const w4 = (0xF0 | c >> 18) | t3 << 8 | t2 << 16 | t1 << 24;
const w = if (n == 1) c else if (n == 2) w2 else if (n == 3) w3 else w4;
o[0..4].* = @bitCast(w);
return o + n;
}
inline fn putNamed(o0: [*]u8, slot: u32) [*]u8 {
const m: u32 = META[slot];
var o = putUtf8(o0, @as(u32, LO[slot]) | @as(u32, HI[slot]) << 8 | (m & 1) << 16);
const k = m >> 1 & 15;
if (k != 0) o = putUtf8(o, SECOND[k - 1]);
return o;
}
inline fn hexVal(c: u8) u32 {
if (c -% '0' < 10) return c -% '0';
const l: u32 = (c | 0x20) -% 'a';
return if (l < 6) l + 10 else 16;
}
export fn render(n: u32) u64 {
const s: [*]const u8 = @as([*]const u8, &buf) + IN_OFF;
var o: [*]u8 = &buf;
var i: u32 = 0;
buf[IN_OFF + n] = '&';
while (true) {
// Copy 32 bytes, then advance to the first '&' among them.
const a: V = s[i..][0..16].*;
const b: V = s[i + 16 ..][0..16].*;
o[0..16].* = a;
o[16..32].* = b;
const amp: V = @splat('&');
const m = bitmask(a == amp) | bitmask(b == amp) << 16;
if (m == 0) {
i += 32;
o += 32;
continue;
}
const k: u32 = @ctz(m);
i += k;
o += k;
if (i >= n) break;
// s[i] is '&'.
const p = s + i + 1;
literal: {
if (p[0] == '#') {
var q: [*]const u8 = undefined;
var v: u32 = 0;
if (p[1] -% '0' < 10) {
q = p + 1;
while (q[0] -% '0' < 10) : (q += 1) {
v = v * 10 + (q[0] - '0');
if (v > 0x10FFFF) v = 0x110000;
}
} else if ((p[1] | 0x20) == 'x' and hexVal(p[2]) < 16) {
q = p + 2;
while (true) : (q += 1) {
const dv = hexVal(q[0]);
if (dv >= 16) break;
v = v << 4 | dv;
if (v > 0x10FFFF) v = 0x110000;
}
} else break :literal;
if (q[0] == ';') q += 1;
if (v -% 0x80 < 32) {
v = CP1252[v - 0x80];
} else if (v == 0 or v -% 0xD800 < 0x800 or v > 0x10FFFF) v = 0xFFFD;
o = putUtf8(o, v);
i = @intCast(@intFromPtr(q) - @intFromPtr(s));
continue;
}
// The name is the run of ASCII letters and digits after '&'.
const w0: V = p[0..16].*;
const w1: V = p[16..32].*;
const nm = ~(alnumBits(w0) | alnumBits(w1) << 16);
const len: u32 = if (nm != 0) @ctz(nm) else 32;
if (len == 0) break :literal;
if (len < 32 and p[len] == ';') {
const m0 = prefixMask(IOTA0, len);
const m1 = prefixMask(IOTA1, len);
if (lookup(w0 & m0, w1 & m1, m0, m1, len)) |e| {
o = putNamed(o, e);
i += len + 2;
continue;
}
}
// html.unescape falls back to the longest legacy name (at most 6
// bytes) that prefixes the name, used without ';'.
var x: u32 = @min(len, 6);
while (x >= 2) : (x -= 1) {
const m0 = prefixMask(IOTA0, x);
if (lookup(w0 & m0, ZERO, m0, ZERO, x)) |e| {
if (META[e] >> 5 & 1 != 0) {
o = putNamed(o, e);
i += x + 1;
break;
}
}
} else break :literal;
continue;
}
o[0] = '&';
o += 1;
i += 1;
}
return @as(u64, @intCast(@intFromPtr(o) - @intFromPtr(&buf))) | @as(u64, @intFromPtr(&buf)) << 32;
}