{"mappings":"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","names":[],"sources":["/assets/npm/%40adraffy/ens-normalize/dist/index.mjs"],"version":3,"sourcesContent":["// created 2025-09-14T17:56:24.099Z\n// compressed base64-encoded blob for include-ens data\n// source: https://github.com/adraffy/ens-normalize.js/blob/main/src/make.js\n// see: https://github.com/adraffy/ens-normalize.js#security\n// SHA-256: 92cbf3a1af3c3c0a91aee0dc542072775f4ebbbc526a84189a12da2d56f5accd\nvar COMPRESSED$1 = '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';\nconst FENCED = new Map([[8217,\"apostrophe\"],[8260,\"fraction slash\"],[12539,\"middle dot\"]]);\nconst NSM_MAX = 4;\n\nfunction decode_arithmetic(bytes) {\r\n\tlet pos = 0;\r\n\tfunction u16() { return (bytes[pos++] << 8) | bytes[pos++]; }\r\n\t\r\n\t// decode the frequency table\r\n\tlet symbol_count = u16();\r\n\tlet total = 1;\r\n\tlet acc = [0, 1]; // first symbol has frequency 1\r\n\tfor (let i = 1; i < symbol_count; i++) {\r\n\t\tacc.push(total += u16());\r\n\t}\r\n\r\n\t// skip the sized-payload that the last 3 symbols index into\r\n\tlet skip = u16();\r\n\tlet pos_payload = pos;\r\n\tpos += skip;\r\n\r\n\tlet read_width = 0;\r\n\tlet read_buffer = 0; \r\n\tfunction read_bit() {\r\n\t\tif (read_width == 0) {\r\n\t\t\t// this will read beyond end of buffer\r\n\t\t\t// but (undefined|0) => zero pad\r\n\t\t\tread_buffer = (read_buffer << 8) | bytes[pos++];\r\n\t\t\tread_width = 8;\r\n\t\t}\r\n\t\treturn (read_buffer >> --read_width) & 1;\r\n\t}\r\n\r\n\tconst N = 31;\r\n\tconst FULL = 2**N;\r\n\tconst HALF = FULL >>> 1;\r\n\tconst QRTR = HALF >> 1;\r\n\tconst MASK = FULL - 1;\r\n\r\n\t// fill register\r\n\tlet register = 0;\r\n\tfor (let i = 0; i < N; i++) register = (register << 1) | read_bit();\r\n\r\n\tlet symbols = [];\r\n\tlet low = 0;\r\n\tlet range = FULL; // treat like a float\r\n\twhile (true) {\r\n\t\tlet value = Math.floor((((register - low + 1) * total) - 1) / range);\r\n\t\tlet start = 0;\r\n\t\tlet end = symbol_count;\r\n\t\twhile (end - start > 1) { // binary search\r\n\t\t\tlet mid = (start + end) >>> 1;\r\n\t\t\tif (value < acc[mid]) {\r\n\t\t\t\tend = mid;\r\n\t\t\t} else {\r\n\t\t\t\tstart = mid;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (start == 0) break; // first symbol is end mark\r\n\t\tsymbols.push(start);\r\n\t\tlet a = low + Math.floor(range * acc[start]   / total);\r\n\t\tlet b = low + Math.floor(range * acc[start+1] / total) - 1;\r\n\t\twhile (((a ^ b) & HALF) == 0) {\r\n\t\t\tregister = (register << 1) & MASK | read_bit();\r\n\t\t\ta = (a << 1) & MASK;\r\n\t\t\tb = (b << 1) & MASK | 1;\r\n\t\t}\r\n\t\twhile (a & ~b & QRTR) {\r\n\t\t\tregister = (register & HALF) | ((register << 1) & (MASK >>> 1)) | read_bit();\r\n\t\t\ta = (a << 1) ^ HALF;\r\n\t\t\tb = ((b ^ HALF) << 1) | HALF | 1;\r\n\t\t}\r\n\t\tlow = a;\r\n\t\trange = 1 + b - a;\r\n\t}\r\n\tlet offset = symbol_count - 4;\r\n\treturn symbols.map(x => { // index into payload\r\n\t\tswitch (x - offset) {\r\n\t\t\tcase 3: return offset + 0x10100 + ((bytes[pos_payload++] << 16) | (bytes[pos_payload++] << 8) | bytes[pos_payload++]);\r\n\t\t\tcase 2: return offset + 0x100 + ((bytes[pos_payload++] << 8) | bytes[pos_payload++]);\r\n\t\t\tcase 1: return offset + bytes[pos_payload++];\r\n\t\t\tdefault: return x - 1;\r\n\t\t}\r\n\t});\r\n}\t\r\n\r\n// returns an iterator which returns the next symbol\r\nfunction read_payload(v) {\r\n\tlet pos = 0;\r\n\treturn () => v[pos++];\r\n}\r\nfunction read_compressed_payload(s) {\r\n\treturn read_payload(decode_arithmetic(unsafe_atob(s)));\r\n}\r\n\r\n// unsafe in the sense:\r\n// expected well-formed Base64 w/o padding \r\n// 20220922: added for https://github.com/adraffy/ens-normalize.js/issues/4\r\nfunction unsafe_atob(s) {\r\n\tlet lookup = [];\r\n\t[...'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'].forEach((c, i) => lookup[c.charCodeAt(0)] = i);\r\n\tlet n = s.length;\r\n\tlet ret = new Uint8Array((6 * n) >> 3);\r\n\tfor (let i = 0, pos = 0, width = 0, carry = 0; i < n; i++) {\r\n\t\tcarry = (carry << 6) | lookup[s.charCodeAt(i)];\r\n\t\twidth += 6;\r\n\t\tif (width >= 8) {\r\n\t\t\tret[pos++] = (carry >> (width -= 8));\r\n\t\t}\r\n\t}\r\n\treturn ret;\r\n}\r\n\r\n// eg. [0,1,2,3...] => [0,-1,1,-2,...]\r\nfunction signed(i) { \r\n\treturn (i & 1) ? (~i >> 1) : (i >> 1);\r\n}\r\n\r\nfunction read_deltas(n, next) {\r\n\tlet v = Array(n);\r\n\tfor (let i = 0, x = 0; i < n; i++) v[i] = x += signed(next());\r\n\treturn v;\r\n}\r\n\r\n// [123][5] => [0 3] [1 1] [0 0]\r\nfunction read_sorted(next, prev = 0) {\r\n\tlet ret = [];\r\n\twhile (true) {\r\n\t\tlet x = next();\r\n\t\tlet n = next();\r\n\t\tif (!n) break;\r\n\t\tprev += x;\r\n\t\tfor (let i = 0; i < n; i++) {\r\n\t\t\tret.push(prev + i);\r\n\t\t}\r\n\t\tprev += n + 1;\r\n\t}\r\n\treturn ret;\r\n}\r\n\r\nfunction read_sorted_arrays(next) {\r\n\treturn read_array_while(() => { \r\n\t\tlet v = read_sorted(next);\r\n\t\tif (v.length) return v;\r\n\t});\r\n}\r\n\r\n// returns map of x => ys\r\nfunction read_mapped(next) {\r\n\tlet ret = [];\r\n\twhile (true) {\r\n\t\tlet w = next();\r\n\t\tif (w == 0) break;\r\n\t\tret.push(read_linear_table(w, next));\r\n\t}\r\n\twhile (true) {\r\n\t\tlet w = next() - 1;\r\n\t\tif (w < 0) break;\r\n\t\tret.push(read_replacement_table(w, next));\r\n\t}\r\n\treturn ret.flat();\r\n}\r\n\r\n// read until next is falsy\r\n// return array of read values\r\nfunction read_array_while(next) {\r\n\tlet v = [];\r\n\twhile (true) {\r\n\t\tlet x = next(v.length);\r\n\t\tif (!x) break;\r\n\t\tv.push(x);\r\n\t}\r\n\treturn v;\r\n}\r\n\r\n// read w columns of length n\r\n// return as n rows of length w\r\nfunction read_transposed(n, w, next) {\r\n\tlet m = Array(n).fill().map(() => []);\r\n\tfor (let i = 0; i < w; i++) {\r\n\t\tread_deltas(n, next).forEach((x, j) => m[j].push(x));\r\n\t}\r\n\treturn m;\r\n}\r\n \r\n// returns [[x, ys], [x+dx, ys+dy], [x+2*dx, ys+2*dy], ...]\r\n// where dx/dy = steps, n = run size, w = length of y\r\nfunction read_linear_table(w, next) {\r\n\tlet dx = 1 + next();\r\n\tlet dy = next();\r\n\tlet vN = read_array_while(next);\r\n\tlet m = read_transposed(vN.length, 1+w, next);\r\n\treturn m.flatMap((v, i) => {\r\n\t\tlet [x, ...ys] = v;\r\n\t\treturn Array(vN[i]).fill().map((_, j) => {\r\n\t\t\tlet j_dy = j * dy;\r\n\t\t\treturn [x + j * dx, ys.map(y => y + j_dy)];\r\n\t\t});\r\n\t});\r\n}\r\n\r\n// return [[x, ys...], ...]\r\n// where w = length of y\r\nfunction read_replacement_table(w, next) { \r\n\tlet n = 1 + next();\r\n\tlet m = read_transposed(n, 1+w, next);\r\n\treturn m.map(v => [v[0], v.slice(1)]);\r\n}\r\n\r\n\r\nfunction read_trie(next) {\r\n\tlet ret = [];\r\n\tlet sorted = read_sorted(next); \r\n\texpand(decode([]), []);\r\n\treturn ret; // not sorted\r\n\tfunction decode(Q) { // characters that lead into this node\r\n\t\tlet S = next(); // state: valid, save, check\r\n\t\tlet B = read_array_while(() => { // buckets leading to new nodes\r\n\t\t\tlet cps = read_sorted(next).map(i => sorted[i]);\r\n\t\t\tif (cps.length) return decode(cps);\r\n\t\t});\r\n\t\treturn {S, B, Q};\r\n\t}\r\n\tfunction expand({S, B}, cps, saved) {\r\n\t\tif (S & 4 && saved === cps[cps.length-1]) return;\r\n\t\tif (S & 2) saved = cps[cps.length-1];\r\n\t\tif (S & 1) ret.push(cps); \r\n\t\tfor (let br of B) {\r\n\t\t\tfor (let cp of br.Q) {\r\n\t\t\t\texpand(br, [...cps, cp], saved);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\n\nfunction hex_cp(cp) {\r\n\treturn cp.toString(16).toUpperCase().padStart(2, '0');\r\n}\r\n\r\nfunction quote_cp(cp) {\r\n\treturn `{${hex_cp(cp)}}`; // raffy convention: like \"\\u{X}\" w/o the \"\\u\"\r\n}\r\n\r\n/*\r\nexport function explode_cp(s) {\r\n\treturn [...s].map(c => c.codePointAt(0));\r\n}\r\n*/\r\nfunction explode_cp(s) { // this is about 2x faster\r\n\tlet cps = [];\r\n\tfor (let pos = 0, len = s.length; pos < len; ) {\r\n\t\tlet cp = s.codePointAt(pos);\r\n\t\tpos += cp < 0x10000 ? 1 : 2;\r\n\t\tcps.push(cp);\r\n\t}\r\n\treturn cps;\r\n}\r\n\r\nfunction str_from_cps(cps) {\r\n\tconst chunk = 4096;\r\n\tlet len = cps.length;\r\n\tif (len < chunk) return String.fromCodePoint(...cps);\r\n\tlet buf = [];\r\n\tfor (let i = 0; i < len; ) {\r\n\t\tbuf.push(String.fromCodePoint(...cps.slice(i, i += chunk)));\r\n\t}\r\n\treturn buf.join('');\r\n}\r\n\r\nfunction compare_arrays(a, b) {\r\n\tlet n = a.length;\r\n\tlet c = n - b.length;\r\n\tfor (let i = 0; c == 0 && i < n; i++) c = a[i] - b[i];\r\n\treturn c;\r\n}\r\n\r\nfunction array_replace(v, a, b) {\r\n\tlet prev = 0;\r\n\twhile (true) {\r\n\t\tlet next = v.indexOf(a, prev);\r\n\t\tif (next < 0) break;\r\n\t\tv[next] = b; \r\n\t\tprev = next + 1;\r\n\t}\r\n}\n\n// created 2025-09-14T17:56:24.099Z\n// compressed base64-encoded blob for include-nf data\n// source: https://github.com/adraffy/ens-normalize.js/blob/main/src/make.js\n// see: https://github.com/adraffy/ens-normalize.js#security\n// SHA-256: 9ef43cc7215aa7a53e4ed9afa3b4f2f8ce00a2c708b9eb96aa409ae6fa3fb6af\nvar COMPRESSED = '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';\n\n// https://unicode.org/reports/tr15/\r\n// for reference implementation\r\n// see: /derive/nf.js\r\n\r\n\r\n// algorithmic hangul\r\n// https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf (page 144)\r\nconst S0 = 0xAC00;\r\nconst L0 = 0x1100;\r\nconst V0 = 0x1161;\r\nconst T0 = 0x11A7;\r\nconst L_COUNT = 19;\r\nconst V_COUNT = 21;\r\nconst T_COUNT = 28;\r\nconst N_COUNT = V_COUNT * T_COUNT;\r\nconst S_COUNT = L_COUNT * N_COUNT;\r\nconst S1 = S0 + S_COUNT;\r\nconst L1 = L0 + L_COUNT;\r\nconst V1 = V0 + V_COUNT;\r\nconst T1 = T0 + T_COUNT;\r\n\r\nfunction unpack_cc(packed) {\r\n\treturn (packed >> 24) & 0xFF;\r\n}\r\nfunction unpack_cp(packed) {\r\n\treturn packed & 0xFFFFFF;\r\n}\r\n\r\nlet SHIFTED_RANK, EXCLUSIONS, DECOMP, RECOMP;\r\n\r\n// export function nf_deinit() {\r\n// \tif (!SHIFTED_RANK) return;\r\n// \tSHIFTED_RANK = EXCLUSIONS = DECOMP = RECOMP = undefined;\r\n// }\r\n\r\nfunction init$1() {\r\n\t//console.time('nf');\r\n\tlet r = read_compressed_payload(COMPRESSED);\r\n\tSHIFTED_RANK = new Map(read_sorted_arrays(r).flatMap((v, i) => v.map(x => [x, (i+1) << 24]))); // pre-shifted\r\n\tEXCLUSIONS = new Set(read_sorted(r));\r\n\tDECOMP = new Map();\r\n\tRECOMP = new Map();\r\n\tfor (let [cp, cps] of read_mapped(r)) {\r\n\t\tif (!EXCLUSIONS.has(cp) && cps.length == 2) {\r\n\t\t\tlet [a, b] = cps;\r\n\t\t\tlet bucket = RECOMP.get(a);\r\n\t\t\tif (!bucket) {\r\n\t\t\t\tbucket = new Map();\r\n\t\t\t\tRECOMP.set(a, bucket);\r\n\t\t\t}\r\n\t\t\tbucket.set(b, cp);\r\n\t\t}\r\n\t\tDECOMP.set(cp, cps.reverse()); // stored reversed\r\n\t}\r\n\t//console.timeEnd('nf');\r\n\t// 20230905: 11ms\r\n}\r\n\r\nfunction is_hangul(cp) {\r\n\treturn cp >= S0 && cp < S1;\r\n}\r\n\r\nfunction compose_pair(a, b) {\r\n\tif (a >= L0 && a < L1 && b >= V0 && b < V1) {\r\n\t\treturn S0 + (a - L0) * N_COUNT + (b - V0) * T_COUNT;\r\n\t} else if (is_hangul(a) && b > T0 && b < T1 && (a - S0) % T_COUNT == 0) {\r\n\t\treturn a + (b - T0);\r\n\t} else {\r\n\t\tlet recomp = RECOMP.get(a);\r\n\t\tif (recomp) {\r\n\t\t\trecomp = recomp.get(b);\r\n\t\t\tif (recomp) {\r\n\t\t\t\treturn recomp;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn -1;\r\n\t}\r\n}\r\n\r\nfunction decomposed(cps) {\r\n\tif (!SHIFTED_RANK) init$1();\r\n\tlet ret = [];\r\n\tlet buf = [];\r\n\tlet check_order = false;\r\n\tfunction add(cp) {\r\n\t\tlet cc = SHIFTED_RANK.get(cp);\r\n\t\tif (cc) {\r\n\t\t\tcheck_order = true;\r\n\t\t\tcp |= cc;\r\n\t\t}\r\n\t\tret.push(cp);\r\n\t}\r\n\tfor (let cp of cps) {\r\n\t\twhile (true) {\r\n\t\t\tif (cp < 0x80) {\r\n\t\t\t\tret.push(cp);\r\n\t\t\t} else if (is_hangul(cp)) {\r\n\t\t\t\tlet s_index = cp - S0;\r\n\t\t\t\tlet l_index = s_index / N_COUNT | 0;\r\n\t\t\t\tlet v_index = (s_index % N_COUNT) / T_COUNT | 0;\r\n\t\t\t\tlet t_index = s_index % T_COUNT;\r\n\t\t\t\tadd(L0 + l_index);\r\n\t\t\t\tadd(V0 + v_index);\r\n\t\t\t\tif (t_index > 0) add(T0 + t_index);\r\n\t\t\t} else {\r\n\t\t\t\tlet mapped = DECOMP.get(cp);\r\n\t\t\t\tif (mapped) {\r\n\t\t\t\t\tbuf.push(...mapped);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tadd(cp);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!buf.length) break;\r\n\t\t\tcp = buf.pop();\r\n\t\t}\r\n\t}\r\n\tif (check_order && ret.length > 1) {\r\n\t\tlet prev_cc = unpack_cc(ret[0]);\r\n\t\tfor (let i = 1; i < ret.length; i++) {\r\n\t\t\tlet cc = unpack_cc(ret[i]);\r\n\t\t\tif (cc == 0 || prev_cc <= cc) {\r\n\t\t\t\tprev_cc = cc;\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tlet j = i-1;\r\n\t\t\twhile (true) {\r\n\t\t\t\tlet tmp = ret[j+1];\r\n\t\t\t\tret[j+1] = ret[j];\r\n\t\t\t\tret[j] = tmp;\r\n\t\t\t\tif (!j) break;\r\n\t\t\t\tprev_cc = unpack_cc(ret[--j]);\r\n\t\t\t\tif (prev_cc <= cc) break;\r\n\t\t\t}\r\n\t\t\tprev_cc = unpack_cc(ret[i]);\r\n\t\t}\r\n\t}\r\n\treturn ret;\r\n}\r\n\r\nfunction composed_from_decomposed(v) {\r\n\tlet ret = [];\r\n\tlet stack = [];\r\n\tlet prev_cp = -1;\r\n\tlet prev_cc = 0;\r\n\tfor (let packed of v) {\r\n\t\tlet cc = unpack_cc(packed);\r\n\t\tlet cp = unpack_cp(packed);\r\n\t\tif (prev_cp == -1) {\r\n\t\t\tif (cc == 0) {\r\n\t\t\t\tprev_cp = cp;\r\n\t\t\t} else {\r\n\t\t\t\tret.push(cp);\r\n\t\t\t}\r\n\t\t} else if (prev_cc > 0 && prev_cc >= cc) {\r\n\t\t\tif (cc == 0) {\r\n\t\t\t\tret.push(prev_cp, ...stack);\r\n\t\t\t\tstack.length = 0;\r\n\t\t\t\tprev_cp = cp;\r\n\t\t\t} else {\r\n\t\t\t\tstack.push(cp);\r\n\t\t\t}\r\n\t\t\tprev_cc = cc;\r\n\t\t} else {\r\n\t\t\tlet composed = compose_pair(prev_cp, cp);\r\n\t\t\tif (composed >= 0) {\r\n\t\t\t\tprev_cp = composed;\r\n\t\t\t} else if (prev_cc == 0 && cc == 0) {\r\n\t\t\t\tret.push(prev_cp);\r\n\t\t\t\tprev_cp = cp;\r\n\t\t\t} else {\r\n\t\t\t\tstack.push(cp);\r\n\t\t\t\tprev_cc = cc;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tif (prev_cp >= 0) {\r\n\t\tret.push(prev_cp, ...stack);\t\r\n\t}\r\n\treturn ret;\r\n}\r\n\r\n// note: cps can be iterable\r\nfunction nfd(cps) {\r\n\treturn decomposed(cps).map(unpack_cp);\r\n}\r\nfunction nfc(cps) {\r\n\treturn composed_from_decomposed(decomposed(cps));\r\n}\n\nconst HYPHEN = 0x2D;\r\nconst STOP = 0x2E;\r\nconst STOP_CH = '.';\r\nconst FE0F = 0xFE0F;\r\nconst UNIQUE_PH = 1;\r\n\r\n// 20230913: replace [...v] with Array_from(v) to avoid large spreads\r\nconst Array_from = x => Array.from(x); // Array.from.bind(Array);\r\n\r\nfunction group_has_cp(g, cp) {\r\n\t// 20230913: keep primary and secondary distinct instead of creating valid union\r\n\treturn g.P.has(cp) || g.Q.has(cp);\r\n}\r\n\r\nclass Emoji extends Array {\r\n\tget is_emoji() { return true; } // free tagging system\r\n}\r\n\r\nlet MAPPED, IGNORED, CM, NSM, ESCAPE, NFC_CHECK, GROUPS, WHOLE_VALID, WHOLE_MAP, VALID, EMOJI_LIST, EMOJI_ROOT;\r\n\r\n// export function ens_deinit() {\r\n// \tnf_deinit();\r\n// \tif (!MAPPED) return;\r\n// \tMAPPED = IGNORED = CM = NSM = ESCAPE = NFC_CHECK = GROUPS = WHOLE_VALID = WHOLE_MAP = VALID = EMOJI_LIST = EMOJI_ROOT = undefined;\r\n// }\r\n\r\nfunction init() {\r\n\tif (MAPPED) return;\r\n\t\r\n\tlet r = read_compressed_payload(COMPRESSED$1);\r\n\tconst read_sorted_array = () => read_sorted(r);\r\n\tconst read_sorted_set = () => new Set(read_sorted_array());\r\n\tconst set_add_many = (set, v) => v.forEach(x => set.add(x));\r\n\r\n\tMAPPED = new Map(read_mapped(r)); \r\n\tIGNORED = read_sorted_set(); // ignored characters are not valid, so just read raw codepoints\r\n\r\n\t/*\r\n\t// direct include from payload is smaller than the decompression code\r\n\tconst FENCED = new Map(read_array_while(() => {\r\n\t\tlet cp = r();\r\n\t\tif (cp) return [cp, read_str(r())];\r\n\t}));\r\n\t*/\r\n\t// 20230217: we still need all CM for proper error formatting\r\n\t// but norm only needs NSM subset that are potentially-valid\r\n\tCM = read_sorted_array();\r\n\tNSM = new Set(read_sorted_array().map(i => CM[i]));\r\n\tCM = new Set(CM);\r\n\t\r\n\tESCAPE = read_sorted_set(); // characters that should not be printed\r\n\tNFC_CHECK = read_sorted_set(); // only needed to illustrate ens_tokenize() transformations\r\n\r\n\tlet chunks = read_sorted_arrays(r);\r\n\tlet unrestricted = r();\r\n\t//const read_chunked = () => new Set(read_sorted_array().flatMap(i => chunks[i]).concat(read_sorted_array()));\r\n\tconst read_chunked = () => {\r\n\t\t// 20230921: build set in parts, 2x faster\r\n\t\tlet set = new Set();\r\n\t\tread_sorted_array().forEach(i => set_add_many(set, chunks[i]));\r\n\t\tset_add_many(set, read_sorted_array());\r\n\t\treturn set; \r\n\t};\r\n\tGROUPS = read_array_while(i => {\r\n\t\t// minifier property mangling seems unsafe\r\n\t\t// so these are manually renamed to single chars\r\n\t\tlet N = read_array_while(r).map(x => x+0x60);\r\n\t\tif (N.length) {\r\n\t\t\tlet R = i >= unrestricted; // unrestricted then restricted\r\n\t\t\tN[0] -= 32; // capitalize\r\n\t\t\tN = str_from_cps(N);\r\n\t\t\tif (R) N=`Restricted[${N}]`;\r\n\t\t\tlet P = read_chunked(); // primary\r\n\t\t\tlet Q = read_chunked(); // secondary\r\n\t\t\tlet M = !r(); // not-whitelisted, check for NSM\r\n\t\t\t// *** this code currently isn't needed ***\r\n\t\t\t/*\r\n\t\t\tlet V = [...P, ...Q].sort((a, b) => a-b); // derive: sorted valid\r\n\t\t\tlet M = r()-1; // number of combining mark\r\n\t\t\tif (M < 0) { // whitelisted\r\n\t\t\t\tM = new Map(read_array_while(() => {\r\n\t\t\t\t\tlet i = r();\r\n\t\t\t\t\tif (i) return [V[i-1], read_array_while(() => {\r\n\t\t\t\t\t\tlet v = read_array_while(r);\r\n\t\t\t\t\t\tif (v.length) return v.map(x => x-1);\r\n\t\t\t\t\t})];\r\n\t\t\t\t}));\r\n\t\t\t}*/\r\n\t\t\treturn {N, P, Q, M, R};\r\n\t\t}\r\n\t});\r\n\r\n\t// decode compressed wholes\r\n\tWHOLE_VALID = read_sorted_set();\r\n\tWHOLE_MAP = new Map();\r\n\tlet wholes = read_sorted_array().concat(Array_from(WHOLE_VALID)).sort((a, b) => a-b); // must be sorted\r\n\twholes.forEach((cp, i) => {\r\n\t\tlet d = r(); \r\n\t\tlet w = wholes[i] = d ? wholes[i-d] : {V: [], M: new Map()};\r\n\t\tw.V.push(cp); // add to member set\r\n\t\tif (!WHOLE_VALID.has(cp)) {\r\n\t\t\tWHOLE_MAP.set(cp, w);  // register with whole map\r\n\t\t}\r\n\t});\r\n\r\n\t// compute confusable-extent complements\r\n\t// usage: WHOLE_MAP.get(cp).M.get(cp) = complement set\r\n\tfor (let {V, M} of new Set(WHOLE_MAP.values())) {\r\n\t\t// connect all groups that have each whole character\r\n\t\tlet recs = [];\r\n\t\tfor (let cp of V) {\r\n\t\t\tlet gs = GROUPS.filter(g => group_has_cp(g, cp));\r\n\t\t\tlet rec = recs.find(({G}) => gs.some(g => G.has(g)));\r\n\t\t\tif (!rec) {\r\n\t\t\t\trec = {G: new Set(), V: []};\r\n\t\t\t\trecs.push(rec);\r\n\t\t\t}\r\n\t\t\trec.V.push(cp);\r\n\t\t\tset_add_many(rec.G, gs);\r\n\t\t}\r\n\t\t// per character cache groups which are not a member of the extent\r\n\t\tlet union = recs.flatMap(x => Array_from(x.G)); // all of the groups used by this whole\r\n\t\tfor (let {G, V} of recs) {\r\n\t\t\tlet complement = new Set(union.filter(g => !G.has(g))); // groups not covered by the extent\r\n\t\t\tfor (let cp of V) {\r\n\t\t\t\tM.set(cp, complement); // this is the same reference\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// compute valid set\r\n\t// 20230924: VALID was union but can be re-used\r\n\tVALID = new Set(); // exists in 1+ groups\r\n\tlet multi = new Set(); // exists in 2+ groups\r\n\tconst add_to_union = cp => VALID.has(cp) ? multi.add(cp) : VALID.add(cp);\r\n\tfor (let g of GROUPS) {\r\n\t\tfor (let cp of g.P) add_to_union(cp);\r\n\t\tfor (let cp of g.Q) add_to_union(cp);\r\n\t}\r\n\t// dual purpose WHOLE_MAP: return placeholder if unique non-confusable\r\n\tfor (let cp of VALID) {\r\n\t\tif (!WHOLE_MAP.has(cp) && !multi.has(cp)) {\r\n\t\t\tWHOLE_MAP.set(cp, UNIQUE_PH);\r\n\t\t}\r\n\t}\r\n\t// add all decomposed parts\r\n\t// see derive: \"Valid is Closed (via Brute-force)\"\r\n\tset_add_many(VALID, nfd(VALID));\r\n\t\r\n\t// decode emoji\r\n\t// 20230719: emoji are now fully-expanded to avoid quirk logic \r\n\tEMOJI_LIST = read_trie(r).map(v => Emoji.from(v)).sort(compare_arrays);\r\n\tEMOJI_ROOT = new Map(); // this has approx 7K nodes (2+ per emoji)\r\n\tfor (let cps of EMOJI_LIST) {\r\n\t\t// 20230719: change to *slightly* stricter algorithm which disallows \r\n\t\t// insertion of misplaced FE0F in emoji sequences (matching ENSIP-15)\r\n\t\t// example: beautified [A B] (eg. flag emoji) \r\n\t\t//  before: allow: [A FE0F B], error: [A FE0F FE0F B] \r\n\t\t//   after: error: both\r\n\t\t// note: this code now matches ENSNormalize.{cs,java} logic\r\n\t\tlet prev = [EMOJI_ROOT];\r\n\t\tfor (let cp of cps) {\r\n\t\t\tlet next = prev.map(node => {\r\n\t\t\t\tlet child = node.get(cp);\r\n\t\t\t\tif (!child) {\r\n\t\t\t\t\t// should this be object? \r\n\t\t\t\t\t// (most have 1-2 items, few have many)\r\n\t\t\t\t\t// 20230719: no, v8 default map is 4?\r\n\t\t\t\t\tchild = new Map();\r\n\t\t\t\t\tnode.set(cp, child);\r\n\t\t\t\t}\r\n\t\t\t\treturn child;\r\n\t\t\t});\r\n\t\t\tif (cp === FE0F) {\r\n\t\t\t\tprev.push(...next); // less than 20 elements\r\n\t\t\t} else {\r\n\t\t\t\tprev = next;\r\n\t\t\t}\r\n\t\t}\r\n\t\tfor (let x of prev) {\r\n\t\t\tx.V = cps;\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// if escaped: {HEX}\r\n//       else: \"x\" {HEX}\r\nfunction quoted_cp(cp) {\r\n\treturn (should_escape(cp) ? '' : `${bidi_qq(safe_str_from_cps([cp]))} `) + quote_cp(cp);\r\n}\r\n\r\n// 20230211: some messages can be mixed-directional and result in spillover\r\n// use 200E after a quoted string to force the remainder of a string from \r\n// acquring the direction of the quote\r\n// https://www.w3.org/International/questions/qa-bidi-unicode-controls#exceptions\r\nfunction bidi_qq(s) {\r\n\treturn `\"${s}\"\\u200E`; // strong LTR\r\n}\r\n\r\nfunction check_label_extension(cps) {\r\n\tif (cps.length >= 4 && cps[2] == HYPHEN && cps[3] == HYPHEN) {\r\n\t\tthrow new Error(`invalid label extension: \"${str_from_cps(cps.slice(0, 4))}\"`); // this can only be ascii so cant be bidi\r\n\t}\r\n}\r\nfunction check_leading_underscore(cps) {\r\n\tconst UNDERSCORE = 0x5F;\r\n\tfor (let i = cps.lastIndexOf(UNDERSCORE); i > 0; ) {\r\n\t\tif (cps[--i] !== UNDERSCORE) {\r\n\t\t\tthrow new Error('underscore allowed only at start');\r\n\t\t}\r\n\t}\r\n}\r\n// check that a fenced cp is not leading, trailing, or touching another fenced cp\r\nfunction check_fenced(cps) {\r\n\tlet cp = cps[0];\r\n\tlet prev = FENCED.get(cp);\r\n\tif (prev) throw error_placement(`leading ${prev}`);\r\n\tlet n = cps.length;\r\n\tlet last = -1; // prevents trailing from throwing\r\n\tfor (let i = 1; i < n; i++) {\r\n\t\tcp = cps[i];\r\n\t\tlet match = FENCED.get(cp);\r\n\t\tif (match) {\r\n\t\t\t// since cps[0] isn't fenced, cps[1] cannot throw\r\n\t\t\tif (last == i) throw error_placement(`${prev} + ${match}`);\r\n\t\t\tlast = i + 1;\r\n\t\t\tprev = match;\r\n\t\t}\r\n\t}\r\n\tif (last == n) throw error_placement(`trailing ${prev}`);\r\n}\r\n\r\n// create a safe to print string \r\n// invisibles are escaped\r\n// leading cm uses placeholder\r\n// if cps exceed max, middle truncate with ellipsis\r\n// quoter(cp) => string, eg. 3000 => \"{3000}\"\r\n// note: in html, you'd call this function then replace [<>&] with entities\r\nfunction safe_str_from_cps(cps, max = Infinity, quoter = quote_cp) {\r\n\t//if (Number.isInteger(cps)) cps = [cps];\r\n\t//if (!Array.isArray(cps)) throw new TypeError(`expected codepoints`);\r\n\tlet buf = [];\r\n\tif (is_combining_mark(cps[0])) buf.push('◌');\r\n\tif (cps.length > max) {\r\n\t\tmax >>= 1;\r\n\t\tcps = [...cps.slice(0, max), 0x2026, ...cps.slice(-max)];\r\n\t}\r\n\tlet prev = 0;\r\n\tlet n = cps.length;\r\n\tfor (let i = 0; i < n; i++) {\r\n\t\tlet cp = cps[i];\r\n\t\tif (should_escape(cp)) {\r\n\t\t\tbuf.push(str_from_cps(cps.slice(prev, i)));\r\n\t\t\tbuf.push(quoter(cp));\r\n\t\t\tprev = i + 1;\r\n\t\t}\r\n\t}\r\n\tbuf.push(str_from_cps(cps.slice(prev, n)));\r\n\treturn buf.join('');\r\n}\r\n\r\n// note: set(s) cannot be exposed because they can be modified\r\n// note: Object.freeze() doesn't work\r\nfunction is_combining_mark(cp, only_nsm) { // 20240127: add extra argument\r\n\tinit();\r\n\treturn only_nsm ? NSM.has(cp) : CM.has(cp);\r\n}\r\nfunction should_escape(cp) {\r\n\tinit();\r\n\treturn ESCAPE.has(cp);\r\n}\r\n\r\n// return all supported emoji as fully-qualified emoji \r\n// ordered by length then lexicographic \r\nfunction ens_emoji() {\r\n\tinit();\r\n\treturn EMOJI_LIST.map(x => x.slice()); // emoji are exposed so copy\r\n}\r\n\r\nfunction ens_normalize_fragment(frag, decompose) {\r\n\tinit();\r\n\tlet nf = decompose ? nfd : nfc;\r\n\treturn frag.split(STOP_CH).map(label => str_from_cps(tokens_from_str(explode_cp(label), nf, filter_fe0f).flat())).join(STOP_CH);\r\n}\r\n\r\nfunction ens_normalize(name) {\r\n\treturn flatten(split(name, nfc, filter_fe0f));\r\n}\r\n\r\nfunction ens_beautify(name) {\r\n\tlet labels = split(name, nfc, x => x); // emoji not exposed\r\n\tfor (let {type, output, error} of labels) {\r\n\t\tif (error) break; // flatten will throw\r\n\r\n\t\t// replace leading/trailing hyphen\r\n\t\t// 20230121: consider beautifing all or leading/trailing hyphen to unicode variant\r\n\t\t// not exactly the same in every font, but very similar: \"-\" vs \"‐\"\r\n\t\t/*\r\n\t\tconst UNICODE_HYPHEN = 0x2010;\r\n\t\t// maybe this should replace all for visual consistancy?\r\n\t\t// `node tools/reg-count.js regex ^-\\{2,\\}` => 592\r\n\t\t//for (let i = 0; i < output.length; i++) if (output[i] == 0x2D) output[i] = 0x2010;\r\n\t\tif (output[0] == HYPHEN) output[0] = UNICODE_HYPHEN;\r\n\t\tlet end = output.length-1;\r\n\t\tif (output[end] == HYPHEN) output[end] = UNICODE_HYPHEN;\r\n\t\t*/\r\n\t\t// 20230123: WHATWG URL uses \"CheckHyphens\" false\r\n\t\t// https://url.spec.whatwg.org/#idna\r\n\r\n\t\t// update ethereum symbol\r\n\t\t// ξ => Ξ if not greek\r\n\t\tif (type !== 'Greek') array_replace(output, 0x3BE, 0x39E);\r\n\r\n\t\t// 20221213: fixes bidi subdomain issue, but breaks invariant (200E is disallowed)\r\n\t\t// could be fixed with special case for: 2D (.) + 200E (LTR)\r\n\t\t// https://discuss.ens.domains/t/bidi-label-ordering-spoof/15824\r\n\t\t//output.splice(0, 0, 0x200E);\r\n\t}\r\n\treturn flatten(labels);\r\n}\r\n\r\nfunction ens_split(name, preserve_emoji) {\r\n\treturn split(name, nfc, preserve_emoji ? x => x.slice() : filter_fe0f); // emoji are exposed so copy\r\n}\r\n\r\nfunction split(name, nf, ef) {\r\n\tif (!name) return []; // 20230719: empty name allowance\r\n\tinit();\r\n\tlet offset = 0;\r\n\t// https://unicode.org/reports/tr46/#Validity_Criteria\r\n\t// 4.) \"The label must not contain a U+002E ( . ) FULL STOP.\"\r\n\treturn name.split(STOP_CH).map(label => {\r\n\t\tlet input = explode_cp(label);\r\n\t\tlet info = {\r\n\t\t\tinput,\r\n\t\t\toffset, // codepoint, not substring!\r\n\t\t};\r\n\t\toffset += input.length + 1; // + stop\r\n\t\ttry {\r\n\t\t\t// 1.) \"The label must be in Unicode Normalization Form NFC\"\r\n\t\t\tlet tokens = info.tokens = tokens_from_str(input, nf, ef);\r\n\t\t\tlet token_count = tokens.length;\r\n\t\t\tlet type;\r\n\t\t\tif (!token_count) { // the label was effectively empty (could of had ignored characters)\r\n\t\t\t\t//norm = [];\r\n\t\t\t\t//type = 'None'; // use this instead of next match, \"ASCII\"\r\n\t\t\t\t// 20230120: change to strict\r\n\t\t\t\t// https://discuss.ens.domains/t/ens-name-normalization-2nd/14564/59\r\n\t\t\t\tthrow new Error(`empty label`);\r\n\t\t\t} \r\n\t\t\tlet norm = info.output = tokens.flat();\r\n\t\t\tcheck_leading_underscore(norm);\r\n\t\t\tlet emoji = info.emoji = token_count > 1 || tokens[0].is_emoji; // same as: tokens.some(x => x.is_emoji);\r\n\t\t\tif (!emoji && norm.every(cp => cp < 0x80)) { // special case for ascii\r\n\t\t\t\t// 20230123: matches matches WHATWG, see note 3.3\r\n\t\t\t\tcheck_label_extension(norm); // only needed for ascii\r\n\t\t\t\t// cant have fenced\r\n\t\t\t\t// cant have cm\r\n\t\t\t\t// cant have wholes\r\n\t\t\t\t// see derive: \"Fastpath ASCII\"\r\n\t\t\t\ttype = 'ASCII';\r\n\t\t\t} else {\r\n\t\t\t\tlet chars = tokens.flatMap(x => x.is_emoji ? [] : x); // all of the nfc tokens concat together\r\n\t\t\t\tif (!chars.length) { // theres no text, just emoji\r\n\t\t\t\t\ttype = 'Emoji';\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// 5.) \"The label must not begin with a combining mark, that is: General_Category=Mark.\"\r\n\t\t\t\t\tif (CM.has(norm[0])) throw error_placement('leading combining mark');\r\n\t\t\t\t\tfor (let i = 1; i < token_count; i++) { // we've already checked the first token\r\n\t\t\t\t\t\tlet cps = tokens[i];\r\n\t\t\t\t\t\tif (!cps.is_emoji && CM.has(cps[0])) { // every text token has emoji neighbors, eg. EtEEEtEt...\r\n\t\t\t\t\t\t\t// bidi_qq() not needed since emoji is LTR and cps is a CM\r\n\t\t\t\t\t\t\tthrow error_placement(`emoji + combining mark: \"${str_from_cps(tokens[i-1])} + ${safe_str_from_cps([cps[0]])}\"`); \r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcheck_fenced(norm);\r\n\t\t\t\t\tlet unique = Array_from(new Set(chars));\r\n\t\t\t\t\tlet [g] = determine_group(unique); // take the first match\r\n\t\t\t\t\t// see derive: \"Matching Groups have Same CM Style\"\r\n\t\t\t\t\t// alternative: could form a hybrid type: Latin/Japanese/...\t\r\n\t\t\t\t\tcheck_group(g, chars); // need text in order\r\n\t\t\t\t\tcheck_whole(g, unique); // only need unique text (order would be required for multiple-char confusables)\r\n\t\t\t\t\ttype = g.N;\r\n\t\t\t\t\t// 20230121: consider exposing restricted flag\r\n\t\t\t\t\t// it's simpler to just check for 'Restricted'\r\n\t\t\t\t\t// or even better: type.endsWith(']')\r\n\t\t\t\t\t//if (g.R) info.restricted = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tinfo.type = type;\r\n\t\t} catch (err) {\r\n\t\t\tinfo.error = err; // use full error object\r\n\t\t}\r\n\t\treturn info;\r\n\t});\r\n}\r\n\r\nfunction check_whole(group, unique) {\r\n\tlet maker;\r\n\tlet shared = [];\r\n\tfor (let cp of unique) {\r\n\t\tlet whole = WHOLE_MAP.get(cp);\r\n\t\tif (whole === UNIQUE_PH) return; // unique, non-confusable\r\n\t\tif (whole) {\r\n\t\t\tlet set = whole.M.get(cp); // groups which have a character that look-like this character\r\n\t\t\tmaker = maker ? maker.filter(g => set.has(g)) : Array_from(set);\r\n\t\t\tif (!maker.length) return; // confusable intersection is empty\r\n\t\t} else {\r\n\t\t\tshared.push(cp); \r\n\t\t}\r\n\t}\r\n\tif (maker) {\r\n\t\t// we have 1+ confusable\r\n\t\t// check if any of the remaining groups\r\n\t\t// contain the shared characters too\r\n\t\tfor (let g of maker) {\r\n\t\t\tif (shared.every(cp => group_has_cp(g, cp))) {\r\n\t\t\t\tthrow new Error(`whole-script confusable: ${group.N}/${g.N}`);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// assumption: unique.size > 0\r\n// returns list of matching groups\r\nfunction determine_group(unique) {\r\n\tlet groups = GROUPS;\r\n\tfor (let cp of unique) {\r\n\t\t// note: we need to dodge CM that are whitelisted\r\n\t\t// but that code isn't currently necessary\r\n\t\tlet gs = groups.filter(g => group_has_cp(g, cp));\r\n\t\tif (!gs.length) {\r\n\t\t\tif (!GROUPS.some(g => group_has_cp(g, cp))) { \r\n\t\t\t\t// the character was composed of valid parts\r\n\t\t\t\t// but it's NFC form is invalid\r\n\t\t\t\t// 20230716: change to more exact statement, see: ENSNormalize.{cs,java}\r\n\t\t\t\t// note: this doesn't have to be a composition\r\n\t\t\t\t// 20230720: change to full check\r\n\t\t\t\tthrow error_disallowed(cp); // this should be rare\r\n\t\t\t} else {\r\n\t\t\t\t// there is no group that contains all these characters\r\n\t\t\t\t// throw using the highest priority group that matched\r\n\t\t\t\t// https://www.unicode.org/reports/tr39/#mixed_script_confusables\r\n\t\t\t\tthrow error_group_member(groups[0], cp);\r\n\t\t\t}\r\n\t\t}\r\n\t\tgroups = gs;\r\n\t\tif (gs.length == 1) break; // there is only one group left\r\n\t}\r\n\t// there are at least 1 group(s) with all of these characters\r\n\treturn groups;\r\n}\r\n\r\n// throw on first error\r\nfunction flatten(split) {\r\n\treturn split.map(({input, error, output}) => {\r\n\t\tif (error) {\r\n\t\t\t// don't print label again if just a single label\r\n\t\t\tlet msg = error.message;\r\n\t\t\t// bidi_qq() only necessary if msg is digits\r\n\t\t\tthrow new Error(split.length == 1 ? msg : `Invalid label ${bidi_qq(safe_str_from_cps(input, 63))}: ${msg}`); \r\n\t\t}\r\n\t\treturn str_from_cps(output);\r\n\t}).join(STOP_CH);\r\n}\r\n\r\nfunction error_disallowed(cp) {\r\n\t// TODO: add cp to error?\r\n\treturn new Error(`disallowed character: ${quoted_cp(cp)}`); \r\n}\r\nfunction error_group_member(g, cp) {\r\n\tlet quoted = quoted_cp(cp);\r\n\tlet gg = GROUPS.find(g => g.P.has(cp)); // only check primary\r\n\tif (gg) {\r\n\t\tquoted = `${gg.N} ${quoted}`;\r\n\t}\r\n\treturn new Error(`illegal mixture: ${g.N} + ${quoted}`);\r\n}\r\nfunction error_placement(where) {\r\n\treturn new Error(`illegal placement: ${where}`);\r\n}\r\n\r\n// assumption: cps.length > 0\r\n// assumption: cps[0] isn't a CM\r\n// assumption: the previous character isn't an emoji\r\nfunction check_group(g, cps) {\r\n\tfor (let cp of cps) {\r\n\t\tif (!group_has_cp(g, cp)) {\r\n\t\t\t// for whitelisted scripts, this will throw illegal mixture on invalid cm, eg. \"e{300}{300}\"\r\n\t\t\t// at the moment, it's unnecessary to introduce an extra error type\r\n\t\t\t// until there exists a whitelisted multi-character\r\n\t\t\t//   eg. if (M < 0 && is_combining_mark(cp)) { ... }\r\n\t\t\t// there are 3 cases:\r\n\t\t\t//   1. illegal cm for wrong group => mixture error\r\n\t\t\t//   2. illegal cm for same group => cm error\r\n\t\t\t//       requires set of whitelist cm per group: \r\n\t\t\t//        eg. new Set([...g.P, ...g.Q].flatMap(nfc).filter(cp => CM.has(cp)))\r\n\t\t\t//   3. wrong group => mixture error\r\n\t\t\tthrow error_group_member(g, cp);\r\n\t\t}\r\n\t}\r\n\t//if (M >= 0) { // we have a known fixed cm count\r\n\tif (g.M) { // we need to check for NSM\r\n\t\tlet decomposed = nfd(cps);\r\n\t\tfor (let i = 1, e = decomposed.length; i < e; i++) { // see: assumption\r\n\t\t\t// 20230210: bugfix: using cps instead of decomposed h/t Carbon225\r\n\t\t\t/*\r\n\t\t\tif (CM.has(decomposed[i])) {\r\n\t\t\t\tlet j = i + 1;\r\n\t\t\t\twhile (j < e && CM.has(decomposed[j])) j++;\r\n\t\t\t\tif (j - i > M) {\r\n\t\t\t\t\tthrow new Error(`too many combining marks: ${g.N} ${bidi_qq(str_from_cps(decomposed.slice(i-1, j)))} (${j-i}/${M})`);\r\n\t\t\t\t}\r\n\t\t\t\ti = j;\r\n\t\t\t}\r\n\t\t\t*/\r\n\t\t\t// 20230217: switch to NSM counting\r\n\t\t\t// https://www.unicode.org/reports/tr39/#Optional_Detection\r\n\t\t\tif (NSM.has(decomposed[i])) {\r\n\t\t\t\tlet j = i + 1;\r\n\t\t\t\tfor (let cp; j < e && NSM.has(cp = decomposed[j]); j++) {\r\n\t\t\t\t\t// a. Forbid sequences of the same nonspacing mark.\r\n\t\t\t\t\tfor (let k = i; k < j; k++) { // O(n^2) but n < 100\r\n\t\t\t\t\t\tif (decomposed[k] == cp) {\r\n\t\t\t\t\t\t\tthrow new Error(`duplicate non-spacing marks: ${quoted_cp(cp)}`);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// parse to end so we have full nsm count\r\n\t\t\t\t// b. Forbid sequences of more than 4 nonspacing marks (gc=Mn or gc=Me).\r\n\t\t\t\tif (j - i > NSM_MAX) {\r\n\t\t\t\t\t// note: this slice starts with a base char or spacing-mark cm\r\n\t\t\t\t\tthrow new Error(`excessive non-spacing marks: ${bidi_qq(safe_str_from_cps(decomposed.slice(i-1, j)))} (${j-i}/${NSM_MAX})`);\r\n\t\t\t\t}\r\n\t\t\t\ti = j;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t// *** this code currently isn't needed ***\r\n\t/*\r\n\tlet cm_whitelist = M instanceof Map;\r\n\tfor (let i = 0, e = cps.length; i < e; ) {\r\n\t\tlet cp = cps[i++];\r\n\t\tlet seqs = cm_whitelist && M.get(cp);\r\n\t\tif (seqs) { \r\n\t\t\t// list of codepoints that can follow\r\n\t\t\t// if this exists, this will always be 1+\r\n\t\t\tlet j = i;\r\n\t\t\twhile (j < e && CM.has(cps[j])) j++;\r\n\t\t\tlet cms = cps.slice(i, j);\r\n\t\t\tlet match = seqs.find(seq => !compare_arrays(seq, cms));\r\n\t\t\tif (!match) throw new Error(`disallowed combining mark sequence: \"${safe_str_from_cps([cp, ...cms])}\"`);\r\n\t\t\ti = j;\r\n\t\t} else if (!V.has(cp)) {\r\n\t\t\t// https://www.unicode.org/reports/tr39/#mixed_script_confusables\r\n\t\t\tlet quoted = quoted_cp(cp);\r\n\t\t\tfor (let cp of cps) {\r\n\t\t\t\tlet u = UNIQUE.get(cp);\r\n\t\t\t\tif (u && u !== g) {\r\n\t\t\t\t\t// if both scripts are restricted this error is confusing\r\n\t\t\t\t\t// because we don't differentiate RestrictedA from RestrictedB \r\n\t\t\t\t\tif (!u.R) quoted = `${quoted} is ${u.N}`;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tthrow new Error(`disallowed ${g.N} character: ${quoted}`);\r\n\t\t\t//throw new Error(`disallowed character: ${quoted} (expected ${g.N})`);\r\n\t\t\t//throw new Error(`${g.N} does not allow: ${quoted}`);\r\n\t\t}\r\n\t}\r\n\tif (!cm_whitelist) {\r\n\t\tlet decomposed = nfd(cps);\r\n\t\tfor (let i = 1, e = decomposed.length; i < e; i++) { // we know it can't be cm leading\r\n\t\t\tif (CM.has(decomposed[i])) {\r\n\t\t\t\tlet j = i + 1;\r\n\t\t\t\twhile (j < e && CM.has(decomposed[j])) j++;\r\n\t\t\t\tif (j - i > M) {\r\n\t\t\t\t\tthrow new Error(`too many combining marks: \"${str_from_cps(decomposed.slice(i-1, j))}\" (${j-i}/${M})`);\r\n\t\t\t\t}\r\n\t\t\t\ti = j;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t*/\r\n}\r\n\r\n// given a list of codepoints\r\n// returns a list of lists, where emoji are a fully-qualified (as Array subclass)\r\n// eg. explode_cp(\"abc💩d\") => [[61, 62, 63], Emoji[1F4A9, FE0F], [64]]\r\n// 20230818: rename for 'process' name collision h/t Javarome\r\n// https://github.com/adraffy/ens-normalize.js/issues/23\r\nfunction tokens_from_str(input, nf, ef) {\r\n\tlet ret = [];\r\n\tlet chars = [];\r\n\tinput = input.slice().reverse(); // flip so we can pop\r\n\twhile (input.length) {\r\n\t\tlet emoji = consume_emoji_reversed(input);\r\n\t\tif (emoji) {\r\n\t\t\tif (chars.length) {\r\n\t\t\t\tret.push(nf(chars));\r\n\t\t\t\tchars = [];\r\n\t\t\t}\r\n\t\t\tret.push(ef(emoji));\r\n\t\t} else {\r\n\t\t\tlet cp = input.pop();\r\n\t\t\tif (VALID.has(cp)) {\r\n\t\t\t\tchars.push(cp);\r\n\t\t\t} else {\r\n\t\t\t\tlet cps = MAPPED.get(cp);\r\n\t\t\t\tif (cps) {\r\n\t\t\t\t\tchars.push(...cps); // less than 10 elements\r\n\t\t\t\t} else if (!IGNORED.has(cp)) {\r\n\t\t\t\t\t// 20230912: unicode 15.1 changed the order of processing such that\r\n\t\t\t\t\t// disallowed parts are only rejected after NFC\r\n\t\t\t\t\t// https://unicode.org/reports/tr46/#Validity_Criteria\r\n\t\t\t\t\t// this doesn't impact normalization as of today\r\n\t\t\t\t\t// technically, this error can be removed as the group logic will apply similar logic\r\n\t\t\t\t\t// however the error type might be less clear\r\n\t\t\t\t\tthrow error_disallowed(cp);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tif (chars.length) {\r\n\t\tret.push(nf(chars));\r\n\t}\r\n\treturn ret;\r\n}\r\n\r\nfunction filter_fe0f(cps) {\r\n\treturn cps.filter(cp => cp != FE0F);\r\n}\r\n\r\n// given array of codepoints\r\n// returns the longest valid emoji sequence (or undefined if no match)\r\n// *MUTATES* the supplied array\r\n// disallows interleaved ignored characters\r\n// fills (optional) eaten array with matched codepoints\r\nfunction consume_emoji_reversed(cps, eaten) {\r\n\tlet node = EMOJI_ROOT;\r\n\tlet emoji;\r\n\tlet pos = cps.length;\r\n\twhile (pos) {\r\n\t\tnode = node.get(cps[--pos]);\r\n\t\tif (!node) break;\r\n\t\tlet {V} = node;\r\n\t\tif (V) { // this is a valid emoji (so far)\r\n\t\t\temoji = V;\r\n\t\t\tif (eaten) eaten.push(...cps.slice(pos).reverse()); // (optional) copy input, used for ens_tokenize()\r\n\t\t\tcps.length = pos; // truncate\r\n\t\t}\r\n\t}\r\n\treturn emoji;\r\n}\r\n\r\n// ************************************************************\r\n// tokenizer \r\n\r\nconst TY_VALID = 'valid';\r\nconst TY_MAPPED = 'mapped';\r\nconst TY_IGNORED = 'ignored';\r\nconst TY_DISALLOWED = 'disallowed';\r\nconst TY_EMOJI = 'emoji';\r\nconst TY_NFC = 'nfc';\r\nconst TY_STOP = 'stop';\r\n\r\nfunction ens_tokenize(name, {\r\n\tnf = true, // collapse unnormalized runs into a single token\r\n} = {}) {\r\n\tinit();\r\n\tlet input = explode_cp(name).reverse();\r\n\tlet eaten = [];\r\n\tlet tokens = [];\r\n\twhile (input.length) {\r\n\t\tlet emoji = consume_emoji_reversed(input, eaten);\r\n\t\tif (emoji) {\r\n\t\t\ttokens.push({\r\n\t\t\t\ttype: TY_EMOJI,\r\n\t\t\t\temoji: emoji.slice(), // copy emoji\r\n\t\t\t\tinput: eaten,\r\n\t\t\t\tcps: filter_fe0f(emoji)\r\n\t\t\t});\r\n\t\t\teaten = []; // reset buffer\r\n\t\t} else {\r\n\t\t\tlet cp = input.pop();\r\n\t\t\tif (cp == STOP) {\r\n\t\t\t\ttokens.push({type: TY_STOP, cp});\r\n\t\t\t} else if (VALID.has(cp)) {\r\n\t\t\t\ttokens.push({type: TY_VALID, cps: [cp]});\r\n\t\t\t} else if (IGNORED.has(cp)) {\r\n\t\t\t\ttokens.push({type: TY_IGNORED, cp});\r\n\t\t\t} else {\r\n\t\t\t\tlet cps = MAPPED.get(cp);\r\n\t\t\t\tif (cps) {\r\n\t\t\t\t\ttokens.push({type: TY_MAPPED, cp, cps: cps.slice()});\r\n\t\t\t\t} else {\r\n\t\t\t\t\ttokens.push({type: TY_DISALLOWED, cp});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tif (nf) {\r\n\t\tfor (let i = 0, start = -1; i < tokens.length; i++) {\r\n\t\t\tlet token = tokens[i];\r\n\t\t\tif (is_valid_or_mapped(token.type)) {\r\n\t\t\t\tif (requires_check(token.cps)) { // normalization might be needed\r\n\t\t\t\t\tlet end = i + 1;\r\n\t\t\t\t\tfor (let pos = end; pos < tokens.length; pos++) { // find adjacent text\r\n\t\t\t\t\t\tlet {type, cps} = tokens[pos];\r\n\t\t\t\t\t\tif (is_valid_or_mapped(type)) {\r\n\t\t\t\t\t\t\tif (!requires_check(cps)) break;\r\n\t\t\t\t\t\t\tend = pos + 1;\r\n\t\t\t\t\t\t} else if (type !== TY_IGNORED) { // || type !== TY_DISALLOWED) { \r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (start < 0) start = i;\r\n\t\t\t\t\tlet slice = tokens.slice(start, end);\r\n\t\t\t\t\tlet cps0 = slice.flatMap(x => is_valid_or_mapped(x.type) ? x.cps : []); // strip junk tokens\r\n\t\t\t\t\tlet cps = nfc(cps0);\r\n\t\t\t\t\tif (compare_arrays(cps, cps0)) { // bundle into an nfc token\r\n\t\t\t\t\t\ttokens.splice(start, end - start, {\r\n\t\t\t\t\t\t\ttype: TY_NFC, \r\n\t\t\t\t\t\t\tinput: cps0, // there are 3 states: tokens0 ==(process)=> input ==(nfc)=> tokens/cps\r\n\t\t\t\t\t\t\tcps, \r\n\t\t\t\t\t\t\ttokens0: collapse_valid_tokens(slice),\r\n\t\t\t\t\t\t\ttokens: ens_tokenize(str_from_cps(cps), {nf: false})\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\ti = start;\r\n\t\t\t\t\t} else { \r\n\t\t\t\t\t\ti = end - 1; // skip to end of slice\r\n\t\t\t\t\t}\r\n\t\t\t\t\tstart = -1; // reset\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstart = i; // remember last\r\n\t\t\t\t}\r\n\t\t\t} else if (token.type !== TY_IGNORED) { // 20221024: is this correct?\r\n\t\t\t\tstart = -1; // reset\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn collapse_valid_tokens(tokens);\r\n}\r\n\r\nfunction is_valid_or_mapped(type) {\r\n\treturn type == TY_VALID || type == TY_MAPPED;\r\n}\r\n\r\nfunction requires_check(cps) {\r\n\treturn cps.some(cp => NFC_CHECK.has(cp));\r\n}\r\n\r\nfunction collapse_valid_tokens(tokens) {\r\n\tfor (let i = 0; i < tokens.length; i++) {\r\n\t\tif (tokens[i].type == TY_VALID) {\r\n\t\t\tlet j = i + 1;\r\n\t\t\twhile (j < tokens.length && tokens[j].type == TY_VALID) j++;\r\n\t\t\ttokens.splice(i, j - i, {type: TY_VALID, cps: tokens.slice(i, j).flatMap(x => x.cps)});\r\n\t\t}\r\n\t}\r\n\treturn tokens;\r\n}\n\nexport { ens_beautify, ens_emoji, ens_normalize, ens_normalize_fragment, ens_split, ens_tokenize, is_combining_mark, nfc, nfd, safe_str_from_cps, should_escape };\n"]}