// 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 32 bytes at a time with SIMD and
// stops only at '&'.
// - Named references use a minimal perfect hash of the 2125 names in
// html.entities.html5, generated offline. A scalar loop finds 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 two 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 cc -target wasm32-freestanding
// -mcpu=generic+simd128 -O3 -s -nostdlib -Wl,--no-entry
// -Wl,-z,stack-size=4096 -Wl,--max-memory=1376256 -o unescape_html.wasm unescape_html.c
#include
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
#define OUT_CAP 1310720u
#define IN_CAP 1048576u
#define IN_OFF (OUT_CAP - IN_CAP)
static u8 buf[OUT_CAP + 64] __attribute__((aligned(16)));
__attribute__((export_name("input_ptr"))) u32 input_ptr(void) { return (u32)(buf + IN_OFF); }
__attribute__((export_name("input_utf8_cap"))) u32 input_utf8_cap(void) { return IN_CAP; }
__attribute__((export_name("output_utf8_cap"))) u32 output_utf8_cap(void) { return OUT_CAP; }
#define N 2125u
#define B 600u
static const u16 DISP[B] = {
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 ';'.
static const u8 LENS[N + 16] = {
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
};
static const u8 LO[N] = {
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
};
static const u8 HI[N] = {
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
};
static const u8 META[N] = {
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.
static const u16 BASE[(N + 15) / 16] = {
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.
static const char BLOB[14004 + 32] =
"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";
static const u32 SECOND[] = { 106,817,819,824,8202,8402,8421,65024 };
static const u16 CP1252[32] = {
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
};
#define IOTA0 wasm_u8x16_const(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
#define IOTA1 wasm_u8x16_const(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31)
static inline u32 mix(u32 x) {
x ^= x >> 16; x *= 0x7FEB352Du;
x ^= x >> 15; x *= 0x846CA68Bu;
x ^= x >> 16;
return x;
}
// Hash of a name zero-padded to 32 bytes in k0 and k1.
static inline u32 name_hash(v128_t k0, v128_t k1, u32 len) {
u64 h = (u64)wasm_i64x2_extract_lane(k0, 0) * 0x9E3779B97F4A7C15ull ^
(u64)wasm_i64x2_extract_lane(k0, 1) * 0xC2B2AE3D27D4EB4Full ^
(u64)wasm_i64x2_extract_lane(k1, 0) * 0x165667B19E3779F9ull ^
(u64)wasm_i64x2_extract_lane(k1, 1) * 0xD6E8FEB86659FD93ull ^ len;
return mix((u32)(h >> 32) ^ (u32)h);
}
// Returns the slot whose name is the first len bytes of k0:k1, or -1.
// m0 and m1 mask the first len bytes; k0 and k1 are zero beyond them.
static inline int lookup(v128_t k0, v128_t k1, v128_t m0, v128_t m1, u32 len) {
u32 h = name_hash(k0, k1, len);
u32 b = (u32)(((u64)h * B) >> 32);
u32 slot = (u32)(((u64)mix(h ^ DISP[b]) * N) >> 32);
if (LENS[slot] != len) return -1;
// Add the lengths of the names before this one in its group of 16.
// Each 8-byte half sums to at most 8 * 31 < 256, so one multiply adds
// its bytes.
v128_t ls = wasm_v128_and(wasm_v128_load(LENS + (slot & ~15u)),
wasm_u8x16_lt(IOTA0, wasm_u8x16_splat((u8)(slot & 15))));
const u64 ones = 0x0101010101010101ull;
u32 off = BASE[slot >> 4] + (u32)(((u64)wasm_i64x2_extract_lane(ls, 0) * ones) >> 56) +
(u32)(((u64)wasm_i64x2_extract_lane(ls, 1) * ones) >> 56);
const u8 *name = (const u8 *)BLOB + off;
v128_t e0 = wasm_i8x16_eq(wasm_v128_and(wasm_v128_load(name), m0), k0);
v128_t e1 = wasm_i8x16_eq(wasm_v128_and(wasm_v128_load(name + 16), m1), k1);
return wasm_i8x16_all_true(wasm_v128_and(e0, e1)) ? (int)slot : -1;
}
static inline v128_t is_alnum16(v128_t w) {
v128_t l = wasm_i8x16_sub(wasm_v128_or(w, wasm_u8x16_splat(0x20)), wasm_u8x16_splat('a'));
v128_t d = wasm_i8x16_sub(w, wasm_u8x16_splat('0'));
return wasm_v128_or(wasm_u8x16_lt(l, wasm_u8x16_splat(26)), wasm_u8x16_lt(d, wasm_u8x16_splat(10)));
}
// Writes c as UTF-8. Always stores 4 bytes (the buffer has room) and
// selects the encoding without branches.
static inline u8 *put_utf8(u8 *o, u32 c) {
u32 n = 1 + (c >= 0x80) + (c >= 0x800) + (c >= 0x10000);
u32 t1 = 0x80 | (c & 63), t2 = 0x80 | (c >> 6 & 63), t3 = 0x80 | (c >> 12 & 63);
u32 w2 = (0xC0 | c >> 6) | t1 << 8;
u32 w3 = (0xE0 | c >> 12) | t2 << 8 | t1 << 16;
u32 w4 = (0xF0 | c >> 18) | t3 << 8 | t2 << 16 | t1 << 24;
u32 w = n == 1 ? c : n == 2 ? w2 : n == 3 ? w3 : w4;
__builtin_memcpy(o, &w, 4);
return o + n;
}
static inline u8 *put_named(u8 *o, u32 slot) {
u32 m = META[slot];
o = put_utf8(o, LO[slot] | (u32)HI[slot] << 8 | (m & 1) << 16);
u32 k = m >> 1 & 15;
if (k) o = put_utf8(o, SECOND[k - 1]);
return o;
}
static inline u32 hex_val(u8 c) {
if ((u32)(c - '0') < 10) return c - '0';
u32 l = (u32)((c | 0x20) - 'a');
return l < 6 ? l + 10 : 16;
}
__attribute__((export_name("render"))) u64 render(u32 n) {
const u8 *s = buf + IN_OFF;
u8 *o = buf;
u32 i = 0;
buf[IN_OFF + n] = '&';
const v128_t amp = wasm_i8x16_splat('&');
for (;;) {
v128_t a = wasm_v128_load(s + i);
v128_t b = wasm_v128_load(s + i + 16);
wasm_v128_store(o, a);
wasm_v128_store(o + 16, b);
u32 m = (u32)wasm_i8x16_bitmask(wasm_i8x16_eq(a, amp)) |
(u32)wasm_i8x16_bitmask(wasm_i8x16_eq(b, amp)) << 16;
if (!m) { i += 32; o += 32; continue; }
u32 k = (u32)__builtin_ctz(m);
i += k; o += k;
if (i >= n) break;
// s[i] is '&'.
const u8 *p = s + i + 1;
if (p[0] == '#') {
const u8 *q;
u32 v = 0;
if ((u32)(p[1] - '0') < 10) {
for (q = p + 1; (u32)(*q - '0') < 10; q++) {
v = v * 10 + (u32)(*q - '0');
if (v > 0x10FFFF) v = 0x110000;
}
} else if ((p[1] | 0x20) == 'x' && hex_val(p[2]) < 16) {
u32 dv;
for (q = p + 2; (dv = hex_val(*q)) < 16; q++) {
v = v << 4 | dv;
if (v > 0x10FFFF) v = 0x110000;
}
} else {
goto literal;
}
if (*q == ';') q++;
if (v - 0x80 < 32) v = CP1252[v - 0x80];
else if (v == 0 || v - 0xD800 < 0x800 || v > 0x10FFFF) v = 0xFFFD;
o = put_utf8(o, v);
i = (u32)(q - s);
continue;
} else {
// The name is the run of ASCII letters and digits after '&'.
v128_t w0 = wasm_v128_load(p), w1 = wasm_v128_load(p + 16);
u32 len = 0;
while (len < 32) {
u32 ch = p[len];
u32 letter = (ch | 0x20) - 'a';
u32 digit = ch - '0';
if (letter >= 26 && digit >= 10) break;
len++;
}
if (len) {
if (p[len] == ';' && len < 32) {
v128_t lv = wasm_u8x16_splat((u8)len);
v128_t m0 = wasm_u8x16_lt(IOTA0, lv), m1 = wasm_u8x16_lt(IOTA1, lv);
int e = lookup(wasm_v128_and(w0, m0), wasm_v128_and(w1, m1), m0, m1, len);
if (e >= 0) { o = put_named(o, (u32)e); i += len + 2; continue; }
}
// html.unescape falls back to the longest legacy name (at most 6
// bytes) that prefixes the name, used without ';'.
const v128_t zero = wasm_i64x2_const(0, 0);
for (u32 x = len < 6 ? len : 6; x >= 2; x--) {
v128_t m0 = wasm_u8x16_lt(IOTA0, wasm_u8x16_splat((u8)x));
int e = lookup(wasm_v128_and(w0, m0), zero, m0, zero, x);
if (e >= 0 && (META[e] >> 5 & 1)) { o = put_named(o, (u32)e); i += x + 1; goto next; }
}
}
}
literal:
*o++ = '&';
i++;
next:;
}
return (u64)(u32)(o - buf) | (u64)(u32)buf << 32;
}