// Copyright (c) 2011, Mike Samuel
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// Neither the name of the OWASP nor the names of its contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

package org.owasp.html;

import java.util.Map;

import com.google.common.collect.ImmutableMap;

/**
 * Utilities for decoding HTML entities, e.g., {@code &amp;}.
 */
final class HtmlEntities {

  /** A trie that maps entity names to strings of referenced code points. */
  public static final Trie<String> ENTITY_TRIE;

  private static final int LONGEST_ENTITY_NAME;

  static {
    final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();

    // Source data: https://html.spec.whatwg.org/multipage/named-characters.html

    builder.put("AElig", "\u00c6");
    builder.put("AMP", "\u0026");
    builder.put("Aacute", "\u00c1");
    builder.put("Abreve", "\u0102");
    builder.put("Acirc", "\u00c2");
    builder.put("Acy", "\u0410");
    builder.put("Afr", "\ud835\udd04");
    builder.put("Agrave", "\u00c0");
    builder.put("Alpha", "\u0391");
    builder.put("Amacr", "\u0100");
    builder.put("And", "\u2a53");
    builder.put("Aogon", "\u0104");
    builder.put("Aopf", "\ud835\udd38");
    builder.put("ApplyFunction", "\u2061");
    builder.put("Aring", "\u00c5");
    builder.put("Ascr", "\ud835\udc9c");
    builder.put("Assign", "\u2254");
    builder.put("Atilde", "\u00c3");
    builder.put("Auml", "\u00c4");
    builder.put("Backslash", "\u2216");
    builder.put("Barv", "\u2ae7");
    builder.put("Barwed", "\u2306");
    builder.put("Bcy", "\u0411");
    builder.put("Because", "\u2235");
    builder.put("Bernoullis", "\u212c");
    builder.put("Beta", "\u0392");
    builder.put("Bfr", "\ud835\udd05");
    builder.put("Bopf", "\ud835\udd39");
    builder.put("Breve", "\u02d8");
    builder.put("Bscr", "\u212c");
    builder.put("Bumpeq", "\u224e");
    builder.put("CHcy", "\u0427");
    builder.put("COPY", "\u00a9");
    builder.put("Cacute", "\u0106");
    builder.put("Cap", "\u22d2");
    builder.put("CapitalDifferentialD", "\u2145");
    builder.put("Cayleys", "\u212d");
    builder.put("Ccaron", "\u010c");
    builder.put("Ccedil", "\u00c7");
    builder.put("Ccirc", "\u0108");
    builder.put("Cconint", "\u2230");
    builder.put("Cdot", "\u010a");
    builder.put("Cedilla", "\u00b8");
    builder.put("CenterDot", "\u00b7");
    builder.put("Cfr", "\u212d");
    builder.put("Chi", "\u03a7");
    builder.put("CircleDot", "\u2299");
    builder.put("CircleMinus", "\u2296");
    builder.put("CirclePlus", "\u2295");
    builder.put("CircleTimes", "\u2297");
    builder.put("ClockwiseContourIntegral", "\u2232");
    builder.put("CloseCurlyDoubleQuote", "\u201d");
    builder.put("CloseCurlyQuote", "\u2019");
    builder.put("Colon", "\u2237");
    builder.put("Colone", "\u2a74");
    builder.put("Congruent", "\u2261");
    builder.put("Conint", "\u222f");
    builder.put("ContourIntegral", "\u222e");
    builder.put("Copf", "\u2102");
    builder.put("Coproduct", "\u2210");
    builder.put("CounterClockwiseContourIntegral", "\u2233");
    builder.put("Cross", "\u2a2f");
    builder.put("Cscr", "\ud835\udc9e");
    builder.put("Cup", "\u22d3");
    builder.put("CupCap", "\u224d");
    builder.put("DD", "\u2145");
    builder.put("DDotrahd", "\u2911");
    builder.put("DJcy", "\u0402");
    builder.put("DScy", "\u0405");
    builder.put("DZcy", "\u040f");
    builder.put("Dagger", "\u2021");
    builder.put("Darr", "\u21a1");
    builder.put("Dashv", "\u2ae4");
    builder.put("Dcaron", "\u010e");
    builder.put("Dcy", "\u0414");
    builder.put("Del", "\u2207");
    builder.put("Delta", "\u0394");
    builder.put("Dfr", "\ud835\udd07");
    builder.put("DiacriticalAcute", "\u00b4");
    builder.put("DiacriticalDot", "\u02d9");
    builder.put("DiacriticalDoubleAcute", "\u02dd");
    builder.put("DiacriticalGrave", "\u0060");
    builder.put("DiacriticalTilde", "\u02dc");
    builder.put("Diamond", "\u22c4");
    builder.put("DifferentialD", "\u2146");
    builder.put("Dopf", "\ud835\udd3b");
    builder.put("Dot", "\u00a8");
    builder.put("DotDot", "\u20dc");
    builder.put("DotEqual", "\u2250");
    builder.put("DoubleContourIntegral", "\u222f");
    builder.put("DoubleDot", "\u00a8");
    builder.put("DoubleDownArrow", "\u21d3");
    builder.put("DoubleLeftArrow", "\u21d0");
    builder.put("DoubleLeftRightArrow", "\u21d4");
    builder.put("DoubleLeftTee", "\u2ae4");
    builder.put("DoubleLongLeftArrow", "\u27f8");
    builder.put("DoubleLongLeftRightArrow", "\u27fa");
    builder.put("DoubleLongRightArrow", "\u27f9");
    builder.put("DoubleRightArrow", "\u21d2");
    builder.put("DoubleRightTee", "\u22a8");
    builder.put("DoubleUpArrow", "\u21d1");
    builder.put("DoubleUpDownArrow", "\u21d5");
    builder.put("DoubleVerticalBar", "\u2225");
    builder.put("DownArrow", "\u2193");
    builder.put("DownArrowBar", "\u2913");
    builder.put("DownArrowUpArrow", "\u21f5");
    builder.put("DownBreve", "\u0311");
    builder.put("DownLeftRightVector", "\u2950");
    builder.put("DownLeftTeeVector", "\u295e");
    builder.put("DownLeftVector", "\u21bd");
    builder.put("DownLeftVectorBar", "\u2956");
    builder.put("DownRightTeeVector", "\u295f");
    builder.put("DownRightVector", "\u21c1");
    builder.put("DownRightVectorBar", "\u2957");
    builder.put("DownTee", "\u22a4");
    builder.put("DownTeeArrow", "\u21a7");
    builder.put("Downarrow", "\u21d3");
    builder.put("Dscr", "\ud835\udc9f");
    builder.put("Dstrok", "\u0110");
    builder.put("ENG", "\u014a");
    builder.put("ETH", "\u00d0");
    builder.put("Eacute", "\u00c9");
    builder.put("Ecaron", "\u011a");
    builder.put("Ecirc", "\u00ca");
    builder.put("Ecy", "\u042d");
    builder.put("Edot", "\u0116");
    builder.put("Efr", "\ud835\udd08");
    builder.put("Egrave", "\u00c8");
    builder.put("Element", "\u2208");
    builder.put("Emacr", "\u0112");
    builder.put("EmptySmallSquare", "\u25fb");
    builder.put("EmptyVerySmallSquare", "\u25ab");
    builder.put("Eogon", "\u0118");
    builder.put("Eopf", "\ud835\udd3c");
    builder.put("Epsilon", "\u0395");
    builder.put("Equal", "\u2a75");
    builder.put("EqualTilde", "\u2242");
    builder.put("Equilibrium", "\u21cc");
    builder.put("Escr", "\u2130");
    builder.put("Esim", "\u2a73");
    builder.put("Eta", "\u0397");
    builder.put("Euml", "\u00cb");
    builder.put("Exists", "\u2203");
    builder.put("ExponentialE", "\u2147");
    builder.put("Fcy", "\u0424");
    builder.put("Ffr", "\ud835\udd09");
    builder.put("FilledSmallSquare", "\u25fc");
    builder.put("FilledVerySmallSquare", "\u25aa");
    builder.put("Fopf", "\ud835\udd3d");
    builder.put("ForAll", "\u2200");
    builder.put("Fouriertrf", "\u2131");
    builder.put("Fscr", "\u2131");
    builder.put("GJcy", "\u0403");
    builder.put("GT", "\u003e");
    builder.put("Gamma", "\u0393");
    builder.put("Gammad", "\u03dc");
    builder.put("Gbreve", "\u011e");
    builder.put("Gcedil", "\u0122");
    builder.put("Gcirc", "\u011c");
    builder.put("Gcy", "\u0413");
    builder.put("Gdot", "\u0120");
    builder.put("Gfr", "\ud835\udd0a");
    builder.put("Gg", "\u22d9");
    builder.put("Gopf", "\ud835\udd3e");
    builder.put("GreaterEqual", "\u2265");
    builder.put("GreaterEqualLess", "\u22db");
    builder.put("GreaterFullEqual", "\u2267");
    builder.put("GreaterGreater", "\u2aa2");
    builder.put("GreaterLess", "\u2277");
    builder.put("GreaterSlantEqual", "\u2a7e");
    builder.put("GreaterTilde", "\u2273");
    builder.put("Gscr", "\ud835\udca2");
    builder.put("Gt", "\u226b");
    builder.put("HARDcy", "\u042a");
    builder.put("Hacek", "\u02c7");
    builder.put("Hat", "\u005e");
    builder.put("Hcirc", "\u0124");
    builder.put("Hfr", "\u210c");
    builder.put("HilbertSpace", "\u210b");
    builder.put("Hopf", "\u210d");
    builder.put("HorizontalLine", "\u2500");
    builder.put("Hscr", "\u210b");
    builder.put("Hstrok", "\u0126");
    builder.put("HumpDownHump", "\u224e");
    builder.put("HumpEqual", "\u224f");
    builder.put("IEcy", "\u0415");
    builder.put("IJlig", "\u0132");
    builder.put("IOcy", "\u0401");
    builder.put("Iacute", "\u00cd");
    builder.put("Icirc", "\u00ce");
    builder.put("Icy", "\u0418");
    builder.put("Idot", "\u0130");
    builder.put("Ifr", "\u2111");
    builder.put("Igrave", "\u00cc");
    builder.put("Im", "\u2111");
    builder.put("Imacr", "\u012a");
    builder.put("ImaginaryI", "\u2148");
    builder.put("Implies", "\u21d2");
    builder.put("Int", "\u222c");
    builder.put("Integral", "\u222b");
    builder.put("Intersection", "\u22c2");
    builder.put("InvisibleComma", "\u2063");
    builder.put("InvisibleTimes", "\u2062");
    builder.put("Iogon", "\u012e");
    builder.put("Iopf", "\ud835\udd40");
    builder.put("Iota", "\u0399");
    builder.put("Iscr", "\u2110");
    builder.put("Itilde", "\u0128");
    builder.put("Iukcy", "\u0406");
    builder.put("Iuml", "\u00cf");
    builder.put("Jcirc", "\u0134");
    builder.put("Jcy", "\u0419");
    builder.put("Jfr", "\ud835\udd0d");
    builder.put("Jopf", "\ud835\udd41");
    builder.put("Jscr", "\ud835\udca5");
    builder.put("Jsercy", "\u0408");
    builder.put("Jukcy", "\u0404");
    builder.put("KHcy", "\u0425");
    builder.put("KJcy", "\u040c");
    builder.put("Kappa", "\u039a");
    builder.put("Kcedil", "\u0136");
    builder.put("Kcy", "\u041a");
    builder.put("Kfr", "\ud835\udd0e");
    builder.put("Kopf", "\ud835\udd42");
    builder.put("Kscr", "\ud835\udca6");
    builder.put("LJcy", "\u0409");
    builder.put("LT", "\u003c");
    builder.put("Lacute", "\u0139");
    builder.put("Lambda", "\u039b");
    builder.put("Lang", "\u27ea");
    builder.put("Laplacetrf", "\u2112");
    builder.put("Larr", "\u219e");
    builder.put("Lcaron", "\u013d");
    builder.put("Lcedil", "\u013b");
    builder.put("Lcy", "\u041b");
    builder.put("LeftAngleBracket", "\u27e8");
    builder.put("LeftArrow", "\u2190");
    builder.put("LeftArrowBar", "\u21e4");
    builder.put("LeftArrowRightArrow", "\u21c6");
    builder.put("LeftCeiling", "\u2308");
    builder.put("LeftDoubleBracket", "\u27e6");
    builder.put("LeftDownTeeVector", "\u2961");
    builder.put("LeftDownVector", "\u21c3");
    builder.put("LeftDownVectorBar", "\u2959");
    builder.put("LeftFloor", "\u230a");
    builder.put("LeftRightArrow", "\u2194");
    builder.put("LeftRightVector", "\u294e");
    builder.put("LeftTee", "\u22a3");
    builder.put("LeftTeeArrow", "\u21a4");
    builder.put("LeftTeeVector", "\u295a");
    builder.put("LeftTriangle", "\u22b2");
    builder.put("LeftTriangleBar", "\u29cf");
    builder.put("LeftTriangleEqual", "\u22b4");
    builder.put("LeftUpDownVector", "\u2951");
    builder.put("LeftUpTeeVector", "\u2960");
    builder.put("LeftUpVector", "\u21bf");
    builder.put("LeftUpVectorBar", "\u2958");
    builder.put("LeftVector", "\u21bc");
    builder.put("LeftVectorBar", "\u2952");
    builder.put("Leftarrow", "\u21d0");
    builder.put("Leftrightarrow", "\u21d4");
    builder.put("LessEqualGreater", "\u22da");
    builder.put("LessFullEqual", "\u2266");
    builder.put("LessGreater", "\u2276");
    builder.put("LessLess", "\u2aa1");
    builder.put("LessSlantEqual", "\u2a7d");
    builder.put("LessTilde", "\u2272");
    builder.put("Lfr", "\ud835\udd0f");
    builder.put("Ll", "\u22d8");
    builder.put("Lleftarrow", "\u21da");
    builder.put("Lmidot", "\u013f");
    builder.put("LongLeftArrow", "\u27f5");
    builder.put("LongLeftRightArrow", "\u27f7");
    builder.put("LongRightArrow", "\u27f6");
    builder.put("Longleftarrow", "\u27f8");
    builder.put("Longleftrightarrow", "\u27fa");
    builder.put("Longrightarrow", "\u27f9");
    builder.put("Lopf", "\ud835\udd43");
    builder.put("LowerLeftArrow", "\u2199");
    builder.put("LowerRightArrow", "\u2198");
    builder.put("Lscr", "\u2112");
    builder.put("Lsh", "\u21b0");
    builder.put("Lstrok", "\u0141");
    builder.put("Lt", "\u226a");
    builder.put("Map", "\u2905");
    builder.put("Mcy", "\u041c");
    builder.put("MediumSpace", "\u205f");
    builder.put("Mellintrf", "\u2133");
    builder.put("Mfr", "\ud835\udd10");
    builder.put("MinusPlus", "\u2213");
    builder.put("Mopf", "\ud835\udd44");
    builder.put("Mscr", "\u2133");
    builder.put("Mu", "\u039c");
    builder.put("NJcy", "\u040a");
    builder.put("Nacute", "\u0143");
    builder.put("Ncaron", "\u0147");
    builder.put("Ncedil", "\u0145");
    builder.put("Ncy", "\u041d");
    builder.put("NegativeMediumSpace", "\u200b");
    builder.put("NegativeThickSpace", "\u200b");
    builder.put("NegativeThinSpace", "\u200b");
    builder.put("NegativeVeryThinSpace", "\u200b");
    builder.put("NestedGreaterGreater", "\u226b");
    builder.put("NestedLessLess", "\u226a");
    builder.put("NewLine", "\n");
    builder.put("Nfr", "\ud835\udd11");
    builder.put("NoBreak", "\u2060");
    builder.put("NonBreakingSpace", "\u00a0");
    builder.put("Nopf", "\u2115");
    builder.put("Not", "\u2aec");
    builder.put("NotCongruent", "\u2262");
    builder.put("NotCupCap", "\u226d");
    builder.put("NotDoubleVerticalBar", "\u2226");
    builder.put("NotElement", "\u2209");
    builder.put("NotEqual", "\u2260");
    builder.put("NotEqualTilde", "\u2242\u0338");
    builder.put("NotExists", "\u2204");
    builder.put("NotGreater", "\u226f");
    builder.put("NotGreaterEqual", "\u2271");
    builder.put("NotGreaterFullEqual", "\u2267\u0338");
    builder.put("NotGreaterGreater", "\u226b\u0338");
    builder.put("NotGreaterLess", "\u2279");
    builder.put("NotGreaterSlantEqual", "\u2a7e\u0338");
    builder.put("NotGreaterTilde", "\u2275");
    builder.put("NotHumpDownHump", "\u224e\u0338");
    builder.put("NotHumpEqual", "\u224f\u0338");
    builder.put("NotLeftTriangle", "\u22ea");
    builder.put("NotLeftTriangleBar", "\u29cf\u0338");
    builder.put("NotLeftTriangleEqual", "\u22ec");
    builder.put("NotLess", "\u226e");
    builder.put("NotLessEqual", "\u2270");
    builder.put("NotLessGreater", "\u2278");
    builder.put("NotLessLess", "\u226a\u0338");
    builder.put("NotLessSlantEqual", "\u2a7d\u0338");
    builder.put("NotLessTilde", "\u2274");
    builder.put("NotNestedGreaterGreater", "\u2aa2\u0338");
    builder.put("NotNestedLessLess", "\u2aa1\u0338");
    builder.put("NotPrecedes", "\u2280");
    builder.put("NotPrecedesEqual", "\u2aaf\u0338");
    builder.put("NotPrecedesSlantEqual", "\u22e0");
    builder.put("NotReverseElement", "\u220c");
    builder.put("NotRightTriangle", "\u22eb");
    builder.put("NotRightTriangleBar", "\u29d0\u0338");
    builder.put("NotRightTriangleEqual", "\u22ed");
    builder.put("NotSquareSubset", "\u228f\u0338");
    builder.put("NotSquareSubsetEqual", "\u22e2");
    builder.put("NotSquareSuperset", "\u2290\u0338");
    builder.put("NotSquareSupersetEqual", "\u22e3");
    builder.put("NotSubset", "\u2282\u20d2");
    builder.put("NotSubsetEqual", "\u2288");
    builder.put("NotSucceeds", "\u2281");
    builder.put("NotSucceedsEqual", "\u2ab0\u0338");
    builder.put("NotSucceedsSlantEqual", "\u22e1");
    builder.put("NotSucceedsTilde", "\u227f\u0338");
    builder.put("NotSuperset", "\u2283\u20d2");
    builder.put("NotSupersetEqual", "\u2289");
    builder.put("NotTilde", "\u2241");
    builder.put("NotTildeEqual", "\u2244");
    builder.put("NotTildeFullEqual", "\u2247");
    builder.put("NotTildeTilde", "\u2249");
    builder.put("NotVerticalBar", "\u2224");
    builder.put("Nscr", "\ud835\udca9");
    builder.put("Ntilde", "\u00d1");
    builder.put("Nu", "\u039d");
    builder.put("OElig", "\u0152");
    builder.put("Oacute", "\u00d3");
    builder.put("Ocirc", "\u00d4");
    builder.put("Ocy", "\u041e");
    builder.put("Odblac", "\u0150");
    builder.put("Ofr", "\ud835\udd12");
    builder.put("Ograve", "\u00d2");
    builder.put("Omacr", "\u014c");
    builder.put("Omega", "\u03a9");
    builder.put("Omicron", "\u039f");
    builder.put("Oopf", "\ud835\udd46");
    builder.put("OpenCurlyDoubleQuote", "\u201c");
    builder.put("OpenCurlyQuote", "\u2018");
    builder.put("Or", "\u2a54");
    builder.put("Oscr", "\ud835\udcaa");
    builder.put("Oslash", "\u00d8");
    builder.put("Otilde", "\u00d5");
    builder.put("Otimes", "\u2a37");
    builder.put("Ouml", "\u00d6");
    builder.put("OverBar", "\u203e");
    builder.put("OverBrace", "\u23de");
    builder.put("OverBracket", "\u23b4");
    builder.put("OverParenthesis", "\u23dc");
    builder.put("PartialD", "\u2202");
    builder.put("Pcy", "\u041f");
    builder.put("Pfr", "\ud835\udd13");
    builder.put("Phi", "\u03a6");
    builder.put("Pi", "\u03a0");
    builder.put("PlusMinus", "\u00b1");
    builder.put("Poincareplane", "\u210c");
    builder.put("Popf", "\u2119");
    builder.put("Pr", "\u2abb");
    builder.put("Precedes", "\u227a");
    builder.put("PrecedesEqual", "\u2aaf");
    builder.put("PrecedesSlantEqual", "\u227c");
    builder.put("PrecedesTilde", "\u227e");
    builder.put("Prime", "\u2033");
    builder.put("Product", "\u220f");
    builder.put("Proportion", "\u2237");
    builder.put("Proportional", "\u221d");
    builder.put("Pscr", "\ud835\udcab");
    builder.put("Psi", "\u03a8");
    builder.put("QUOT", "\"");
    builder.put("Qfr", "\ud835\udd14");
    builder.put("Qopf", "\u211a");
    builder.put("Qscr", "\ud835\udcac");
    builder.put("RBarr", "\u2910");
    builder.put("REG", "\u00ae");
    builder.put("Racute", "\u0154");
    builder.put("Rang", "\u27eb");
    builder.put("Rarr", "\u21a0");
    builder.put("Rarrtl", "\u2916");
    builder.put("Rcaron", "\u0158");
    builder.put("Rcedil", "\u0156");
    builder.put("Rcy", "\u0420");
    builder.put("Re", "\u211c");
    builder.put("ReverseElement", "\u220b");
    builder.put("ReverseEquilibrium", "\u21cb");
    builder.put("ReverseUpEquilibrium", "\u296f");
    builder.put("Rfr", "\u211c");
    builder.put("Rho", "\u03a1");
    builder.put("RightAngleBracket", "\u27e9");
    builder.put("RightArrow", "\u2192");
    builder.put("RightArrowBar", "\u21e5");
    builder.put("RightArrowLeftArrow", "\u21c4");
    builder.put("RightCeiling", "\u2309");
    builder.put("RightDoubleBracket", "\u27e7");
    builder.put("RightDownTeeVector", "\u295d");
    builder.put("RightDownVector", "\u21c2");
    builder.put("RightDownVectorBar", "\u2955");
    builder.put("RightFloor", "\u230b");
    builder.put("RightTee", "\u22a2");
    builder.put("RightTeeArrow", "\u21a6");
    builder.put("RightTeeVector", "\u295b");
    builder.put("RightTriangle", "\u22b3");
    builder.put("RightTriangleBar", "\u29d0");
    builder.put("RightTriangleEqual", "\u22b5");
    builder.put("RightUpDownVector", "\u294f");
    builder.put("RightUpTeeVector", "\u295c");
    builder.put("RightUpVector", "\u21be");
    builder.put("RightUpVectorBar", "\u2954");
    builder.put("RightVector", "\u21c0");
    builder.put("RightVectorBar", "\u2953");
    builder.put("Rightarrow", "\u21d2");
    builder.put("Ropf", "\u211d");
    builder.put("RoundImplies", "\u2970");
    builder.put("Rrightarrow", "\u21db");
    builder.put("Rscr", "\u211b");
    builder.put("Rsh", "\u21b1");
    builder.put("RuleDelayed", "\u29f4");
    builder.put("SHCHcy", "\u0429");
    builder.put("SHcy", "\u0428");
    builder.put("SOFTcy", "\u042c");
    builder.put("Sacute", "\u015a");
    builder.put("Sc", "\u2abc");
    builder.put("Scaron", "\u0160");
    builder.put("Scedil", "\u015e");
    builder.put("Scirc", "\u015c");
    builder.put("Scy", "\u0421");
    builder.put("Sfr", "\ud835\udd16");
    builder.put("ShortDownArrow", "\u2193");
    builder.put("ShortLeftArrow", "\u2190");
    builder.put("ShortRightArrow", "\u2192");
    builder.put("ShortUpArrow", "\u2191");
    builder.put("Sigma", "\u03a3");
    builder.put("SmallCircle", "\u2218");
    builder.put("Sopf", "\ud835\udd4a");
    builder.put("Sqrt", "\u221a");
    builder.put("Square", "\u25a1");
    builder.put("SquareIntersection", "\u2293");
    builder.put("SquareSubset", "\u228f");
    builder.put("SquareSubsetEqual", "\u2291");
    builder.put("SquareSuperset", "\u2290");
    builder.put("SquareSupersetEqual", "\u2292");
    builder.put("SquareUnion", "\u2294");
    builder.put("Sscr", "\ud835\udcae");
    builder.put("Star", "\u22c6");
    builder.put("Sub", "\u22d0");
    builder.put("Subset", "\u22d0");
    builder.put("SubsetEqual", "\u2286");
    builder.put("Succeeds", "\u227b");
    builder.put("SucceedsEqual", "\u2ab0");
    builder.put("SucceedsSlantEqual", "\u227d");
    builder.put("SucceedsTilde", "\u227f");
    builder.put("SuchThat", "\u220b");
    builder.put("Sum", "\u2211");
    builder.put("Sup", "\u22d1");
    builder.put("Superset", "\u2283");
    builder.put("SupersetEqual", "\u2287");
    builder.put("Supset", "\u22d1");
    builder.put("THORN", "\u00de");
    builder.put("TRADE", "\u2122");
    builder.put("TSHcy", "\u040b");
    builder.put("TScy", "\u0426");
    builder.put("Tab", "\u0009");
    builder.put("Tau", "\u03a4");
    builder.put("Tcaron", "\u0164");
    builder.put("Tcedil", "\u0162");
    builder.put("Tcy", "\u0422");
    builder.put("Tfr", "\ud835\udd17");
    builder.put("Therefore", "\u2234");
    builder.put("Theta", "\u0398");
    builder.put("ThickSpace", "\u205f\u200a");
    builder.put("ThinSpace", "\u2009");
    builder.put("Tilde", "\u223c");
    builder.put("TildeEqual", "\u2243");
    builder.put("TildeFullEqual", "\u2245");
    builder.put("TildeTilde", "\u2248");
    builder.put("Topf", "\ud835\udd4b");
    builder.put("TripleDot", "\u20db");
    builder.put("Tscr", "\ud835\udcaf");
    builder.put("Tstrok", "\u0166");
    builder.put("Uacute", "\u00da");
    builder.put("Uarr", "\u219f");
    builder.put("Uarrocir", "\u2949");
    builder.put("Ubrcy", "\u040e");
    builder.put("Ubreve", "\u016c");
    builder.put("Ucirc", "\u00db");
    builder.put("Ucy", "\u0423");
    builder.put("Udblac", "\u0170");
    builder.put("Ufr", "\ud835\udd18");
    builder.put("Ugrave", "\u00d9");
    builder.put("Umacr", "\u016a");
    builder.put("UnderBar", "\u005f");
    builder.put("UnderBrace", "\u23df");
    builder.put("UnderBracket", "\u23b5");
    builder.put("UnderParenthesis", "\u23dd");
    builder.put("Union", "\u22c3");
    builder.put("UnionPlus", "\u228e");
    builder.put("Uogon", "\u0172");
    builder.put("Uopf", "\ud835\udd4c");
    builder.put("UpArrow", "\u2191");
    builder.put("UpArrowBar", "\u2912");
    builder.put("UpArrowDownArrow", "\u21c5");
    builder.put("UpDownArrow", "\u2195");
    builder.put("UpEquilibrium", "\u296e");
    builder.put("UpTee", "\u22a5");
    builder.put("UpTeeArrow", "\u21a5");
    builder.put("Uparrow", "\u21d1");
    builder.put("Updownarrow", "\u21d5");
    builder.put("UpperLeftArrow", "\u2196");
    builder.put("UpperRightArrow", "\u2197");
    builder.put("Upsi", "\u03d2");
    builder.put("Upsilon", "\u03a5");
    builder.put("Uring", "\u016e");
    builder.put("Uscr", "\ud835\udcb0");
    builder.put("Utilde", "\u0168");
    builder.put("Uuml", "\u00dc");
    builder.put("VDash", "\u22ab");
    builder.put("Vbar", "\u2aeb");
    builder.put("Vcy", "\u0412");
    builder.put("Vdash", "\u22a9");
    builder.put("Vdashl", "\u2ae6");
    builder.put("Vee", "\u22c1");
    builder.put("Verbar", "\u2016");
    builder.put("Vert", "\u2016");
    builder.put("VerticalBar", "\u2223");
    builder.put("VerticalLine", "\u007c");
    builder.put("VerticalSeparator", "\u2758");
    builder.put("VerticalTilde", "\u2240");
    builder.put("VeryThinSpace", "\u200a");
    builder.put("Vfr", "\ud835\udd19");
    builder.put("Vopf", "\ud835\udd4d");
    builder.put("Vscr", "\ud835\udcb1");
    builder.put("Vvdash", "\u22aa");
    builder.put("Wcirc", "\u0174");
    builder.put("Wedge", "\u22c0");
    builder.put("Wfr", "\ud835\udd1a");
    builder.put("Wopf", "\ud835\udd4e");
    builder.put("Wscr", "\ud835\udcb2");
    builder.put("Xfr", "\ud835\udd1b");
    builder.put("Xi", "\u039e");
    builder.put("Xopf", "\ud835\udd4f");
    builder.put("Xscr", "\ud835\udcb3");
    builder.put("YAcy", "\u042f");
    builder.put("YIcy", "\u0407");
    builder.put("YUcy", "\u042e");
    builder.put("Yacute", "\u00dd");
    builder.put("Ycirc", "\u0176");
    builder.put("Ycy", "\u042b");
    builder.put("Yfr", "\ud835\udd1c");
    builder.put("Yopf", "\ud835\udd50");
    builder.put("Yscr", "\ud835\udcb4");
    builder.put("Yuml", "\u0178");
    builder.put("ZHcy", "\u0416");
    builder.put("Zacute", "\u0179");
    builder.put("Zcaron", "\u017d");
    builder.put("Zcy", "\u0417");
    builder.put("Zdot", "\u017b");
    builder.put("ZeroWidthSpace", "\u200b");
    builder.put("Zeta", "\u0396");
    builder.put("Zfr", "\u2128");
    builder.put("Zopf", "\u2124");
    builder.put("Zscr", "\ud835\udcb5");
    builder.put("aacute", "\u00e1");
    builder.put("abreve", "\u0103");
    builder.put("ac", "\u223e");
    builder.put("acE", "\u223e\u0333");
    builder.put("acd", "\u223f");
    builder.put("acirc", "\u00e2");
    builder.put("acute", "\u00b4");
    builder.put("acy", "\u0430");
    builder.put("aelig", "\u00e6");
    builder.put("af", "\u2061");
    builder.put("afr", "\ud835\udd1e");
    builder.put("agrave", "\u00e0");
    builder.put("alefsym", "\u2135");
    builder.put("aleph", "\u2135");
    builder.put("alpha", "\u03b1");
    builder.put("amacr", "\u0101");
    builder.put("amalg", "\u2a3f");
    builder.put("amp", "\u0026");
    builder.put("and", "\u2227");
    builder.put("andand", "\u2a55");
    builder.put("andd", "\u2a5c");
    builder.put("andslope", "\u2a58");
    builder.put("andv", "\u2a5a");
    builder.put("ang", "\u2220");
    builder.put("ange", "\u29a4");
    builder.put("angle", "\u2220");
    builder.put("angmsd", "\u2221");
    builder.put("angmsdaa", "\u29a8");
    builder.put("angmsdab", "\u29a9");
    builder.put("angmsdac", "\u29aa");
    builder.put("angmsdad", "\u29ab");
    builder.put("angmsdae", "\u29ac");
    builder.put("angmsdaf", "\u29ad");
    builder.put("angmsdag", "\u29ae");
    builder.put("angmsdah", "\u29af");
    builder.put("angrt", "\u221f");
    builder.put("angrtvb", "\u22be");
    builder.put("angrtvbd", "\u299d");
    builder.put("angsph", "\u2222");
    builder.put("angst", "\u00c5");
    builder.put("angzarr", "\u237c");
    builder.put("aogon", "\u0105");
    builder.put("aopf", "\ud835\udd52");
    builder.put("ap", "\u2248");
    builder.put("apE", "\u2a70");
    builder.put("apacir", "\u2a6f");
    builder.put("ape", "\u224a");
    builder.put("apid", "\u224b");
    builder.put("apos", "\u0027");
    builder.put("approx", "\u2248");
    builder.put("approxeq", "\u224a");
    builder.put("aring", "\u00e5");
    builder.put("ascr", "\ud835\udcb6");
    builder.put("ast", "\u002a");
    builder.put("asymp", "\u2248");
    builder.put("asympeq", "\u224d");
    builder.put("atilde", "\u00e3");
    builder.put("auml", "\u00e4");
    builder.put("awconint", "\u2233");
    builder.put("awint", "\u2a11");
    builder.put("bNot", "\u2aed");
    builder.put("backcong", "\u224c");
    builder.put("backepsilon", "\u03f6");
    builder.put("backprime", "\u2035");
    builder.put("backsim", "\u223d");
    builder.put("backsimeq", "\u22cd");
    builder.put("barvee", "\u22bd");
    builder.put("barwed", "\u2305");
    builder.put("barwedge", "\u2305");
    builder.put("bbrk", "\u23b5");
    builder.put("bbrktbrk", "\u23b6");
    builder.put("bcong", "\u224c");
    builder.put("bcy", "\u0431");
    builder.put("bdquo", "\u201e");
    builder.put("becaus", "\u2235");
    builder.put("because", "\u2235");
    builder.put("bemptyv", "\u29b0");
    builder.put("bepsi", "\u03f6");
    builder.put("bernou", "\u212c");
    builder.put("beta", "\u03b2");
    builder.put("beth", "\u2136");
    builder.put("between", "\u226c");
    builder.put("bfr", "\ud835\udd1f");
    builder.put("bigcap", "\u22c2");
    builder.put("bigcirc", "\u25ef");
    builder.put("bigcup", "\u22c3");
    builder.put("bigodot", "\u2a00");
    builder.put("bigoplus", "\u2a01");
    builder.put("bigotimes", "\u2a02");
    builder.put("bigsqcup", "\u2a06");
    builder.put("bigstar", "\u2605");
    builder.put("bigtriangledown", "\u25bd");
    builder.put("bigtriangleup", "\u25b3");
    builder.put("biguplus", "\u2a04");
    builder.put("bigvee", "\u22c1");
    builder.put("bigwedge", "\u22c0");
    builder.put("bkarow", "\u290d");
    builder.put("blacklozenge", "\u29eb");
    builder.put("blacksquare", "\u25aa");
    builder.put("blacktriangle", "\u25b4");
    builder.put("blacktriangledown", "\u25be");
    builder.put("blacktriangleleft", "\u25c2");
    builder.put("blacktriangleright", "\u25b8");
    builder.put("blank", "\u2423");
    builder.put("blk12", "\u2592");
    builder.put("blk14", "\u2591");
    builder.put("blk34", "\u2593");
    builder.put("block", "\u2588");
    builder.put("bne", "\u003d\u20e5");
    builder.put("bnequiv", "\u2261\u20e5");
    builder.put("bnot", "\u2310");
    builder.put("bopf", "\ud835\udd53");
    builder.put("bot", "\u22a5");
    builder.put("bottom", "\u22a5");
    builder.put("bowtie", "\u22c8");
    builder.put("boxDL", "\u2557");
    builder.put("boxDR", "\u2554");
    builder.put("boxDl", "\u2556");
    builder.put("boxDr", "\u2553");
    builder.put("boxH", "\u2550");
    builder.put("boxHD", "\u2566");
    builder.put("boxHU", "\u2569");
    builder.put("boxHd", "\u2564");
    builder.put("boxHu", "\u2567");
    builder.put("boxUL", "\u255d");
    builder.put("boxUR", "\u255a");
    builder.put("boxUl", "\u255c");
    builder.put("boxUr", "\u2559");
    builder.put("boxV", "\u2551");
    builder.put("boxVH", "\u256c");
    builder.put("boxVL", "\u2563");
    builder.put("boxVR", "\u2560");
    builder.put("boxVh", "\u256b");
    builder.put("boxVl", "\u2562");
    builder.put("boxVr", "\u255f");
    builder.put("boxbox", "\u29c9");
    builder.put("boxdL", "\u2555");
    builder.put("boxdR", "\u2552");
    builder.put("boxdl", "\u2510");
    builder.put("boxdr", "\u250c");
    builder.put("boxh", "\u2500");
    builder.put("boxhD", "\u2565");
    builder.put("boxhU", "\u2568");
    builder.put("boxhd", "\u252c");
    builder.put("boxhu", "\u2534");
    builder.put("boxminus", "\u229f");
    builder.put("boxplus", "\u229e");
    builder.put("boxtimes", "\u22a0");
    builder.put("boxuL", "\u255b");
    builder.put("boxuR", "\u2558");
    builder.put("boxul", "\u2518");
    builder.put("boxur", "\u2514");
    builder.put("boxv", "\u2502");
    builder.put("boxvH", "\u256a");
    builder.put("boxvL", "\u2561");
    builder.put("boxvR", "\u255e");
    builder.put("boxvh", "\u253c");
    builder.put("boxvl", "\u2524");
    builder.put("boxvr", "\u251c");
    builder.put("bprime", "\u2035");
    builder.put("breve", "\u02d8");
    builder.put("brvbar", "\u00a6");
    builder.put("bscr", "\ud835\udcb7");
    builder.put("bsemi", "\u204f");
    builder.put("bsim", "\u223d");
    builder.put("bsime", "\u22cd");
    builder.put("bsol", "\\");
    builder.put("bsolb", "\u29c5");
    builder.put("bsolhsub", "\u27c8");
    builder.put("bull", "\u2022");
    builder.put("bullet", "\u2022");
    builder.put("bump", "\u224e");
    builder.put("bumpE", "\u2aae");
    builder.put("bumpe", "\u224f");
    builder.put("bumpeq", "\u224f");
    builder.put("cacute", "\u0107");
    builder.put("cap", "\u2229");
    builder.put("capand", "\u2a44");
    builder.put("capbrcup", "\u2a49");
    builder.put("capcap", "\u2a4b");
    builder.put("capcup", "\u2a47");
    builder.put("capdot", "\u2a40");
    builder.put("caps", "\u2229\ufe00");
    builder.put("caret", "\u2041");
    builder.put("caron", "\u02c7");
    builder.put("ccaps", "\u2a4d");
    builder.put("ccaron", "\u010d");
    builder.put("ccedil", "\u00e7");
    builder.put("ccirc", "\u0109");
    builder.put("ccups", "\u2a4c");
    builder.put("ccupssm", "\u2a50");
    builder.put("cdot", "\u010b");
    builder.put("cedil", "\u00b8");
    builder.put("cemptyv", "\u29b2");
    builder.put("cent", "\u00a2");
    builder.put("centerdot", "\u00b7");
    builder.put("cfr", "\ud835\udd20");
    builder.put("chcy", "\u0447");
    builder.put("check", "\u2713");
    builder.put("checkmark", "\u2713");
    builder.put("chi", "\u03c7");
    builder.put("cir", "\u25cb");
    builder.put("cirE", "\u29c3");
    builder.put("circ", "\u02c6");
    builder.put("circeq", "\u2257");
    builder.put("circlearrowleft", "\u21ba");
    builder.put("circlearrowright", "\u21bb");
    builder.put("circledR", "\u00ae");
    builder.put("circledS", "\u24c8");
    builder.put("circledast", "\u229b");
    builder.put("circledcirc", "\u229a");
    builder.put("circleddash", "\u229d");
    builder.put("cire", "\u2257");
    builder.put("cirfnint", "\u2a10");
    builder.put("cirmid", "\u2aef");
    builder.put("cirscir", "\u29c2");
    builder.put("clubs", "\u2663");
    builder.put("clubsuit", "\u2663");
    builder.put("colon", "\u003a");
    builder.put("colone", "\u2254");
    builder.put("coloneq", "\u2254");
    builder.put("comma", "\u002c");
    builder.put("commat", "\u0040");
    builder.put("comp", "\u2201");
    builder.put("compfn", "\u2218");
    builder.put("complement", "\u2201");
    builder.put("complexes", "\u2102");
    builder.put("cong", "\u2245");
    builder.put("congdot", "\u2a6d");
    builder.put("conint", "\u222e");
    builder.put("copf", "\ud835\udd54");
    builder.put("coprod", "\u2210");
    builder.put("copy", "\u00a9");
    builder.put("copysr", "\u2117");
    builder.put("crarr", "\u21b5");
    builder.put("cross", "\u2717");
    builder.put("cscr", "\ud835\udcb8");
    builder.put("csub", "\u2acf");
    builder.put("csube", "\u2ad1");
    builder.put("csup", "\u2ad0");
    builder.put("csupe", "\u2ad2");
    builder.put("ctdot", "\u22ef");
    builder.put("cudarrl", "\u2938");
    builder.put("cudarrr", "\u2935");
    builder.put("cuepr", "\u22de");
    builder.put("cuesc", "\u22df");
    builder.put("cularr", "\u21b6");
    builder.put("cularrp", "\u293d");
    builder.put("cup", "\u222a");
    builder.put("cupbrcap", "\u2a48");
    builder.put("cupcap", "\u2a46");
    builder.put("cupcup", "\u2a4a");
    builder.put("cupdot", "\u228d");
    builder.put("cupor", "\u2a45");
    builder.put("cups", "\u222a\ufe00");
    builder.put("curarr", "\u21b7");
    builder.put("curarrm", "\u293c");
    builder.put("curlyeqprec", "\u22de");
    builder.put("curlyeqsucc", "\u22df");
    builder.put("curlyvee", "\u22ce");
    builder.put("curlywedge", "\u22cf");
    builder.put("curren", "\u00a4");
    builder.put("curvearrowleft", "\u21b6");
    builder.put("curvearrowright", "\u21b7");
    builder.put("cuvee", "\u22ce");
    builder.put("cuwed", "\u22cf");
    builder.put("cwconint", "\u2232");
    builder.put("cwint", "\u2231");
    builder.put("cylcty", "\u232d");
    builder.put("dArr", "\u21d3");
    builder.put("dHar", "\u2965");
    builder.put("dagger", "\u2020");
    builder.put("daleth", "\u2138");
    builder.put("darr", "\u2193");
    builder.put("dash", "\u2010");
    builder.put("dashv", "\u22a3");
    builder.put("dbkarow", "\u290f");
    builder.put("dblac", "\u02dd");
    builder.put("dcaron", "\u010f");
    builder.put("dcy", "\u0434");
    builder.put("dd", "\u2146");
    builder.put("ddagger", "\u2021");
    builder.put("ddarr", "\u21ca");
    builder.put("ddotseq", "\u2a77");
    builder.put("deg", "\u00b0");
    builder.put("delta", "\u03b4");
    builder.put("demptyv", "\u29b1");
    builder.put("dfisht", "\u297f");
    builder.put("dfr", "\ud835\udd21");
    builder.put("dharl", "\u21c3");
    builder.put("dharr", "\u21c2");
    builder.put("diam", "\u22c4");
    builder.put("diamond", "\u22c4");
    builder.put("diamondsuit", "\u2666");
    builder.put("diams", "\u2666");
    builder.put("die", "\u00a8");
    builder.put("digamma", "\u03dd");
    builder.put("disin", "\u22f2");
    builder.put("div", "\u00f7");
    builder.put("divide", "\u00f7");
    builder.put("divideontimes", "\u22c7");
    builder.put("divonx", "\u22c7");
    builder.put("djcy", "\u0452");
    builder.put("dlcorn", "\u231e");
    builder.put("dlcrop", "\u230d");
    builder.put("dollar", "\u0024");
    builder.put("dopf", "\ud835\udd55");
    builder.put("dot", "\u02d9");
    builder.put("doteq", "\u2250");
    builder.put("doteqdot", "\u2251");
    builder.put("dotminus", "\u2238");
    builder.put("dotplus", "\u2214");
    builder.put("dotsquare", "\u22a1");
    builder.put("doublebarwedge", "\u2306");
    builder.put("downarrow", "\u2193");
    builder.put("downdownarrows", "\u21ca");
    builder.put("downharpoonleft", "\u21c3");
    builder.put("downharpoonright", "\u21c2");
    builder.put("drbkarow", "\u2910");
    builder.put("drcorn", "\u231f");
    builder.put("drcrop", "\u230c");
    builder.put("dscr", "\ud835\udcb9");
    builder.put("dscy", "\u0455");
    builder.put("dsol", "\u29f6");
    builder.put("dstrok", "\u0111");
    builder.put("dtdot", "\u22f1");
    builder.put("dtri", "\u25bf");
    builder.put("dtrif", "\u25be");
    builder.put("duarr", "\u21f5");
    builder.put("duhar", "\u296f");
    builder.put("dwangle", "\u29a6");
    builder.put("dzcy", "\u045f");
    builder.put("dzigrarr", "\u27ff");
    builder.put("eDDot", "\u2a77");
    builder.put("eDot", "\u2251");
    builder.put("eacute", "\u00e9");
    builder.put("easter", "\u2a6e");
    builder.put("ecaron", "\u011b");
    builder.put("ecir", "\u2256");
    builder.put("ecirc", "\u00ea");
    builder.put("ecolon", "\u2255");
    builder.put("ecy", "\u044d");
    builder.put("edot", "\u0117");
    builder.put("ee", "\u2147");
    builder.put("efDot", "\u2252");
    builder.put("efr", "\ud835\udd22");
    builder.put("eg", "\u2a9a");
    builder.put("egrave", "\u00e8");
    builder.put("egs", "\u2a96");
    builder.put("egsdot", "\u2a98");
    builder.put("el", "\u2a99");
    builder.put("elinters", "\u23e7");
    builder.put("ell", "\u2113");
    builder.put("els", "\u2a95");
    builder.put("elsdot", "\u2a97");
    builder.put("emacr", "\u0113");
    builder.put("empty", "\u2205");
    builder.put("emptyset", "\u2205");
    builder.put("emptyv", "\u2205");
    builder.put("emsp13", "\u2004");
    builder.put("emsp14", "\u2005");
    builder.put("emsp", "\u2003");
    builder.put("eng", "\u014b");
    builder.put("ensp", "\u2002");
    builder.put("eogon", "\u0119");
    builder.put("eopf", "\ud835\udd56");
    builder.put("epar", "\u22d5");
    builder.put("eparsl", "\u29e3");
    builder.put("eplus", "\u2a71");
    builder.put("epsi", "\u03b5");
    builder.put("epsilon", "\u03b5");
    builder.put("epsiv", "\u03f5");
    builder.put("eqcirc", "\u2256");
    builder.put("eqcolon", "\u2255");
    builder.put("eqsim", "\u2242");
    builder.put("eqslantgtr", "\u2a96");
    builder.put("eqslantless", "\u2a95");
    builder.put("equals", "\u003d");
    builder.put("equest", "\u225f");
    builder.put("equiv", "\u2261");
    builder.put("equivDD", "\u2a78");
    builder.put("eqvparsl", "\u29e5");
    builder.put("erDot", "\u2253");
    builder.put("erarr", "\u2971");
    builder.put("escr", "\u212f");
    builder.put("esdot", "\u2250");
    builder.put("esim", "\u2242");
    builder.put("eta", "\u03b7");
    builder.put("eth", "\u00f0");
    builder.put("euml", "\u00eb");
    builder.put("euro", "\u20ac");
    builder.put("excl", "\u0021");
    builder.put("exist", "\u2203");
    builder.put("expectation", "\u2130");
    builder.put("exponentiale", "\u2147");
    builder.put("fallingdotseq", "\u2252");
    builder.put("fcy", "\u0444");
    builder.put("female", "\u2640");
    builder.put("ffilig", "\ufb03");
    builder.put("fflig", "\ufb00");
    builder.put("ffllig", "\ufb04");
    builder.put("ffr", "\ud835\udd23");
    builder.put("filig", "\ufb01");
    builder.put("fjlig", "\u0066\u006a");
    builder.put("flat", "\u266d");
    builder.put("fllig", "\ufb02");
    builder.put("fltns", "\u25b1");
    builder.put("fnof", "\u0192");
    builder.put("fopf", "\ud835\udd57");
    builder.put("forall", "\u2200");
    builder.put("fork", "\u22d4");
    builder.put("forkv", "\u2ad9");
    builder.put("fpartint", "\u2a0d");
    builder.put("frac12", "\u00bd");
    builder.put("frac13", "\u2153");
    builder.put("frac14", "\u00bc");
    builder.put("frac15", "\u2155");
    builder.put("frac16", "\u2159");
    builder.put("frac18", "\u215b");
    builder.put("frac23", "\u2154");
    builder.put("frac25", "\u2156");
    builder.put("frac34", "\u00be");
    builder.put("frac35", "\u2157");
    builder.put("frac38", "\u215c");
    builder.put("frac45", "\u2158");
    builder.put("frac56", "\u215a");
    builder.put("frac58", "\u215d");
    builder.put("frac78", "\u215e");
    builder.put("frasl", "\u2044");
    builder.put("frown", "\u2322");
    builder.put("fscr", "\ud835\udcbb");
    builder.put("gE", "\u2267");
    builder.put("gEl", "\u2a8c");
    builder.put("gacute", "\u01f5");
    builder.put("gamma", "\u03b3");
    builder.put("gammad", "\u03dd");
    builder.put("gap", "\u2a86");
    builder.put("gbreve", "\u011f");
    builder.put("gcirc", "\u011d");
    builder.put("gcy", "\u0433");
    builder.put("gdot", "\u0121");
    builder.put("ge", "\u2265");
    builder.put("gel", "\u22db");
    builder.put("geq", "\u2265");
    builder.put("geqq", "\u2267");
    builder.put("geqslant", "\u2a7e");
    builder.put("ges", "\u2a7e");
    builder.put("gescc", "\u2aa9");
    builder.put("gesdot", "\u2a80");
    builder.put("gesdoto", "\u2a82");
    builder.put("gesdotol", "\u2a84");
    builder.put("gesl", "\u22db\ufe00");
    builder.put("gesles", "\u2a94");
    builder.put("gfr", "\ud835\udd24");
    builder.put("gg", "\u226b");
    builder.put("ggg", "\u22d9");
    builder.put("gimel", "\u2137");
    builder.put("gjcy", "\u0453");
    builder.put("gl", "\u2277");
    builder.put("glE", "\u2a92");
    builder.put("gla", "\u2aa5");
    builder.put("glj", "\u2aa4");
    builder.put("gnE", "\u2269");
    builder.put("gnap", "\u2a8a");
    builder.put("gnapprox", "\u2a8a");
    builder.put("gne", "\u2a88");
    builder.put("gneq", "\u2a88");
    builder.put("gneqq", "\u2269");
    builder.put("gnsim", "\u22e7");
    builder.put("gopf", "\ud835\udd58");
    builder.put("grave", "\u0060");
    builder.put("gscr", "\u210a");
    builder.put("gsim", "\u2273");
    builder.put("gsime", "\u2a8e");
    builder.put("gsiml", "\u2a90");
    builder.put("gt", "\u003e");
    builder.put("gtcc", "\u2aa7");
    builder.put("gtcir", "\u2a7a");
    builder.put("gtdot", "\u22d7");
    builder.put("gtlPar", "\u2995");
    builder.put("gtquest", "\u2a7c");
    builder.put("gtrapprox", "\u2a86");
    builder.put("gtrarr", "\u2978");
    builder.put("gtrdot", "\u22d7");
    builder.put("gtreqless", "\u22db");
    builder.put("gtreqqless", "\u2a8c");
    builder.put("gtrless", "\u2277");
    builder.put("gtrsim", "\u2273");
    builder.put("gvertneqq", "\u2269\ufe00");
    builder.put("gvnE", "\u2269\ufe00");
    builder.put("hArr", "\u21d4");
    builder.put("hairsp", "\u200a");
    builder.put("half", "\u00bd");
    builder.put("hamilt", "\u210b");
    builder.put("hardcy", "\u044a");
    builder.put("harr", "\u2194");
    builder.put("harrcir", "\u2948");
    builder.put("harrw", "\u21ad");
    builder.put("hbar", "\u210f");
    builder.put("hcirc", "\u0125");
    builder.put("hearts", "\u2665");
    builder.put("heartsuit", "\u2665");
    builder.put("hellip", "\u2026");
    builder.put("hercon", "\u22b9");
    builder.put("hfr", "\ud835\udd25");
    builder.put("hksearow", "\u2925");
    builder.put("hkswarow", "\u2926");
    builder.put("hoarr", "\u21ff");
    builder.put("homtht", "\u223b");
    builder.put("hookleftarrow", "\u21a9");
    builder.put("hookrightarrow", "\u21aa");
    builder.put("hopf", "\ud835\udd59");
    builder.put("horbar", "\u2015");
    builder.put("hscr", "\ud835\udcbd");
    builder.put("hslash", "\u210f");
    builder.put("hstrok", "\u0127");
    builder.put("hybull", "\u2043");
    builder.put("hyphen", "\u2010");
    builder.put("iacute", "\u00ed");
    builder.put("ic", "\u2063");
    builder.put("icirc", "\u00ee");
    builder.put("icy", "\u0438");
    builder.put("iecy", "\u0435");
    builder.put("iexcl", "\u00a1");
    builder.put("iff", "\u21d4");
    builder.put("ifr", "\ud835\udd26");
    builder.put("igrave", "\u00ec");
    builder.put("ii", "\u2148");
    builder.put("iiiint", "\u2a0c");
    builder.put("iiint", "\u222d");
    builder.put("iinfin", "\u29dc");
    builder.put("iiota", "\u2129");
    builder.put("ijlig", "\u0133");
    builder.put("imacr", "\u012b");
    builder.put("image", "\u2111");
    builder.put("imagline", "\u2110");
    builder.put("imagpart", "\u2111");
    builder.put("imath", "\u0131");
    builder.put("imof", "\u22b7");
    builder.put("imped", "\u01b5");
    builder.put("in", "\u2208");
    builder.put("incare", "\u2105");
    builder.put("infin", "\u221e");
    builder.put("infintie", "\u29dd");
    builder.put("inodot", "\u0131");
    builder.put("int", "\u222b");
    builder.put("intcal", "\u22ba");
    builder.put("integers", "\u2124");
    builder.put("intercal", "\u22ba");
    builder.put("intlarhk", "\u2a17");
    builder.put("intprod", "\u2a3c");
    builder.put("iocy", "\u0451");
    builder.put("iogon", "\u012f");
    builder.put("iopf", "\ud835\udd5a");
    builder.put("iota", "\u03b9");
    builder.put("iprod", "\u2a3c");
    builder.put("iquest", "\u00bf");
    builder.put("iscr", "\ud835\udcbe");
    builder.put("isin", "\u2208");
    builder.put("isinE", "\u22f9");
    builder.put("isindot", "\u22f5");
    builder.put("isins", "\u22f4");
    builder.put("isinsv", "\u22f3");
    builder.put("isinv", "\u2208");
    builder.put("it", "\u2062");
    builder.put("itilde", "\u0129");
    builder.put("iukcy", "\u0456");
    builder.put("iuml", "\u00ef");
    builder.put("jcirc", "\u0135");
    builder.put("jcy", "\u0439");
    builder.put("jfr", "\ud835\udd27");
    builder.put("jmath", "\u0237");
    builder.put("jopf", "\ud835\udd5b");
    builder.put("jscr", "\ud835\udcbf");
    builder.put("jsercy", "\u0458");
    builder.put("jukcy", "\u0454");
    builder.put("kappa", "\u03ba");
    builder.put("kappav", "\u03f0");
    builder.put("kcedil", "\u0137");
    builder.put("kcy", "\u043a");
    builder.put("kfr", "\ud835\udd28");
    builder.put("kgreen", "\u0138");
    builder.put("khcy", "\u0445");
    builder.put("kjcy", "\u045c");
    builder.put("kopf", "\ud835\udd5c");
    builder.put("kscr", "\ud835\udcc0");
    builder.put("lAarr", "\u21da");
    builder.put("lArr", "\u21d0");
    builder.put("lAtail", "\u291b");
    builder.put("lBarr", "\u290e");
    builder.put("lE", "\u2266");
    builder.put("lEg", "\u2a8b");
    builder.put("lHar", "\u2962");
    builder.put("lacute", "\u013a");
    builder.put("laemptyv", "\u29b4");
    builder.put("lagran", "\u2112");
    builder.put("lambda", "\u03bb");
    builder.put("lang", "\u27e8");
    builder.put("langd", "\u2991");
    builder.put("langle", "\u27e8");
    builder.put("lap", "\u2a85");
    builder.put("laquo", "\u00ab");
    builder.put("larr", "\u2190");
    builder.put("larrb", "\u21e4");
    builder.put("larrbfs", "\u291f");
    builder.put("larrfs", "\u291d");
    builder.put("larrhk", "\u21a9");
    builder.put("larrlp", "\u21ab");
    builder.put("larrpl", "\u2939");
    builder.put("larrsim", "\u2973");
    builder.put("larrtl", "\u21a2");
    builder.put("lat", "\u2aab");
    builder.put("latail", "\u2919");
    builder.put("late", "\u2aad");
    builder.put("lates", "\u2aad\ufe00");
    builder.put("lbarr", "\u290c");
    builder.put("lbbrk", "\u2772");
    builder.put("lbrace", "\u007b");
    builder.put("lbrack", "\u005b");
    builder.put("lbrke", "\u298b");
    builder.put("lbrksld", "\u298f");
    builder.put("lbrkslu", "\u298d");
    builder.put("lcaron", "\u013e");
    builder.put("lcedil", "\u013c");
    builder.put("lceil", "\u2308");
    builder.put("lcub", "\u007b");
    builder.put("lcy", "\u043b");
    builder.put("ldca", "\u2936");
    builder.put("ldquo", "\u201c");
    builder.put("ldquor", "\u201e");
    builder.put("ldrdhar", "\u2967");
    builder.put("ldrushar", "\u294b");
    builder.put("ldsh", "\u21b2");
    builder.put("le", "\u2264");
    builder.put("leftarrow", "\u2190");
    builder.put("leftarrowtail", "\u21a2");
    builder.put("leftharpoondown", "\u21bd");
    builder.put("leftharpoonup", "\u21bc");
    builder.put("leftleftarrows", "\u21c7");
    builder.put("leftrightarrow", "\u2194");
    builder.put("leftrightarrows", "\u21c6");
    builder.put("leftrightharpoons", "\u21cb");
    builder.put("leftrightsquigarrow", "\u21ad");
    builder.put("leftthreetimes", "\u22cb");
    builder.put("leg", "\u22da");
    builder.put("leq", "\u2264");
    builder.put("leqq", "\u2266");
    builder.put("leqslant", "\u2a7d");
    builder.put("les", "\u2a7d");
    builder.put("lescc", "\u2aa8");
    builder.put("lesdot", "\u2a7f");
    builder.put("lesdoto", "\u2a81");
    builder.put("lesdotor", "\u2a83");
    builder.put("lesg", "\u22da\ufe00");
    builder.put("lesges", "\u2a93");
    builder.put("lessapprox", "\u2a85");
    builder.put("lessdot", "\u22d6");
    builder.put("lesseqgtr", "\u22da");
    builder.put("lesseqqgtr", "\u2a8b");
    builder.put("lessgtr", "\u2276");
    builder.put("lesssim", "\u2272");
    builder.put("lfisht", "\u297c");
    builder.put("lfloor", "\u230a");
    builder.put("lfr", "\ud835\udd29");
    builder.put("lg", "\u2276");
    builder.put("lgE", "\u2a91");
    builder.put("lhard", "\u21bd");
    builder.put("lharu", "\u21bc");
    builder.put("lharul", "\u296a");
    builder.put("lhblk", "\u2584");
    builder.put("ljcy", "\u0459");
    builder.put("ll", "\u226a");
    builder.put("llarr", "\u21c7");
    builder.put("llcorner", "\u231e");
    builder.put("llhard", "\u296b");
    builder.put("lltri", "\u25fa");
    builder.put("lmidot", "\u0140");
    builder.put("lmoust", "\u23b0");
    builder.put("lmoustache", "\u23b0");
    builder.put("lnE", "\u2268");
    builder.put("lnap", "\u2a89");
    builder.put("lnapprox", "\u2a89");
    builder.put("lne", "\u2a87");
    builder.put("lneq", "\u2a87");
    builder.put("lneqq", "\u2268");
    builder.put("lnsim", "\u22e6");
    builder.put("loang", "\u27ec");
    builder.put("loarr", "\u21fd");
    builder.put("lobrk", "\u27e6");
    builder.put("longleftarrow", "\u27f5");
    builder.put("longleftrightarrow", "\u27f7");
    builder.put("longmapsto", "\u27fc");
    builder.put("longrightarrow", "\u27f6");
    builder.put("looparrowleft", "\u21ab");
    builder.put("looparrowright", "\u21ac");
    builder.put("lopar", "\u2985");
    builder.put("lopf", "\ud835\udd5d");
    builder.put("loplus", "\u2a2d");
    builder.put("lotimes", "\u2a34");
    builder.put("lowast", "\u2217");
    builder.put("lowbar", "\u005f");
    builder.put("loz", "\u25ca");
    builder.put("lozenge", "\u25ca");
    builder.put("lozf", "\u29eb");
    builder.put("lpar", "\u0028");
    builder.put("lparlt", "\u2993");
    builder.put("lrarr", "\u21c6");
    builder.put("lrcorner", "\u231f");
    builder.put("lrhar", "\u21cb");
    builder.put("lrhard", "\u296d");
    builder.put("lrm", "\u200e");
    builder.put("lrtri", "\u22bf");
    builder.put("lsaquo", "\u2039");
    builder.put("lscr", "\ud835\udcc1");
    builder.put("lsh", "\u21b0");
    builder.put("lsim", "\u2272");
    builder.put("lsime", "\u2a8d");
    builder.put("lsimg", "\u2a8f");
    builder.put("lsqb", "\u005b");
    builder.put("lsquo", "\u2018");
    builder.put("lsquor", "\u201a");
    builder.put("lstrok", "\u0142");
    builder.put("lt", "\u003c");
    builder.put("ltcc", "\u2aa6");
    builder.put("ltcir", "\u2a79");
    builder.put("ltdot", "\u22d6");
    builder.put("lthree", "\u22cb");
    builder.put("ltimes", "\u22c9");
    builder.put("ltlarr", "\u2976");
    builder.put("ltquest", "\u2a7b");
    builder.put("ltrPar", "\u2996");
    builder.put("ltri", "\u25c3");
    builder.put("ltrie", "\u22b4");
    builder.put("ltrif", "\u25c2");
    builder.put("lurdshar", "\u294a");
    builder.put("luruhar", "\u2966");
    builder.put("lvertneqq", "\u2268\ufe00");
    builder.put("lvnE", "\u2268\ufe00");
    builder.put("mDDot", "\u223a");
    builder.put("macr", "\u00af");
    builder.put("male", "\u2642");
    builder.put("malt", "\u2720");
    builder.put("maltese", "\u2720");
    builder.put("map", "\u21a6");
    builder.put("mapsto", "\u21a6");
    builder.put("mapstodown", "\u21a7");
    builder.put("mapstoleft", "\u21a4");
    builder.put("mapstoup", "\u21a5");
    builder.put("marker", "\u25ae");
    builder.put("mcomma", "\u2a29");
    builder.put("mcy", "\u043c");
    builder.put("mdash", "\u2014");
    builder.put("measuredangle", "\u2221");
    builder.put("mfr", "\ud835\udd2a");
    builder.put("mho", "\u2127");
    builder.put("micro", "\u00b5");
    builder.put("mid", "\u2223");
    builder.put("midast", "\u002a");
    builder.put("midcir", "\u2af0");
    builder.put("middot", "\u00b7");
    builder.put("minus", "\u2212");
    builder.put("minusb", "\u229f");
    builder.put("minusd", "\u2238");
    builder.put("minusdu", "\u2a2a");
    builder.put("mlcp", "\u2adb");
    builder.put("mldr", "\u2026");
    builder.put("mnplus", "\u2213");
    builder.put("models", "\u22a7");
    builder.put("mopf", "\ud835\udd5e");
    builder.put("mp", "\u2213");
    builder.put("mscr", "\ud835\udcc2");
    builder.put("mstpos", "\u223e");
    builder.put("mu", "\u03bc");
    builder.put("multimap", "\u22b8");
    builder.put("mumap", "\u22b8");
    builder.put("nGg", "\u22d9\u0338");
    builder.put("nGt", "\u226b\u20d2");
    builder.put("nGtv", "\u226b\u0338");
    builder.put("nLeftarrow", "\u21cd");
    builder.put("nLeftrightarrow", "\u21ce");
    builder.put("nLl", "\u22d8\u0338");
    builder.put("nLt", "\u226a\u20d2");
    builder.put("nLtv", "\u226a\u0338");
    builder.put("nRightarrow", "\u21cf");
    builder.put("nVDash", "\u22af");
    builder.put("nVdash", "\u22ae");
    builder.put("nabla", "\u2207");
    builder.put("nacute", "\u0144");
    builder.put("nang", "\u2220\u20d2");
    builder.put("nap", "\u2249");
    builder.put("napE", "\u2a70\u0338");
    builder.put("napid", "\u224b\u0338");
    builder.put("napos", "\u0149");
    builder.put("napprox", "\u2249");
    builder.put("natur", "\u266e");
    builder.put("natural", "\u266e");
    builder.put("naturals", "\u2115");
    builder.put("nbsp", "\u00a0");
    builder.put("nbump", "\u224e\u0338");
    builder.put("nbumpe", "\u224f\u0338");
    builder.put("ncap", "\u2a43");
    builder.put("ncaron", "\u0148");
    builder.put("ncedil", "\u0146");
    builder.put("ncong", "\u2247");
    builder.put("ncongdot", "\u2a6d\u0338");
    builder.put("ncup", "\u2a42");
    builder.put("ncy", "\u043d");
    builder.put("ndash", "\u2013");
    builder.put("ne", "\u2260");
    builder.put("neArr", "\u21d7");
    builder.put("nearhk", "\u2924");
    builder.put("nearr", "\u2197");
    builder.put("nearrow", "\u2197");
    builder.put("nedot", "\u2250\u0338");
    builder.put("nequiv", "\u2262");
    builder.put("nesear", "\u2928");
    builder.put("nesim", "\u2242\u0338");
    builder.put("nexist", "\u2204");
    builder.put("nexists", "\u2204");
    builder.put("nfr", "\ud835\udd2b");
    builder.put("ngE", "\u2267\u0338");
    builder.put("nge", "\u2271");
    builder.put("ngeq", "\u2271");
    builder.put("ngeqq", "\u2267\u0338");
    builder.put("ngeqslant", "\u2a7e\u0338");
    builder.put("nges", "\u2a7e\u0338");
    builder.put("ngsim", "\u2275");
    builder.put("ngt", "\u226f");
    builder.put("ngtr", "\u226f");
    builder.put("nhArr", "\u21ce");
    builder.put("nharr", "\u21ae");
    builder.put("nhpar", "\u2af2");
    builder.put("ni", "\u220b");
    builder.put("nis", "\u22fc");
    builder.put("nisd", "\u22fa");
    builder.put("niv", "\u220b");
    builder.put("njcy", "\u045a");
    builder.put("nlArr", "\u21cd");
    builder.put("nlE", "\u2266\u0338");
    builder.put("nlarr", "\u219a");
    builder.put("nldr", "\u2025");
    builder.put("nle", "\u2270");
    builder.put("nleftarrow", "\u219a");
    builder.put("nleftrightarrow", "\u21ae");
    builder.put("nleq", "\u2270");
    builder.put("nleqq", "\u2266\u0338");
    builder.put("nleqslant", "\u2a7d\u0338");
    builder.put("nles", "\u2a7d\u0338");
    builder.put("nless", "\u226e");
    builder.put("nlsim", "\u2274");
    builder.put("nlt", "\u226e");
    builder.put("nltri", "\u22ea");
    builder.put("nltrie", "\u22ec");
    builder.put("nmid", "\u2224");
    builder.put("nopf", "\ud835\udd5f");
    builder.put("not", "\u00ac");
    builder.put("notin", "\u2209");
    builder.put("notinE", "\u22f9\u0338");
    builder.put("notindot", "\u22f5\u0338");
    builder.put("notinva", "\u2209");
    builder.put("notinvb", "\u22f7");
    builder.put("notinvc", "\u22f6");
    builder.put("notni", "\u220c");
    builder.put("notniva", "\u220c");
    builder.put("notnivb", "\u22fe");
    builder.put("notnivc", "\u22fd");
    builder.put("npar", "\u2226");
    builder.put("nparallel", "\u2226");
    builder.put("nparsl", "\u2afd\u20e5");
    builder.put("npart", "\u2202\u0338");
    builder.put("npolint", "\u2a14");
    builder.put("npr", "\u2280");
    builder.put("nprcue", "\u22e0");
    builder.put("npre", "\u2aaf\u0338");
    builder.put("nprec", "\u2280");
    builder.put("npreceq", "\u2aaf\u0338");
    builder.put("nrArr", "\u21cf");
    builder.put("nrarr", "\u219b");
    builder.put("nrarrc", "\u2933\u0338");
    builder.put("nrarrw", "\u219d\u0338");
    builder.put("nrightarrow", "\u219b");
    builder.put("nrtri", "\u22eb");
    builder.put("nrtrie", "\u22ed");
    builder.put("nsc", "\u2281");
    builder.put("nsccue", "\u22e1");
    builder.put("nsce", "\u2ab0\u0338");
    builder.put("nscr", "\ud835\udcc3");
    builder.put("nshortmid", "\u2224");
    builder.put("nshortparallel", "\u2226");
    builder.put("nsim", "\u2241");
    builder.put("nsime", "\u2244");
    builder.put("nsimeq", "\u2244");
    builder.put("nsmid", "\u2224");
    builder.put("nspar", "\u2226");
    builder.put("nsqsube", "\u22e2");
    builder.put("nsqsupe", "\u22e3");
    builder.put("nsub", "\u2284");
    builder.put("nsubE", "\u2ac5\u0338");
    builder.put("nsube", "\u2288");
    builder.put("nsubset", "\u2282\u20d2");
    builder.put("nsubseteq", "\u2288");
    builder.put("nsubseteqq", "\u2ac5\u0338");
    builder.put("nsucc", "\u2281");
    builder.put("nsucceq", "\u2ab0\u0338");
    builder.put("nsup", "\u2285");
    builder.put("nsupE", "\u2ac6\u0338");
    builder.put("nsupe", "\u2289");
    builder.put("nsupset", "\u2283\u20d2");
    builder.put("nsupseteq", "\u2289");
    builder.put("nsupseteqq", "\u2ac6\u0338");
    builder.put("ntgl", "\u2279");
    builder.put("ntilde", "\u00f1");
    builder.put("ntlg", "\u2278");
    builder.put("ntriangleleft", "\u22ea");
    builder.put("ntrianglelefteq", "\u22ec");
    builder.put("ntriangleright", "\u22eb");
    builder.put("ntrianglerighteq", "\u22ed");
    builder.put("nu", "\u03bd");
    builder.put("num", "\u0023");
    builder.put("numero", "\u2116");
    builder.put("numsp", "\u2007");
    builder.put("nvDash", "\u22ad");
    builder.put("nvHarr", "\u2904");
    builder.put("nvap", "\u224d\u20d2");
    builder.put("nvdash", "\u22ac");
    builder.put("nvge", "\u2265\u20d2");
    builder.put("nvgt", "\u003e\u20d2");
    builder.put("nvinfin", "\u29de");
    builder.put("nvlArr", "\u2902");
    builder.put("nvle", "\u2264\u20d2");
    builder.put("nvlt", "\u003c\u20d2");
    builder.put("nvltrie", "\u22b4\u20d2");
    builder.put("nvrArr", "\u2903");
    builder.put("nvrtrie", "\u22b5\u20d2");
    builder.put("nvsim", "\u223c\u20d2");
    builder.put("nwArr", "\u21d6");
    builder.put("nwarhk", "\u2923");
    builder.put("nwarr", "\u2196");
    builder.put("nwarrow", "\u2196");
    builder.put("nwnear", "\u2927");
    builder.put("oS", "\u24c8");
    builder.put("oacute", "\u00f3");
    builder.put("oast", "\u229b");
    builder.put("ocir", "\u229a");
    builder.put("ocirc", "\u00f4");
    builder.put("ocy", "\u043e");
    builder.put("odash", "\u229d");
    builder.put("odblac", "\u0151");
    builder.put("odiv", "\u2a38");
    builder.put("odot", "\u2299");
    builder.put("odsold", "\u29bc");
    builder.put("oelig", "\u0153");
    builder.put("ofcir", "\u29bf");
    builder.put("ofr", "\ud835\udd2c");
    builder.put("ogon", "\u02db");
    builder.put("ograve", "\u00f2");
    builder.put("ogt", "\u29c1");
    builder.put("ohbar", "\u29b5");
    builder.put("ohm", "\u03a9");
    builder.put("oint", "\u222e");
    builder.put("olarr", "\u21ba");
    builder.put("olcir", "\u29be");
    builder.put("olcross", "\u29bb");
    builder.put("oline", "\u203e");
    builder.put("olt", "\u29c0");
    builder.put("omacr", "\u014d");
    builder.put("omega", "\u03c9");
    builder.put("omicron", "\u03bf");
    builder.put("omid", "\u29b6");
    builder.put("ominus", "\u2296");
    builder.put("oopf", "\ud835\udd60");
    builder.put("opar", "\u29b7");
    builder.put("operp", "\u29b9");
    builder.put("oplus", "\u2295");
    builder.put("or", "\u2228");
    builder.put("orarr", "\u21bb");
    builder.put("ord", "\u2a5d");
    builder.put("order", "\u2134");
    builder.put("orderof", "\u2134");
    builder.put("ordf", "\u00aa");
    builder.put("ordm", "\u00ba");
    builder.put("origof", "\u22b6");
    builder.put("oror", "\u2a56");
    builder.put("orslope", "\u2a57");
    builder.put("orv", "\u2a5b");
    builder.put("oscr", "\u2134");
    builder.put("oslash", "\u00f8");
    builder.put("osol", "\u2298");
    builder.put("otilde", "\u00f5");
    builder.put("otimes", "\u2297");
    builder.put("otimesas", "\u2a36");
    builder.put("ouml", "\u00f6");
    builder.put("ovbar", "\u233d");
    builder.put("par", "\u2225");
    builder.put("para", "\u00b6");
    builder.put("parallel", "\u2225");
    builder.put("parsim", "\u2af3");
    builder.put("parsl", "\u2afd");
    builder.put("part", "\u2202");
    builder.put("pcy", "\u043f");
    builder.put("percnt", "\u0025");
    builder.put("period", "\u002e");
    builder.put("permil", "\u2030");
    builder.put("perp", "\u22a5");
    builder.put("pertenk", "\u2031");
    builder.put("pfr", "\ud835\udd2d");
    builder.put("phi", "\u03c6");
    builder.put("phiv", "\u03d5");
    builder.put("phmmat", "\u2133");
    builder.put("phone", "\u260e");
    builder.put("pi", "\u03c0");
    builder.put("pitchfork", "\u22d4");
    builder.put("piv", "\u03d6");
    builder.put("planck", "\u210f");
    builder.put("planckh", "\u210e");
    builder.put("plankv", "\u210f");
    builder.put("plus", "\u002b");
    builder.put("plusacir", "\u2a23");
    builder.put("plusb", "\u229e");
    builder.put("pluscir", "\u2a22");
    builder.put("plusdo", "\u2214");
    builder.put("plusdu", "\u2a25");
    builder.put("pluse", "\u2a72");
    builder.put("plusmn", "\u00b1");
    builder.put("plussim", "\u2a26");
    builder.put("plustwo", "\u2a27");
    builder.put("pm", "\u00b1");
    builder.put("pointint", "\u2a15");
    builder.put("popf", "\ud835\udd61");
    builder.put("pound", "\u00a3");
    builder.put("pr", "\u227a");
    builder.put("prE", "\u2ab3");
    builder.put("prap", "\u2ab7");
    builder.put("prcue", "\u227c");
    builder.put("pre", "\u2aaf");
    builder.put("prec", "\u227a");
    builder.put("precapprox", "\u2ab7");
    builder.put("preccurlyeq", "\u227c");
    builder.put("preceq", "\u2aaf");
    builder.put("precnapprox", "\u2ab9");
    builder.put("precneqq", "\u2ab5");
    builder.put("precnsim", "\u22e8");
    builder.put("precsim", "\u227e");
    builder.put("prime", "\u2032");
    builder.put("primes", "\u2119");
    builder.put("prnE", "\u2ab5");
    builder.put("prnap", "\u2ab9");
    builder.put("prnsim", "\u22e8");
    builder.put("prod", "\u220f");
    builder.put("profalar", "\u232e");
    builder.put("profline", "\u2312");
    builder.put("profsurf", "\u2313");
    builder.put("prop", "\u221d");
    builder.put("propto", "\u221d");
    builder.put("prsim", "\u227e");
    builder.put("prurel", "\u22b0");
    builder.put("pscr", "\ud835\udcc5");
    builder.put("psi", "\u03c8");
    builder.put("puncsp", "\u2008");
    builder.put("qfr", "\ud835\udd2e");
    builder.put("qint", "\u2a0c");
    builder.put("qopf", "\ud835\udd62");
    builder.put("qprime", "\u2057");
    builder.put("qscr", "\ud835\udcc6");
    builder.put("quaternions", "\u210d");
    builder.put("quatint", "\u2a16");
    builder.put("quest", "\u003f");
    builder.put("questeq", "\u225f");
    builder.put("quot", "\"");
    builder.put("rAarr", "\u21db");
    builder.put("rArr", "\u21d2");
    builder.put("rAtail", "\u291c");
    builder.put("rBarr", "\u290f");
    builder.put("rHar", "\u2964");
    builder.put("race", "\u223d\u0331");
    builder.put("racute", "\u0155");
    builder.put("radic", "\u221a");
    builder.put("raemptyv", "\u29b3");
    builder.put("rang", "\u27e9");
    builder.put("rangd", "\u2992");
    builder.put("range", "\u29a5");
    builder.put("rangle", "\u27e9");
    builder.put("raquo", "\u00bb");
    builder.put("rarr", "\u2192");
    builder.put("rarrap", "\u2975");
    builder.put("rarrb", "\u21e5");
    builder.put("rarrbfs", "\u2920");
    builder.put("rarrc", "\u2933");
    builder.put("rarrfs", "\u291e");
    builder.put("rarrhk", "\u21aa");
    builder.put("rarrlp", "\u21ac");
    builder.put("rarrpl", "\u2945");
    builder.put("rarrsim", "\u2974");
    builder.put("rarrtl", "\u21a3");
    builder.put("rarrw", "\u219d");
    builder.put("ratail", "\u291a");
    builder.put("ratio", "\u2236");
    builder.put("rationals", "\u211a");
    builder.put("rbarr", "\u290d");
    builder.put("rbbrk", "\u2773");
    builder.put("rbrace", "\u007d");
    builder.put("rbrack", "\u005d");
    builder.put("rbrke", "\u298c");
    builder.put("rbrksld", "\u298e");
    builder.put("rbrkslu", "\u2990");
    builder.put("rcaron", "\u0159");
    builder.put("rcedil", "\u0157");
    builder.put("rceil", "\u2309");
    builder.put("rcub", "\u007d");
    builder.put("rcy", "\u0440");
    builder.put("rdca", "\u2937");
    builder.put("rdldhar", "\u2969");
    builder.put("rdquo", "\u201d");
    builder.put("rdquor", "\u201d");
    builder.put("rdsh", "\u21b3");
    builder.put("real", "\u211c");
    builder.put("realine", "\u211b");
    builder.put("realpart", "\u211c");
    builder.put("reals", "\u211d");
    builder.put("rect", "\u25ad");
    builder.put("reg", "\u00ae");
    builder.put("rfisht", "\u297d");
    builder.put("rfloor", "\u230b");
    builder.put("rfr", "\ud835\udd2f");
    builder.put("rhard", "\u21c1");
    builder.put("rharu", "\u21c0");
    builder.put("rharul", "\u296c");
    builder.put("rho", "\u03c1");
    builder.put("rhov", "\u03f1");
    builder.put("rightarrow", "\u2192");
    builder.put("rightarrowtail", "\u21a3");
    builder.put("rightharpoondown", "\u21c1");
    builder.put("rightharpoonup", "\u21c0");
    builder.put("rightleftarrows", "\u21c4");
    builder.put("rightleftharpoons", "\u21cc");
    builder.put("rightrightarrows", "\u21c9");
    builder.put("rightsquigarrow", "\u219d");
    builder.put("rightthreetimes", "\u22cc");
    builder.put("ring", "\u02da");
    builder.put("risingdotseq", "\u2253");
    builder.put("rlarr", "\u21c4");
    builder.put("rlhar", "\u21cc");
    builder.put("rlm", "\u200f");
    builder.put("rmoust", "\u23b1");
    builder.put("rmoustache", "\u23b1");
    builder.put("rnmid", "\u2aee");
    builder.put("roang", "\u27ed");
    builder.put("roarr", "\u21fe");
    builder.put("robrk", "\u27e7");
    builder.put("ropar", "\u2986");
    builder.put("ropf", "\ud835\udd63");
    builder.put("roplus", "\u2a2e");
    builder.put("rotimes", "\u2a35");
    builder.put("rpar", "\u0029");
    builder.put("rpargt", "\u2994");
    builder.put("rppolint", "\u2a12");
    builder.put("rrarr", "\u21c9");
    builder.put("rsaquo", "\u203a");
    builder.put("rscr", "\ud835\udcc7");
    builder.put("rsh", "\u21b1");
    builder.put("rsqb", "\u005d");
    builder.put("rsquo", "\u2019");
    builder.put("rsquor", "\u2019");
    builder.put("rthree", "\u22cc");
    builder.put("rtimes", "\u22ca");
    builder.put("rtri", "\u25b9");
    builder.put("rtrie", "\u22b5");
    builder.put("rtrif", "\u25b8");
    builder.put("rtriltri", "\u29ce");
    builder.put("ruluhar", "\u2968");
    builder.put("rx", "\u211e");
    builder.put("sacute", "\u015b");
    builder.put("sbquo", "\u201a");
    builder.put("sc", "\u227b");
    builder.put("scE", "\u2ab4");
    builder.put("scap", "\u2ab8");
    builder.put("scaron", "\u0161");
    builder.put("sccue", "\u227d");
    builder.put("sce", "\u2ab0");
    builder.put("scedil", "\u015f");
    builder.put("scirc", "\u015d");
    builder.put("scnE", "\u2ab6");
    builder.put("scnap", "\u2aba");
    builder.put("scnsim", "\u22e9");
    builder.put("scpolint", "\u2a13");
    builder.put("scsim", "\u227f");
    builder.put("scy", "\u0441");
    builder.put("sdot", "\u22c5");
    builder.put("sdotb", "\u22a1");
    builder.put("sdote", "\u2a66");
    builder.put("seArr", "\u21d8");
    builder.put("searhk", "\u2925");
    builder.put("searr", "\u2198");
    builder.put("searrow", "\u2198");
    builder.put("sect", "\u00a7");
    builder.put("semi", "\u003b");
    builder.put("seswar", "\u2929");
    builder.put("setminus", "\u2216");
    builder.put("setmn", "\u2216");
    builder.put("sext", "\u2736");
    builder.put("sfr", "\ud835\udd30");
    builder.put("sfrown", "\u2322");
    builder.put("sharp", "\u266f");
    builder.put("shchcy", "\u0449");
    builder.put("shcy", "\u0448");
    builder.put("shortmid", "\u2223");
    builder.put("shortparallel", "\u2225");
    builder.put("shy", "\u00ad");
    builder.put("sigma", "\u03c3");
    builder.put("sigmaf", "\u03c2");
    builder.put("sigmav", "\u03c2");
    builder.put("sim", "\u223c");
    builder.put("simdot", "\u2a6a");
    builder.put("sime", "\u2243");
    builder.put("simeq", "\u2243");
    builder.put("simg", "\u2a9e");
    builder.put("simgE", "\u2aa0");
    builder.put("siml", "\u2a9d");
    builder.put("simlE", "\u2a9f");
    builder.put("simne", "\u2246");
    builder.put("simplus", "\u2a24");
    builder.put("simrarr", "\u2972");
    builder.put("slarr", "\u2190");
    builder.put("smallsetminus", "\u2216");
    builder.put("smashp", "\u2a33");
    builder.put("smeparsl", "\u29e4");
    builder.put("smid", "\u2223");
    builder.put("smile", "\u2323");
    builder.put("smt", "\u2aaa");
    builder.put("smte", "\u2aac");
    builder.put("smtes", "\u2aac\ufe00");
    builder.put("softcy", "\u044c");
    builder.put("sol", "\u002f");
    builder.put("solb", "\u29c4");
    builder.put("solbar", "\u233f");
    builder.put("sopf", "\ud835\udd64");
    builder.put("spades", "\u2660");
    builder.put("spadesuit", "\u2660");
    builder.put("spar", "\u2225");
    builder.put("sqcap", "\u2293");
    builder.put("sqcaps", "\u2293\ufe00");
    builder.put("sqcup", "\u2294");
    builder.put("sqcups", "\u2294\ufe00");
    builder.put("sqsub", "\u228f");
    builder.put("sqsube", "\u2291");
    builder.put("sqsubset", "\u228f");
    builder.put("sqsubseteq", "\u2291");
    builder.put("sqsup", "\u2290");
    builder.put("sqsupe", "\u2292");
    builder.put("sqsupset", "\u2290");
    builder.put("sqsupseteq", "\u2292");
    builder.put("squ", "\u25a1");
    builder.put("square", "\u25a1");
    builder.put("squarf", "\u25aa");
    builder.put("squf", "\u25aa");
    builder.put("srarr", "\u2192");
    builder.put("sscr", "\ud835\udcc8");
    builder.put("ssetmn", "\u2216");
    builder.put("ssmile", "\u2323");
    builder.put("sstarf", "\u22c6");
    builder.put("star", "\u2606");
    builder.put("starf", "\u2605");
    builder.put("straightepsilon", "\u03f5");
    builder.put("straightphi", "\u03d5");
    builder.put("strns", "\u00af");
    builder.put("sub", "\u2282");
    builder.put("subE", "\u2ac5");
    builder.put("subdot", "\u2abd");
    builder.put("sube", "\u2286");
    builder.put("subedot", "\u2ac3");
    builder.put("submult", "\u2ac1");
    builder.put("subnE", "\u2acb");
    builder.put("subne", "\u228a");
    builder.put("subplus", "\u2abf");
    builder.put("subrarr", "\u2979");
    builder.put("subset", "\u2282");
    builder.put("subseteq", "\u2286");
    builder.put("subseteqq", "\u2ac5");
    builder.put("subsetneq", "\u228a");
    builder.put("subsetneqq", "\u2acb");
    builder.put("subsim", "\u2ac7");
    builder.put("subsub", "\u2ad5");
    builder.put("subsup", "\u2ad3");
    builder.put("succ", "\u227b");
    builder.put("succapprox", "\u2ab8");
    builder.put("succcurlyeq", "\u227d");
    builder.put("succeq", "\u2ab0");
    builder.put("succnapprox", "\u2aba");
    builder.put("succneqq", "\u2ab6");
    builder.put("succnsim", "\u22e9");
    builder.put("succsim", "\u227f");
    builder.put("sum", "\u2211");
    builder.put("sung", "\u266a");
    builder.put("sup1", "\u00b9");
    builder.put("sup2", "\u00b2");
    builder.put("sup3", "\u00b3");
    builder.put("sup", "\u2283");
    builder.put("supE", "\u2ac6");
    builder.put("supdot", "\u2abe");
    builder.put("supdsub", "\u2ad8");
    builder.put("supe", "\u2287");
    builder.put("supedot", "\u2ac4");
    builder.put("suphsol", "\u27c9");
    builder.put("suphsub", "\u2ad7");
    builder.put("suplarr", "\u297b");
    builder.put("supmult", "\u2ac2");
    builder.put("supnE", "\u2acc");
    builder.put("supne", "\u228b");
    builder.put("supplus", "\u2ac0");
    builder.put("supset", "\u2283");
    builder.put("supseteq", "\u2287");
    builder.put("supseteqq", "\u2ac6");
    builder.put("supsetneq", "\u228b");
    builder.put("supsetneqq", "\u2acc");
    builder.put("supsim", "\u2ac8");
    builder.put("supsub", "\u2ad4");
    builder.put("supsup", "\u2ad6");
    builder.put("swArr", "\u21d9");
    builder.put("swarhk", "\u2926");
    builder.put("swarr", "\u2199");
    builder.put("swarrow", "\u2199");
    builder.put("swnwar", "\u292a");
    builder.put("szlig", "\u00df");
    builder.put("target", "\u2316");
    builder.put("tau", "\u03c4");
    builder.put("tbrk", "\u23b4");
    builder.put("tcaron", "\u0165");
    builder.put("tcedil", "\u0163");
    builder.put("tcy", "\u0442");
    builder.put("tdot", "\u20db");
    builder.put("telrec", "\u2315");
    builder.put("tfr", "\ud835\udd31");
    builder.put("there4", "\u2234");
    builder.put("therefore", "\u2234");
    builder.put("theta", "\u03b8");
    builder.put("thetasym", "\u03d1");
    builder.put("thetav", "\u03d1");
    builder.put("thickapprox", "\u2248");
    builder.put("thicksim", "\u223c");
    builder.put("thinsp", "\u2009");
    builder.put("thkap", "\u2248");
    builder.put("thksim", "\u223c");
    builder.put("thorn", "\u00fe");
    builder.put("tilde", "\u02dc");
    builder.put("times", "\u00d7");
    builder.put("timesb", "\u22a0");
    builder.put("timesbar", "\u2a31");
    builder.put("timesd", "\u2a30");
    builder.put("tint", "\u222d");
    builder.put("toea", "\u2928");
    builder.put("top", "\u22a4");
    builder.put("topbot", "\u2336");
    builder.put("topcir", "\u2af1");
    builder.put("topf", "\ud835\udd65");
    builder.put("topfork", "\u2ada");
    builder.put("tosa", "\u2929");
    builder.put("tprime", "\u2034");
    builder.put("trade", "\u2122");
    builder.put("triangle", "\u25b5");
    builder.put("triangledown", "\u25bf");
    builder.put("triangleleft", "\u25c3");
    builder.put("trianglelefteq", "\u22b4");
    builder.put("triangleq", "\u225c");
    builder.put("triangleright", "\u25b9");
    builder.put("trianglerighteq", "\u22b5");
    builder.put("tridot", "\u25ec");
    builder.put("trie", "\u225c");
    builder.put("triminus", "\u2a3a");
    builder.put("triplus", "\u2a39");
    builder.put("trisb", "\u29cd");
    builder.put("tritime", "\u2a3b");
    builder.put("trpezium", "\u23e2");
    builder.put("tscr", "\ud835\udcc9");
    builder.put("tscy", "\u0446");
    builder.put("tshcy", "\u045b");
    builder.put("tstrok", "\u0167");
    builder.put("twixt", "\u226c");
    builder.put("twoheadleftarrow", "\u219e");
    builder.put("twoheadrightarrow", "\u21a0");
    builder.put("uArr", "\u21d1");
    builder.put("uHar", "\u2963");
    builder.put("uacute", "\u00fa");
    builder.put("uarr", "\u2191");
    builder.put("ubrcy", "\u045e");
    builder.put("ubreve", "\u016d");
    builder.put("ucirc", "\u00fb");
    builder.put("ucy", "\u0443");
    builder.put("udarr", "\u21c5");
    builder.put("udblac", "\u0171");
    builder.put("udhar", "\u296e");
    builder.put("ufisht", "\u297e");
    builder.put("ufr", "\ud835\udd32");
    builder.put("ugrave", "\u00f9");
    builder.put("uharl", "\u21bf");
    builder.put("uharr", "\u21be");
    builder.put("uhblk", "\u2580");
    builder.put("ulcorn", "\u231c");
    builder.put("ulcorner", "\u231c");
    builder.put("ulcrop", "\u230f");
    builder.put("ultri", "\u25f8");
    builder.put("umacr", "\u016b");
    builder.put("uml", "\u00a8");
    builder.put("uogon", "\u0173");
    builder.put("uopf", "\ud835\udd66");
    builder.put("uparrow", "\u2191");
    builder.put("updownarrow", "\u2195");
    builder.put("upharpoonleft", "\u21bf");
    builder.put("upharpoonright", "\u21be");
    builder.put("uplus", "\u228e");
    builder.put("upsi", "\u03c5");
    builder.put("upsih", "\u03d2");
    builder.put("upsilon", "\u03c5");
    builder.put("upuparrows", "\u21c8");
    builder.put("urcorn", "\u231d");
    builder.put("urcorner", "\u231d");
    builder.put("urcrop", "\u230e");
    builder.put("uring", "\u016f");
    builder.put("urtri", "\u25f9");
    builder.put("uscr", "\ud835\udcca");
    builder.put("utdot", "\u22f0");
    builder.put("utilde", "\u0169");
    builder.put("utri", "\u25b5");
    builder.put("utrif", "\u25b4");
    builder.put("uuarr", "\u21c8");
    builder.put("uuml", "\u00fc");
    builder.put("uwangle", "\u29a7");
    builder.put("vArr", "\u21d5");
    builder.put("vBar", "\u2ae8");
    builder.put("vBarv", "\u2ae9");
    builder.put("vDash", "\u22a8");
    builder.put("vangrt", "\u299c");
    builder.put("varepsilon", "\u03f5");
    builder.put("varkappa", "\u03f0");
    builder.put("varnothing", "\u2205");
    builder.put("varphi", "\u03d5");
    builder.put("varpi", "\u03d6");
    builder.put("varpropto", "\u221d");
    builder.put("varr", "\u2195");
    builder.put("varrho", "\u03f1");
    builder.put("varsigma", "\u03c2");
    builder.put("varsubsetneq", "\u228a\ufe00");
    builder.put("varsubsetneqq", "\u2acb\ufe00");
    builder.put("varsupsetneq", "\u228b\ufe00");
    builder.put("varsupsetneqq", "\u2acc\ufe00");
    builder.put("vartheta", "\u03d1");
    builder.put("vartriangleleft", "\u22b2");
    builder.put("vartriangleright", "\u22b3");
    builder.put("vcy", "\u0432");
    builder.put("vdash", "\u22a2");
    builder.put("vee", "\u2228");
    builder.put("veebar", "\u22bb");
    builder.put("veeeq", "\u225a");
    builder.put("vellip", "\u22ee");
    builder.put("verbar", "\u007c");
    builder.put("vert", "\u007c");
    builder.put("vfr", "\ud835\udd33");
    builder.put("vltri", "\u22b2");
    builder.put("vnsub", "\u2282\u20d2");
    builder.put("vnsup", "\u2283\u20d2");
    builder.put("vopf", "\ud835\udd67");
    builder.put("vprop", "\u221d");
    builder.put("vrtri", "\u22b3");
    builder.put("vscr", "\ud835\udccb");
    builder.put("vsubnE", "\u2acb\ufe00");
    builder.put("vsubne", "\u228a\ufe00");
    builder.put("vsupnE", "\u2acc\ufe00");
    builder.put("vsupne", "\u228b\ufe00");
    builder.put("vzigzag", "\u299a");
    builder.put("wcirc", "\u0175");
    builder.put("wedbar", "\u2a5f");
    builder.put("wedge", "\u2227");
    builder.put("wedgeq", "\u2259");
    builder.put("weierp", "\u2118");
    builder.put("wfr", "\ud835\udd34");
    builder.put("wopf", "\ud835\udd68");
    builder.put("wp", "\u2118");
    builder.put("wr", "\u2240");
    builder.put("wreath", "\u2240");
    builder.put("wscr", "\ud835\udccc");
    builder.put("xcap", "\u22c2");
    builder.put("xcirc", "\u25ef");
    builder.put("xcup", "\u22c3");
    builder.put("xdtri", "\u25bd");
    builder.put("xfr", "\ud835\udd35");
    builder.put("xhArr", "\u27fa");
    builder.put("xharr", "\u27f7");
    builder.put("xi", "\u03be");
    builder.put("xlArr", "\u27f8");
    builder.put("xlarr", "\u27f5");
    builder.put("xmap", "\u27fc");
    builder.put("xnis", "\u22fb");
    builder.put("xodot", "\u2a00");
    builder.put("xopf", "\ud835\udd69");
    builder.put("xoplus", "\u2a01");
    builder.put("xotime", "\u2a02");
    builder.put("xrArr", "\u27f9");
    builder.put("xrarr", "\u27f6");
    builder.put("xscr", "\ud835\udccd");
    builder.put("xsqcup", "\u2a06");
    builder.put("xuplus", "\u2a04");
    builder.put("xutri", "\u25b3");
    builder.put("xvee", "\u22c1");
    builder.put("xwedge", "\u22c0");
    builder.put("yacute", "\u00fd");
    builder.put("yacy", "\u044f");
    builder.put("ycirc", "\u0177");
    builder.put("ycy", "\u044b");
    builder.put("yen", "\u00a5");
    builder.put("yfr", "\ud835\udd36");
    builder.put("yicy", "\u0457");
    builder.put("yopf", "\ud835\udd6a");
    builder.put("yscr", "\ud835\udcce");
    builder.put("yucy", "\u044e");
    builder.put("yuml", "\u00ff");
    builder.put("zacute", "\u017a");
    builder.put("zcaron", "\u017e");
    builder.put("zcy", "\u0437");
    builder.put("zdot", "\u017c");
    builder.put("zeetrf", "\u2128");
    builder.put("zeta", "\u03b6");
    builder.put("zfr", "\ud835\udd37");
    builder.put("zhcy", "\u0436");
    builder.put("zigrarr", "\u21dd");
    builder.put("zopf", "\ud835\udd6b");
    builder.put("zscr", "\ud835\udccf");
    builder.put("zwj", "\u200d");
    builder.put("zwnj", "\u200c");

    final Map<String, String> entityNameToCodePointMap = builder.build();

    int longestEntityName = 0;
    for (String entityName : entityNameToCodePointMap.keySet()) {
      if (entityName.length() > longestEntityName) {
        longestEntityName = entityName.length();
      }
    }

    ENTITY_TRIE = new Trie<String>(entityNameToCodePointMap);
    LONGEST_ENTITY_NAME = longestEntityName;
  }

  /**
   * Decodes any HTML entity at the given location and appends it to a string
   * builder.  This handles both named and numeric entities.
   *
   * @param html HTML text.
   * @param offset the position of the sequence to decode in {@code html}.
   * @param limit the last position that could be part of the sequence to decode
   *    in {@code html}.
   * @param sb string builder to append to.
   * @return The offset after the end of the decoded sequence in {@code html}.
   */
  public static int appendDecodedEntity(
      String html, int offset, int limit, StringBuilder sb) {
    char ch = html.charAt(offset);
    if ('&' != ch) {
      sb.append(ch);
      return offset + 1;
    }

    int entityLimit = Math.min(limit, offset + LONGEST_ENTITY_NAME + 2); // + 2 for & and ; characters
    int end = -1;
    int tail = -1;
    if (entityLimit == limit) {
      // Assume a broken entity that ends at the end until shown otherwise.
      end = tail = entityLimit;
    }
    entityloop:
    for (int i = offset + 1; i < entityLimit; ++i) {
      switch (html.charAt(i)) {
        case ';':  // An unbroken entity.
          end = i;
          tail = end + 1;
          break entityloop;
        case '#':
        case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
        case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
        case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
        case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
        case 'Y': case 'Z':
        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
        case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
        case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
        case 's': case 't': case 'u': case 'v': case 'w': case 'x':
        case 'y': case 'z':
        case '0': case '1': case '2': case '3': case '4': case '5':
        case '6': case '7': case '8': case '9':
          break;
        case '=':
          // An equal sign after an entity missing a closing semicolon should
          // never have the semicolon inserted since that causes trouble with
          // parameters in partially encoded URLs.
          sb.append('&');
          return offset + 1;
        default:  // A possible broken entity.
          end = i;
          tail = i;
          break entityloop;
      }
    }
    if (end < 0 || offset + 2 >= end) {
      sb.append('&');
      return offset + 1;
    }
    // Now we know where the entity ends, and that there is at least one
    // character in the entity name
    char ch1 = html.charAt(offset + 1);
    char ch2 = html.charAt(offset + 2);
    int codepoint = -1;
    if ('#' == ch1) {
      // numeric entity
      if ('x' == ch2 || 'X' == ch2) {
        if (end == offset + 3) {  // No digits
          sb.append('&');
          return offset + 1;
        }
        codepoint = 0;
        // hex literal
        digloop:
        for (int i = offset + 3; i < end; ++i) {
          char digit = html.charAt(i);
          switch (digit & 0xfff8) {
            case 0x30: case 0x38: // ASCII 48-57 are '0'-'9'
              int decDig = digit & 0xf;
              if (decDig < 10) {
                codepoint = (codepoint << 4) | decDig;
              } else {
                codepoint = -1;
                break digloop;
              }
              break;
            // ASCII 65-70 and 97-102 are 'A'-'Z' && 'a'-'z'
            case 0x40: case 0x60:
              int hexDig = (digit & 0x7);
              if (hexDig != 0 && hexDig < 7) {
                codepoint = (codepoint << 4) | (hexDig + 9);
              } else {
                codepoint = -1;
                break digloop;
              }
              break;
            default:
              codepoint = -1;
              break digloop;
          }
        }
        if (codepoint > Character.MAX_CODE_POINT) {
          codepoint = 0xfffd;  // Unknown.
        }
      } else {
        codepoint = 0;
        // decimal literal
        digloop:
        for (int i = offset + 2; i < end; ++i) {
          char digit = html.charAt(i);
          switch (digit & 0xfff8) {
            case 0x30: case 0x38: // ASCII 48-57 are '0'-'9'
              int decDig = digit - '0';
              if (decDig < 10) {
                codepoint = (codepoint * 10) + decDig;
              } else {
                codepoint = -1;
                break digloop;
              }
              break;
            default:
              codepoint = -1;
              break digloop;
          }
        }
        if (codepoint > Character.MAX_CODE_POINT) {
          codepoint = 0xfffd;  // Unknown.
        }
      }
    } else {
      Trie<String> t = ENTITY_TRIE;
      for (int i = offset + 1; i < end; ++i) {
        char nameChar = html.charAt(i);
        t = t.lookup(nameChar);
        if (t == null) { break; }
      }
      if (t == null) {
        t = ENTITY_TRIE;
        for (int i = offset + 1; i < end; ++i) {
          char nameChar = html.charAt(i);
          if ('Z' >= nameChar && nameChar >= 'A') { nameChar |= 32; }
          t = t.lookup(nameChar);
          if (t == null) { break; }
        }
      }
      if (t != null && t.isTerminal()) {
        sb.append(t.getValue());
        return tail;
      }
    }
    if (codepoint < 0) {
      sb.append('&');
      return offset + 1;
    } else {
      sb.appendCodePoint(codepoint);
      return tail;
    }
  }

//  /** A possible entity name like "amp" or "gt". */
//  public static boolean isEntityName(String name) {
//    Trie t = ENTITY_TRIE;
//    int n = name.length();
//
//    // Treat AMP the same amp, but not Amp.
//    boolean isUcase = true;
//    for (int i = 0; i < n; ++i) {
//      char ch = name.charAt(i);
//      if (!('A' <= ch && ch <= 'Z')) {
//        isUcase = false;
//        break;
//      }
//    }
//
//    if (isUcase) { name = Strings.toLowerCase(name); }
//
//    for (int i = 0; i < n; ++i) {
//      t = t.lookup(name.charAt(i));
//      if (t == null) { return false; }
//    }
//    return t.isTerminal();
//  }

  private HtmlEntities() { /* uninstantiable */ }
}
