[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/script-modules/latex-to-mathml/ -> index.js (source)

   1  // node_modules/temml/dist/temml.mjs
   2  var ParseError = class _ParseError {
   3    constructor(message, token) {
   4      let error = " " + message;
   5      let start;
   6      const loc = token && token.loc;
   7      if (loc && loc.start <= loc.end) {
   8        const input = loc.lexer.input;
   9        start = loc.start;
  10        const end = loc.end;
  11        if (start === input.length) {
  12          error += " at end of input: ";
  13        } else {
  14          error += " at position " + (start + 1) + ": ";
  15        }
  16        const underlined = input.slice(start, end).replace(/[^]/g, "$&\u0332");
  17        let left;
  18        if (start > 15) {
  19          left = "\u2026" + input.slice(start - 15, start);
  20        } else {
  21          left = input.slice(0, start);
  22        }
  23        let right;
  24        if (end + 15 < input.length) {
  25          right = input.slice(end, end + 15) + "\u2026";
  26        } else {
  27          right = input.slice(end);
  28        }
  29        error += left + underlined + right;
  30      }
  31      const self = new Error(error);
  32      self.name = "ParseError";
  33      self.__proto__ = _ParseError.prototype;
  34      self.position = start;
  35      return self;
  36    }
  37  };
  38  ParseError.prototype.__proto__ = Error.prototype;
  39  var deflt = function(setting, defaultIfUndefined) {
  40    return setting === void 0 ? defaultIfUndefined : setting;
  41  };
  42  var uppercase = /([A-Z])/g;
  43  var hyphenate = function(str) {
  44    return str.replace(uppercase, "-$1").toLowerCase();
  45  };
  46  var ESCAPE_LOOKUP = {
  47    "&": "&amp;",
  48    ">": "&gt;",
  49    "<": "&lt;",
  50    '"': "&quot;",
  51    "'": "&#x27;"
  52  };
  53  var ESCAPE_REGEX = /[&><"']/g;
  54  function escape(text2) {
  55    return String(text2).replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
  56  }
  57  var getBaseElem = function(group) {
  58    if (group.type === "ordgroup") {
  59      if (group.body.length === 1) {
  60        return getBaseElem(group.body[0]);
  61      } else {
  62        return group;
  63      }
  64    } else if (group.type === "color") {
  65      if (group.body.length === 1) {
  66        return getBaseElem(group.body[0]);
  67      } else {
  68        return group;
  69      }
  70    } else if (group.type === "font") {
  71      return getBaseElem(group.body);
  72    } else {
  73      return group;
  74    }
  75  };
  76  var isCharacterBox = function(group) {
  77    const baseElem = getBaseElem(group);
  78    return baseElem.type === "mathord" || baseElem.type === "textord" || baseElem.type === "atom";
  79  };
  80  var assert = function(value) {
  81    if (!value) {
  82      throw new Error("Expected non-null, but got " + String(value));
  83    }
  84    return value;
  85  };
  86  var protocolFromUrl = function(url) {
  87    const protocol = /^[\x00-\x20]*([^\\/#?]*?)(:|&#0*58|&#x0*3a|&colon)/i.exec(url);
  88    if (!protocol) {
  89      return "_relative";
  90    }
  91    if (protocol[2] !== ":") {
  92      return null;
  93    }
  94    if (!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(protocol[1])) {
  95      return null;
  96    }
  97    return protocol[1].toLowerCase();
  98  };
  99  var round = function(n) {
 100    return +n.toFixed(4);
 101  };
 102  var utils = {
 103    deflt,
 104    escape,
 105    hyphenate,
 106    getBaseElem,
 107    isCharacterBox,
 108    protocolFromUrl,
 109    round
 110  };
 111  var Settings = class {
 112    constructor(options) {
 113      options = options || {};
 114      this.displayMode = utils.deflt(options.displayMode, false);
 115      this.annotate = utils.deflt(options.annotate, false);
 116      this.leqno = utils.deflt(options.leqno, false);
 117      this.throwOnError = utils.deflt(options.throwOnError, false);
 118      this.errorColor = utils.deflt(options.errorColor, "#b22222");
 119      this.macros = options.macros || {};
 120      this.wrap = utils.deflt(options.wrap, "tex");
 121      this.xml = utils.deflt(options.xml, false);
 122      this.colorIsTextColor = utils.deflt(options.colorIsTextColor, false);
 123      this.strict = utils.deflt(options.strict, false);
 124      this.trust = utils.deflt(options.trust, false);
 125      this.maxSize = options.maxSize === void 0 ? [Infinity, Infinity] : Array.isArray(options.maxSize) ? options.maxSize : [Infinity, Infinity];
 126      this.maxExpand = Math.max(0, utils.deflt(options.maxExpand, 1e3));
 127    }
 128    /**
 129     * Check whether to test potentially dangerous input, and return
 130     * `true` (trusted) or `false` (untrusted).  The sole argument `context`
 131     * should be an object with `command` field specifying the relevant LaTeX
 132     * command (as a string starting with `\`), and any other arguments, etc.
 133     * If `context` has a `url` field, a `protocol` field will automatically
 134     * get added by this function (changing the specified object).
 135     */
 136    isTrusted(context) {
 137      if (context.url && !context.protocol) {
 138        const protocol = utils.protocolFromUrl(context.url);
 139        if (protocol == null) {
 140          return false;
 141        }
 142        context.protocol = protocol;
 143      }
 144      const trust = typeof this.trust === "function" ? this.trust(context) : this.trust;
 145      return Boolean(trust);
 146    }
 147  };
 148  var _functions = {};
 149  var _mathmlGroupBuilders = {};
 150  function defineFunction({
 151    type,
 152    names,
 153    props,
 154    handler,
 155    mathmlBuilder: mathmlBuilder2
 156  }) {
 157    const data = {
 158      type,
 159      numArgs: props.numArgs,
 160      argTypes: props.argTypes,
 161      allowedInArgument: !!props.allowedInArgument,
 162      allowedInText: !!props.allowedInText,
 163      allowedInMath: props.allowedInMath === void 0 ? true : props.allowedInMath,
 164      numOptionalArgs: props.numOptionalArgs || 0,
 165      infix: !!props.infix,
 166      primitive: !!props.primitive,
 167      handler
 168    };
 169    for (let i = 0; i < names.length; ++i) {
 170      _functions[names[i]] = data;
 171    }
 172    if (type) {
 173      if (mathmlBuilder2) {
 174        _mathmlGroupBuilders[type] = mathmlBuilder2;
 175      }
 176    }
 177  }
 178  function defineFunctionBuilders({ type, mathmlBuilder: mathmlBuilder2 }) {
 179    defineFunction({
 180      type,
 181      names: [],
 182      props: { numArgs: 0 },
 183      handler() {
 184        throw new Error("Should never be called.");
 185      },
 186      mathmlBuilder: mathmlBuilder2
 187    });
 188  }
 189  var normalizeArgument = function(arg) {
 190    return arg.type === "ordgroup" && arg.body.length === 1 ? arg.body[0] : arg;
 191  };
 192  var ordargument = function(arg) {
 193    return arg.type === "ordgroup" ? arg.body : [arg];
 194  };
 195  var DocumentFragment = class {
 196    constructor(children) {
 197      this.children = children;
 198      this.classes = [];
 199      this.style = {};
 200    }
 201    hasClass(className) {
 202      return this.classes.includes(className);
 203    }
 204    /** Convert the fragment into a node. */
 205    toNode() {
 206      const frag = document.createDocumentFragment();
 207      for (let i = 0; i < this.children.length; i++) {
 208        frag.appendChild(this.children[i].toNode());
 209      }
 210      return frag;
 211    }
 212    /** Convert the fragment into HTML markup. */
 213    toMarkup() {
 214      let markup = "";
 215      for (let i = 0; i < this.children.length; i++) {
 216        markup += this.children[i].toMarkup();
 217      }
 218      return markup;
 219    }
 220    /**
 221     * Converts the math node into a string, similar to innerText. Applies to
 222     * MathDomNode's only.
 223     */
 224    toText() {
 225      const toText = (child) => child.toText();
 226      return this.children.map(toText).join("");
 227    }
 228  };
 229  var createClass = function(classes) {
 230    return classes.filter((cls) => cls).join(" ");
 231  };
 232  var initNode = function(classes, style) {
 233    this.classes = classes || [];
 234    this.attributes = {};
 235    this.style = style || {};
 236  };
 237  var toNode = function(tagName) {
 238    const node = document.createElement(tagName);
 239    node.className = createClass(this.classes);
 240    for (const style in this.style) {
 241      if (Object.prototype.hasOwnProperty.call(this.style, style)) {
 242        node.style[style] = this.style[style];
 243      }
 244    }
 245    for (const attr in this.attributes) {
 246      if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
 247        node.setAttribute(attr, this.attributes[attr]);
 248      }
 249    }
 250    for (let i = 0; i < this.children.length; i++) {
 251      node.appendChild(this.children[i].toNode());
 252    }
 253    return node;
 254  };
 255  var toMarkup = function(tagName) {
 256    let markup = `<$tagName}`;
 257    if (this.classes.length) {
 258      markup += ` class="$utils.escape(createClass(this.classes))}"`;
 259    }
 260    let styles = "";
 261    for (const style in this.style) {
 262      if (Object.prototype.hasOwnProperty.call(this.style, style)) {
 263        styles += `$utils.hyphenate(style)}:$this.style[style]};`;
 264      }
 265    }
 266    if (styles) {
 267      markup += ` style="$styles}"`;
 268    }
 269    for (const attr in this.attributes) {
 270      if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
 271        markup += ` $attr}="$utils.escape(this.attributes[attr])}"`;
 272      }
 273    }
 274    markup += ">";
 275    for (let i = 0; i < this.children.length; i++) {
 276      markup += this.children[i].toMarkup();
 277    }
 278    markup += `</$tagName}>`;
 279    return markup;
 280  };
 281  var Span = class {
 282    constructor(classes, children, style) {
 283      initNode.call(this, classes, style);
 284      this.children = children || [];
 285    }
 286    setAttribute(attribute, value) {
 287      this.attributes[attribute] = value;
 288    }
 289    toNode() {
 290      return toNode.call(this, "span");
 291    }
 292    toMarkup() {
 293      return toMarkup.call(this, "span");
 294    }
 295  };
 296  var TextNode$1 = class TextNode {
 297    constructor(text2) {
 298      this.text = text2;
 299    }
 300    toNode() {
 301      return document.createTextNode(this.text);
 302    }
 303    toMarkup() {
 304      return utils.escape(this.text);
 305    }
 306  };
 307  var AnchorNode = class {
 308    constructor(href, classes, children) {
 309      this.href = href;
 310      this.classes = classes;
 311      this.children = children || [];
 312    }
 313    toNode() {
 314      const node = document.createElement("a");
 315      node.setAttribute("href", this.href);
 316      if (this.classes.length > 0) {
 317        node.className = createClass(this.classes);
 318      }
 319      for (let i = 0; i < this.children.length; i++) {
 320        node.appendChild(this.children[i].toNode());
 321      }
 322      return node;
 323    }
 324    toMarkup() {
 325      let markup = `<a href='$utils.escape(this.href)}'`;
 326      if (this.classes.length > 0) {
 327        markup += ` class="$utils.escape(createClass(this.classes))}"`;
 328      }
 329      markup += ">";
 330      for (let i = 0; i < this.children.length; i++) {
 331        markup += this.children[i].toMarkup();
 332      }
 333      markup += "</a>";
 334      return markup;
 335    }
 336  };
 337  var Img = class {
 338    constructor(src, alt, style) {
 339      this.alt = alt;
 340      this.src = src;
 341      this.classes = ["mord"];
 342      this.style = style;
 343    }
 344    hasClass(className) {
 345      return this.classes.includes(className);
 346    }
 347    toNode() {
 348      const node = document.createElement("img");
 349      node.src = this.src;
 350      node.alt = this.alt;
 351      node.className = "mord";
 352      for (const style in this.style) {
 353        if (Object.prototype.hasOwnProperty.call(this.style, style)) {
 354          node.style[style] = this.style[style];
 355        }
 356      }
 357      return node;
 358    }
 359    toMarkup() {
 360      let markup = `<img src='$this.src}' alt='$this.alt}'`;
 361      let styles = "";
 362      for (const style in this.style) {
 363        if (Object.prototype.hasOwnProperty.call(this.style, style)) {
 364          styles += `$utils.hyphenate(style)}:$this.style[style]};`;
 365        }
 366      }
 367      if (styles) {
 368        markup += ` style="$utils.escape(styles)}"`;
 369      }
 370      markup += ">";
 371      return markup;
 372    }
 373  };
 374  function newDocumentFragment(children) {
 375    return new DocumentFragment(children);
 376  }
 377  var MathNode = class {
 378    constructor(type, children, classes, style) {
 379      this.type = type;
 380      this.attributes = {};
 381      this.children = children || [];
 382      this.classes = classes || [];
 383      this.style = style || {};
 384      this.label = "";
 385    }
 386    /**
 387     * Sets an attribute on a MathML node. MathML depends on attributes to convey a
 388     * semantic content, so this is used heavily.
 389     */
 390    setAttribute(name, value) {
 391      this.attributes[name] = value;
 392    }
 393    /**
 394     * Gets an attribute on a MathML node.
 395     */
 396    getAttribute(name) {
 397      return this.attributes[name];
 398    }
 399    setLabel(value) {
 400      this.label = value;
 401    }
 402    /**
 403     * Converts the math node into a MathML-namespaced DOM element.
 404     */
 405    toNode() {
 406      const node = document.createElementNS("http://www.w3.org/1998/Math/MathML", this.type);
 407      for (const attr in this.attributes) {
 408        if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
 409          node.setAttribute(attr, this.attributes[attr]);
 410        }
 411      }
 412      if (this.classes.length > 0) {
 413        node.className = createClass(this.classes);
 414      }
 415      for (const style in this.style) {
 416        if (Object.prototype.hasOwnProperty.call(this.style, style)) {
 417          node.style[style] = this.style[style];
 418        }
 419      }
 420      for (let i = 0; i < this.children.length; i++) {
 421        node.appendChild(this.children[i].toNode());
 422      }
 423      return node;
 424    }
 425    /**
 426     * Converts the math node into an HTML markup string.
 427     */
 428    toMarkup() {
 429      let markup = "<" + this.type;
 430      for (const attr in this.attributes) {
 431        if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
 432          markup += " " + attr + '="';
 433          markup += utils.escape(this.attributes[attr]);
 434          markup += '"';
 435        }
 436      }
 437      if (this.classes.length > 0) {
 438        markup += ` class="$utils.escape(createClass(this.classes))}"`;
 439      }
 440      let styles = "";
 441      for (const style in this.style) {
 442        if (Object.prototype.hasOwnProperty.call(this.style, style)) {
 443          styles += `$utils.hyphenate(style)}:$this.style[style]};`;
 444        }
 445      }
 446      if (styles) {
 447        markup += ` style="$styles}"`;
 448      }
 449      markup += ">";
 450      for (let i = 0; i < this.children.length; i++) {
 451        markup += this.children[i].toMarkup();
 452      }
 453      markup += "</" + this.type + ">";
 454      return markup;
 455    }
 456    /**
 457     * Converts the math node into a string, similar to innerText, but escaped.
 458     */
 459    toText() {
 460      return this.children.map((child) => child.toText()).join("");
 461    }
 462  };
 463  var TextNode2 = class {
 464    constructor(text2) {
 465      this.text = text2;
 466    }
 467    /**
 468     * Converts the text node into a DOM text node.
 469     */
 470    toNode() {
 471      return document.createTextNode(this.text);
 472    }
 473    /**
 474     * Converts the text node into escaped HTML markup
 475     * (representing the text itself).
 476     */
 477    toMarkup() {
 478      return utils.escape(this.toText());
 479    }
 480    /**
 481     * Converts the text node into a string
 482     * (representing the text itself).
 483     */
 484    toText() {
 485      return this.text;
 486    }
 487  };
 488  var wrapWithMstyle = (expression) => {
 489    let node;
 490    if (expression.length === 1 && expression[0].type === "mrow") {
 491      node = expression.pop();
 492      node.type = "mstyle";
 493    } else {
 494      node = new MathNode("mstyle", expression);
 495    }
 496    return node;
 497  };
 498  var mathMLTree = {
 499    MathNode,
 500    TextNode: TextNode2,
 501    newDocumentFragment
 502  };
 503  var estimatedWidth = (node) => {
 504    let width = 0;
 505    if (node.body) {
 506      for (const item of node.body) {
 507        width += estimatedWidth(item);
 508      }
 509    } else if (node.type === "supsub") {
 510      width += estimatedWidth(node.base);
 511      if (node.sub) {
 512        width += 0.7 * estimatedWidth(node.sub);
 513      }
 514      if (node.sup) {
 515        width += 0.7 * estimatedWidth(node.sup);
 516      }
 517    } else if (node.type === "mathord" || node.type === "textord") {
 518      for (const ch of node.text.split("")) {
 519        const codePoint = ch.codePointAt(0);
 520        if (96 < codePoint && codePoint < 123 || 944 < codePoint && codePoint < 970) {
 521          width += 0.56;
 522        } else if (47 < codePoint && codePoint < 58) {
 523          width += 0.5;
 524        } else {
 525          width += 0.92;
 526        }
 527      }
 528    } else {
 529      width += 1;
 530    }
 531    return width;
 532  };
 533  var stretchyCodePoint = {
 534    widehat: "^",
 535    widecheck: "\u02C7",
 536    widetilde: "~",
 537    wideparen: "\u23DC",
 538    // \u23dc
 539    utilde: "~",
 540    overleftarrow: "\u2190",
 541    underleftarrow: "\u2190",
 542    xleftarrow: "\u2190",
 543    overrightarrow: "\u2192",
 544    underrightarrow: "\u2192",
 545    xrightarrow: "\u2192",
 546    underbrace: "\u23DF",
 547    overbrace: "\u23DE",
 548    overgroup: "\u23E0",
 549    overparen: "\u23DC",
 550    undergroup: "\u23E1",
 551    underparen: "\u23DD",
 552    overleftrightarrow: "\u2194",
 553    underleftrightarrow: "\u2194",
 554    xleftrightarrow: "\u2194",
 555    Overrightarrow: "\u21D2",
 556    xRightarrow: "\u21D2",
 557    overleftharpoon: "\u21BC",
 558    xleftharpoonup: "\u21BC",
 559    overrightharpoon: "\u21C0",
 560    xrightharpoonup: "\u21C0",
 561    xLeftarrow: "\u21D0",
 562    xLeftrightarrow: "\u21D4",
 563    xhookleftarrow: "\u21A9",
 564    xhookrightarrow: "\u21AA",
 565    xmapsto: "\u21A6",
 566    xrightharpoondown: "\u21C1",
 567    xleftharpoondown: "\u21BD",
 568    xtwoheadleftarrow: "\u219E",
 569    xtwoheadrightarrow: "\u21A0",
 570    xlongequal: "=",
 571    xrightleftarrows: "\u21C4",
 572    yields: "\u2192",
 573    yieldsLeft: "\u2190",
 574    mesomerism: "\u2194",
 575    longrightharpoonup: "\u21C0",
 576    longleftharpoondown: "\u21BD",
 577    eqrightharpoonup: "\u21C0",
 578    eqleftharpoondown: "\u21BD",
 579    "\\cdrightarrow": "\u2192",
 580    "\\cdleftarrow": "\u2190",
 581    "\\cdlongequal": "="
 582  };
 583  var mathMLnode = function(label) {
 584    const child = new mathMLTree.TextNode(stretchyCodePoint[label.slice(1)]);
 585    const node = new mathMLTree.MathNode("mo", [child]);
 586    node.setAttribute("stretchy", "true");
 587    return node;
 588  };
 589  var crookedWides = ["\\widetilde", "\\widehat", "\\widecheck", "\\utilde"];
 590  var accentNode = (group) => {
 591    const mo = mathMLnode(group.label);
 592    if (crookedWides.includes(group.label)) {
 593      const width = estimatedWidth(group.base);
 594      if (1 < width && width < 1.6) {
 595        mo.classes.push("tml-crooked-2");
 596      } else if (1.6 <= width && width < 2.5) {
 597        mo.classes.push("tml-crooked-3");
 598      } else if (2.5 <= width) {
 599        mo.classes.push("tml-crooked-4");
 600      }
 601    }
 602    return mo;
 603  };
 604  var stretchy = {
 605    mathMLnode,
 606    accentNode
 607  };
 608  var ATOMS = {
 609    bin: 1,
 610    close: 1,
 611    inner: 1,
 612    open: 1,
 613    punct: 1,
 614    rel: 1
 615  };
 616  var NON_ATOMS = {
 617    "accent-token": 1,
 618    mathord: 1,
 619    "op-token": 1,
 620    spacing: 1,
 621    textord: 1
 622  };
 623  var symbols = {
 624    math: {},
 625    text: {}
 626  };
 627  function defineSymbol(mode, group, replace, name, acceptUnicodeChar) {
 628    symbols[mode][name] = { group, replace };
 629    if (acceptUnicodeChar && replace) {
 630      symbols[mode][replace] = symbols[mode][name];
 631    }
 632  }
 633  var math = "math";
 634  var text = "text";
 635  var accent = "accent-token";
 636  var bin = "bin";
 637  var close = "close";
 638  var inner = "inner";
 639  var mathord = "mathord";
 640  var op = "op-token";
 641  var open = "open";
 642  var punct = "punct";
 643  var rel = "rel";
 644  var spacing = "spacing";
 645  var textord = "textord";
 646  defineSymbol(math, rel, "\u2261", "\\equiv", true);
 647  defineSymbol(math, rel, "\u227A", "\\prec", true);
 648  defineSymbol(math, rel, "\u227B", "\\succ", true);
 649  defineSymbol(math, rel, "\u223C", "\\sim", true);
 650  defineSymbol(math, rel, "\u27C2", "\\perp", true);
 651  defineSymbol(math, rel, "\u2AAF", "\\preceq", true);
 652  defineSymbol(math, rel, "\u2AB0", "\\succeq", true);
 653  defineSymbol(math, rel, "\u2243", "\\simeq", true);
 654  defineSymbol(math, rel, "\u224C", "\\backcong", true);
 655  defineSymbol(math, rel, "|", "\\mid", true);
 656  defineSymbol(math, rel, "\u226A", "\\ll", true);
 657  defineSymbol(math, rel, "\u226B", "\\gg", true);
 658  defineSymbol(math, rel, "\u224D", "\\asymp", true);
 659  defineSymbol(math, rel, "\u2225", "\\parallel");
 660  defineSymbol(math, rel, "\u2323", "\\smile", true);
 661  defineSymbol(math, rel, "\u2291", "\\sqsubseteq", true);
 662  defineSymbol(math, rel, "\u2292", "\\sqsupseteq", true);
 663  defineSymbol(math, rel, "\u2250", "\\doteq", true);
 664  defineSymbol(math, rel, "\u2322", "\\frown", true);
 665  defineSymbol(math, rel, "\u220B", "\\ni", true);
 666  defineSymbol(math, rel, "\u220C", "\\notni", true);
 667  defineSymbol(math, rel, "\u221D", "\\propto", true);
 668  defineSymbol(math, rel, "\u22A2", "\\vdash", true);
 669  defineSymbol(math, rel, "\u22A3", "\\dashv", true);
 670  defineSymbol(math, rel, "\u220B", "\\owns");
 671  defineSymbol(math, rel, "\u2258", "\\arceq", true);
 672  defineSymbol(math, rel, "\u2259", "\\wedgeq", true);
 673  defineSymbol(math, rel, "\u225A", "\\veeeq", true);
 674  defineSymbol(math, rel, "\u225B", "\\stareq", true);
 675  defineSymbol(math, rel, "\u225D", "\\eqdef", true);
 676  defineSymbol(math, rel, "\u225E", "\\measeq", true);
 677  defineSymbol(math, rel, "\u225F", "\\questeq", true);
 678  defineSymbol(math, rel, "\u2260", "\\ne", true);
 679  defineSymbol(math, rel, "\u2260", "\\neq");
 680  defineSymbol(math, rel, "\u2A75", "\\eqeq", true);
 681  defineSymbol(math, rel, "\u2A76", "\\eqeqeq", true);
 682  defineSymbol(math, rel, "\u2237", "\\dblcolon", true);
 683  defineSymbol(math, rel, "\u2254", "\\coloneqq", true);
 684  defineSymbol(math, rel, "\u2255", "\\eqqcolon", true);
 685  defineSymbol(math, rel, "\u2239", "\\eqcolon", true);
 686  defineSymbol(math, rel, "\u2A74", "\\Coloneqq", true);
 687  defineSymbol(math, punct, ".", "\\ldotp");
 688  defineSymbol(math, punct, "\xB7", "\\cdotp");
 689  defineSymbol(math, textord, "#", "\\#");
 690  defineSymbol(text, textord, "#", "\\#");
 691  defineSymbol(math, textord, "&", "\\&");
 692  defineSymbol(text, textord, "&", "\\&");
 693  defineSymbol(math, textord, "\u2135", "\\aleph", true);
 694  defineSymbol(math, textord, "\u2200", "\\forall", true);
 695  defineSymbol(math, textord, "\u210F", "\\hbar", true);
 696  defineSymbol(math, textord, "\u2203", "\\exists", true);
 697  defineSymbol(math, bin, "\u2207", "\\nabla", true);
 698  defineSymbol(math, textord, "\u266D", "\\flat", true);
 699  defineSymbol(math, textord, "\u2113", "\\ell", true);
 700  defineSymbol(math, textord, "\u266E", "\\natural", true);
 701  defineSymbol(math, textord, "\u212B", "\\Angstrom", true);
 702  defineSymbol(text, textord, "\u212B", "\\Angstrom", true);
 703  defineSymbol(math, textord, "\u2663", "\\clubsuit", true);
 704  defineSymbol(math, textord, "\u2667", "\\varclubsuit", true);
 705  defineSymbol(math, textord, "\u2118", "\\wp", true);
 706  defineSymbol(math, textord, "\u266F", "\\sharp", true);
 707  defineSymbol(math, textord, "\u2662", "\\diamondsuit", true);
 708  defineSymbol(math, textord, "\u2666", "\\vardiamondsuit", true);
 709  defineSymbol(math, textord, "\u211C", "\\Re", true);
 710  defineSymbol(math, textord, "\u2661", "\\heartsuit", true);
 711  defineSymbol(math, textord, "\u2665", "\\varheartsuit", true);
 712  defineSymbol(math, textord, "\u2111", "\\Im", true);
 713  defineSymbol(math, textord, "\u2660", "\\spadesuit", true);
 714  defineSymbol(math, textord, "\u2664", "\\varspadesuit", true);
 715  defineSymbol(math, textord, "\u2640", "\\female", true);
 716  defineSymbol(math, textord, "\u2642", "\\male", true);
 717  defineSymbol(math, textord, "\xA7", "\\S", true);
 718  defineSymbol(text, textord, "\xA7", "\\S");
 719  defineSymbol(math, textord, "\xB6", "\\P", true);
 720  defineSymbol(text, textord, "\xB6", "\\P");
 721  defineSymbol(text, textord, "\u263A", "\\smiley", true);
 722  defineSymbol(math, textord, "\u263A", "\\smiley", true);
 723  defineSymbol(math, textord, "\u2020", "\\dag");
 724  defineSymbol(text, textord, "\u2020", "\\dag");
 725  defineSymbol(text, textord, "\u2020", "\\textdagger");
 726  defineSymbol(math, textord, "\u2021", "\\ddag");
 727  defineSymbol(text, textord, "\u2021", "\\ddag");
 728  defineSymbol(text, textord, "\u2021", "\\textdaggerdbl");
 729  defineSymbol(math, close, "\u23B1", "\\rmoustache", true);
 730  defineSymbol(math, open, "\u23B0", "\\lmoustache", true);
 731  defineSymbol(math, close, "\u27EF", "\\rgroup", true);
 732  defineSymbol(math, open, "\u27EE", "\\lgroup", true);
 733  defineSymbol(math, bin, "\u2213", "\\mp", true);
 734  defineSymbol(math, bin, "\u2296", "\\ominus", true);
 735  defineSymbol(math, bin, "\u228E", "\\uplus", true);
 736  defineSymbol(math, bin, "\u2293", "\\sqcap", true);
 737  defineSymbol(math, bin, "\u2217", "\\ast");
 738  defineSymbol(math, bin, "\u2294", "\\sqcup", true);
 739  defineSymbol(math, bin, "\u25EF", "\\bigcirc", true);
 740  defineSymbol(math, bin, "\u2219", "\\bullet", true);
 741  defineSymbol(math, bin, "\u2021", "\\ddagger");
 742  defineSymbol(math, bin, "\u2240", "\\wr", true);
 743  defineSymbol(math, bin, "\u2A3F", "\\amalg");
 744  defineSymbol(math, bin, "&", "\\And");
 745  defineSymbol(math, bin, "\u2AFD", "\\sslash", true);
 746  defineSymbol(math, rel, "\u27F5", "\\longleftarrow", true);
 747  defineSymbol(math, rel, "\u21D0", "\\Leftarrow", true);
 748  defineSymbol(math, rel, "\u27F8", "\\Longleftarrow", true);
 749  defineSymbol(math, rel, "\u27F6", "\\longrightarrow", true);
 750  defineSymbol(math, rel, "\u21D2", "\\Rightarrow", true);
 751  defineSymbol(math, rel, "\u27F9", "\\Longrightarrow", true);
 752  defineSymbol(math, rel, "\u2194", "\\leftrightarrow", true);
 753  defineSymbol(math, rel, "\u27F7", "\\longleftrightarrow", true);
 754  defineSymbol(math, rel, "\u21D4", "\\Leftrightarrow", true);
 755  defineSymbol(math, rel, "\u27FA", "\\Longleftrightarrow", true);
 756  defineSymbol(math, rel, "\u21A4", "\\mapsfrom", true);
 757  defineSymbol(math, rel, "\u21A6", "\\mapsto", true);
 758  defineSymbol(math, rel, "\u27FC", "\\longmapsto", true);
 759  defineSymbol(math, rel, "\u2197", "\\nearrow", true);
 760  defineSymbol(math, rel, "\u21A9", "\\hookleftarrow", true);
 761  defineSymbol(math, rel, "\u21AA", "\\hookrightarrow", true);
 762  defineSymbol(math, rel, "\u2198", "\\searrow", true);
 763  defineSymbol(math, rel, "\u21BC", "\\leftharpoonup", true);
 764  defineSymbol(math, rel, "\u21C0", "\\rightharpoonup", true);
 765  defineSymbol(math, rel, "\u2199", "\\swarrow", true);
 766  defineSymbol(math, rel, "\u21BD", "\\leftharpoondown", true);
 767  defineSymbol(math, rel, "\u21C1", "\\rightharpoondown", true);
 768  defineSymbol(math, rel, "\u2196", "\\nwarrow", true);
 769  defineSymbol(math, rel, "\u21CC", "\\rightleftharpoons", true);
 770  defineSymbol(math, mathord, "\u21AF", "\\lightning", true);
 771  defineSymbol(math, mathord, "\u220E", "\\QED", true);
 772  defineSymbol(math, mathord, "\u2030", "\\permil", true);
 773  defineSymbol(text, textord, "\u2030", "\\permil");
 774  defineSymbol(math, mathord, "\u2609", "\\astrosun", true);
 775  defineSymbol(math, mathord, "\u263C", "\\sun", true);
 776  defineSymbol(math, mathord, "\u263E", "\\leftmoon", true);
 777  defineSymbol(math, mathord, "\u263D", "\\rightmoon", true);
 778  defineSymbol(math, mathord, "\u2295", "\\Earth");
 779  defineSymbol(math, rel, "\u226E", "\\nless", true);
 780  defineSymbol(math, rel, "\u2A87", "\\lneq", true);
 781  defineSymbol(math, rel, "\u2268", "\\lneqq", true);
 782  defineSymbol(math, rel, "\u2268\uFE00", "\\lvertneqq");
 783  defineSymbol(math, rel, "\u22E6", "\\lnsim", true);
 784  defineSymbol(math, rel, "\u2A89", "\\lnapprox", true);
 785  defineSymbol(math, rel, "\u2280", "\\nprec", true);
 786  defineSymbol(math, rel, "\u22E0", "\\npreceq", true);
 787  defineSymbol(math, rel, "\u22E8", "\\precnsim", true);
 788  defineSymbol(math, rel, "\u2AB9", "\\precnapprox", true);
 789  defineSymbol(math, rel, "\u2241", "\\nsim", true);
 790  defineSymbol(math, rel, "\u2224", "\\nmid", true);
 791  defineSymbol(math, rel, "\u2224", "\\nshortmid");
 792  defineSymbol(math, rel, "\u22AC", "\\nvdash", true);
 793  defineSymbol(math, rel, "\u22AD", "\\nvDash", true);
 794  defineSymbol(math, rel, "\u22EA", "\\ntriangleleft");
 795  defineSymbol(math, rel, "\u22EC", "\\ntrianglelefteq", true);
 796  defineSymbol(math, rel, "\u2284", "\\nsubset", true);
 797  defineSymbol(math, rel, "\u2285", "\\nsupset", true);
 798  defineSymbol(math, rel, "\u228A", "\\subsetneq", true);
 799  defineSymbol(math, rel, "\u228A\uFE00", "\\varsubsetneq");
 800  defineSymbol(math, rel, "\u2ACB", "\\subsetneqq", true);
 801  defineSymbol(math, rel, "\u2ACB\uFE00", "\\varsubsetneqq");
 802  defineSymbol(math, rel, "\u226F", "\\ngtr", true);
 803  defineSymbol(math, rel, "\u2A88", "\\gneq", true);
 804  defineSymbol(math, rel, "\u2269", "\\gneqq", true);
 805  defineSymbol(math, rel, "\u2269\uFE00", "\\gvertneqq");
 806  defineSymbol(math, rel, "\u22E7", "\\gnsim", true);
 807  defineSymbol(math, rel, "\u2A8A", "\\gnapprox", true);
 808  defineSymbol(math, rel, "\u2281", "\\nsucc", true);
 809  defineSymbol(math, rel, "\u22E1", "\\nsucceq", true);
 810  defineSymbol(math, rel, "\u22E9", "\\succnsim", true);
 811  defineSymbol(math, rel, "\u2ABA", "\\succnapprox", true);
 812  defineSymbol(math, rel, "\u2246", "\\ncong", true);
 813  defineSymbol(math, rel, "\u2226", "\\nparallel", true);
 814  defineSymbol(math, rel, "\u2226", "\\nshortparallel");
 815  defineSymbol(math, rel, "\u22AF", "\\nVDash", true);
 816  defineSymbol(math, rel, "\u22EB", "\\ntriangleright");
 817  defineSymbol(math, rel, "\u22ED", "\\ntrianglerighteq", true);
 818  defineSymbol(math, rel, "\u228B", "\\supsetneq", true);
 819  defineSymbol(math, rel, "\u228B", "\\varsupsetneq");
 820  defineSymbol(math, rel, "\u2ACC", "\\supsetneqq", true);
 821  defineSymbol(math, rel, "\u2ACC\uFE00", "\\varsupsetneqq");
 822  defineSymbol(math, rel, "\u22AE", "\\nVdash", true);
 823  defineSymbol(math, rel, "\u2AB5", "\\precneqq", true);
 824  defineSymbol(math, rel, "\u2AB6", "\\succneqq", true);
 825  defineSymbol(math, bin, "\u22B4", "\\unlhd");
 826  defineSymbol(math, bin, "\u22B5", "\\unrhd");
 827  defineSymbol(math, rel, "\u219A", "\\nleftarrow", true);
 828  defineSymbol(math, rel, "\u219B", "\\nrightarrow", true);
 829  defineSymbol(math, rel, "\u21CD", "\\nLeftarrow", true);
 830  defineSymbol(math, rel, "\u21CF", "\\nRightarrow", true);
 831  defineSymbol(math, rel, "\u21AE", "\\nleftrightarrow", true);
 832  defineSymbol(math, rel, "\u21CE", "\\nLeftrightarrow", true);
 833  defineSymbol(math, rel, "\u25B3", "\\vartriangle");
 834  defineSymbol(math, textord, "\u210F", "\\hslash");
 835  defineSymbol(math, textord, "\u25BD", "\\triangledown");
 836  defineSymbol(math, textord, "\u25CA", "\\lozenge");
 837  defineSymbol(math, textord, "\u24C8", "\\circledS");
 838  defineSymbol(math, textord, "\xAE", "\\circledR", true);
 839  defineSymbol(text, textord, "\xAE", "\\circledR");
 840  defineSymbol(text, textord, "\xAE", "\\textregistered");
 841  defineSymbol(math, textord, "\u2221", "\\measuredangle", true);
 842  defineSymbol(math, textord, "\u2204", "\\nexists");
 843  defineSymbol(math, textord, "\u2127", "\\mho");
 844  defineSymbol(math, textord, "\u2132", "\\Finv", true);
 845  defineSymbol(math, textord, "\u2141", "\\Game", true);
 846  defineSymbol(math, textord, "\u2035", "\\backprime");
 847  defineSymbol(math, textord, "\u2036", "\\backdprime");
 848  defineSymbol(math, textord, "\u2037", "\\backtrprime");
 849  defineSymbol(math, textord, "\u25B2", "\\blacktriangle");
 850  defineSymbol(math, textord, "\u25BC", "\\blacktriangledown");
 851  defineSymbol(math, textord, "\u25A0", "\\blacksquare");
 852  defineSymbol(math, textord, "\u29EB", "\\blacklozenge");
 853  defineSymbol(math, textord, "\u2605", "\\bigstar");
 854  defineSymbol(math, textord, "\u2222", "\\sphericalangle", true);
 855  defineSymbol(math, textord, "\u2201", "\\complement", true);
 856  defineSymbol(math, textord, "\xF0", "\\eth", true);
 857  defineSymbol(text, textord, "\xF0", "\xF0");
 858  defineSymbol(math, textord, "\u2571", "\\diagup");
 859  defineSymbol(math, textord, "\u2572", "\\diagdown");
 860  defineSymbol(math, textord, "\u25A1", "\\square");
 861  defineSymbol(math, textord, "\u25A1", "\\Box");
 862  defineSymbol(math, textord, "\u25CA", "\\Diamond");
 863  defineSymbol(math, textord, "\xA5", "\\yen", true);
 864  defineSymbol(text, textord, "\xA5", "\\yen", true);
 865  defineSymbol(math, textord, "\u2713", "\\checkmark", true);
 866  defineSymbol(text, textord, "\u2713", "\\checkmark");
 867  defineSymbol(math, textord, "\u2717", "\\ballotx", true);
 868  defineSymbol(text, textord, "\u2717", "\\ballotx");
 869  defineSymbol(text, textord, "\u2022", "\\textbullet");
 870  defineSymbol(math, textord, "\u2136", "\\beth", true);
 871  defineSymbol(math, textord, "\u2138", "\\daleth", true);
 872  defineSymbol(math, textord, "\u2137", "\\gimel", true);
 873  defineSymbol(math, textord, "\u03DD", "\\digamma", true);
 874  defineSymbol(math, textord, "\u03F0", "\\varkappa");
 875  defineSymbol(math, open, "\u231C", "\\ulcorner", true);
 876  defineSymbol(math, close, "\u231D", "\\urcorner", true);
 877  defineSymbol(math, open, "\u231E", "\\llcorner", true);
 878  defineSymbol(math, close, "\u231F", "\\lrcorner", true);
 879  defineSymbol(math, rel, "\u2266", "\\leqq", true);
 880  defineSymbol(math, rel, "\u2A7D", "\\leqslant", true);
 881  defineSymbol(math, rel, "\u2A95", "\\eqslantless", true);
 882  defineSymbol(math, rel, "\u2272", "\\lesssim", true);
 883  defineSymbol(math, rel, "\u2A85", "\\lessapprox", true);
 884  defineSymbol(math, rel, "\u224A", "\\approxeq", true);
 885  defineSymbol(math, bin, "\u22D6", "\\lessdot");
 886  defineSymbol(math, rel, "\u22D8", "\\lll", true);
 887  defineSymbol(math, rel, "\u2276", "\\lessgtr", true);
 888  defineSymbol(math, rel, "\u22DA", "\\lesseqgtr", true);
 889  defineSymbol(math, rel, "\u2A8B", "\\lesseqqgtr", true);
 890  defineSymbol(math, rel, "\u2251", "\\doteqdot");
 891  defineSymbol(math, rel, "\u2253", "\\risingdotseq", true);
 892  defineSymbol(math, rel, "\u2252", "\\fallingdotseq", true);
 893  defineSymbol(math, rel, "\u223D", "\\backsim", true);
 894  defineSymbol(math, rel, "\u22CD", "\\backsimeq", true);
 895  defineSymbol(math, rel, "\u2AC5", "\\subseteqq", true);
 896  defineSymbol(math, rel, "\u22D0", "\\Subset", true);
 897  defineSymbol(math, rel, "\u228F", "\\sqsubset", true);
 898  defineSymbol(math, rel, "\u227C", "\\preccurlyeq", true);
 899  defineSymbol(math, rel, "\u22DE", "\\curlyeqprec", true);
 900  defineSymbol(math, rel, "\u227E", "\\precsim", true);
 901  defineSymbol(math, rel, "\u2AB7", "\\precapprox", true);
 902  defineSymbol(math, rel, "\u22B2", "\\vartriangleleft");
 903  defineSymbol(math, rel, "\u22B4", "\\trianglelefteq");
 904  defineSymbol(math, rel, "\u22A8", "\\vDash", true);
 905  defineSymbol(math, rel, "\u22AB", "\\VDash", true);
 906  defineSymbol(math, rel, "\u22AA", "\\Vvdash", true);
 907  defineSymbol(math, rel, "\u2323", "\\smallsmile");
 908  defineSymbol(math, rel, "\u2322", "\\smallfrown");
 909  defineSymbol(math, rel, "\u224F", "\\bumpeq", true);
 910  defineSymbol(math, rel, "\u224E", "\\Bumpeq", true);
 911  defineSymbol(math, rel, "\u2267", "\\geqq", true);
 912  defineSymbol(math, rel, "\u2A7E", "\\geqslant", true);
 913  defineSymbol(math, rel, "\u2A96", "\\eqslantgtr", true);
 914  defineSymbol(math, rel, "\u2273", "\\gtrsim", true);
 915  defineSymbol(math, rel, "\u2A86", "\\gtrapprox", true);
 916  defineSymbol(math, bin, "\u22D7", "\\gtrdot");
 917  defineSymbol(math, rel, "\u22D9", "\\ggg", true);
 918  defineSymbol(math, rel, "\u2277", "\\gtrless", true);
 919  defineSymbol(math, rel, "\u22DB", "\\gtreqless", true);
 920  defineSymbol(math, rel, "\u2A8C", "\\gtreqqless", true);
 921  defineSymbol(math, rel, "\u2256", "\\eqcirc", true);
 922  defineSymbol(math, rel, "\u2257", "\\circeq", true);
 923  defineSymbol(math, rel, "\u225C", "\\triangleq", true);
 924  defineSymbol(math, rel, "\u223C", "\\thicksim");
 925  defineSymbol(math, rel, "\u2248", "\\thickapprox");
 926  defineSymbol(math, rel, "\u2AC6", "\\supseteqq", true);
 927  defineSymbol(math, rel, "\u22D1", "\\Supset", true);
 928  defineSymbol(math, rel, "\u2290", "\\sqsupset", true);
 929  defineSymbol(math, rel, "\u227D", "\\succcurlyeq", true);
 930  defineSymbol(math, rel, "\u22DF", "\\curlyeqsucc", true);
 931  defineSymbol(math, rel, "\u227F", "\\succsim", true);
 932  defineSymbol(math, rel, "\u2AB8", "\\succapprox", true);
 933  defineSymbol(math, rel, "\u22B3", "\\vartriangleright");
 934  defineSymbol(math, rel, "\u22B5", "\\trianglerighteq");
 935  defineSymbol(math, rel, "\u22A9", "\\Vdash", true);
 936  defineSymbol(math, rel, "\u2223", "\\shortmid");
 937  defineSymbol(math, rel, "\u2225", "\\shortparallel");
 938  defineSymbol(math, rel, "\u226C", "\\between", true);
 939  defineSymbol(math, rel, "\u22D4", "\\pitchfork", true);
 940  defineSymbol(math, rel, "\u221D", "\\varpropto");
 941  defineSymbol(math, rel, "\u25C0", "\\blacktriangleleft");
 942  defineSymbol(math, rel, "\u2234", "\\therefore", true);
 943  defineSymbol(math, rel, "\u220D", "\\backepsilon");
 944  defineSymbol(math, rel, "\u25B6", "\\blacktriangleright");
 945  defineSymbol(math, rel, "\u2235", "\\because", true);
 946  defineSymbol(math, rel, "\u22D8", "\\llless");
 947  defineSymbol(math, rel, "\u22D9", "\\gggtr");
 948  defineSymbol(math, bin, "\u22B2", "\\lhd");
 949  defineSymbol(math, bin, "\u22B3", "\\rhd");
 950  defineSymbol(math, rel, "\u2242", "\\eqsim", true);
 951  defineSymbol(math, rel, "\u2251", "\\Doteq", true);
 952  defineSymbol(math, rel, "\u297D", "\\strictif", true);
 953  defineSymbol(math, rel, "\u297C", "\\strictfi", true);
 954  defineSymbol(math, bin, "\u2214", "\\dotplus", true);
 955  defineSymbol(math, bin, "\u2216", "\\smallsetminus");
 956  defineSymbol(math, bin, "\u22D2", "\\Cap", true);
 957  defineSymbol(math, bin, "\u22D3", "\\Cup", true);
 958  defineSymbol(math, bin, "\u2A5E", "\\doublebarwedge", true);
 959  defineSymbol(math, bin, "\u229F", "\\boxminus", true);
 960  defineSymbol(math, bin, "\u229E", "\\boxplus", true);
 961  defineSymbol(math, bin, "\u29C4", "\\boxslash", true);
 962  defineSymbol(math, bin, "\u22C7", "\\divideontimes", true);
 963  defineSymbol(math, bin, "\u22C9", "\\ltimes", true);
 964  defineSymbol(math, bin, "\u22CA", "\\rtimes", true);
 965  defineSymbol(math, bin, "\u22CB", "\\leftthreetimes", true);
 966  defineSymbol(math, bin, "\u22CC", "\\rightthreetimes", true);
 967  defineSymbol(math, bin, "\u22CF", "\\curlywedge", true);
 968  defineSymbol(math, bin, "\u22CE", "\\curlyvee", true);
 969  defineSymbol(math, bin, "\u229D", "\\circleddash", true);
 970  defineSymbol(math, bin, "\u229B", "\\circledast", true);
 971  defineSymbol(math, bin, "\u22BA", "\\intercal", true);
 972  defineSymbol(math, bin, "\u22D2", "\\doublecap");
 973  defineSymbol(math, bin, "\u22D3", "\\doublecup");
 974  defineSymbol(math, bin, "\u22A0", "\\boxtimes", true);
 975  defineSymbol(math, bin, "\u22C8", "\\bowtie", true);
 976  defineSymbol(math, bin, "\u22C8", "\\Join");
 977  defineSymbol(math, bin, "\u27D5", "\\leftouterjoin", true);
 978  defineSymbol(math, bin, "\u27D6", "\\rightouterjoin", true);
 979  defineSymbol(math, bin, "\u27D7", "\\fullouterjoin", true);
 980  defineSymbol(math, bin, "\u2238", "\\dotminus", true);
 981  defineSymbol(math, bin, "\u27D1", "\\wedgedot", true);
 982  defineSymbol(math, bin, "\u27C7", "\\veedot", true);
 983  defineSymbol(math, bin, "\u2A62", "\\doublebarvee", true);
 984  defineSymbol(math, bin, "\u2A63", "\\veedoublebar", true);
 985  defineSymbol(math, bin, "\u2A5F", "\\wedgebar", true);
 986  defineSymbol(math, bin, "\u2A60", "\\wedgedoublebar", true);
 987  defineSymbol(math, bin, "\u2A54", "\\Vee", true);
 988  defineSymbol(math, bin, "\u2A53", "\\Wedge", true);
 989  defineSymbol(math, bin, "\u2A43", "\\barcap", true);
 990  defineSymbol(math, bin, "\u2A42", "\\barcup", true);
 991  defineSymbol(math, bin, "\u2A48", "\\capbarcup", true);
 992  defineSymbol(math, bin, "\u2A40", "\\capdot", true);
 993  defineSymbol(math, bin, "\u2A47", "\\capovercup", true);
 994  defineSymbol(math, bin, "\u2A46", "\\cupovercap", true);
 995  defineSymbol(math, bin, "\u2A4D", "\\closedvarcap", true);
 996  defineSymbol(math, bin, "\u2A4C", "\\closedvarcup", true);
 997  defineSymbol(math, bin, "\u2A2A", "\\minusdot", true);
 998  defineSymbol(math, bin, "\u2A2B", "\\minusfdots", true);
 999  defineSymbol(math, bin, "\u2A2C", "\\minusrdots", true);
1000  defineSymbol(math, bin, "\u22BB", "\\Xor", true);
1001  defineSymbol(math, bin, "\u22BC", "\\Nand", true);
1002  defineSymbol(math, bin, "\u22BD", "\\Nor", true);
1003  defineSymbol(math, bin, "\u22BD", "\\barvee");
1004  defineSymbol(math, bin, "\u2AF4", "\\interleave", true);
1005  defineSymbol(math, bin, "\u29E2", "\\shuffle", true);
1006  defineSymbol(math, bin, "\u2AF6", "\\threedotcolon", true);
1007  defineSymbol(math, bin, "\u2982", "\\typecolon", true);
1008  defineSymbol(math, bin, "\u223E", "\\invlazys", true);
1009  defineSymbol(math, bin, "\u2A4B", "\\twocaps", true);
1010  defineSymbol(math, bin, "\u2A4A", "\\twocups", true);
1011  defineSymbol(math, bin, "\u2A4E", "\\Sqcap", true);
1012  defineSymbol(math, bin, "\u2A4F", "\\Sqcup", true);
1013  defineSymbol(math, bin, "\u2A56", "\\veeonvee", true);
1014  defineSymbol(math, bin, "\u2A55", "\\wedgeonwedge", true);
1015  defineSymbol(math, bin, "\u29D7", "\\blackhourglass", true);
1016  defineSymbol(math, bin, "\u29C6", "\\boxast", true);
1017  defineSymbol(math, bin, "\u29C8", "\\boxbox", true);
1018  defineSymbol(math, bin, "\u29C7", "\\boxcircle", true);
1019  defineSymbol(math, bin, "\u229C", "\\circledequal", true);
1020  defineSymbol(math, bin, "\u29B7", "\\circledparallel", true);
1021  defineSymbol(math, bin, "\u29B6", "\\circledvert", true);
1022  defineSymbol(math, bin, "\u29B5", "\\circlehbar", true);
1023  defineSymbol(math, bin, "\u27E1", "\\concavediamond", true);
1024  defineSymbol(math, bin, "\u27E2", "\\concavediamondtickleft", true);
1025  defineSymbol(math, bin, "\u27E3", "\\concavediamondtickright", true);
1026  defineSymbol(math, bin, "\u22C4", "\\diamond", true);
1027  defineSymbol(math, bin, "\u29D6", "\\hourglass", true);
1028  defineSymbol(math, bin, "\u27E0", "\\lozengeminus", true);
1029  defineSymbol(math, bin, "\u233D", "\\obar", true);
1030  defineSymbol(math, bin, "\u29B8", "\\obslash", true);
1031  defineSymbol(math, bin, "\u2A38", "\\odiv", true);
1032  defineSymbol(math, bin, "\u29C1", "\\ogreaterthan", true);
1033  defineSymbol(math, bin, "\u29C0", "\\olessthan", true);
1034  defineSymbol(math, bin, "\u29B9", "\\operp", true);
1035  defineSymbol(math, bin, "\u2A37", "\\Otimes", true);
1036  defineSymbol(math, bin, "\u2A36", "\\otimeshat", true);
1037  defineSymbol(math, bin, "\u22C6", "\\star", true);
1038  defineSymbol(math, bin, "\u25B3", "\\triangle", true);
1039  defineSymbol(math, bin, "\u2A3A", "\\triangleminus", true);
1040  defineSymbol(math, bin, "\u2A39", "\\triangleplus", true);
1041  defineSymbol(math, bin, "\u2A3B", "\\triangletimes", true);
1042  defineSymbol(math, bin, "\u27E4", "\\whitesquaretickleft", true);
1043  defineSymbol(math, bin, "\u27E5", "\\whitesquaretickright", true);
1044  defineSymbol(math, bin, "\u2A33", "\\smashtimes", true);
1045  defineSymbol(math, rel, "\u21E2", "\\dashrightarrow", true);
1046  defineSymbol(math, rel, "\u21E0", "\\dashleftarrow", true);
1047  defineSymbol(math, rel, "\u21C7", "\\leftleftarrows", true);
1048  defineSymbol(math, rel, "\u21C6", "\\leftrightarrows", true);
1049  defineSymbol(math, rel, "\u21DA", "\\Lleftarrow", true);
1050  defineSymbol(math, rel, "\u219E", "\\twoheadleftarrow", true);
1051  defineSymbol(math, rel, "\u21A2", "\\leftarrowtail", true);
1052  defineSymbol(math, rel, "\u21AB", "\\looparrowleft", true);
1053  defineSymbol(math, rel, "\u21CB", "\\leftrightharpoons", true);
1054  defineSymbol(math, rel, "\u21B6", "\\curvearrowleft", true);
1055  defineSymbol(math, rel, "\u21BA", "\\circlearrowleft", true);
1056  defineSymbol(math, rel, "\u21B0", "\\Lsh", true);
1057  defineSymbol(math, rel, "\u21C8", "\\upuparrows", true);
1058  defineSymbol(math, rel, "\u21BF", "\\upharpoonleft", true);
1059  defineSymbol(math, rel, "\u21C3", "\\downharpoonleft", true);
1060  defineSymbol(math, rel, "\u22B6", "\\origof", true);
1061  defineSymbol(math, rel, "\u22B7", "\\imageof", true);
1062  defineSymbol(math, rel, "\u22B8", "\\multimap", true);
1063  defineSymbol(math, rel, "\u21AD", "\\leftrightsquigarrow", true);
1064  defineSymbol(math, rel, "\u21C9", "\\rightrightarrows", true);
1065  defineSymbol(math, rel, "\u21C4", "\\rightleftarrows", true);
1066  defineSymbol(math, rel, "\u21A0", "\\twoheadrightarrow", true);
1067  defineSymbol(math, rel, "\u21A3", "\\rightarrowtail", true);
1068  defineSymbol(math, rel, "\u21AC", "\\looparrowright", true);
1069  defineSymbol(math, rel, "\u21B7", "\\curvearrowright", true);
1070  defineSymbol(math, rel, "\u21BB", "\\circlearrowright", true);
1071  defineSymbol(math, rel, "\u21B1", "\\Rsh", true);
1072  defineSymbol(math, rel, "\u21CA", "\\downdownarrows", true);
1073  defineSymbol(math, rel, "\u21BE", "\\upharpoonright", true);
1074  defineSymbol(math, rel, "\u21C2", "\\downharpoonright", true);
1075  defineSymbol(math, rel, "\u21DD", "\\rightsquigarrow", true);
1076  defineSymbol(math, rel, "\u21DD", "\\leadsto");
1077  defineSymbol(math, rel, "\u21DB", "\\Rrightarrow", true);
1078  defineSymbol(math, rel, "\u21BE", "\\restriction");
1079  defineSymbol(math, textord, "\u2018", "`");
1080  defineSymbol(math, textord, "$", "\\$");
1081  defineSymbol(text, textord, "$", "\\$");
1082  defineSymbol(text, textord, "$", "\\textdollar");
1083  defineSymbol(math, textord, "\xA2", "\\cent");
1084  defineSymbol(text, textord, "\xA2", "\\cent");
1085  defineSymbol(math, textord, "%", "\\%");
1086  defineSymbol(text, textord, "%", "\\%");
1087  defineSymbol(math, textord, "_", "\\_");
1088  defineSymbol(text, textord, "_", "\\_");
1089  defineSymbol(text, textord, "_", "\\textunderscore");
1090  defineSymbol(text, textord, "\u2423", "\\textvisiblespace", true);
1091  defineSymbol(math, textord, "\u2220", "\\angle", true);
1092  defineSymbol(math, textord, "\u221E", "\\infty", true);
1093  defineSymbol(math, textord, "\u2032", "\\prime");
1094  defineSymbol(math, textord, "\u2033", "\\dprime");
1095  defineSymbol(math, textord, "\u2034", "\\trprime");
1096  defineSymbol(math, textord, "\u2057", "\\qprime");
1097  defineSymbol(math, textord, "\u25B3", "\\triangle");
1098  defineSymbol(text, textord, "\u0391", "\\Alpha", true);
1099  defineSymbol(text, textord, "\u0392", "\\Beta", true);
1100  defineSymbol(text, textord, "\u0393", "\\Gamma", true);
1101  defineSymbol(text, textord, "\u0394", "\\Delta", true);
1102  defineSymbol(text, textord, "\u0395", "\\Epsilon", true);
1103  defineSymbol(text, textord, "\u0396", "\\Zeta", true);
1104  defineSymbol(text, textord, "\u0397", "\\Eta", true);
1105  defineSymbol(text, textord, "\u0398", "\\Theta", true);
1106  defineSymbol(text, textord, "\u0399", "\\Iota", true);
1107  defineSymbol(text, textord, "\u039A", "\\Kappa", true);
1108  defineSymbol(text, textord, "\u039B", "\\Lambda", true);
1109  defineSymbol(text, textord, "\u039C", "\\Mu", true);
1110  defineSymbol(text, textord, "\u039D", "\\Nu", true);
1111  defineSymbol(text, textord, "\u039E", "\\Xi", true);
1112  defineSymbol(text, textord, "\u039F", "\\Omicron", true);
1113  defineSymbol(text, textord, "\u03A0", "\\Pi", true);
1114  defineSymbol(text, textord, "\u03A1", "\\Rho", true);
1115  defineSymbol(text, textord, "\u03A3", "\\Sigma", true);
1116  defineSymbol(text, textord, "\u03A4", "\\Tau", true);
1117  defineSymbol(text, textord, "\u03A5", "\\Upsilon", true);
1118  defineSymbol(text, textord, "\u03A6", "\\Phi", true);
1119  defineSymbol(text, textord, "\u03A7", "\\Chi", true);
1120  defineSymbol(text, textord, "\u03A8", "\\Psi", true);
1121  defineSymbol(text, textord, "\u03A9", "\\Omega", true);
1122  defineSymbol(math, mathord, "\u0391", "\\Alpha", true);
1123  defineSymbol(math, mathord, "\u0392", "\\Beta", true);
1124  defineSymbol(math, mathord, "\u0393", "\\Gamma", true);
1125  defineSymbol(math, mathord, "\u0394", "\\Delta", true);
1126  defineSymbol(math, mathord, "\u0395", "\\Epsilon", true);
1127  defineSymbol(math, mathord, "\u0396", "\\Zeta", true);
1128  defineSymbol(math, mathord, "\u0397", "\\Eta", true);
1129  defineSymbol(math, mathord, "\u0398", "\\Theta", true);
1130  defineSymbol(math, mathord, "\u0399", "\\Iota", true);
1131  defineSymbol(math, mathord, "\u039A", "\\Kappa", true);
1132  defineSymbol(math, mathord, "\u039B", "\\Lambda", true);
1133  defineSymbol(math, mathord, "\u039C", "\\Mu", true);
1134  defineSymbol(math, mathord, "\u039D", "\\Nu", true);
1135  defineSymbol(math, mathord, "\u039E", "\\Xi", true);
1136  defineSymbol(math, mathord, "\u039F", "\\Omicron", true);
1137  defineSymbol(math, mathord, "\u03A0", "\\Pi", true);
1138  defineSymbol(math, mathord, "\u03A1", "\\Rho", true);
1139  defineSymbol(math, mathord, "\u03A3", "\\Sigma", true);
1140  defineSymbol(math, mathord, "\u03A4", "\\Tau", true);
1141  defineSymbol(math, mathord, "\u03A5", "\\Upsilon", true);
1142  defineSymbol(math, mathord, "\u03A6", "\\Phi", true);
1143  defineSymbol(math, mathord, "\u03A7", "\\Chi", true);
1144  defineSymbol(math, mathord, "\u03A8", "\\Psi", true);
1145  defineSymbol(math, mathord, "\u03A9", "\\Omega", true);
1146  defineSymbol(math, open, "\xAC", "\\neg", true);
1147  defineSymbol(math, open, "\xAC", "\\lnot");
1148  defineSymbol(math, textord, "\u22A4", "\\top");
1149  defineSymbol(math, textord, "\u22A5", "\\bot");
1150  defineSymbol(math, textord, "\u2205", "\\emptyset");
1151  defineSymbol(math, textord, "\u2300", "\\varnothing");
1152  defineSymbol(math, mathord, "\u03B1", "\\alpha", true);
1153  defineSymbol(math, mathord, "\u03B2", "\\beta", true);
1154  defineSymbol(math, mathord, "\u03B3", "\\gamma", true);
1155  defineSymbol(math, mathord, "\u03B4", "\\delta", true);
1156  defineSymbol(math, mathord, "\u03F5", "\\epsilon", true);
1157  defineSymbol(math, mathord, "\u03B6", "\\zeta", true);
1158  defineSymbol(math, mathord, "\u03B7", "\\eta", true);
1159  defineSymbol(math, mathord, "\u03B8", "\\theta", true);
1160  defineSymbol(math, mathord, "\u03B9", "\\iota", true);
1161  defineSymbol(math, mathord, "\u03BA", "\\kappa", true);
1162  defineSymbol(math, mathord, "\u03BB", "\\lambda", true);
1163  defineSymbol(math, mathord, "\u03BC", "\\mu", true);
1164  defineSymbol(math, mathord, "\u03BD", "\\nu", true);
1165  defineSymbol(math, mathord, "\u03BE", "\\xi", true);
1166  defineSymbol(math, mathord, "\u03BF", "\\omicron", true);
1167  defineSymbol(math, mathord, "\u03C0", "\\pi", true);
1168  defineSymbol(math, mathord, "\u03C1", "\\rho", true);
1169  defineSymbol(math, mathord, "\u03C3", "\\sigma", true);
1170  defineSymbol(math, mathord, "\u03C4", "\\tau", true);
1171  defineSymbol(math, mathord, "\u03C5", "\\upsilon", true);
1172  defineSymbol(math, mathord, "\u03D5", "\\phi", true);
1173  defineSymbol(math, mathord, "\u03C7", "\\chi", true);
1174  defineSymbol(math, mathord, "\u03C8", "\\psi", true);
1175  defineSymbol(math, mathord, "\u03C9", "\\omega", true);
1176  defineSymbol(math, mathord, "\u03B5", "\\varepsilon", true);
1177  defineSymbol(math, mathord, "\u03D1", "\\vartheta", true);
1178  defineSymbol(math, mathord, "\u03D6", "\\varpi", true);
1179  defineSymbol(math, mathord, "\u03F1", "\\varrho", true);
1180  defineSymbol(math, mathord, "\u03C2", "\\varsigma", true);
1181  defineSymbol(math, mathord, "\u03C6", "\\varphi", true);
1182  defineSymbol(math, mathord, "\u03D8", "\\Coppa", true);
1183  defineSymbol(math, mathord, "\u03D9", "\\coppa", true);
1184  defineSymbol(math, mathord, "\u03D9", "\\varcoppa", true);
1185  defineSymbol(math, mathord, "\u03DE", "\\Koppa", true);
1186  defineSymbol(math, mathord, "\u03DF", "\\koppa", true);
1187  defineSymbol(math, mathord, "\u03E0", "\\Sampi", true);
1188  defineSymbol(math, mathord, "\u03E1", "\\sampi", true);
1189  defineSymbol(math, mathord, "\u03DA", "\\Stigma", true);
1190  defineSymbol(math, mathord, "\u03DB", "\\stigma", true);
1191  defineSymbol(math, mathord, "\u2AEB", "\\Bot");
1192  defineSymbol(math, bin, "\u2217", "\u2217", true);
1193  defineSymbol(math, bin, "+", "+");
1194  defineSymbol(math, bin, "\u2217", "*");
1195  defineSymbol(math, bin, "\u2044", "/", true);
1196  defineSymbol(math, bin, "\u2044", "\u2044");
1197  defineSymbol(math, bin, "\u2212", "-", true);
1198  defineSymbol(math, bin, "\u22C5", "\\cdot", true);
1199  defineSymbol(math, bin, "\u2218", "\\circ", true);
1200  defineSymbol(math, bin, "\xF7", "\\div", true);
1201  defineSymbol(math, bin, "\xB1", "\\pm", true);
1202  defineSymbol(math, bin, "\xD7", "\\times", true);
1203  defineSymbol(math, bin, "\u2229", "\\cap", true);
1204  defineSymbol(math, bin, "\u222A", "\\cup", true);
1205  defineSymbol(math, bin, "\u2216", "\\setminus", true);
1206  defineSymbol(math, bin, "\u2227", "\\land");
1207  defineSymbol(math, bin, "\u2228", "\\lor");
1208  defineSymbol(math, bin, "\u2227", "\\wedge", true);
1209  defineSymbol(math, bin, "\u2228", "\\vee", true);
1210  defineSymbol(math, open, "\u27E6", "\\llbracket", true);
1211  defineSymbol(math, close, "\u27E7", "\\rrbracket", true);
1212  defineSymbol(math, open, "\u27E8", "\\langle", true);
1213  defineSymbol(math, open, "\u27EA", "\\lAngle", true);
1214  defineSymbol(math, open, "\u2989", "\\llangle", true);
1215  defineSymbol(math, open, "|", "\\lvert");
1216  defineSymbol(math, open, "\u2016", "\\lVert", true);
1217  defineSymbol(math, textord, "!", "\\oc");
1218  defineSymbol(math, textord, "?", "\\wn");
1219  defineSymbol(math, textord, "\u2193", "\\shpos");
1220  defineSymbol(math, textord, "\u2195", "\\shift");
1221  defineSymbol(math, textord, "\u2191", "\\shneg");
1222  defineSymbol(math, close, "?", "?");
1223  defineSymbol(math, close, "!", "!");
1224  defineSymbol(math, close, "\u203C", "\u203C");
1225  defineSymbol(math, close, "\u27E9", "\\rangle", true);
1226  defineSymbol(math, close, "\u27EB", "\\rAngle", true);
1227  defineSymbol(math, close, "\u298A", "\\rrangle", true);
1228  defineSymbol(math, close, "|", "\\rvert");
1229  defineSymbol(math, close, "\u2016", "\\rVert");
1230  defineSymbol(math, open, "\u2983", "\\lBrace", true);
1231  defineSymbol(math, close, "\u2984", "\\rBrace", true);
1232  defineSymbol(math, rel, "=", "\\equal", true);
1233  defineSymbol(math, rel, ":", ":");
1234  defineSymbol(math, rel, "\u2248", "\\approx", true);
1235  defineSymbol(math, rel, "\u2245", "\\cong", true);
1236  defineSymbol(math, rel, "\u2265", "\\ge");
1237  defineSymbol(math, rel, "\u2265", "\\geq", true);
1238  defineSymbol(math, rel, "\u2190", "\\gets");
1239  defineSymbol(math, rel, ">", "\\gt", true);
1240  defineSymbol(math, rel, "\u2208", "\\in", true);
1241  defineSymbol(math, rel, "\u2209", "\\notin", true);
1242  defineSymbol(math, rel, "\uE020", "\\@not");
1243  defineSymbol(math, rel, "\u2282", "\\subset", true);
1244  defineSymbol(math, rel, "\u2283", "\\supset", true);
1245  defineSymbol(math, rel, "\u2286", "\\subseteq", true);
1246  defineSymbol(math, rel, "\u2287", "\\supseteq", true);
1247  defineSymbol(math, rel, "\u2288", "\\nsubseteq", true);
1248  defineSymbol(math, rel, "\u2288", "\\nsubseteqq");
1249  defineSymbol(math, rel, "\u2289", "\\nsupseteq", true);
1250  defineSymbol(math, rel, "\u2289", "\\nsupseteqq");
1251  defineSymbol(math, rel, "\u22A8", "\\models");
1252  defineSymbol(math, rel, "\u2190", "\\leftarrow", true);
1253  defineSymbol(math, rel, "\u2264", "\\le");
1254  defineSymbol(math, rel, "\u2264", "\\leq", true);
1255  defineSymbol(math, rel, "<", "\\lt", true);
1256  defineSymbol(math, rel, "\u2192", "\\rightarrow", true);
1257  defineSymbol(math, rel, "\u2192", "\\to");
1258  defineSymbol(math, rel, "\u2271", "\\ngeq", true);
1259  defineSymbol(math, rel, "\u2271", "\\ngeqq");
1260  defineSymbol(math, rel, "\u2271", "\\ngeqslant");
1261  defineSymbol(math, rel, "\u2270", "\\nleq", true);
1262  defineSymbol(math, rel, "\u2270", "\\nleqq");
1263  defineSymbol(math, rel, "\u2270", "\\nleqslant");
1264  defineSymbol(math, rel, "\u2AEB", "\\Perp", true);
1265  defineSymbol(math, spacing, "\xA0", "\\ ");
1266  defineSymbol(math, spacing, "\xA0", "\\space");
1267  defineSymbol(math, spacing, "\xA0", "\\nobreakspace");
1268  defineSymbol(text, spacing, "\xA0", "\\ ");
1269  defineSymbol(text, spacing, "\xA0", " ");
1270  defineSymbol(text, spacing, "\xA0", "\\space");
1271  defineSymbol(text, spacing, "\xA0", "\\nobreakspace");
1272  defineSymbol(math, spacing, null, "\\nobreak");
1273  defineSymbol(math, spacing, null, "\\allowbreak");
1274  defineSymbol(math, punct, ",", ",");
1275  defineSymbol(text, punct, ":", ":");
1276  defineSymbol(math, punct, ";", ";");
1277  defineSymbol(math, bin, "\u22BC", "\\barwedge");
1278  defineSymbol(math, bin, "\u22BB", "\\veebar");
1279  defineSymbol(math, bin, "\u2299", "\\odot", true);
1280  defineSymbol(math, bin, "\u2295\uFE0E", "\\oplus");
1281  defineSymbol(math, bin, "\u2297", "\\otimes", true);
1282  defineSymbol(math, textord, "\u2202", "\\partial", true);
1283  defineSymbol(math, bin, "\u2298", "\\oslash", true);
1284  defineSymbol(math, bin, "\u229A", "\\circledcirc", true);
1285  defineSymbol(math, bin, "\u22A1", "\\boxdot", true);
1286  defineSymbol(math, bin, "\u25B3", "\\bigtriangleup");
1287  defineSymbol(math, bin, "\u25BD", "\\bigtriangledown");
1288  defineSymbol(math, bin, "\u2020", "\\dagger");
1289  defineSymbol(math, bin, "\u22C4", "\\diamond");
1290  defineSymbol(math, bin, "\u25C3", "\\triangleleft");
1291  defineSymbol(math, bin, "\u25B9", "\\triangleright");
1292  defineSymbol(math, open, "{", "\\{");
1293  defineSymbol(text, textord, "{", "\\{");
1294  defineSymbol(text, textord, "{", "\\textbraceleft");
1295  defineSymbol(math, close, "}", "\\}");
1296  defineSymbol(text, textord, "}", "\\}");
1297  defineSymbol(text, textord, "}", "\\textbraceright");
1298  defineSymbol(math, open, "{", "\\lbrace");
1299  defineSymbol(math, close, "}", "\\rbrace");
1300  defineSymbol(math, open, "[", "\\lbrack", true);
1301  defineSymbol(text, textord, "[", "\\lbrack", true);
1302  defineSymbol(math, close, "]", "\\rbrack", true);
1303  defineSymbol(text, textord, "]", "\\rbrack", true);
1304  defineSymbol(math, open, "(", "\\lparen", true);
1305  defineSymbol(math, close, ")", "\\rparen", true);
1306  defineSymbol(math, open, "\u2987", "\\llparenthesis", true);
1307  defineSymbol(math, close, "\u2988", "\\rrparenthesis", true);
1308  defineSymbol(text, textord, "<", "\\textless", true);
1309  defineSymbol(text, textord, ">", "\\textgreater", true);
1310  defineSymbol(math, open, "\u230A", "\\lfloor", true);
1311  defineSymbol(math, close, "\u230B", "\\rfloor", true);
1312  defineSymbol(math, open, "\u2308", "\\lceil", true);
1313  defineSymbol(math, close, "\u2309", "\\rceil", true);
1314  defineSymbol(math, textord, "\\", "\\backslash");
1315  defineSymbol(math, textord, "|", "|");
1316  defineSymbol(math, textord, "|", "\\vert");
1317  defineSymbol(text, textord, "|", "\\textbar", true);
1318  defineSymbol(math, textord, "\u2016", "\\|");
1319  defineSymbol(math, textord, "\u2016", "\\Vert");
1320  defineSymbol(text, textord, "\u2016", "\\textbardbl");
1321  defineSymbol(text, textord, "~", "\\textasciitilde");
1322  defineSymbol(text, textord, "\\", "\\textbackslash");
1323  defineSymbol(text, textord, "^", "\\textasciicircum");
1324  defineSymbol(math, rel, "\u2191", "\\uparrow", true);
1325  defineSymbol(math, rel, "\u21D1", "\\Uparrow", true);
1326  defineSymbol(math, rel, "\u2193", "\\downarrow", true);
1327  defineSymbol(math, rel, "\u21D3", "\\Downarrow", true);
1328  defineSymbol(math, rel, "\u2195", "\\updownarrow", true);
1329  defineSymbol(math, rel, "\u21D5", "\\Updownarrow", true);
1330  defineSymbol(math, op, "\u2210", "\\coprod");
1331  defineSymbol(math, op, "\u22C1", "\\bigvee");
1332  defineSymbol(math, op, "\u22C0", "\\bigwedge");
1333  defineSymbol(math, op, "\u2A04", "\\biguplus");
1334  defineSymbol(math, op, "\u2A04", "\\bigcupplus");
1335  defineSymbol(math, op, "\u2A03", "\\bigcupdot");
1336  defineSymbol(math, op, "\u2A07", "\\bigdoublevee");
1337  defineSymbol(math, op, "\u2A08", "\\bigdoublewedge");
1338  defineSymbol(math, op, "\u22C2", "\\bigcap");
1339  defineSymbol(math, op, "\u22C3", "\\bigcup");
1340  defineSymbol(math, op, "\u222B", "\\int");
1341  defineSymbol(math, op, "\u222B", "\\intop");
1342  defineSymbol(math, op, "\u222C", "\\iint");
1343  defineSymbol(math, op, "\u222D", "\\iiint");
1344  defineSymbol(math, op, "\u220F", "\\prod");
1345  defineSymbol(math, op, "\u2211", "\\sum");
1346  defineSymbol(math, op, "\u2A02", "\\bigotimes");
1347  defineSymbol(math, op, "\u2A01", "\\bigoplus");
1348  defineSymbol(math, op, "\u2A00", "\\bigodot");
1349  defineSymbol(math, op, "\u2A09", "\\bigtimes");
1350  defineSymbol(math, op, "\u222E", "\\oint");
1351  defineSymbol(math, op, "\u222F", "\\oiint");
1352  defineSymbol(math, op, "\u2230", "\\oiiint");
1353  defineSymbol(math, op, "\u2231", "\\intclockwise");
1354  defineSymbol(math, op, "\u2232", "\\varointclockwise");
1355  defineSymbol(math, op, "\u2A0C", "\\iiiint");
1356  defineSymbol(math, op, "\u2A0D", "\\intbar");
1357  defineSymbol(math, op, "\u2A0E", "\\intBar");
1358  defineSymbol(math, op, "\u2A0F", "\\fint");
1359  defineSymbol(math, op, "\u2A12", "\\rppolint");
1360  defineSymbol(math, op, "\u2A13", "\\scpolint");
1361  defineSymbol(math, op, "\u2A15", "\\pointint");
1362  defineSymbol(math, op, "\u2A16", "\\sqint");
1363  defineSymbol(math, op, "\u2A17", "\\intlarhk");
1364  defineSymbol(math, op, "\u2A18", "\\intx");
1365  defineSymbol(math, op, "\u2A19", "\\intcap");
1366  defineSymbol(math, op, "\u2A1A", "\\intcup");
1367  defineSymbol(math, op, "\u2A05", "\\bigsqcap");
1368  defineSymbol(math, op, "\u2A06", "\\bigsqcup");
1369  defineSymbol(math, op, "\u222B", "\\smallint");
1370  defineSymbol(text, inner, "\u2026", "\\textellipsis");
1371  defineSymbol(math, inner, "\u2026", "\\mathellipsis");
1372  defineSymbol(text, inner, "\u2026", "\\ldots", true);
1373  defineSymbol(math, inner, "\u2026", "\\ldots", true);
1374  defineSymbol(math, inner, "\u22F0", "\\iddots", true);
1375  defineSymbol(math, inner, "\u22EF", "\\@cdots", true);
1376  defineSymbol(math, inner, "\u22F1", "\\ddots", true);
1377  defineSymbol(math, textord, "\u22EE", "\\varvdots");
1378  defineSymbol(text, textord, "\u22EE", "\\varvdots");
1379  defineSymbol(math, accent, "\u02CA", "\\acute");
1380  defineSymbol(math, accent, "`", "\\grave");
1381  defineSymbol(math, accent, "\xA8", "\\ddot");
1382  defineSymbol(math, accent, "\u2026", "\\dddot");
1383  defineSymbol(math, accent, "\u2026.", "\\ddddot");
1384  defineSymbol(math, accent, "~", "\\tilde");
1385  defineSymbol(math, accent, "\u203E", "\\bar");
1386  defineSymbol(math, accent, "\u02D8", "\\breve");
1387  defineSymbol(math, accent, "\u02C7", "\\check");
1388  defineSymbol(math, accent, "^", "\\hat");
1389  defineSymbol(math, accent, "\u2192", "\\vec");
1390  defineSymbol(math, accent, "\u02D9", "\\dot");
1391  defineSymbol(math, accent, "\u02DA", "\\mathring");
1392  defineSymbol(math, mathord, "\u0131", "\\imath", true);
1393  defineSymbol(math, mathord, "\u0237", "\\jmath", true);
1394  defineSymbol(math, textord, "\u0131", "\u0131");
1395  defineSymbol(math, textord, "\u0237", "\u0237");
1396  defineSymbol(text, textord, "\u0131", "\\i", true);
1397  defineSymbol(text, textord, "\u0237", "\\j", true);
1398  defineSymbol(text, textord, "\xDF", "\\ss", true);
1399  defineSymbol(text, textord, "\xE6", "\\ae", true);
1400  defineSymbol(text, textord, "\u0153", "\\oe", true);
1401  defineSymbol(text, textord, "\xF8", "\\o", true);
1402  defineSymbol(math, mathord, "\xF8", "\\o", true);
1403  defineSymbol(text, textord, "\xC6", "\\AE", true);
1404  defineSymbol(text, textord, "\u0152", "\\OE", true);
1405  defineSymbol(text, textord, "\xD8", "\\O", true);
1406  defineSymbol(math, mathord, "\xD8", "\\O", true);
1407  defineSymbol(text, accent, "\u02CA", "\\'");
1408  defineSymbol(text, accent, "\u02CB", "\\`");
1409  defineSymbol(text, accent, "\u02C6", "\\^");
1410  defineSymbol(text, accent, "\u02DC", "\\~");
1411  defineSymbol(text, accent, "\u02C9", "\\=");
1412  defineSymbol(text, accent, "\u02D8", "\\u");
1413  defineSymbol(text, accent, "\u02D9", "\\.");
1414  defineSymbol(text, accent, "\xB8", "\\c");
1415  defineSymbol(text, accent, "\u02DA", "\\r");
1416  defineSymbol(text, accent, "\u02C7", "\\v");
1417  defineSymbol(text, accent, "\xA8", '\\"');
1418  defineSymbol(text, accent, "\u02DD", "\\H");
1419  defineSymbol(math, accent, "\u02CA", "\\'");
1420  defineSymbol(math, accent, "\u02CB", "\\`");
1421  defineSymbol(math, accent, "\u02C6", "\\^");
1422  defineSymbol(math, accent, "\u02DC", "\\~");
1423  defineSymbol(math, accent, "\u02C9", "\\=");
1424  defineSymbol(math, accent, "\u02D8", "\\u");
1425  defineSymbol(math, accent, "\u02D9", "\\.");
1426  defineSymbol(math, accent, "\xB8", "\\c");
1427  defineSymbol(math, accent, "\u02DA", "\\r");
1428  defineSymbol(math, accent, "\u02C7", "\\v");
1429  defineSymbol(math, accent, "\xA8", '\\"');
1430  defineSymbol(math, accent, "\u02DD", "\\H");
1431  var ligatures = {
1432    "--": true,
1433    "---": true,
1434    "``": true,
1435    "''": true
1436  };
1437  defineSymbol(text, textord, "\u2013", "--", true);
1438  defineSymbol(text, textord, "\u2013", "\\textendash");
1439  defineSymbol(text, textord, "\u2014", "---", true);
1440  defineSymbol(text, textord, "\u2014", "\\textemdash");
1441  defineSymbol(text, textord, "\u2018", "`", true);
1442  defineSymbol(text, textord, "\u2018", "\\textquoteleft");
1443  defineSymbol(text, textord, "\u2019", "'", true);
1444  defineSymbol(text, textord, "\u2019", "\\textquoteright");
1445  defineSymbol(text, textord, "\u201C", "``", true);
1446  defineSymbol(text, textord, "\u201C", "\\textquotedblleft");
1447  defineSymbol(text, textord, "\u201D", "''", true);
1448  defineSymbol(text, textord, "\u201D", "\\textquotedblright");
1449  defineSymbol(math, textord, "\xB0", "\\degree", true);
1450  defineSymbol(text, textord, "\xB0", "\\degree");
1451  defineSymbol(text, textord, "\xB0", "\\textdegree", true);
1452  defineSymbol(math, textord, "\xA3", "\\pounds");
1453  defineSymbol(math, textord, "\xA3", "\\mathsterling", true);
1454  defineSymbol(text, textord, "\xA3", "\\pounds");
1455  defineSymbol(text, textord, "\xA3", "\\textsterling", true);
1456  defineSymbol(math, textord, "\u2720", "\\maltese");
1457  defineSymbol(text, textord, "\u2720", "\\maltese");
1458  defineSymbol(math, textord, "\u20AC", "\\euro", true);
1459  defineSymbol(text, textord, "\u20AC", "\\euro", true);
1460  defineSymbol(text, textord, "\u20AC", "\\texteuro");
1461  defineSymbol(math, textord, "\xA9", "\\copyright", true);
1462  defineSymbol(text, textord, "\xA9", "\\textcopyright");
1463  defineSymbol(math, textord, "\u2300", "\\diameter", true);
1464  defineSymbol(text, textord, "\u2300", "\\diameter");
1465  defineSymbol(math, textord, "\u{1D6E4}", "\\varGamma");
1466  defineSymbol(math, textord, "\u{1D6E5}", "\\varDelta");
1467  defineSymbol(math, textord, "\u{1D6E9}", "\\varTheta");
1468  defineSymbol(math, textord, "\u{1D6EC}", "\\varLambda");
1469  defineSymbol(math, textord, "\u{1D6EF}", "\\varXi");
1470  defineSymbol(math, textord, "\u{1D6F1}", "\\varPi");
1471  defineSymbol(math, textord, "\u{1D6F4}", "\\varSigma");
1472  defineSymbol(math, textord, "\u{1D6F6}", "\\varUpsilon");
1473  defineSymbol(math, textord, "\u{1D6F7}", "\\varPhi");
1474  defineSymbol(math, textord, "\u{1D6F9}", "\\varPsi");
1475  defineSymbol(math, textord, "\u{1D6FA}", "\\varOmega");
1476  defineSymbol(text, textord, "\u{1D6E4}", "\\varGamma");
1477  defineSymbol(text, textord, "\u{1D6E5}", "\\varDelta");
1478  defineSymbol(text, textord, "\u{1D6E9}", "\\varTheta");
1479  defineSymbol(text, textord, "\u{1D6EC}", "\\varLambda");
1480  defineSymbol(text, textord, "\u{1D6EF}", "\\varXi");
1481  defineSymbol(text, textord, "\u{1D6F1}", "\\varPi");
1482  defineSymbol(text, textord, "\u{1D6F4}", "\\varSigma");
1483  defineSymbol(text, textord, "\u{1D6F6}", "\\varUpsilon");
1484  defineSymbol(text, textord, "\u{1D6F7}", "\\varPhi");
1485  defineSymbol(text, textord, "\u{1D6F9}", "\\varPsi");
1486  defineSymbol(text, textord, "\u{1D6FA}", "\\varOmega");
1487  var mathTextSymbols = '0123456789/@."';
1488  for (let i = 0; i < mathTextSymbols.length; i++) {
1489    const ch = mathTextSymbols.charAt(i);
1490    defineSymbol(math, textord, ch, ch);
1491  }
1492  var textSymbols = '0123456789!@*()-=+";:?/.,';
1493  for (let i = 0; i < textSymbols.length; i++) {
1494    const ch = textSymbols.charAt(i);
1495    defineSymbol(text, textord, ch, ch);
1496  }
1497  var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1498  for (let i = 0; i < letters.length; i++) {
1499    const ch = letters.charAt(i);
1500    defineSymbol(math, mathord, ch, ch);
1501    defineSymbol(text, textord, ch, ch);
1502  }
1503  var narrow = "\xC7\xD0\xDE\xE7\xFE\u2102\u210D\u2115\u2119\u211A\u211D\u2124\u210E\u210F\u210A\u210B\u210C\u2110\u2111\u2112\u2113\u2118\u211B\u211C\u212C\u2130\u2131\u2133\u212D\u2128";
1504  for (let i = 0; i < narrow.length; i++) {
1505    const ch = narrow.charAt(i);
1506    defineSymbol(math, mathord, ch, ch);
1507    defineSymbol(text, textord, ch, ch);
1508  }
1509  var wideChar = "";
1510  for (let i = 0; i < letters.length; i++) {
1511    wideChar = String.fromCharCode(55349, 56320 + i);
1512    defineSymbol(math, mathord, wideChar, wideChar);
1513    defineSymbol(text, textord, wideChar, wideChar);
1514    wideChar = String.fromCharCode(55349, 56372 + i);
1515    defineSymbol(math, mathord, wideChar, wideChar);
1516    defineSymbol(text, textord, wideChar, wideChar);
1517    wideChar = String.fromCharCode(55349, 56424 + i);
1518    defineSymbol(math, mathord, wideChar, wideChar);
1519    defineSymbol(text, textord, wideChar, wideChar);
1520    wideChar = String.fromCharCode(55349, 56580 + i);
1521    defineSymbol(math, mathord, wideChar, wideChar);
1522    defineSymbol(text, textord, wideChar, wideChar);
1523    wideChar = String.fromCharCode(55349, 56736 + i);
1524    defineSymbol(math, mathord, wideChar, wideChar);
1525    defineSymbol(text, textord, wideChar, wideChar);
1526    wideChar = String.fromCharCode(55349, 56788 + i);
1527    defineSymbol(math, mathord, wideChar, wideChar);
1528    defineSymbol(text, textord, wideChar, wideChar);
1529    wideChar = String.fromCharCode(55349, 56840 + i);
1530    defineSymbol(math, mathord, wideChar, wideChar);
1531    defineSymbol(text, textord, wideChar, wideChar);
1532    wideChar = String.fromCharCode(55349, 56944 + i);
1533    defineSymbol(math, mathord, wideChar, wideChar);
1534    defineSymbol(text, textord, wideChar, wideChar);
1535    wideChar = String.fromCharCode(55349, 56632 + i);
1536    defineSymbol(math, mathord, wideChar, wideChar);
1537    defineSymbol(text, textord, wideChar, wideChar);
1538    const ch = letters.charAt(i);
1539    wideChar = String.fromCharCode(55349, 56476 + i);
1540    defineSymbol(math, mathord, ch, wideChar);
1541    defineSymbol(text, textord, ch, wideChar);
1542  }
1543  for (let i = 0; i < 10; i++) {
1544    wideChar = String.fromCharCode(55349, 57294 + i);
1545    defineSymbol(math, mathord, wideChar, wideChar);
1546    defineSymbol(text, textord, wideChar, wideChar);
1547    wideChar = String.fromCharCode(55349, 57314 + i);
1548    defineSymbol(math, mathord, wideChar, wideChar);
1549    defineSymbol(text, textord, wideChar, wideChar);
1550    wideChar = String.fromCharCode(55349, 57324 + i);
1551    defineSymbol(math, mathord, wideChar, wideChar);
1552    defineSymbol(text, textord, wideChar, wideChar);
1553    wideChar = String.fromCharCode(55349, 57334 + i);
1554    defineSymbol(math, mathord, wideChar, wideChar);
1555    defineSymbol(text, textord, wideChar, wideChar);
1556  }
1557  var openDelims = "([{\u230A\u2308\u27E8\u27EE\u23B0\u27E6\u2983";
1558  var closeDelims = ")]}\u230B\u2309\u27E9\u27EF\u23B1\u27E6\u2984";
1559  function setLineBreaks(expression, wrapMode, isDisplayMode) {
1560    const mtrs = [];
1561    let mrows = [];
1562    let block = [];
1563    let numTopLevelEquals = 0;
1564    let i = 0;
1565    let level = 0;
1566    while (i < expression.length) {
1567      while (expression[i] instanceof DocumentFragment) {
1568        expression.splice(i, 1, ...expression[i].children);
1569      }
1570      const node = expression[i];
1571      if (node.attributes && node.attributes.linebreak && node.attributes.linebreak === "newline") {
1572        if (block.length > 0) {
1573          mrows.push(new mathMLTree.MathNode("mrow", block));
1574        }
1575        mrows.push(node);
1576        block = [];
1577        const mtd = new mathMLTree.MathNode("mtd", mrows);
1578        mtd.style.textAlign = "left";
1579        mtrs.push(new mathMLTree.MathNode("mtr", [mtd]));
1580        mrows = [];
1581        i += 1;
1582        continue;
1583      }
1584      block.push(node);
1585      if (node.type && node.type === "mo" && node.children.length === 1 && !Object.hasOwn(node.attributes, "movablelimits")) {
1586        const ch = node.children[0].text;
1587        if (openDelims.indexOf(ch) > -1) {
1588          level += 1;
1589        } else if (closeDelims.indexOf(ch) > -1) {
1590          level -= 1;
1591        } else if (level === 0 && wrapMode === "=" && ch === "=") {
1592          numTopLevelEquals += 1;
1593          if (numTopLevelEquals > 1) {
1594            block.pop();
1595            const element = new mathMLTree.MathNode("mrow", block);
1596            mrows.push(element);
1597            block = [node];
1598          }
1599        } else if (level === 0 && wrapMode === "tex" && ch !== "\u2207") {
1600          const next = i < expression.length - 1 ? expression[i + 1] : null;
1601          let glueIsFreeOfNobreak = true;
1602          if (!(next && next.type === "mtext" && next.attributes.linebreak && next.attributes.linebreak === "nobreak")) {
1603            for (let j = i + 1; j < expression.length; j++) {
1604              const nd = expression[j];
1605              if (nd.type && nd.type === "mspace" && !(nd.attributes.linebreak && nd.attributes.linebreak === "newline")) {
1606                block.push(nd);
1607                i += 1;
1608                if (nd.attributes && nd.attributes.linebreak && nd.attributes.linebreak === "nobreak") {
1609                  glueIsFreeOfNobreak = false;
1610                }
1611              } else {
1612                break;
1613              }
1614            }
1615          }
1616          if (glueIsFreeOfNobreak) {
1617            const element = new mathMLTree.MathNode("mrow", block);
1618            mrows.push(element);
1619            block = [];
1620          }
1621        }
1622      }
1623      i += 1;
1624    }
1625    if (block.length > 0) {
1626      const element = new mathMLTree.MathNode("mrow", block);
1627      mrows.push(element);
1628    }
1629    if (mtrs.length > 0) {
1630      const mtd = new mathMLTree.MathNode("mtd", mrows);
1631      mtd.style.textAlign = "left";
1632      const mtr = new mathMLTree.MathNode("mtr", [mtd]);
1633      mtrs.push(mtr);
1634      const mtable = new mathMLTree.MathNode("mtable", mtrs);
1635      if (!isDisplayMode) {
1636        mtable.setAttribute("columnalign", "left");
1637        mtable.setAttribute("rowspacing", "0em");
1638      }
1639      return mtable;
1640    }
1641    return mathMLTree.newDocumentFragment(mrows);
1642  }
1643  var makeText = function(text2, mode, style) {
1644    if (symbols[mode][text2] && symbols[mode][text2].replace && text2.charCodeAt(0) !== 55349 && !(Object.prototype.hasOwnProperty.call(ligatures, text2) && style && (style.fontFamily && style.fontFamily.slice(4, 6) === "tt" || style.font && style.font.slice(4, 6) === "tt"))) {
1645      text2 = symbols[mode][text2].replace;
1646    }
1647    return new mathMLTree.TextNode(text2);
1648  };
1649  var copyChar = (newRow, child) => {
1650    if (newRow.children.length === 0 || newRow.children[newRow.children.length - 1].type !== "mtext") {
1651      const mtext = new mathMLTree.MathNode(
1652        "mtext",
1653        [new mathMLTree.TextNode(child.children[0].text)]
1654      );
1655      newRow.children.push(mtext);
1656    } else {
1657      newRow.children[newRow.children.length - 1].children[0].text += child.children[0].text;
1658    }
1659  };
1660  var consolidateText = (mrow) => {
1661    if (mrow.type !== "mrow" && mrow.type !== "mstyle") {
1662      return mrow;
1663    }
1664    if (mrow.children.length === 0) {
1665      return mrow;
1666    }
1667    const newRow = new mathMLTree.MathNode("mrow");
1668    for (let i = 0; i < mrow.children.length; i++) {
1669      const child = mrow.children[i];
1670      if (child.type === "mtext" && Object.keys(child.attributes).length === 0) {
1671        copyChar(newRow, child);
1672      } else if (child.type === "mrow") {
1673        let canConsolidate = true;
1674        for (let j = 0; j < child.children.length; j++) {
1675          const grandChild = child.children[j];
1676          if (grandChild.type !== "mtext" || Object.keys(child.attributes).length !== 0) {
1677            canConsolidate = false;
1678            break;
1679          }
1680        }
1681        if (canConsolidate) {
1682          for (let j = 0; j < child.children.length; j++) {
1683            const grandChild = child.children[j];
1684            copyChar(newRow, grandChild);
1685          }
1686        } else {
1687          newRow.children.push(child);
1688        }
1689      } else {
1690        newRow.children.push(child);
1691      }
1692    }
1693    for (let i = 0; i < newRow.children.length; i++) {
1694      if (newRow.children[i].type === "mtext") {
1695        const mtext = newRow.children[i];
1696        if (mtext.children[0].text.charAt(0) === " ") {
1697          mtext.children[0].text = "\xA0" + mtext.children[0].text.slice(1);
1698        }
1699        const L = mtext.children[0].text.length;
1700        if (L > 0 && mtext.children[0].text.charAt(L - 1) === " ") {
1701          mtext.children[0].text = mtext.children[0].text.slice(0, -1) + "\xA0";
1702        }
1703        for (const [key, value] of Object.entries(mrow.attributes)) {
1704          mtext.attributes[key] = value;
1705        }
1706      }
1707    }
1708    if (newRow.children.length === 1 && newRow.children[0].type === "mtext") {
1709      return newRow.children[0];
1710    } else {
1711      return newRow;
1712    }
1713  };
1714  var makeRow = function(body, semisimple = false) {
1715    if (body.length === 1 && !(body[0] instanceof DocumentFragment)) {
1716      return body[0];
1717    } else if (!semisimple) {
1718      if (body[0] instanceof MathNode && body[0].type === "mo" && !body[0].attributes.fence) {
1719        body[0].attributes.lspace = "0em";
1720        body[0].attributes.rspace = "0em";
1721      }
1722      const end = body.length - 1;
1723      if (body[end] instanceof MathNode && body[end].type === "mo" && !body[end].attributes.fence) {
1724        body[end].attributes.lspace = "0em";
1725        body[end].attributes.rspace = "0em";
1726      }
1727    }
1728    return new mathMLTree.MathNode("mrow", body);
1729  };
1730  function isNumberPunctuation(group) {
1731    if (!group) {
1732      return false;
1733    }
1734    if (group.type === "mi" && group.children.length === 1) {
1735      const child = group.children[0];
1736      return child instanceof TextNode2 && child.text === ".";
1737    } else if (group.type === "mtext" && group.children.length === 1) {
1738      const child = group.children[0];
1739      return child instanceof TextNode2 && child.text === "\u2008";
1740    } else if (group.type === "mo" && group.children.length === 1 && group.getAttribute("separator") === "true" && group.getAttribute("lspace") === "0em" && group.getAttribute("rspace") === "0em") {
1741      const child = group.children[0];
1742      return child instanceof TextNode2 && child.text === ",";
1743    } else {
1744      return false;
1745    }
1746  }
1747  var isComma = (expression, i) => {
1748    const node = expression[i];
1749    const followingNode = expression[i + 1];
1750    return node.type === "atom" && node.text === "," && // Don't consolidate if there is a space after the comma.
1751    node.loc && followingNode.loc && node.loc.end === followingNode.loc.start;
1752  };
1753  var isRel = (item) => {
1754    return item.type === "atom" && item.family === "rel" || item.type === "mclass" && item.mclass === "mrel";
1755  };
1756  var buildExpression = function(expression, style, semisimple = false) {
1757    if (!semisimple && expression.length === 1) {
1758      const group = buildGroup$1(expression[0], style);
1759      if (group instanceof MathNode && group.type === "mo") {
1760        group.setAttribute("lspace", "0em");
1761        group.setAttribute("rspace", "0em");
1762      }
1763      return [group];
1764    }
1765    const groups = [];
1766    const groupArray = [];
1767    let lastGroup;
1768    for (let i = 0; i < expression.length; i++) {
1769      groupArray.push(buildGroup$1(expression[i], style));
1770    }
1771    for (let i = 0; i < groupArray.length; i++) {
1772      const group = groupArray[i];
1773      if (i < expression.length - 1 && isRel(expression[i]) && isRel(expression[i + 1])) {
1774        group.setAttribute("rspace", "0em");
1775      }
1776      if (i > 0 && isRel(expression[i]) && isRel(expression[i - 1])) {
1777        group.setAttribute("lspace", "0em");
1778      }
1779      if (group.type === "mn" && lastGroup && lastGroup.type === "mn") {
1780        lastGroup.children.push(...group.children);
1781        continue;
1782      } else if (isNumberPunctuation(group) && lastGroup && lastGroup.type === "mn") {
1783        lastGroup.children.push(...group.children);
1784        continue;
1785      } else if (lastGroup && lastGroup.type === "mn" && i < groupArray.length - 1 && groupArray[i + 1].type === "mn" && isComma(expression, i)) {
1786        lastGroup.children.push(...group.children);
1787        continue;
1788      } else if (group.type === "mn" && isNumberPunctuation(lastGroup)) {
1789        group.children = [...lastGroup.children, ...group.children];
1790        groups.pop();
1791      } else if ((group.type === "msup" || group.type === "msub") && group.children.length >= 1 && lastGroup && (lastGroup.type === "mn" || isNumberPunctuation(lastGroup))) {
1792        const base = group.children[0];
1793        if (base instanceof MathNode && base.type === "mn" && lastGroup) {
1794          base.children = [...lastGroup.children, ...base.children];
1795          groups.pop();
1796        }
1797      }
1798      groups.push(group);
1799      lastGroup = group;
1800    }
1801    return groups;
1802  };
1803  var buildExpressionRow = function(expression, style, semisimple = false) {
1804    return makeRow(buildExpression(expression, style, semisimple), semisimple);
1805  };
1806  var buildGroup$1 = function(group, style) {
1807    if (!group) {
1808      return new mathMLTree.MathNode("mrow");
1809    }
1810    if (_mathmlGroupBuilders[group.type]) {
1811      const result = _mathmlGroupBuilders[group.type](group, style);
1812      return result;
1813    } else {
1814      throw new ParseError("Got group of unknown type: '" + group.type + "'");
1815    }
1816  };
1817  var glue$1 = (_) => {
1818    return new mathMLTree.MathNode("mtd", [], [], { padding: "0", width: "50%" });
1819  };
1820  var labelContainers = ["mrow", "mtd", "mtable", "mtr"];
1821  var getLabel = (parent) => {
1822    for (const node of parent.children) {
1823      if (node.type && labelContainers.includes(node.type)) {
1824        if (node.classes && node.classes[0] === "tml-label") {
1825          const label = node.label;
1826          return label;
1827        } else {
1828          const label = getLabel(node);
1829          if (label) {
1830            return label;
1831          }
1832        }
1833      } else if (!node.type) {
1834        const label = getLabel(node);
1835        if (label) {
1836          return label;
1837        }
1838      }
1839    }
1840  };
1841  var taggedExpression = (expression, tag, style, leqno) => {
1842    tag = buildExpressionRow(tag[0].body, style);
1843    tag = consolidateText(tag);
1844    tag.classes.push("tml-tag");
1845    const label = getLabel(expression);
1846    expression = new mathMLTree.MathNode("mtd", [expression]);
1847    const rowArray = [glue$1(), expression, glue$1()];
1848    rowArray[leqno ? 0 : 2].classes.push(leqno ? "tml-left" : "tml-right");
1849    rowArray[leqno ? 0 : 2].children.push(tag);
1850    const mtr = new mathMLTree.MathNode("mtr", rowArray, ["tml-tageqn"]);
1851    if (label) {
1852      mtr.setAttribute("id", label);
1853    }
1854    const table = new mathMLTree.MathNode("mtable", [mtr]);
1855    table.style.width = "100%";
1856    table.setAttribute("displaystyle", "true");
1857    return table;
1858  };
1859  function buildMathML(tree, texExpression, style, settings) {
1860    let tag = null;
1861    if (tree.length === 1 && tree[0].type === "tag") {
1862      tag = tree[0].tag;
1863      tree = tree[0].body;
1864    }
1865    const expression = buildExpression(tree, style);
1866    if (expression.length === 1 && expression[0] instanceof AnchorNode) {
1867      return expression[0];
1868    }
1869    const wrap = settings.displayMode || settings.annotate ? "none" : settings.wrap;
1870    const n1 = expression.length === 0 ? null : expression[0];
1871    let wrapper = expression.length === 1 && tag === null && n1 instanceof MathNode ? expression[0] : setLineBreaks(expression, wrap, settings.displayMode);
1872    if (tag) {
1873      wrapper = taggedExpression(wrapper, tag, style, settings.leqno);
1874    }
1875    if (settings.annotate) {
1876      const annotation = new mathMLTree.MathNode(
1877        "annotation",
1878        [new mathMLTree.TextNode(texExpression)]
1879      );
1880      annotation.setAttribute("encoding", "application/x-tex");
1881      wrapper = new mathMLTree.MathNode("semantics", [wrapper, annotation]);
1882    }
1883    const math2 = new mathMLTree.MathNode("math", [wrapper]);
1884    if (settings.xml) {
1885      math2.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML");
1886    }
1887    if (wrapper.style.width) {
1888      math2.style.width = "100%";
1889    }
1890    if (settings.displayMode) {
1891      math2.setAttribute("display", "block");
1892      math2.style.display = "block math";
1893      math2.classes = ["tml-display"];
1894    }
1895    return math2;
1896  }
1897  var smalls = "aceg\u0131\u0237mnopqrsuvwxyz\u03B1\u03B3\u03B5\u03B7\u03B9\u03BA\u03BC\u03BD\u03BF\u03C0\u03C1\u03C2\u03C3\u03C4\u03C5\u03C7\u03C9\u03D5\u{1D41A}\u{1D41C}\u{1D41E}\u{1D420}\u{1D426}\u{1D427}\u{1D428}\u{1D429}\u{1D42A}\u{1D42B}\u{1D42C}\u{1D42E}\u{1D42F}\u{1D430}\u{1D431}\u{1D432}\u{1D433}";
1898  var talls = "ABCDEFGHIJKLMNOPQRSTUVWXYZbdfhklt\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A\u039B\u039C\u039D\u039E\u039F\u03A0\u03A1\u03A3\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\u03B2\u03B4\u03BB\u03B6\u03C6\u03B8\u03C8\u{1D400}\u{1D401}\u{1D402}\u{1D403}\u{1D404}\u{1D405}\u{1D406}\u{1D407}\u{1D408}\u{1D409}\u{1D40A}\u{1D40B}\u{1D40C}\u{1D40D}\u{1D40E}\u{1D40F}\u{1D410}\u{1D411}\u{1D412}\u{1D413}\u{1D414}\u{1D415}\u{1D416}\u{1D417}\u{1D418}\u{1D419}\u{1D41B}\u{1D41D}\u{1D41F}\u{1D421}\u{1D424}\u{1D425}\u{1D42D}";
1899  var longSmalls = /* @__PURE__ */ new Set([
1900    "\\alpha",
1901    "\\gamma",
1902    "\\delta",
1903    "\\epsilon",
1904    "\\eta",
1905    "\\iota",
1906    "\\kappa",
1907    "\\mu",
1908    "\\nu",
1909    "\\pi",
1910    "\\rho",
1911    "\\sigma",
1912    "\\tau",
1913    "\\upsilon",
1914    "\\chi",
1915    "\\psi",
1916    "\\omega",
1917    "\\imath",
1918    "\\jmath"
1919  ]);
1920  var longTalls = /* @__PURE__ */ new Set([
1921    "\\Gamma",
1922    "\\Delta",
1923    "\\Sigma",
1924    "\\Omega",
1925    "\\beta",
1926    "\\delta",
1927    "\\lambda",
1928    "\\theta",
1929    "\\psi"
1930  ]);
1931  var mathmlBuilder$a = (group, style) => {
1932    const accentNode2 = group.isStretchy ? stretchy.accentNode(group) : new mathMLTree.MathNode("mo", [makeText(group.label, group.mode)]);
1933    if (group.label === "\\vec") {
1934      accentNode2.style.transform = "scale(0.75) translate(10%, 30%)";
1935    } else {
1936      accentNode2.style.mathStyle = "normal";
1937      accentNode2.style.mathDepth = "0";
1938      if (needWebkitShift.has(group.label) && utils.isCharacterBox(group.base)) {
1939        let shift = "";
1940        const ch = group.base.text;
1941        if (smalls.indexOf(ch) > -1 || longSmalls.has(ch)) {
1942          shift = "tml-xshift";
1943        }
1944        if (talls.indexOf(ch) > -1 || longTalls.has(ch)) {
1945          shift = "tml-capshift";
1946        }
1947        if (shift) {
1948          accentNode2.classes.push(shift);
1949        }
1950      }
1951    }
1952    if (!group.isStretchy) {
1953      accentNode2.setAttribute("stretchy", "false");
1954    }
1955    const node = new mathMLTree.MathNode(
1956      group.label === "\\c" ? "munder" : "mover",
1957      [buildGroup$1(group.base, style), accentNode2]
1958    );
1959    return node;
1960  };
1961  var nonStretchyAccents = /* @__PURE__ */ new Set([
1962    "\\acute",
1963    "\\grave",
1964    "\\ddot",
1965    "\\dddot",
1966    "\\ddddot",
1967    "\\tilde",
1968    "\\bar",
1969    "\\breve",
1970    "\\check",
1971    "\\hat",
1972    "\\vec",
1973    "\\dot",
1974    "\\mathring"
1975  ]);
1976  var needWebkitShift = /* @__PURE__ */ new Set([
1977    "\\acute",
1978    "\\bar",
1979    "\\breve",
1980    "\\check",
1981    "\\dot",
1982    "\\ddot",
1983    "\\grave",
1984    "\\hat",
1985    "\\mathring",
1986    "\\'",
1987    "\\^",
1988    "\\~",
1989    "\\=",
1990    "\\u",
1991    "\\.",
1992    '\\"',
1993    "\\r",
1994    "\\H",
1995    "\\v"
1996  ]);
1997  var combiningChar = {
1998    "\\`": "\u0300",
1999    "\\'": "\u0301",
2000    "\\^": "\u0302",
2001    "\\~": "\u0303",
2002    "\\=": "\u0304",
2003    "\\u": "\u0306",
2004    "\\.": "\u0307",
2005    '\\"': "\u0308",
2006    "\\r": "\u030A",
2007    "\\H": "\u030B",
2008    "\\v": "\u030C"
2009  };
2010  defineFunction({
2011    type: "accent",
2012    names: [
2013      "\\acute",
2014      "\\grave",
2015      "\\ddot",
2016      "\\dddot",
2017      "\\ddddot",
2018      "\\tilde",
2019      "\\bar",
2020      "\\breve",
2021      "\\check",
2022      "\\hat",
2023      "\\vec",
2024      "\\dot",
2025      "\\mathring",
2026      "\\overparen",
2027      "\\widecheck",
2028      "\\widehat",
2029      "\\wideparen",
2030      "\\widetilde",
2031      "\\overrightarrow",
2032      "\\overleftarrow",
2033      "\\Overrightarrow",
2034      "\\overleftrightarrow",
2035      "\\overgroup",
2036      "\\overleftharpoon",
2037      "\\overrightharpoon"
2038    ],
2039    props: {
2040      numArgs: 1
2041    },
2042    handler: (context, args) => {
2043      const base = normalizeArgument(args[0]);
2044      const isStretchy = !nonStretchyAccents.has(context.funcName);
2045      return {
2046        type: "accent",
2047        mode: context.parser.mode,
2048        label: context.funcName,
2049        isStretchy,
2050        base
2051      };
2052    },
2053    mathmlBuilder: mathmlBuilder$a
2054  });
2055  defineFunction({
2056    type: "accent",
2057    names: ["\\'", "\\`", "\\^", "\\~", "\\=", "\\c", "\\u", "\\.", '\\"', "\\r", "\\H", "\\v"],
2058    props: {
2059      numArgs: 1,
2060      allowedInText: true,
2061      allowedInMath: true,
2062      argTypes: ["primitive"]
2063    },
2064    handler: (context, args) => {
2065      const base = normalizeArgument(args[0]);
2066      const mode = context.parser.mode;
2067      if (mode === "math" && context.parser.settings.strict) {
2068        console.log(`Temml parse error: Command $context.funcName} is invalid in math mode.`);
2069      }
2070      if (mode === "text" && base.text && base.text.length === 1 && context.funcName in combiningChar && smalls.indexOf(base.text) > -1) {
2071        return {
2072          type: "textord",
2073          mode: "text",
2074          text: base.text + combiningChar[context.funcName]
2075        };
2076      } else {
2077        return {
2078          type: "accent",
2079          mode,
2080          label: context.funcName,
2081          isStretchy: false,
2082          base
2083        };
2084      }
2085    },
2086    mathmlBuilder: mathmlBuilder$a
2087  });
2088  defineFunction({
2089    type: "accentUnder",
2090    names: [
2091      "\\underleftarrow",
2092      "\\underrightarrow",
2093      "\\underleftrightarrow",
2094      "\\undergroup",
2095      "\\underparen",
2096      "\\utilde"
2097    ],
2098    props: {
2099      numArgs: 1
2100    },
2101    handler: ({ parser, funcName }, args) => {
2102      const base = args[0];
2103      return {
2104        type: "accentUnder",
2105        mode: parser.mode,
2106        label: funcName,
2107        base
2108      };
2109    },
2110    mathmlBuilder: (group, style) => {
2111      const accentNode2 = stretchy.accentNode(group);
2112      accentNode2.style["math-depth"] = 0;
2113      const node = new mathMLTree.MathNode("munder", [
2114        buildGroup$1(group.base, style),
2115        accentNode2
2116      ]);
2117      return node;
2118    }
2119  });
2120  var ptPerUnit = {
2121    // Convert to CSS (Postscipt) points, not TeX points
2122    // https://en.wikibooks.org/wiki/LaTeX/Lengths and
2123    // https://tex.stackexchange.com/a/8263
2124    pt: 800 / 803,
2125    // convert TeX point to CSS (Postscript) point
2126    pc: 12 * 800 / 803,
2127    // pica
2128    dd: 1238 / 1157 * 800 / 803,
2129    // didot
2130    cc: 14856 / 1157 * 800 / 803,
2131    // cicero (12 didot)
2132    nd: 685 / 642 * 800 / 803,
2133    // new didot
2134    nc: 1370 / 107 * 800 / 803,
2135    // new cicero (12 new didot)
2136    sp: 1 / 65536 * 800 / 803,
2137    // scaled point (TeX's internal smallest unit)
2138    mm: 25.4 / 72,
2139    cm: 2.54 / 72,
2140    in: 1 / 72,
2141    px: 96 / 72
2142  };
2143  var validUnits = [
2144    "em",
2145    "ex",
2146    "mu",
2147    "pt",
2148    "mm",
2149    "cm",
2150    "in",
2151    "px",
2152    "bp",
2153    "pc",
2154    "dd",
2155    "cc",
2156    "nd",
2157    "nc",
2158    "sp"
2159  ];
2160  var validUnit = function(unit) {
2161    if (typeof unit !== "string") {
2162      unit = unit.unit;
2163    }
2164    return validUnits.indexOf(unit) > -1;
2165  };
2166  var emScale = (styleLevel) => {
2167    const scriptLevel2 = Math.max(styleLevel - 1, 0);
2168    return [1, 0.7, 0.5][scriptLevel2];
2169  };
2170  var calculateSize = function(sizeValue, style) {
2171    let number = sizeValue.number;
2172    if (style.maxSize[0] < 0 && number > 0) {
2173      return { number: 0, unit: "em" };
2174    }
2175    const unit = sizeValue.unit;
2176    switch (unit) {
2177      case "mm":
2178      case "cm":
2179      case "in":
2180      case "px": {
2181        const numInCssPts = number * ptPerUnit[unit];
2182        if (numInCssPts > style.maxSize[1]) {
2183          return { number: style.maxSize[1], unit: "pt" };
2184        }
2185        return { number, unit };
2186      }
2187      case "em":
2188      case "ex": {
2189        if (unit === "ex") {
2190          number *= 0.431;
2191        }
2192        number = Math.min(number / emScale(style.level), style.maxSize[0]);
2193        return { number: utils.round(number), unit: "em" };
2194      }
2195      case "bp": {
2196        if (number > style.maxSize[1]) {
2197          number = style.maxSize[1];
2198        }
2199        return { number, unit: "pt" };
2200      }
2201      case "pt":
2202      case "pc":
2203      case "dd":
2204      case "cc":
2205      case "nd":
2206      case "nc":
2207      case "sp": {
2208        number = Math.min(number * ptPerUnit[unit], style.maxSize[1]);
2209        return { number: utils.round(number), unit: "pt" };
2210      }
2211      case "mu": {
2212        number = Math.min(number / 18, style.maxSize[0]);
2213        return { number: utils.round(number), unit: "em" };
2214      }
2215      default:
2216        throw new ParseError("Invalid unit: '" + unit + "'");
2217    }
2218  };
2219  var padding$2 = (width) => {
2220    const node = new mathMLTree.MathNode("mspace");
2221    node.setAttribute("width", width + "em");
2222    return node;
2223  };
2224  var paddedNode = (group, lspace = 0.3, rspace = 0, mustSmash = false) => {
2225    if (group == null && rspace === 0) {
2226      return padding$2(lspace);
2227    }
2228    const row = group ? [group] : [];
2229    if (lspace !== 0) {
2230      row.unshift(padding$2(lspace));
2231    }
2232    if (rspace > 0) {
2233      row.push(padding$2(rspace));
2234    }
2235    if (mustSmash) {
2236      const mpadded = new mathMLTree.MathNode("mpadded", row);
2237      mpadded.setAttribute("height", "0");
2238      return mpadded;
2239    } else {
2240      return new mathMLTree.MathNode("mrow", row);
2241    }
2242  };
2243  var labelSize = (size, scriptLevel2) => Number(size) / emScale(scriptLevel2);
2244  var munderoverNode = (fName, body, below, style) => {
2245    const arrowNode = stretchy.mathMLnode(fName);
2246    const isEq = fName.slice(1, 3) === "eq";
2247    const minWidth = fName.charAt(1) === "x" ? "1.75" : fName.slice(2, 4) === "cd" ? "3.0" : isEq ? "1.0" : "2.0";
2248    arrowNode.setAttribute("lspace", "0");
2249    arrowNode.setAttribute("rspace", isEq ? "0.5em" : "0");
2250    const labelStyle = style.withLevel(style.level < 2 ? 2 : 3);
2251    const minArrowWidth = labelSize(minWidth, labelStyle.level);
2252    const dummyWidth = labelSize(minWidth, 3);
2253    const emptyLabel = paddedNode(null, minArrowWidth.toFixed(4), 0);
2254    const dummyNode = paddedNode(null, dummyWidth.toFixed(4), 0);
2255    const space = labelSize(isEq ? 0 : 0.3, labelStyle.level).toFixed(4);
2256    let upperNode;
2257    let lowerNode;
2258    const gotUpper = body && body.body && // \hphantom        visible content
2259    (body.body.body || body.body.length > 0);
2260    if (gotUpper) {
2261      let label = buildGroup$1(body, labelStyle);
2262      const mustSmash = fName === "\\\\cdrightarrow" || fName === "\\\\cdleftarrow";
2263      label = paddedNode(label, space, space, mustSmash);
2264      upperNode = new mathMLTree.MathNode("mover", [label, dummyNode]);
2265    }
2266    const gotLower = below && below.body && (below.body.body || below.body.length > 0);
2267    if (gotLower) {
2268      let label = buildGroup$1(below, labelStyle);
2269      label = paddedNode(label, space, space);
2270      lowerNode = new mathMLTree.MathNode("munder", [label, dummyNode]);
2271    }
2272    let node;
2273    if (!gotUpper && !gotLower) {
2274      node = new mathMLTree.MathNode("mover", [arrowNode, emptyLabel]);
2275    } else if (gotUpper && gotLower) {
2276      node = new mathMLTree.MathNode("munderover", [arrowNode, lowerNode, upperNode]);
2277    } else if (gotUpper) {
2278      node = new mathMLTree.MathNode("mover", [arrowNode, upperNode]);
2279    } else {
2280      node = new mathMLTree.MathNode("munder", [arrowNode, lowerNode]);
2281    }
2282    if (minWidth === "3.0") {
2283      node.style.height = "1em";
2284    }
2285    node.setAttribute("accent", "false");
2286    return node;
2287  };
2288  defineFunction({
2289    type: "xArrow",
2290    names: [
2291      "\\xleftarrow",
2292      "\\xrightarrow",
2293      "\\xLeftarrow",
2294      "\\xRightarrow",
2295      "\\xleftrightarrow",
2296      "\\xLeftrightarrow",
2297      "\\xhookleftarrow",
2298      "\\xhookrightarrow",
2299      "\\xmapsto",
2300      "\\xrightharpoondown",
2301      "\\xrightharpoonup",
2302      "\\xleftharpoondown",
2303      "\\xleftharpoonup",
2304      "\\xlongequal",
2305      "\\xtwoheadrightarrow",
2306      "\\xtwoheadleftarrow",
2307      // The next 5 functions are here only to support mhchem
2308      "\\yields",
2309      "\\yieldsLeft",
2310      "\\mesomerism",
2311      "\\longrightharpoonup",
2312      "\\longleftharpoondown",
2313      // The next 3 functions are here only to support the {CD} environment.
2314      "\\\\cdrightarrow",
2315      "\\\\cdleftarrow",
2316      "\\\\cdlongequal"
2317    ],
2318    props: {
2319      numArgs: 1,
2320      numOptionalArgs: 1
2321    },
2322    handler({ parser, funcName }, args, optArgs) {
2323      return {
2324        type: "xArrow",
2325        mode: parser.mode,
2326        name: funcName,
2327        body: args[0],
2328        below: optArgs[0]
2329      };
2330    },
2331    mathmlBuilder(group, style) {
2332      const node = munderoverNode(group.name, group.body, group.below, style);
2333      const row = [node];
2334      row.unshift(padding$2(0.2778));
2335      row.push(padding$2(0.2778));
2336      return new mathMLTree.MathNode("mrow", row);
2337    }
2338  });
2339  var arrowComponent = {
2340    "\\xtofrom": ["\\xrightarrow", "\\xleftarrow"],
2341    "\\xleftrightharpoons": ["\\xleftharpoonup", "\\xrightharpoondown"],
2342    "\\xrightleftharpoons": ["\\xrightharpoonup", "\\xleftharpoondown"],
2343    "\\yieldsLeftRight": ["\\yields", "\\yieldsLeft"],
2344    // The next three all get the same harpoon glyphs. Only the lengths and paddings differ.
2345    "\\equilibrium": ["\\longrightharpoonup", "\\longleftharpoondown"],
2346    "\\equilibriumRight": ["\\longrightharpoonup", "\\eqleftharpoondown"],
2347    "\\equilibriumLeft": ["\\eqrightharpoonup", "\\longleftharpoondown"]
2348  };
2349  defineFunction({
2350    type: "stackedArrow",
2351    names: [
2352      "\\xtofrom",
2353      // expfeil
2354      "\\xleftrightharpoons",
2355      // mathtools
2356      "\\xrightleftharpoons",
2357      // mathtools
2358      "\\yieldsLeftRight",
2359      // mhchem
2360      "\\equilibrium",
2361      // mhchem
2362      "\\equilibriumRight",
2363      "\\equilibriumLeft"
2364    ],
2365    props: {
2366      numArgs: 1,
2367      numOptionalArgs: 1
2368    },
2369    handler({ parser, funcName }, args, optArgs) {
2370      const lowerArrowBody = args[0] ? {
2371        type: "hphantom",
2372        mode: parser.mode,
2373        body: args[0]
2374      } : null;
2375      const upperArrowBelow = optArgs[0] ? {
2376        type: "hphantom",
2377        mode: parser.mode,
2378        body: optArgs[0]
2379      } : null;
2380      return {
2381        type: "stackedArrow",
2382        mode: parser.mode,
2383        name: funcName,
2384        body: args[0],
2385        upperArrowBelow,
2386        lowerArrowBody,
2387        below: optArgs[0]
2388      };
2389    },
2390    mathmlBuilder(group, style) {
2391      const topLabel = arrowComponent[group.name][0];
2392      const botLabel = arrowComponent[group.name][1];
2393      const topArrow = munderoverNode(topLabel, group.body, group.upperArrowBelow, style);
2394      const botArrow = munderoverNode(botLabel, group.lowerArrowBody, group.below, style);
2395      let wrapper;
2396      const raiseNode = new mathMLTree.MathNode("mpadded", [topArrow]);
2397      raiseNode.setAttribute("voffset", "0.3em");
2398      raiseNode.setAttribute("height", "+0.3em");
2399      raiseNode.setAttribute("depth", "-0.3em");
2400      if (group.name === "\\equilibriumLeft") {
2401        const botNode = new mathMLTree.MathNode("mpadded", [botArrow]);
2402        botNode.setAttribute("width", "0.5em");
2403        wrapper = new mathMLTree.MathNode(
2404          "mpadded",
2405          [padding$2(0.2778), botNode, raiseNode, padding$2(0.2778)]
2406        );
2407      } else {
2408        raiseNode.setAttribute("width", group.name === "\\equilibriumRight" ? "0.5em" : "0");
2409        wrapper = new mathMLTree.MathNode(
2410          "mpadded",
2411          [padding$2(0.2778), raiseNode, botArrow, padding$2(0.2778)]
2412        );
2413      }
2414      wrapper.setAttribute("voffset", "-0.18em");
2415      wrapper.setAttribute("height", "-0.18em");
2416      wrapper.setAttribute("depth", "+0.18em");
2417      return wrapper;
2418    }
2419  });
2420  function assertNodeType(node, type) {
2421    if (!node || node.type !== type) {
2422      throw new Error(
2423        `Expected node of type $type}, but got ` + (node ? `node of type $node.type}` : String(node))
2424      );
2425    }
2426    return node;
2427  }
2428  function assertSymbolNodeType(node) {
2429    const typedNode = checkSymbolNodeType(node);
2430    if (!typedNode) {
2431      throw new Error(
2432        `Expected node of symbol group type, but got ` + (node ? `node of type $node.type}` : String(node))
2433      );
2434    }
2435    return typedNode;
2436  }
2437  function checkSymbolNodeType(node) {
2438    if (node && (node.type === "atom" || Object.prototype.hasOwnProperty.call(NON_ATOMS, node.type))) {
2439      return node;
2440    }
2441    return null;
2442  }
2443  var cdArrowFunctionName = {
2444    ">": "\\\\cdrightarrow",
2445    "<": "\\\\cdleftarrow",
2446    "=": "\\\\cdlongequal",
2447    A: "\\uparrow",
2448    V: "\\downarrow",
2449    "|": "\\Vert",
2450    ".": "no arrow"
2451  };
2452  var newCell = () => {
2453    return { type: "styling", body: [], mode: "math", scriptLevel: "display" };
2454  };
2455  var isStartOfArrow = (node) => {
2456    return node.type === "textord" && node.text === "@";
2457  };
2458  var isLabelEnd = (node, endChar) => {
2459    return (node.type === "mathord" || node.type === "atom") && node.text === endChar;
2460  };
2461  function cdArrow(arrowChar, labels, parser) {
2462    const funcName = cdArrowFunctionName[arrowChar];
2463    switch (funcName) {
2464      case "\\\\cdrightarrow":
2465      case "\\\\cdleftarrow":
2466        return parser.callFunction(funcName, [labels[0]], [labels[1]]);
2467      case "\\uparrow":
2468      case "\\downarrow": {
2469        const leftLabel = parser.callFunction("\\\\cdleft", [labels[0]], []);
2470        const bareArrow = {
2471          type: "atom",
2472          text: funcName,
2473          mode: "math",
2474          family: "rel"
2475        };
2476        const sizedArrow = parser.callFunction("\\Big", [bareArrow], []);
2477        const rightLabel = parser.callFunction("\\\\cdright", [labels[1]], []);
2478        const arrowGroup = {
2479          type: "ordgroup",
2480          mode: "math",
2481          body: [leftLabel, sizedArrow, rightLabel],
2482          semisimple: true
2483        };
2484        return parser.callFunction("\\\\cdparent", [arrowGroup], []);
2485      }
2486      case "\\\\cdlongequal":
2487        return parser.callFunction("\\\\cdlongequal", [], []);
2488      case "\\Vert": {
2489        const arrow = { type: "textord", text: "\\Vert", mode: "math" };
2490        return parser.callFunction("\\Big", [arrow], []);
2491      }
2492      default:
2493        return { type: "textord", text: " ", mode: "math" };
2494    }
2495  }
2496  function parseCD(parser) {
2497    const parsedRows = [];
2498    parser.gullet.beginGroup();
2499    parser.gullet.macros.set("\\cr", "\\\\\\relax");
2500    parser.gullet.beginGroup();
2501    while (true) {
2502      parsedRows.push(parser.parseExpression(false, "\\\\"));
2503      parser.gullet.endGroup();
2504      parser.gullet.beginGroup();
2505      const next = parser.fetch().text;
2506      if (next === "&" || next === "\\\\") {
2507        parser.consume();
2508      } else if (next === "\\end") {
2509        if (parsedRows[parsedRows.length - 1].length === 0) {
2510          parsedRows.pop();
2511        }
2512        break;
2513      } else {
2514        throw new ParseError("Expected \\\\ or \\cr or \\end", parser.nextToken);
2515      }
2516    }
2517    let row = [];
2518    const body = [row];
2519    for (let i = 0; i < parsedRows.length; i++) {
2520      const rowNodes = parsedRows[i];
2521      let cell = newCell();
2522      for (let j = 0; j < rowNodes.length; j++) {
2523        if (!isStartOfArrow(rowNodes[j])) {
2524          cell.body.push(rowNodes[j]);
2525        } else {
2526          row.push(cell);
2527          j += 1;
2528          const arrowChar = assertSymbolNodeType(rowNodes[j]).text;
2529          const labels = new Array(2);
2530          labels[0] = { type: "ordgroup", mode: "math", body: [] };
2531          labels[1] = { type: "ordgroup", mode: "math", body: [] };
2532          if ("=|.".indexOf(arrowChar) > -1) ;
2533          else if ("<>AV".indexOf(arrowChar) > -1) {
2534            for (let labelNum = 0; labelNum < 2; labelNum++) {
2535              let inLabel = true;
2536              for (let k = j + 1; k < rowNodes.length; k++) {
2537                if (isLabelEnd(rowNodes[k], arrowChar)) {
2538                  inLabel = false;
2539                  j = k;
2540                  break;
2541                }
2542                if (isStartOfArrow(rowNodes[k])) {
2543                  throw new ParseError(
2544                    "Missing a " + arrowChar + " character to complete a CD arrow.",
2545                    rowNodes[k]
2546                  );
2547                }
2548                labels[labelNum].body.push(rowNodes[k]);
2549              }
2550              if (inLabel) {
2551                throw new ParseError(
2552                  "Missing a " + arrowChar + " character to complete a CD arrow.",
2553                  rowNodes[j]
2554                );
2555              }
2556            }
2557          } else {
2558            throw new ParseError(`Expected one of "<>AV=|." after @.`);
2559          }
2560          const arrow = cdArrow(arrowChar, labels, parser);
2561          row.push(arrow);
2562          cell = newCell();
2563        }
2564      }
2565      if (i % 2 === 0) {
2566        row.push(cell);
2567      } else {
2568        row.shift();
2569      }
2570      row = [];
2571      body.push(row);
2572    }
2573    body.pop();
2574    parser.gullet.endGroup();
2575    parser.gullet.endGroup();
2576    return {
2577      type: "array",
2578      mode: "math",
2579      body,
2580      tags: null,
2581      labels: new Array(body.length + 1).fill(""),
2582      envClasses: ["jot", "cd"],
2583      cols: [],
2584      hLinesBeforeRow: new Array(body.length + 1).fill([])
2585    };
2586  }
2587  defineFunction({
2588    type: "cdlabel",
2589    names: ["\\\\cdleft", "\\\\cdright"],
2590    props: {
2591      numArgs: 1
2592    },
2593    handler({ parser, funcName }, args) {
2594      return {
2595        type: "cdlabel",
2596        mode: parser.mode,
2597        side: funcName.slice(4),
2598        label: args[0]
2599      };
2600    },
2601    mathmlBuilder(group, style) {
2602      if (group.label.body.length === 0) {
2603        return new mathMLTree.MathNode("mrow", style);
2604      }
2605      const mtd = new mathMLTree.MathNode("mtd", [buildGroup$1(group.label, style)]);
2606      mtd.style.padding = "0";
2607      const mtr = new mathMLTree.MathNode("mtr", [mtd]);
2608      const mtable = new mathMLTree.MathNode("mtable", [mtr]);
2609      const label = new mathMLTree.MathNode("mpadded", [mtable]);
2610      label.setAttribute("width", "0");
2611      label.setAttribute("displaystyle", "false");
2612      label.setAttribute("scriptlevel", "1");
2613      if (group.side === "left") {
2614        label.style.display = "flex";
2615        label.style.justifyContent = "flex-end";
2616      }
2617      return label;
2618    }
2619  });
2620  defineFunction({
2621    type: "cdlabelparent",
2622    names: ["\\\\cdparent"],
2623    props: {
2624      numArgs: 1
2625    },
2626    handler({ parser }, args) {
2627      return {
2628        type: "cdlabelparent",
2629        mode: parser.mode,
2630        fragment: args[0]
2631      };
2632    },
2633    mathmlBuilder(group, style) {
2634      return new mathMLTree.MathNode("mrow", [buildGroup$1(group.fragment, style)]);
2635    }
2636  });
2637  defineFunction({
2638    type: "textord",
2639    names: ["\\@char"],
2640    props: {
2641      numArgs: 1,
2642      allowedInText: true
2643    },
2644    handler({ parser, token }, args) {
2645      const arg = assertNodeType(args[0], "ordgroup");
2646      const group = arg.body;
2647      let number = "";
2648      for (let i = 0; i < group.length; i++) {
2649        const node = assertNodeType(group[i], "textord");
2650        number += node.text;
2651      }
2652      const code = parseInt(number);
2653      if (isNaN(code)) {
2654        throw new ParseError(`\\@char has non-numeric argument $number}`, token);
2655      }
2656      return {
2657        type: "textord",
2658        mode: parser.mode,
2659        text: String.fromCodePoint(code)
2660      };
2661    }
2662  });
2663  var htmlRegEx = /^(#[a-f0-9]{3}|#?[a-f0-9]{6})$/i;
2664  var htmlOrNameRegEx = /^(#[a-f0-9]{3}|#?[a-f0-9]{6}|[a-z]+)$/i;
2665  var RGBregEx = /^ *\d{1,3} *(?:, *\d{1,3} *){2}$/;
2666  var rgbRegEx = /^ *[10](?:\.\d*)? *(?:, *[10](?:\.\d*)? *){2}$/;
2667  var xcolorHtmlRegEx = /^[a-f0-9]{6}$/i;
2668  var toHex = (num) => {
2669    let str = num.toString(16);
2670    if (str.length === 1) {
2671      str = "0" + str;
2672    }
2673    return str;
2674  };
2675  var xcolors = JSON.parse(`{
2676    "Apricot": "#ffb484",
2677    "Aquamarine": "#08b4bc",
2678    "Bittersweet": "#c84c14",
2679    "blue": "#0000FF",
2680    "Blue": "#303494",
2681    "BlueGreen": "#08b4bc",
2682    "BlueViolet": "#503c94",
2683    "BrickRed": "#b8341c",
2684    "brown": "#BF8040",
2685    "Brown": "#802404",
2686    "BurntOrange": "#f8941c",
2687    "CadetBlue": "#78749c",
2688    "CarnationPink": "#f884b4",
2689    "Cerulean": "#08a4e4",
2690    "CornflowerBlue": "#40ace4",
2691    "cyan": "#00FFFF",
2692    "Cyan": "#08acec",
2693    "Dandelion": "#ffbc44",
2694    "darkgray": "#404040",
2695    "DarkOrchid": "#a8548c",
2696    "Emerald": "#08ac9c",
2697    "ForestGreen": "#089c54",
2698    "Fuchsia": "#90348c",
2699    "Goldenrod": "#ffdc44",
2700    "gray": "#808080",
2701    "Gray": "#98949c",
2702    "green": "#00FF00",
2703    "Green": "#08a44c",
2704    "GreenYellow": "#e0e474",
2705    "JungleGreen": "#08ac9c",
2706    "Lavender": "#f89cc4",
2707    "lightgray": "#c0c0c0",
2708    "lime": "#BFFF00",
2709    "LimeGreen": "#90c43c",
2710    "magenta": "#FF00FF",
2711    "Magenta": "#f0048c",
2712    "Mahogany": "#b0341c",
2713    "Maroon": "#b03434",
2714    "Melon": "#f89c7c",
2715    "MidnightBlue": "#086494",
2716    "Mulberry": "#b03c94",
2717    "NavyBlue": "#086cbc",
2718    "olive": "#7F7F00",
2719    "OliveGreen": "#407c34",
2720    "orange": "#FF8000",
2721    "Orange": "#f8843c",
2722    "OrangeRed": "#f0145c",
2723    "Orchid": "#b074ac",
2724    "Peach": "#f8945c",
2725    "Periwinkle": "#8074bc",
2726    "PineGreen": "#088c74",
2727    "pink": "#ff7f7f",
2728    "Plum": "#98248c",
2729    "ProcessBlue": "#08b4ec",
2730    "purple": "#BF0040",
2731    "Purple": "#a0449c",
2732    "RawSienna": "#983c04",
2733    "red": "#ff0000",
2734    "Red": "#f01c24",
2735    "RedOrange": "#f86434",
2736    "RedViolet": "#a0246c",
2737    "Rhodamine": "#f0549c",
2738    "Royallue": "#0874bc",
2739    "RoyalPurple": "#683c9c",
2740    "RubineRed": "#f0047c",
2741    "Salmon": "#f8948c",
2742    "SeaGreen": "#30bc9c",
2743    "Sepia": "#701404",
2744    "SkyBlue": "#48c4dc",
2745    "SpringGreen": "#c8dc64",
2746    "Tan": "#e09c74",
2747    "teal": "#007F7F",
2748    "TealBlue": "#08acb4",
2749    "Thistle": "#d884b4",
2750    "Turquoise": "#08b4cc",
2751    "violet": "#800080",
2752    "Violet": "#60449c",
2753    "VioletRed": "#f054a4",
2754    "WildStrawberry": "#f0246c",
2755    "yellow": "#FFFF00",
2756    "Yellow": "#fff404",
2757    "YellowGreen": "#98cc6c",
2758    "YellowOrange": "#ffa41c"
2759  }`);
2760  var colorFromSpec = (model, spec) => {
2761    let color = "";
2762    if (model === "HTML") {
2763      if (!htmlRegEx.test(spec)) {
2764        throw new ParseError("Invalid HTML input.");
2765      }
2766      color = spec;
2767    } else if (model === "RGB") {
2768      if (!RGBregEx.test(spec)) {
2769        throw new ParseError("Invalid RGB input.");
2770      }
2771      spec.split(",").map((e) => {
2772        color += toHex(Number(e.trim()));
2773      });
2774    } else {
2775      if (!rgbRegEx.test(spec)) {
2776        throw new ParseError("Invalid rbg input.");
2777      }
2778      spec.split(",").map((e) => {
2779        const num = Number(e.trim());
2780        if (num > 1) {
2781          throw new ParseError("Color rgb input must be < 1.");
2782        }
2783        color += toHex(Number((num * 255).toFixed(0)));
2784      });
2785    }
2786    if (color.charAt(0) !== "#") {
2787      color = "#" + color;
2788    }
2789    return color;
2790  };
2791  var validateColor = (color, macros2, token) => {
2792    const macroName = `\\\\color@$color}`;
2793    const match = htmlOrNameRegEx.exec(color);
2794    if (!match) {
2795      throw new ParseError("Invalid color: '" + color + "'", token);
2796    }
2797    if (xcolorHtmlRegEx.test(color)) {
2798      return "#" + color;
2799    } else if (color.charAt(0) === "#") {
2800      return color;
2801    } else if (macros2.has(macroName)) {
2802      color = macros2.get(macroName).tokens[0].text;
2803    } else if (xcolors[color]) {
2804      color = xcolors[color];
2805    }
2806    return color;
2807  };
2808  var mathmlBuilder$9 = (group, style) => {
2809    let expr = buildExpression(group.body, style.withColor(group.color));
2810    expr = expr.map((e) => {
2811      e.style.color = group.color;
2812      return e;
2813    });
2814    return mathMLTree.newDocumentFragment(expr);
2815  };
2816  defineFunction({
2817    type: "color",
2818    names: ["\\textcolor"],
2819    props: {
2820      numArgs: 2,
2821      numOptionalArgs: 1,
2822      allowedInText: true,
2823      argTypes: ["raw", "raw", "original"]
2824    },
2825    handler({ parser, token }, args, optArgs) {
2826      const model = optArgs[0] && assertNodeType(optArgs[0], "raw").string;
2827      let color = "";
2828      if (model) {
2829        const spec = assertNodeType(args[0], "raw").string;
2830        color = colorFromSpec(model, spec);
2831      } else {
2832        color = validateColor(assertNodeType(args[0], "raw").string, parser.gullet.macros, token);
2833      }
2834      const body = args[1];
2835      return {
2836        type: "color",
2837        mode: parser.mode,
2838        color,
2839        isTextColor: true,
2840        body: ordargument(body)
2841      };
2842    },
2843    mathmlBuilder: mathmlBuilder$9
2844  });
2845  defineFunction({
2846    type: "color",
2847    names: ["\\color"],
2848    props: {
2849      numArgs: 1,
2850      numOptionalArgs: 1,
2851      allowedInText: true,
2852      argTypes: ["raw", "raw"]
2853    },
2854    handler({ parser, breakOnTokenText, token }, args, optArgs) {
2855      const model = optArgs[0] && assertNodeType(optArgs[0], "raw").string;
2856      let color = "";
2857      if (model) {
2858        const spec = assertNodeType(args[0], "raw").string;
2859        color = colorFromSpec(model, spec);
2860      } else {
2861        color = validateColor(assertNodeType(args[0], "raw").string, parser.gullet.macros, token);
2862      }
2863      const body = parser.parseExpression(true, breakOnTokenText, true);
2864      return {
2865        type: "color",
2866        mode: parser.mode,
2867        color,
2868        isTextColor: false,
2869        body
2870      };
2871    },
2872    mathmlBuilder: mathmlBuilder$9
2873  });
2874  defineFunction({
2875    type: "color",
2876    names: ["\\definecolor"],
2877    props: {
2878      numArgs: 3,
2879      allowedInText: true,
2880      argTypes: ["raw", "raw", "raw"]
2881    },
2882    handler({ parser, funcName, token }, args) {
2883      const name = assertNodeType(args[0], "raw").string;
2884      if (!/^[A-Za-z]+$/.test(name)) {
2885        throw new ParseError("Color name must be latin letters.", token);
2886      }
2887      const model = assertNodeType(args[1], "raw").string;
2888      if (!["HTML", "RGB", "rgb"].includes(model)) {
2889        throw new ParseError("Color model must be HTML, RGB, or rgb.", token);
2890      }
2891      const spec = assertNodeType(args[2], "raw").string;
2892      const color = colorFromSpec(model, spec);
2893      parser.gullet.macros.set(`\\\\color@$name}`, { tokens: [{ text: color }], numArgs: 0 });
2894      return { type: "internal", mode: parser.mode };
2895    }
2896    // No mathmlBuilder. The point of \definecolor is to set a macro.
2897  });
2898  defineFunction({
2899    type: "cr",
2900    names: ["\\\\"],
2901    props: {
2902      numArgs: 0,
2903      numOptionalArgs: 0,
2904      allowedInText: true
2905    },
2906    handler({ parser }, args, optArgs) {
2907      const size = parser.gullet.future().text === "[" ? parser.parseSizeGroup(true) : null;
2908      const newLine = !parser.settings.displayMode;
2909      return {
2910        type: "cr",
2911        mode: parser.mode,
2912        newLine,
2913        size: size && assertNodeType(size, "size").value
2914      };
2915    },
2916    // The following builder is called only at the top level,
2917    // not within tabular/array environments.
2918    mathmlBuilder(group, style) {
2919      const node = new mathMLTree.MathNode("mo");
2920      if (group.newLine) {
2921        node.setAttribute("linebreak", "newline");
2922        if (group.size) {
2923          const size = calculateSize(group.size, style);
2924          node.setAttribute("height", size.number + size.unit);
2925        }
2926      }
2927      return node;
2928    }
2929  });
2930  var globalMap = {
2931    "\\global": "\\global",
2932    "\\long": "\\\\globallong",
2933    "\\\\globallong": "\\\\globallong",
2934    "\\def": "\\gdef",
2935    "\\gdef": "\\gdef",
2936    "\\edef": "\\xdef",
2937    "\\xdef": "\\xdef",
2938    "\\let": "\\\\globallet",
2939    "\\futurelet": "\\\\globalfuture"
2940  };
2941  var checkControlSequence = (tok) => {
2942    const name = tok.text;
2943    if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) {
2944      throw new ParseError("Expected a control sequence", tok);
2945    }
2946    return name;
2947  };
2948  var getRHS = (parser) => {
2949    let tok = parser.gullet.popToken();
2950    if (tok.text === "=") {
2951      tok = parser.gullet.popToken();
2952      if (tok.text === " ") {
2953        tok = parser.gullet.popToken();
2954      }
2955    }
2956    return tok;
2957  };
2958  var letCommand = (parser, name, tok, global) => {
2959    let macro = parser.gullet.macros.get(tok.text);
2960    if (macro == null) {
2961      tok.noexpand = true;
2962      macro = {
2963        tokens: [tok],
2964        numArgs: 0,
2965        // reproduce the same behavior in expansion
2966        unexpandable: !parser.gullet.isExpandable(tok.text)
2967      };
2968    }
2969    parser.gullet.macros.set(name, macro, global);
2970  };
2971  defineFunction({
2972    type: "internal",
2973    names: [
2974      "\\global",
2975      "\\long",
2976      "\\\\globallong"
2977      // can’t be entered directly
2978    ],
2979    props: {
2980      numArgs: 0,
2981      allowedInText: true
2982    },
2983    handler({ parser, funcName }) {
2984      parser.consumeSpaces();
2985      const token = parser.fetch();
2986      if (globalMap[token.text]) {
2987        if (funcName === "\\global" || funcName === "\\\\globallong") {
2988          token.text = globalMap[token.text];
2989        }
2990        return assertNodeType(parser.parseFunction(), "internal");
2991      }
2992      throw new ParseError(`Invalid token after macro prefix`, token);
2993    }
2994  });
2995  defineFunction({
2996    type: "internal",
2997    names: ["\\def", "\\gdef", "\\edef", "\\xdef"],
2998    props: {
2999      numArgs: 0,
3000      allowedInText: true,
3001      primitive: true
3002    },
3003    handler({ parser, funcName }) {
3004      let tok = parser.gullet.popToken();
3005      const name = tok.text;
3006      if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) {
3007        throw new ParseError("Expected a control sequence", tok);
3008      }
3009      let numArgs = 0;
3010      let insert;
3011      const delimiters2 = [[]];
3012      while (parser.gullet.future().text !== "{") {
3013        tok = parser.gullet.popToken();
3014        if (tok.text === "#") {
3015          if (parser.gullet.future().text === "{") {
3016            insert = parser.gullet.future();
3017            delimiters2[numArgs].push("{");
3018            break;
3019          }
3020          tok = parser.gullet.popToken();
3021          if (!/^[1-9]$/.test(tok.text)) {
3022            throw new ParseError(`Invalid argument number "$tok.text}"`);
3023          }
3024          if (parseInt(tok.text) !== numArgs + 1) {
3025            throw new ParseError(`Argument number "$tok.text}" out of order`);
3026          }
3027          numArgs++;
3028          delimiters2.push([]);
3029        } else if (tok.text === "EOF") {
3030          throw new ParseError("Expected a macro definition");
3031        } else {
3032          delimiters2[numArgs].push(tok.text);
3033        }
3034      }
3035      let { tokens } = parser.gullet.consumeArg();
3036      if (insert) {
3037        tokens.unshift(insert);
3038      }
3039      if (funcName === "\\edef" || funcName === "\\xdef") {
3040        tokens = parser.gullet.expandTokens(tokens);
3041        if (tokens.length > parser.gullet.settings.maxExpand) {
3042          throw new ParseError("Too many expansions in an " + funcName);
3043        }
3044        tokens.reverse();
3045      }
3046      parser.gullet.macros.set(
3047        name,
3048        { tokens, numArgs, delimiters: delimiters2 },
3049        funcName === globalMap[funcName]
3050      );
3051      return { type: "internal", mode: parser.mode };
3052    }
3053  });
3054  defineFunction({
3055    type: "internal",
3056    names: [
3057      "\\let",
3058      "\\\\globallet"
3059      // can’t be entered directly
3060    ],
3061    props: {
3062      numArgs: 0,
3063      allowedInText: true,
3064      primitive: true
3065    },
3066    handler({ parser, funcName }) {
3067      const name = checkControlSequence(parser.gullet.popToken());
3068      parser.gullet.consumeSpaces();
3069      const tok = getRHS(parser);
3070      letCommand(parser, name, tok, funcName === "\\\\globallet");
3071      return { type: "internal", mode: parser.mode };
3072    }
3073  });
3074  defineFunction({
3075    type: "internal",
3076    names: [
3077      "\\futurelet",
3078      "\\\\globalfuture"
3079      // can’t be entered directly
3080    ],
3081    props: {
3082      numArgs: 0,
3083      allowedInText: true,
3084      primitive: true
3085    },
3086    handler({ parser, funcName }) {
3087      const name = checkControlSequence(parser.gullet.popToken());
3088      const middle = parser.gullet.popToken();
3089      const tok = parser.gullet.popToken();
3090      letCommand(parser, name, tok, funcName === "\\\\globalfuture");
3091      parser.gullet.pushToken(tok);
3092      parser.gullet.pushToken(middle);
3093      return { type: "internal", mode: parser.mode };
3094    }
3095  });
3096  defineFunction({
3097    type: "internal",
3098    names: ["\\newcommand", "\\renewcommand", "\\providecommand"],
3099    props: {
3100      numArgs: 0,
3101      allowedInText: true,
3102      primitive: true
3103    },
3104    handler({ parser, funcName }) {
3105      let name = "";
3106      const tok = parser.gullet.popToken();
3107      if (tok.text === "{") {
3108        name = checkControlSequence(parser.gullet.popToken());
3109        parser.gullet.popToken();
3110      } else {
3111        name = checkControlSequence(tok);
3112      }
3113      const exists = parser.gullet.isDefined(name);
3114      if (exists && funcName === "\\newcommand") {
3115        throw new ParseError(
3116          `\\newcommand{$name}} attempting to redefine $name}; use \\renewcommand`
3117        );
3118      }
3119      if (!exists && funcName === "\\renewcommand") {
3120        throw new ParseError(
3121          `\\renewcommand{$name}} when command $name} does not yet exist; use \\newcommand`
3122        );
3123      }
3124      let numArgs = 0;
3125      if (parser.gullet.future().text === "[") {
3126        let tok2 = parser.gullet.popToken();
3127        tok2 = parser.gullet.popToken();
3128        if (!/^[0-9]$/.test(tok2.text)) {
3129          throw new ParseError(`Invalid number of arguments: "$tok2.text}"`);
3130        }
3131        numArgs = parseInt(tok2.text);
3132        tok2 = parser.gullet.popToken();
3133        if (tok2.text !== "]") {
3134          throw new ParseError(`Invalid argument "$tok2.text}"`);
3135        }
3136      }
3137      const { tokens } = parser.gullet.consumeArg();
3138      if (!(funcName === "\\providecommand" && parser.gullet.macros.has(name))) {
3139        parser.gullet.macros.set(
3140          name,
3141          { tokens, numArgs }
3142        );
3143      }
3144      return { type: "internal", mode: parser.mode };
3145    }
3146  });
3147  var delimiterSizes = {
3148    "\\bigl": { mclass: "mopen", size: 1 },
3149    "\\Bigl": { mclass: "mopen", size: 2 },
3150    "\\biggl": { mclass: "mopen", size: 3 },
3151    "\\Biggl": { mclass: "mopen", size: 4 },
3152    "\\bigr": { mclass: "mclose", size: 1 },
3153    "\\Bigr": { mclass: "mclose", size: 2 },
3154    "\\biggr": { mclass: "mclose", size: 3 },
3155    "\\Biggr": { mclass: "mclose", size: 4 },
3156    "\\bigm": { mclass: "mrel", size: 1 },
3157    "\\Bigm": { mclass: "mrel", size: 2 },
3158    "\\biggm": { mclass: "mrel", size: 3 },
3159    "\\Biggm": { mclass: "mrel", size: 4 },
3160    "\\big": { mclass: "mord", size: 1 },
3161    "\\Big": { mclass: "mord", size: 2 },
3162    "\\bigg": { mclass: "mord", size: 3 },
3163    "\\Bigg": { mclass: "mord", size: 4 }
3164  };
3165  var delimiters = [
3166    "(",
3167    "\\lparen",
3168    ")",
3169    "\\rparen",
3170    "[",
3171    "\\lbrack",
3172    "]",
3173    "\\rbrack",
3174    "\\{",
3175    "\\lbrace",
3176    "\\}",
3177    "\\rbrace",
3178    "\u2987",
3179    "\\llparenthesis",
3180    "\u2988",
3181    "\\rrparenthesis",
3182    "\\lfloor",
3183    "\\rfloor",
3184    "\u230A",
3185    "\u230B",
3186    "\\lceil",
3187    "\\rceil",
3188    "\u2308",
3189    "\u2309",
3190    "<",
3191    ">",
3192    "\\langle",
3193    "\u27E8",
3194    "\\rangle",
3195    "\u27E9",
3196    "\\lAngle",
3197    "\u27EA",
3198    "\\rAngle",
3199    "\u27EB",
3200    "\\llangle",
3201    "\u2989",
3202    "\\rrangle",
3203    "\u298A",
3204    "\\lt",
3205    "\\gt",
3206    "\\lvert",
3207    "\\rvert",
3208    "\\lVert",
3209    "\\rVert",
3210    "\\lgroup",
3211    "\\rgroup",
3212    "\u27EE",
3213    "\u27EF",
3214    "\\lmoustache",
3215    "\\rmoustache",
3216    "\u23B0",
3217    "\u23B1",
3218    "\\llbracket",
3219    "\\rrbracket",
3220    "\u27E6",
3221    "\u27E6",
3222    "\\lBrace",
3223    "\\rBrace",
3224    "\u2983",
3225    "\u2984",
3226    "/",
3227    "\\backslash",
3228    "|",
3229    "\\vert",
3230    "\\|",
3231    "\\Vert",
3232    "\u2016",
3233    "\\uparrow",
3234    "\\Uparrow",
3235    "\\downarrow",
3236    "\\Downarrow",
3237    "\\updownarrow",
3238    "\\Updownarrow",
3239    "."
3240  ];
3241  var dels = ["}", "\\left", "\\middle", "\\right"];
3242  var isDelimiter = (str) => str.length > 0 && (delimiters.includes(str) || delimiterSizes[str] || dels.includes(str));
3243  var sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3];
3244  function checkDelimiter(delim, context) {
3245    const symDelim = checkSymbolNodeType(delim);
3246    if (symDelim && delimiters.includes(symDelim.text)) {
3247      if (["<", "\\lt"].includes(symDelim.text)) {
3248        symDelim.text = "\u27E8";
3249      }
3250      if ([">", "\\gt"].includes(symDelim.text)) {
3251        symDelim.text = "\u27E9";
3252      }
3253      return symDelim;
3254    } else if (symDelim) {
3255      throw new ParseError(`Invalid delimiter '$symDelim.text}' after '$context.funcName}'`, delim);
3256    } else {
3257      throw new ParseError(`Invalid delimiter type '$delim.type}'`, delim);
3258    }
3259  }
3260  var needExplicitStretch = ["/", "\\", "\\backslash", "\\vert", "|"];
3261  defineFunction({
3262    type: "delimsizing",
3263    names: [
3264      "\\bigl",
3265      "\\Bigl",
3266      "\\biggl",
3267      "\\Biggl",
3268      "\\bigr",
3269      "\\Bigr",
3270      "\\biggr",
3271      "\\Biggr",
3272      "\\bigm",
3273      "\\Bigm",
3274      "\\biggm",
3275      "\\Biggm",
3276      "\\big",
3277      "\\Big",
3278      "\\bigg",
3279      "\\Bigg"
3280    ],
3281    props: {
3282      numArgs: 1,
3283      argTypes: ["primitive"]
3284    },
3285    handler: (context, args) => {
3286      const delim = checkDelimiter(args[0], context);
3287      return {
3288        type: "delimsizing",
3289        mode: context.parser.mode,
3290        size: delimiterSizes[context.funcName].size,
3291        mclass: delimiterSizes[context.funcName].mclass,
3292        delim: delim.text
3293      };
3294    },
3295    mathmlBuilder: (group) => {
3296      const children = [];
3297      if (group.delim === ".") {
3298        group.delim = "";
3299      }
3300      children.push(makeText(group.delim, group.mode));
3301      const node = new mathMLTree.MathNode("mo", children);
3302      if (group.mclass === "mopen" || group.mclass === "mclose") {
3303        node.setAttribute("fence", "true");
3304      } else {
3305        node.setAttribute("fence", "false");
3306      }
3307      if (needExplicitStretch.includes(group.delim) || group.delim.indexOf("arrow") > -1) {
3308        node.setAttribute("stretchy", "true");
3309      }
3310      node.setAttribute("symmetric", "true");
3311      node.setAttribute("minsize", sizeToMaxHeight[group.size] + "em");
3312      node.setAttribute("maxsize", sizeToMaxHeight[group.size] + "em");
3313      return node;
3314    }
3315  });
3316  function assertParsed(group) {
3317    if (!group.body) {
3318      throw new Error("Bug: The leftright ParseNode wasn't fully parsed.");
3319    }
3320  }
3321  defineFunction({
3322    type: "leftright-right",
3323    names: ["\\right"],
3324    props: {
3325      numArgs: 1,
3326      argTypes: ["primitive"]
3327    },
3328    handler: (context, args) => {
3329      return {
3330        type: "leftright-right",
3331        mode: context.parser.mode,
3332        delim: checkDelimiter(args[0], context).text
3333      };
3334    }
3335  });
3336  defineFunction({
3337    type: "leftright",
3338    names: ["\\left"],
3339    props: {
3340      numArgs: 1,
3341      argTypes: ["primitive"]
3342    },
3343    handler: (context, args) => {
3344      const delim = checkDelimiter(args[0], context);
3345      const parser = context.parser;
3346      ++parser.leftrightDepth;
3347      let body = parser.parseExpression(false, null, true);
3348      let nextToken = parser.fetch();
3349      while (nextToken.text === "\\middle") {
3350        parser.consume();
3351        const middle = parser.fetch().text;
3352        if (!symbols.math[middle]) {
3353          throw new ParseError(`Invalid delimiter '$middle}' after '\\middle'`);
3354        }
3355        checkDelimiter({ type: "atom", mode: "math", text: middle }, { funcName: "\\middle" });
3356        body.push({ type: "middle", mode: "math", delim: middle });
3357        parser.consume();
3358        body = body.concat(parser.parseExpression(false, null, true));
3359        nextToken = parser.fetch();
3360      }
3361      --parser.leftrightDepth;
3362      parser.expect("\\right", false);
3363      const right = assertNodeType(parser.parseFunction(), "leftright-right");
3364      return {
3365        type: "leftright",
3366        mode: parser.mode,
3367        body,
3368        left: delim.text,
3369        right: right.delim
3370      };
3371    },
3372    mathmlBuilder: (group, style) => {
3373      assertParsed(group);
3374      const inner2 = buildExpression(group.body, style);
3375      if (group.left === ".") {
3376        group.left = "";
3377      }
3378      const leftNode = new mathMLTree.MathNode("mo", [makeText(group.left, group.mode)]);
3379      leftNode.setAttribute("fence", "true");
3380      leftNode.setAttribute("form", "prefix");
3381      if (group.left === "/" || group.left === "\\" || group.left.indexOf("arrow") > -1) {
3382        leftNode.setAttribute("stretchy", "true");
3383      }
3384      inner2.unshift(leftNode);
3385      if (group.right === ".") {
3386        group.right = "";
3387      }
3388      const rightNode = new mathMLTree.MathNode("mo", [makeText(group.right, group.mode)]);
3389      rightNode.setAttribute("fence", "true");
3390      rightNode.setAttribute("form", "postfix");
3391      if (group.right === "\u2216" || group.right.indexOf("arrow") > -1) {
3392        rightNode.setAttribute("stretchy", "true");
3393      }
3394      if (group.body.length > 0) {
3395        const lastElement = group.body[group.body.length - 1];
3396        if (lastElement.type === "color" && !lastElement.isTextColor) {
3397          rightNode.setAttribute("mathcolor", lastElement.color);
3398        }
3399      }
3400      inner2.push(rightNode);
3401      return makeRow(inner2);
3402    }
3403  });
3404  defineFunction({
3405    type: "middle",
3406    names: ["\\middle"],
3407    props: {
3408      numArgs: 1,
3409      argTypes: ["primitive"]
3410    },
3411    handler: (context, args) => {
3412      const delim = checkDelimiter(args[0], context);
3413      if (!context.parser.leftrightDepth) {
3414        throw new ParseError("\\middle without preceding \\left", delim);
3415      }
3416      return {
3417        type: "middle",
3418        mode: context.parser.mode,
3419        delim: delim.text
3420      };
3421    },
3422    mathmlBuilder: (group, style) => {
3423      const textNode = makeText(group.delim, group.mode);
3424      const middleNode = new mathMLTree.MathNode("mo", [textNode]);
3425      middleNode.setAttribute("fence", "true");
3426      if (group.delim.indexOf("arrow") > -1) {
3427        middleNode.setAttribute("stretchy", "true");
3428      }
3429      middleNode.setAttribute("form", "prefix");
3430      middleNode.setAttribute("lspace", "0.05em");
3431      middleNode.setAttribute("rspace", "0.05em");
3432      return middleNode;
3433    }
3434  });
3435  var padding$1 = (_) => {
3436    const node = new mathMLTree.MathNode("mspace");
3437    node.setAttribute("width", "3pt");
3438    return node;
3439  };
3440  var mathmlBuilder$8 = (group, style) => {
3441    let node;
3442    if (group.label.indexOf("colorbox") > -1 || group.label === "\\boxed") {
3443      node = new mathMLTree.MathNode("mrow", [
3444        padding$1(),
3445        buildGroup$1(group.body, style),
3446        padding$1()
3447      ]);
3448    } else {
3449      node = new mathMLTree.MathNode("menclose", [buildGroup$1(group.body, style)]);
3450    }
3451    switch (group.label) {
3452      case "\\overline":
3453        node.setAttribute("notation", "top");
3454        node.classes.push("tml-overline");
3455        break;
3456      case "\\underline":
3457        node.setAttribute("notation", "bottom");
3458        node.classes.push("tml-underline");
3459        break;
3460      case "\\cancel":
3461        node.setAttribute("notation", "updiagonalstrike");
3462        node.children.push(new mathMLTree.MathNode("mrow", [], ["tml-cancel", "upstrike"]));
3463        break;
3464      case "\\bcancel":
3465        node.setAttribute("notation", "downdiagonalstrike");
3466        node.children.push(new mathMLTree.MathNode("mrow", [], ["tml-cancel", "downstrike"]));
3467        break;
3468      case "\\sout":
3469        node.setAttribute("notation", "horizontalstrike");
3470        node.children.push(new mathMLTree.MathNode("mrow", [], ["tml-cancel", "sout"]));
3471        break;
3472      case "\\xcancel":
3473        node.setAttribute("notation", "updiagonalstrike downdiagonalstrike");
3474        node.classes.push("tml-xcancel");
3475        break;
3476      case "\\longdiv":
3477        node.setAttribute("notation", "longdiv");
3478        node.classes.push("longdiv-top");
3479        node.children.push(new mathMLTree.MathNode("mrow", [], ["longdiv-arc"]));
3480        break;
3481      case "\\phase":
3482        node.setAttribute("notation", "phasorangle");
3483        node.classes.push("phasor-bottom");
3484        node.children.push(new mathMLTree.MathNode("mrow", [], ["phasor-angle"]));
3485        break;
3486      case "\\textcircled":
3487        node.setAttribute("notation", "circle");
3488        node.classes.push("circle-pad");
3489        node.children.push(new mathMLTree.MathNode("mrow", [], ["textcircle"]));
3490        break;
3491      case "\\angl":
3492        node.setAttribute("notation", "actuarial");
3493        node.classes.push("actuarial");
3494        break;
3495      case "\\boxed":
3496        node.setAttribute("notation", "box");
3497        node.classes.push("tml-box");
3498        node.setAttribute("scriptlevel", "0");
3499        node.setAttribute("displaystyle", "true");
3500        break;
3501      case "\\fbox":
3502        node.setAttribute("notation", "box");
3503        node.classes.push("tml-fbox");
3504        break;
3505      case "\\fcolorbox":
3506      case "\\colorbox": {
3507        const style2 = { padding: "3pt 0 3pt 0" };
3508        if (group.label === "\\fcolorbox") {
3509          style2.border = "0.0667em solid " + String(group.borderColor);
3510        }
3511        node.style = style2;
3512        break;
3513      }
3514    }
3515    if (group.backgroundColor) {
3516      node.setAttribute("mathbackground", group.backgroundColor);
3517    }
3518    return node;
3519  };
3520  defineFunction({
3521    type: "enclose",
3522    names: ["\\colorbox"],
3523    props: {
3524      numArgs: 2,
3525      numOptionalArgs: 1,
3526      allowedInText: true,
3527      argTypes: ["raw", "raw", "text"]
3528    },
3529    handler({ parser, funcName }, args, optArgs) {
3530      const model = optArgs[0] && assertNodeType(optArgs[0], "raw").string;
3531      let color = "";
3532      if (model) {
3533        const spec = assertNodeType(args[0], "raw").string;
3534        color = colorFromSpec(model, spec);
3535      } else {
3536        color = validateColor(assertNodeType(args[0], "raw").string, parser.gullet.macros);
3537      }
3538      const body = args[1];
3539      return {
3540        type: "enclose",
3541        mode: parser.mode,
3542        label: funcName,
3543        backgroundColor: color,
3544        body
3545      };
3546    },
3547    mathmlBuilder: mathmlBuilder$8
3548  });
3549  defineFunction({
3550    type: "enclose",
3551    names: ["\\fcolorbox"],
3552    props: {
3553      numArgs: 3,
3554      numOptionalArgs: 1,
3555      allowedInText: true,
3556      argTypes: ["raw", "raw", "raw", "text"]
3557    },
3558    handler({ parser, funcName }, args, optArgs) {
3559      const model = optArgs[0] && assertNodeType(optArgs[0], "raw").string;
3560      let borderColor = "";
3561      let backgroundColor;
3562      if (model) {
3563        const borderSpec = assertNodeType(args[0], "raw").string;
3564        const backgroundSpec = assertNodeType(args[0], "raw").string;
3565        borderColor = colorFromSpec(model, borderSpec);
3566        backgroundColor = colorFromSpec(model, backgroundSpec);
3567      } else {
3568        borderColor = validateColor(assertNodeType(args[0], "raw").string, parser.gullet.macros);
3569        backgroundColor = validateColor(assertNodeType(args[1], "raw").string, parser.gullet.macros);
3570      }
3571      const body = args[2];
3572      return {
3573        type: "enclose",
3574        mode: parser.mode,
3575        label: funcName,
3576        backgroundColor,
3577        borderColor,
3578        body
3579      };
3580    },
3581    mathmlBuilder: mathmlBuilder$8
3582  });
3583  defineFunction({
3584    type: "enclose",
3585    names: ["\\fbox"],
3586    props: {
3587      numArgs: 1,
3588      argTypes: ["hbox"],
3589      allowedInText: true
3590    },
3591    handler({ parser }, args) {
3592      return {
3593        type: "enclose",
3594        mode: parser.mode,
3595        label: "\\fbox",
3596        body: args[0]
3597      };
3598    }
3599  });
3600  defineFunction({
3601    type: "enclose",
3602    names: [
3603      "\\angl",
3604      "\\cancel",
3605      "\\bcancel",
3606      "\\xcancel",
3607      "\\sout",
3608      "\\overline",
3609      "\\boxed",
3610      "\\longdiv",
3611      "\\phase"
3612    ],
3613    props: {
3614      numArgs: 1
3615    },
3616    handler({ parser, funcName }, args) {
3617      const body = args[0];
3618      return {
3619        type: "enclose",
3620        mode: parser.mode,
3621        label: funcName,
3622        body
3623      };
3624    },
3625    mathmlBuilder: mathmlBuilder$8
3626  });
3627  defineFunction({
3628    type: "enclose",
3629    names: ["\\underline"],
3630    props: {
3631      numArgs: 1,
3632      allowedInText: true
3633    },
3634    handler({ parser, funcName }, args) {
3635      const body = args[0];
3636      return {
3637        type: "enclose",
3638        mode: parser.mode,
3639        label: funcName,
3640        body
3641      };
3642    },
3643    mathmlBuilder: mathmlBuilder$8
3644  });
3645  defineFunction({
3646    type: "enclose",
3647    names: ["\\textcircled"],
3648    props: {
3649      numArgs: 1,
3650      argTypes: ["text"],
3651      allowedInArgument: true,
3652      allowedInText: true
3653    },
3654    handler({ parser, funcName }, args) {
3655      const body = args[0];
3656      return {
3657        type: "enclose",
3658        mode: parser.mode,
3659        label: funcName,
3660        body
3661      };
3662    },
3663    mathmlBuilder: mathmlBuilder$8
3664  });
3665  var _environments = {};
3666  function defineEnvironment({ type, names, props, handler, mathmlBuilder: mathmlBuilder2 }) {
3667    const data = {
3668      type,
3669      numArgs: props.numArgs || 0,
3670      allowedInText: false,
3671      numOptionalArgs: 0,
3672      handler
3673    };
3674    for (let i = 0; i < names.length; ++i) {
3675      _environments[names[i]] = data;
3676    }
3677    if (mathmlBuilder2) {
3678      _mathmlGroupBuilders[type] = mathmlBuilder2;
3679    }
3680  }
3681  var SourceLocation = class _SourceLocation {
3682    constructor(lexer, start, end) {
3683      this.lexer = lexer;
3684      this.start = start;
3685      this.end = end;
3686    }
3687    /**
3688     * Merges two `SourceLocation`s from location providers, given they are
3689     * provided in order of appearance.
3690     * - Returns the first one's location if only the first is provided.
3691     * - Returns a merged range of the first and the last if both are provided
3692     *   and their lexers match.
3693     * - Otherwise, returns null.
3694     */
3695    static range(first, second) {
3696      if (!second) {
3697        return first && first.loc;
3698      } else if (!first || !first.loc || !second.loc || first.loc.lexer !== second.loc.lexer) {
3699        return null;
3700      } else {
3701        return new _SourceLocation(first.loc.lexer, first.loc.start, second.loc.end);
3702      }
3703    }
3704  };
3705  var Token = class _Token {
3706    constructor(text2, loc) {
3707      this.text = text2;
3708      this.loc = loc;
3709    }
3710    /**
3711     * Given a pair of tokens (this and endToken), compute a `Token` encompassing
3712     * the whole input range enclosed by these two.
3713     */
3714    range(endToken, text2) {
3715      return new _Token(text2, SourceLocation.range(this, endToken));
3716    }
3717  };
3718  var StyleLevel = {
3719    DISPLAY: 0,
3720    TEXT: 1,
3721    SCRIPT: 2,
3722    SCRIPTSCRIPT: 3
3723  };
3724  var _macros = {};
3725  function defineMacro(name, body) {
3726    _macros[name] = body;
3727  }
3728  var macros = _macros;
3729  defineMacro("\\noexpand", function(context) {
3730    const t = context.popToken();
3731    if (context.isExpandable(t.text)) {
3732      t.noexpand = true;
3733      t.treatAsRelax = true;
3734    }
3735    return { tokens: [t], numArgs: 0 };
3736  });
3737  defineMacro("\\expandafter", function(context) {
3738    const t = context.popToken();
3739    context.expandOnce(true);
3740    return { tokens: [t], numArgs: 0 };
3741  });
3742  defineMacro("\\@firstoftwo", function(context) {
3743    const args = context.consumeArgs(2);
3744    return { tokens: args[0], numArgs: 0 };
3745  });
3746  defineMacro("\\@secondoftwo", function(context) {
3747    const args = context.consumeArgs(2);
3748    return { tokens: args[1], numArgs: 0 };
3749  });
3750  defineMacro("\\@ifnextchar", function(context) {
3751    const args = context.consumeArgs(3);
3752    context.consumeSpaces();
3753    const nextToken = context.future();
3754    if (args[0].length === 1 && args[0][0].text === nextToken.text) {
3755      return { tokens: args[1], numArgs: 0 };
3756    } else {
3757      return { tokens: args[2], numArgs: 0 };
3758    }
3759  });
3760  defineMacro("\\@ifstar", "\\@ifnextchar *{\\@firstoftwo{#1}}");
3761  defineMacro("\\TextOrMath", function(context) {
3762    const args = context.consumeArgs(2);
3763    if (context.mode === "text") {
3764      return { tokens: args[0], numArgs: 0 };
3765    } else {
3766      return { tokens: args[1], numArgs: 0 };
3767    }
3768  });
3769  var stringFromArg = (arg) => {
3770    let str = "";
3771    for (let i = arg.length - 1; i > -1; i--) {
3772      str += arg[i].text;
3773    }
3774    return str;
3775  };
3776  var digitToNumber = {
3777    0: 0,
3778    1: 1,
3779    2: 2,
3780    3: 3,
3781    4: 4,
3782    5: 5,
3783    6: 6,
3784    7: 7,
3785    8: 8,
3786    9: 9,
3787    a: 10,
3788    A: 10,
3789    b: 11,
3790    B: 11,
3791    c: 12,
3792    C: 12,
3793    d: 13,
3794    D: 13,
3795    e: 14,
3796    E: 14,
3797    f: 15,
3798    F: 15
3799  };
3800  var nextCharNumber = (context) => {
3801    const numStr = context.future().text;
3802    if (numStr === "EOF") {
3803      return [null, ""];
3804    }
3805    return [digitToNumber[numStr.charAt(0)], numStr];
3806  };
3807  var appendCharNumbers = (number, numStr, base) => {
3808    for (let i = 1; i < numStr.length; i++) {
3809      const digit = digitToNumber[numStr.charAt(i)];
3810      number *= base;
3811      number += digit;
3812    }
3813    return number;
3814  };
3815  defineMacro("\\char", function(context) {
3816    let token = context.popToken();
3817    let base;
3818    let number = "";
3819    if (token.text === "'") {
3820      base = 8;
3821      token = context.popToken();
3822    } else if (token.text === '"') {
3823      base = 16;
3824      token = context.popToken();
3825    } else if (token.text === "`") {
3826      token = context.popToken();
3827      if (token.text[0] === "\\") {
3828        number = token.text.charCodeAt(1);
3829      } else if (token.text === "EOF") {
3830        throw new ParseError("\\char` missing argument");
3831      } else {
3832        number = token.text.charCodeAt(0);
3833      }
3834    } else {
3835      base = 10;
3836    }
3837    if (base) {
3838      let numStr = token.text;
3839      number = digitToNumber[numStr.charAt(0)];
3840      if (number == null || number >= base) {
3841        throw new ParseError(`Invalid base-$base} digit $token.text}`);
3842      }
3843      number = appendCharNumbers(number, numStr, base);
3844      let digit;
3845      [digit, numStr] = nextCharNumber(context);
3846      while (digit != null && digit < base) {
3847        number *= base;
3848        number += digit;
3849        number = appendCharNumbers(number, numStr, base);
3850        context.popToken();
3851        [digit, numStr] = nextCharNumber(context);
3852      }
3853    }
3854    return `\\@char{$number}}`;
3855  });
3856  function recreateArgStr(context) {
3857    const tokens = context.consumeArgs(1)[0];
3858    let str = "";
3859    let expectedLoc = tokens[tokens.length - 1].loc.start;
3860    for (let i = tokens.length - 1; i >= 0; i--) {
3861      const actualLoc = tokens[i].loc.start;
3862      if (actualLoc > expectedLoc) {
3863        str += " ";
3864        expectedLoc = actualLoc;
3865      }
3866      str += tokens[i].text;
3867      expectedLoc += tokens[i].text.length;
3868    }
3869    return str;
3870  }
3871  defineMacro("\\surd", "\\sqrt{\\vphantom{|}}");
3872  defineMacro("\u2295", "\\oplus");
3873  defineMacro("\\long", "");
3874  defineMacro("\\bgroup", "{");
3875  defineMacro("\\egroup", "}");
3876  defineMacro("~", "\\nobreakspace");
3877  defineMacro("\\lq", "`");
3878  defineMacro("\\rq", "'");
3879  defineMacro("\\aa", "\\r a");
3880  defineMacro("\\Bbbk", "\\Bbb{k}");
3881  defineMacro("\\mathstrut", "\\vphantom{(}");
3882  defineMacro("\\underbar", "\\underline{\\text{#1}}");
3883  defineMacro("\\vdots", "{\\varvdots\\rule{0pt}{15pt}}");
3884  defineMacro("\u22EE", "\\vdots");
3885  defineMacro("\\arraystretch", "1");
3886  defineMacro("\\arraycolsep", "6pt");
3887  defineMacro("\\substack", "\\begin{subarray}{c}#1\\end{subarray}");
3888  defineMacro("\\iff", "\\DOTSB\\;\\Longleftrightarrow\\;");
3889  defineMacro("\\implies", "\\DOTSB\\;\\Longrightarrow\\;");
3890  defineMacro("\\impliedby", "\\DOTSB\\;\\Longleftarrow\\;");
3891  var dotsByToken = {
3892    ",": "\\dotsc",
3893    "\\not": "\\dotsb",
3894    // \keybin@ checks for the following:
3895    "+": "\\dotsb",
3896    "=": "\\dotsb",
3897    "<": "\\dotsb",
3898    ">": "\\dotsb",
3899    "-": "\\dotsb",
3900    "*": "\\dotsb",
3901    ":": "\\dotsb",
3902    // Symbols whose definition starts with \DOTSB:
3903    "\\DOTSB": "\\dotsb",
3904    "\\coprod": "\\dotsb",
3905    "\\bigvee": "\\dotsb",
3906    "\\bigwedge": "\\dotsb",
3907    "\\biguplus": "\\dotsb",
3908    "\\bigcap": "\\dotsb",
3909    "\\bigcup": "\\dotsb",
3910    "\\prod": "\\dotsb",
3911    "\\sum": "\\dotsb",
3912    "\\bigotimes": "\\dotsb",
3913    "\\bigoplus": "\\dotsb",
3914    "\\bigodot": "\\dotsb",
3915    "\\bigsqcap": "\\dotsb",
3916    "\\bigsqcup": "\\dotsb",
3917    "\\bigtimes": "\\dotsb",
3918    "\\And": "\\dotsb",
3919    "\\longrightarrow": "\\dotsb",
3920    "\\Longrightarrow": "\\dotsb",
3921    "\\longleftarrow": "\\dotsb",
3922    "\\Longleftarrow": "\\dotsb",
3923    "\\longleftrightarrow": "\\dotsb",
3924    "\\Longleftrightarrow": "\\dotsb",
3925    "\\mapsto": "\\dotsb",
3926    "\\longmapsto": "\\dotsb",
3927    "\\hookrightarrow": "\\dotsb",
3928    "\\doteq": "\\dotsb",
3929    // Symbols whose definition starts with \mathbin:
3930    "\\mathbin": "\\dotsb",
3931    // Symbols whose definition starts with \mathrel:
3932    "\\mathrel": "\\dotsb",
3933    "\\relbar": "\\dotsb",
3934    "\\Relbar": "\\dotsb",
3935    "\\xrightarrow": "\\dotsb",
3936    "\\xleftarrow": "\\dotsb",
3937    // Symbols whose definition starts with \DOTSI:
3938    "\\DOTSI": "\\dotsi",
3939    "\\int": "\\dotsi",
3940    "\\oint": "\\dotsi",
3941    "\\iint": "\\dotsi",
3942    "\\iiint": "\\dotsi",
3943    "\\iiiint": "\\dotsi",
3944    "\\idotsint": "\\dotsi",
3945    // Symbols whose definition starts with \DOTSX:
3946    "\\DOTSX": "\\dotsx"
3947  };
3948  defineMacro("\\dots", function(context) {
3949    let thedots = "\\dotso";
3950    const next = context.expandAfterFuture().text;
3951    if (next in dotsByToken) {
3952      thedots = dotsByToken[next];
3953    } else if (next.slice(0, 4) === "\\not") {
3954      thedots = "\\dotsb";
3955    } else if (next in symbols.math) {
3956      if (["bin", "rel"].includes(symbols.math[next].group)) {
3957        thedots = "\\dotsb";
3958      }
3959    }
3960    return thedots;
3961  });
3962  var spaceAfterDots = {
3963    // \rightdelim@ checks for the following:
3964    ")": true,
3965    "]": true,
3966    "\\rbrack": true,
3967    "\\}": true,
3968    "\\rbrace": true,
3969    "\\rangle": true,
3970    "\\rceil": true,
3971    "\\rfloor": true,
3972    "\\rgroup": true,
3973    "\\rmoustache": true,
3974    "\\right": true,
3975    "\\bigr": true,
3976    "\\biggr": true,
3977    "\\Bigr": true,
3978    "\\Biggr": true,
3979    // \extra@ also tests for the following:
3980    $: true,
3981    // \extrap@ checks for the following:
3982    ";": true,
3983    ".": true,
3984    ",": true
3985  };
3986  defineMacro("\\dotso", function(context) {
3987    const next = context.future().text;
3988    if (next in spaceAfterDots) {
3989      return "\\ldots\\,";
3990    } else {
3991      return "\\ldots";
3992    }
3993  });
3994  defineMacro("\\dotsc", function(context) {
3995    const next = context.future().text;
3996    if (next in spaceAfterDots && next !== ",") {
3997      return "\\ldots\\,";
3998    } else {
3999      return "\\ldots";
4000    }
4001  });
4002  defineMacro("\\cdots", function(context) {
4003    const next = context.future().text;
4004    if (next in spaceAfterDots) {
4005      return "\\@cdots\\,";
4006    } else {
4007      return "\\@cdots";
4008    }
4009  });
4010  defineMacro("\\dotsb", "\\cdots");
4011  defineMacro("\\dotsm", "\\cdots");
4012  defineMacro("\\dotsi", "\\!\\cdots");
4013  defineMacro("\\idotsint", "\\dotsi");
4014  defineMacro("\\dotsx", "\\ldots\\,");
4015  defineMacro("\\DOTSI", "\\relax");
4016  defineMacro("\\DOTSB", "\\relax");
4017  defineMacro("\\DOTSX", "\\relax");
4018  defineMacro("\\tmspace", "\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax");
4019  defineMacro("\\,", "{\\tmspace+{3mu}{.1667em}}");
4020  defineMacro("\\thinspace", "\\,");
4021  defineMacro("\\>", "\\mskip{4mu}");
4022  defineMacro("\\:", "{\\tmspace+{4mu}{.2222em}}");
4023  defineMacro("\\medspace", "\\:");
4024  defineMacro("\\;", "{\\tmspace+{5mu}{.2777em}}");
4025  defineMacro("\\thickspace", "\\;");
4026  defineMacro("\\!", "{\\tmspace-{3mu}{.1667em}}");
4027  defineMacro("\\negthinspace", "\\!");
4028  defineMacro("\\negmedspace", "{\\tmspace-{4mu}{.2222em}}");
4029  defineMacro("\\negthickspace", "{\\tmspace-{5mu}{.277em}}");
4030  defineMacro("\\enspace", "\\kern.5em ");
4031  defineMacro("\\enskip", "\\hskip.5em\\relax");
4032  defineMacro("\\quad", "\\hskip1em\\relax");
4033  defineMacro("\\qquad", "\\hskip2em\\relax");
4034  defineMacro("\\AA", "\\TextOrMath{\\Angstrom}{\\mathring{A}}\\relax");
4035  defineMacro("\\tag", "\\@ifstar\\tag@literal\\tag@paren");
4036  defineMacro("\\tag@paren", "\\tag@literal{({#1})}");
4037  defineMacro("\\tag@literal", (context) => {
4038    if (context.macros.get("\\df@tag")) {
4039      throw new ParseError("Multiple \\tag");
4040    }
4041    return "\\gdef\\df@tag{\\text{#1}}";
4042  });
4043  defineMacro("\\notag", "\\nonumber");
4044  defineMacro("\\nonumber", "\\gdef\\@eqnsw{0}");
4045  defineMacro("\\bmod", "\\mathbin{\\text{mod}}");
4046  defineMacro(
4047    "\\pod",
4048    "\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"
4049  );
4050  defineMacro("\\pmod", "\\pod{{\\rm mod}\\mkern6mu#1}");
4051  defineMacro(
4052    "\\mod",
4053    "\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"
4054  );
4055  defineMacro("\\newline", "\\\\\\relax");
4056  defineMacro("\\TeX", "\\textrm{T}\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125em\\textrm{X}");
4057  defineMacro(
4058    "\\LaTeX",
4059    "\\textrm{L}\\kern-.35em\\raisebox{0.2em}{\\scriptstyle A}\\kern-.15em\\TeX"
4060  );
4061  defineMacro(
4062    "\\Temml",
4063    // eslint-disable-next-line max-len
4064    "\\textrm{T}\\kern-0.2em\\lower{0.2em}{\\textrm{E}}\\kern-0.08em{\\textrm{M}\\kern-0.08em\\raise{0.2em}\\textrm{M}\\kern-0.08em\\textrm{L}}"
4065  );
4066  defineMacro("\\hspace", "\\@ifstar\\@hspacer\\@hspace");
4067  defineMacro("\\@hspace", "\\hskip #1\\relax");
4068  defineMacro("\\@hspacer", "\\rule{0pt}{0pt}\\hskip #1\\relax");
4069  defineMacro("\\colon", `\\mathpunct{\\char"3a}`);
4070  defineMacro("\\prescript", "\\pres@cript{_{#1}^{#2}}{}{#3}");
4071  defineMacro("\\ordinarycolon", `\\char"3a`);
4072  defineMacro("\\vcentcolon", "\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}}");
4073  defineMacro("\\coloneq", '\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}\\char"2212}');
4074  defineMacro("\\Coloneq", '\\mathrel{\\char"2237\\char"2212}');
4075  defineMacro("\\Eqqcolon", '\\mathrel{\\char"3d\\char"2237}');
4076  defineMacro("\\Eqcolon", '\\mathrel{\\char"2212\\char"2237}');
4077  defineMacro("\\colonapprox", '\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}\\char"2248}');
4078  defineMacro("\\Colonapprox", '\\mathrel{\\char"2237\\char"2248}');
4079  defineMacro("\\colonsim", '\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}\\char"223c}');
4080  defineMacro("\\Colonsim", '\\mathrel{\\raisebox{0.035em}{\\ordinarycolon}\\char"223c}');
4081  defineMacro("\\ratio", "\\vcentcolon");
4082  defineMacro("\\coloncolon", "\\dblcolon");
4083  defineMacro("\\colonequals", "\\coloneqq");
4084  defineMacro("\\coloncolonequals", "\\Coloneqq");
4085  defineMacro("\\equalscolon", "\\eqqcolon");
4086  defineMacro("\\equalscoloncolon", "\\Eqqcolon");
4087  defineMacro("\\colonminus", "\\coloneq");
4088  defineMacro("\\coloncolonminus", "\\Coloneq");
4089  defineMacro("\\minuscolon", "\\eqcolon");
4090  defineMacro("\\minuscoloncolon", "\\Eqcolon");
4091  defineMacro("\\coloncolonapprox", "\\Colonapprox");
4092  defineMacro("\\coloncolonsim", "\\Colonsim");
4093  defineMacro("\\notni", "\\mathrel{\\char`\u220C}");
4094  defineMacro("\\limsup", "\\DOTSB\\operatorname*{lim\\,sup}");
4095  defineMacro("\\liminf", "\\DOTSB\\operatorname*{lim\\,inf}");
4096  defineMacro("\\injlim", "\\DOTSB\\operatorname*{inj\\,lim}");
4097  defineMacro("\\projlim", "\\DOTSB\\operatorname*{proj\\,lim}");
4098  defineMacro("\\varlimsup", "\\DOTSB\\operatorname*{\\overline{\\text{lim}}}");
4099  defineMacro("\\varliminf", "\\DOTSB\\operatorname*{\\underline{\\text{lim}}}");
4100  defineMacro("\\varinjlim", "\\DOTSB\\operatorname*{\\underrightarrow{\\text{lim}}}");
4101  defineMacro("\\varprojlim", "\\DOTSB\\operatorname*{\\underleftarrow{\\text{lim}}}");
4102  defineMacro("\\centerdot", "{\\medspace\\rule{0.167em}{0.189em}\\medspace}");
4103  defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}");
4104  defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}");
4105  defineMacro("\\plim", "\\DOTSB\\operatorname*{plim}");
4106  defineMacro("\\leftmodels", "\\mathop{\\reflectbox{$\\models$}}");
4107  defineMacro("\\bra", "\\mathinner{\\langle{#1}|}");
4108  defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}");
4109  defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}");
4110  defineMacro("\\Bra", "\\left\\langle#1\\right|");
4111  defineMacro("\\Ket", "\\left|#1\\right\\rangle");
4112  var replaceVert = (argStr, match) => {
4113    const ch = match[0] === "|" ? "\\vert" : "\\Vert";
4114    const replaceStr = `}\\,\\middle$ch}\\,{`;
4115    return argStr.slice(0, match.index) + replaceStr + argStr.slice(match.index + match[0].length);
4116  };
4117  defineMacro("\\Braket", function(context) {
4118    let argStr = recreateArgStr(context);
4119    const regEx = /\|\||\||\\\|/g;
4120    let match;
4121    while ((match = regEx.exec(argStr)) !== null) {
4122      argStr = replaceVert(argStr, match);
4123    }
4124    return "\\left\\langle{" + argStr + "}\\right\\rangle";
4125  });
4126  defineMacro("\\Set", function(context) {
4127    let argStr = recreateArgStr(context);
4128    const match = /\|\||\||\\\|/.exec(argStr);
4129    if (match) {
4130      argStr = replaceVert(argStr, match);
4131    }
4132    return "\\left\\{\\:{" + argStr + "}\\:\\right\\}";
4133  });
4134  defineMacro("\\set", function(context) {
4135    const argStr = recreateArgStr(context);
4136    return "\\{{" + argStr.replace(/\|/, "}\\mid{") + "}\\}";
4137  });
4138  defineMacro("\\angln", "{\\angl n}");
4139  defineMacro("\\odv", "\\@ifstar\\odv@next\\odv@numerator");
4140  defineMacro("\\odv@numerator", "\\frac{\\mathrm{d}#1}{\\mathrm{d}#2}");
4141  defineMacro("\\odv@next", "\\frac{\\mathrm{d}}{\\mathrm{d}#2}#1");
4142  defineMacro("\\pdv", "\\@ifstar\\pdv@next\\pdv@numerator");
4143  var pdvHelper = (args) => {
4144    const numerator = args[0][0].text;
4145    const denoms = stringFromArg(args[1]).split(",");
4146    const power = String(denoms.length);
4147    const numOp = power === "1" ? "\\partial" : `\\partial^$power}`;
4148    let denominator = "";
4149    denoms.map((e) => {
4150      denominator += "\\partial " + e.trim() + "\\,";
4151    });
4152    return [numerator, numOp, denominator.replace(/\\,$/, "")];
4153  };
4154  defineMacro("\\pdv@numerator", function(context) {
4155    const [numerator, numOp, denominator] = pdvHelper(context.consumeArgs(2));
4156    return `\\frac{$numOp} $numerator}}{$denominator}}`;
4157  });
4158  defineMacro("\\pdv@next", function(context) {
4159    const [numerator, numOp, denominator] = pdvHelper(context.consumeArgs(2));
4160    return `\\frac{$numOp}}{$denominator}} $numerator}`;
4161  });
4162  defineMacro("\\upalpha", "\\up@greek{\\alpha}");
4163  defineMacro("\\upbeta", "\\up@greek{\\beta}");
4164  defineMacro("\\upgamma", "\\up@greek{\\gamma}");
4165  defineMacro("\\updelta", "\\up@greek{\\delta}");
4166  defineMacro("\\upepsilon", "\\up@greek{\\epsilon}");
4167  defineMacro("\\upzeta", "\\up@greek{\\zeta}");
4168  defineMacro("\\upeta", "\\up@greek{\\eta}");
4169  defineMacro("\\uptheta", "\\up@greek{\\theta}");
4170  defineMacro("\\upiota", "\\up@greek{\\iota}");
4171  defineMacro("\\upkappa", "\\up@greek{\\kappa}");
4172  defineMacro("\\uplambda", "\\up@greek{\\lambda}");
4173  defineMacro("\\upmu", "\\up@greek{\\mu}");
4174  defineMacro("\\upnu", "\\up@greek{\\nu}");
4175  defineMacro("\\upxi", "\\up@greek{\\xi}");
4176  defineMacro("\\upomicron", "\\up@greek{\\omicron}");
4177  defineMacro("\\uppi", "\\up@greek{\\pi}");
4178  defineMacro("\\upalpha", "\\up@greek{\\alpha}");
4179  defineMacro("\\uprho", "\\up@greek{\\rho}");
4180  defineMacro("\\upsigma", "\\up@greek{\\sigma}");
4181  defineMacro("\\uptau", "\\up@greek{\\tau}");
4182  defineMacro("\\upupsilon", "\\up@greek{\\upsilon}");
4183  defineMacro("\\upphi", "\\up@greek{\\phi}");
4184  defineMacro("\\upchi", "\\up@greek{\\chi}");
4185  defineMacro("\\uppsi", "\\up@greek{\\psi}");
4186  defineMacro("\\upomega", "\\up@greek{\\omega}");
4187  defineMacro("\\invamp", '\\mathbin{\\char"214b}');
4188  defineMacro("\\parr", '\\mathbin{\\char"214b}');
4189  defineMacro("\\with", '\\mathbin{\\char"26}');
4190  defineMacro("\\multimapinv", '\\mathrel{\\char"27dc}');
4191  defineMacro("\\multimapboth", '\\mathrel{\\char"29df}');
4192  defineMacro("\\scoh", '{\\mkern5mu\\char"2322\\mkern5mu}');
4193  defineMacro("\\sincoh", '{\\mkern5mu\\char"2323\\mkern5mu}');
4194  defineMacro("\\coh", `{\\mkern5mu\\rule{}{0.7em}\\mathrlap{\\smash{\\raise2mu{\\char"2322}}}
4195  {\\smash{\\lower4mu{\\char"2323}}}\\mkern5mu}`);
4196  defineMacro("\\incoh", `{\\mkern5mu\\rule{}{0.7em}\\mathrlap{\\smash{\\raise2mu{\\char"2323}}}
4197  {\\smash{\\lower4mu{\\char"2322}}}\\mkern5mu}`);
4198  defineMacro("\\standardstate", "\\text{\\tiny\\char`\u29B5}");
4199  defineMacro("\\ce", function(context) {
4200    return chemParse(context.consumeArgs(1)[0], "ce");
4201  });
4202  defineMacro("\\pu", function(context) {
4203    return chemParse(context.consumeArgs(1)[0], "pu");
4204  });
4205  defineMacro("\\uniDash", `{\\rule{0.672em}{0.06em}}`);
4206  defineMacro("\\triDash", `{\\rule{0.15em}{0.06em}\\kern2mu\\rule{0.15em}{0.06em}\\kern2mu\\rule{0.15em}{0.06em}}`);
4207  defineMacro("\\tripleDash", `\\kern0.075em\\raise0.25em{\\triDash}\\kern0.075em`);
4208  defineMacro("\\tripleDashOverLine", `\\kern0.075em\\mathrlap{\\raise0.125em{\\uniDash}}\\raise0.34em{\\triDash}\\kern0.075em`);
4209  defineMacro("\\tripleDashOverDoubleLine", `\\kern0.075em\\mathrlap{\\mathrlap{\\raise0.48em{\\triDash}}\\raise0.27em{\\uniDash}}{\\raise0.05em{\\uniDash}}\\kern0.075em`);
4210  defineMacro("\\tripleDashBetweenDoubleLine", `\\kern0.075em\\mathrlap{\\mathrlap{\\raise0.48em{\\uniDash}}\\raise0.27em{\\triDash}}{\\raise0.05em{\\uniDash}}\\kern0.075em`);
4211  var chemParse = function(tokens, stateMachine) {
4212    var str = "";
4213    var expectedLoc = tokens.length && tokens[tokens.length - 1].loc.start;
4214    for (var i = tokens.length - 1; i >= 0; i--) {
4215      if (tokens[i].loc.start > expectedLoc) {
4216        str += " ";
4217        expectedLoc = tokens[i].loc.start;
4218      }
4219      str += tokens[i].text;
4220      expectedLoc += tokens[i].text.length;
4221    }
4222    var tex = texify.go(mhchemParser.go(str, stateMachine));
4223    return tex;
4224  };
4225  var mhchemParser = {
4226    //
4227    // Parses mchem \ce syntax
4228    //
4229    // Call like
4230    //   go("H2O");
4231    //
4232    go: function(input, stateMachine) {
4233      if (!input) {
4234        return [];
4235      }
4236      if (stateMachine === void 0) {
4237        stateMachine = "ce";
4238      }
4239      var state = "0";
4240      var buffer = {};
4241      buffer["parenthesisLevel"] = 0;
4242      input = input.replace(/\n/g, " ");
4243      input = input.replace(/[\u2212\u2013\u2014\u2010]/g, "-");
4244      input = input.replace(/[\u2026]/g, "...");
4245      var lastInput;
4246      var watchdog = 10;
4247      var output = [];
4248      while (true) {
4249        if (lastInput !== input) {
4250          watchdog = 10;
4251          lastInput = input;
4252        } else {
4253          watchdog--;
4254        }
4255        var machine = mhchemParser.stateMachines[stateMachine];
4256        var t = machine.transitions[state] || machine.transitions["*"];
4257        iterateTransitions:
4258          for (var i = 0; i < t.length; i++) {
4259            var matches = mhchemParser.patterns.match_(t[i].pattern, input);
4260            if (matches) {
4261              var task = t[i].task;
4262              for (var iA = 0; iA < task.action_.length; iA++) {
4263                var o;
4264                if (machine.actions[task.action_[iA].type_]) {
4265                  o = machine.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option);
4266                } else if (mhchemParser.actions[task.action_[iA].type_]) {
4267                  o = mhchemParser.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option);
4268                } else {
4269                  throw ["MhchemBugA", "mhchem bug A. Please report. (" + task.action_[iA].type_ + ")"];
4270                }
4271                mhchemParser.concatArray(output, o);
4272              }
4273              state = task.nextState || state;
4274              if (input.length > 0) {
4275                if (!task.revisit) {
4276                  input = matches.remainder;
4277                }
4278                if (!task.toContinue) {
4279                  break iterateTransitions;
4280                }
4281              } else {
4282                return output;
4283              }
4284            }
4285          }
4286        if (watchdog <= 0) {
4287          throw ["MhchemBugU", "mhchem bug U. Please report."];
4288        }
4289      }
4290    },
4291    concatArray: function(a, b) {
4292      if (b) {
4293        if (Array.isArray(b)) {
4294          for (var iB = 0; iB < b.length; iB++) {
4295            a.push(b[iB]);
4296          }
4297        } else {
4298          a.push(b);
4299        }
4300      }
4301    },
4302    patterns: {
4303      //
4304      // Matching patterns
4305      // either regexps or function that return null or {match_:"a", remainder:"bc"}
4306      //
4307      patterns: {
4308        // property names must not look like integers ("2") for correct property traversal order, later on
4309        "empty": /^$/,
4310        "else": /^./,
4311        "else2": /^./,
4312        "space": /^\s/,
4313        "space A": /^\s(?=[A-Z\\$])/,
4314        "space$": /^\s$/,
4315        "a-z": /^[a-z]/,
4316        "x": /^x/,
4317        "x$": /^x$/,
4318        "i$": /^i$/,
4319        "letters": /^(?:[a-zA-Z\u03B1-\u03C9\u0391-\u03A9?@]|(?:\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))))+/,
4320        "\\greek": /^\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))/,
4321        "one lowercase latin letter $": /^(?:([a-z])(?:$|[^a-zA-Z]))$/,
4322        "$one lowercase latin letter$ $": /^\$(?:([a-z])(?:$|[^a-zA-Z]))\$$/,
4323        "one lowercase greek letter $": /^(?:\$?[\u03B1-\u03C9]\$?|\$?\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega)\s*\$?)(?:\s+|\{\}|(?![a-zA-Z]))$/,
4324        "digits": /^[0-9]+/,
4325        "-9.,9": /^[+\-]?(?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))/,
4326        "-9.,9 no missing 0": /^[+\-]?[0-9]+(?:[.,][0-9]+)?/,
4327        "(-)(9.,9)(e)(99)": function(input) {
4328          var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))?(\((?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))\))?(?:([eE]|\s*(\*|x|\\times|\u00D7)\s*10\^)([+\-]?[0-9]+|\{[+\-]?[0-9]+\}))?/);
4329          if (m && m[0]) {
4330            return { match_: m.splice(1), remainder: input.substr(m[0].length) };
4331          }
4332          return null;
4333        },
4334        "(-)(9)^(-9)": function(input) {
4335          var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+)?)\^([+\-]?[0-9]+|\{[+\-]?[0-9]+\})/);
4336          if (m && m[0]) {
4337            return { match_: m.splice(1), remainder: input.substr(m[0].length) };
4338          }
4339          return null;
4340        },
4341        "state of aggregation $": function(input) {
4342          var a = mhchemParser.patterns.findObserveGroups(input, "", /^\([a-z]{1,3}(?=[\),])/, ")", "");
4343          if (a && a.remainder.match(/^($|[\s,;\)\]\}])/)) {
4344            return a;
4345          }
4346          var m = input.match(/^(?:\((?:\\ca\s?)?\$[amothc]\$\))/);
4347          if (m) {
4348            return { match_: m[0], remainder: input.substr(m[0].length) };
4349          }
4350          return null;
4351        },
4352        "_{(state of aggregation)}$": /^_\{(\([a-z]{1,3}\))\}/,
4353        "{[(": /^(?:\\\{|\[|\()/,
4354        ")]}": /^(?:\)|\]|\\\})/,
4355        ", ": /^[,;]\s*/,
4356        ",": /^[,;]/,
4357        ".": /^[.]/,
4358        ". ": /^([.\u22C5\u00B7\u2022])\s*/,
4359        "...": /^\.\.\.(?=$|[^.])/,
4360        "* ": /^([*])\s*/,
4361        "^{(...)}": function(input) {
4362          return mhchemParser.patterns.findObserveGroups(input, "^{", "", "", "}");
4363        },
4364        "^($...$)": function(input) {
4365          return mhchemParser.patterns.findObserveGroups(input, "^", "$", "$", "");
4366        },
4367        "^a": /^\^([0-9]+|[^\\_])/,
4368        "^\\x{}{}": function(input) {
4369          return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true);
4370        },
4371        "^\\x{}": function(input) {
4372          return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", "");
4373        },
4374        "^\\x": /^\^(\\[a-zA-Z]+)\s*/,
4375        "^(-1)": /^\^(-?\d+)/,
4376        "'": /^'/,
4377        "_{(...)}": function(input) {
4378          return mhchemParser.patterns.findObserveGroups(input, "_{", "", "", "}");
4379        },
4380        "_($...$)": function(input) {
4381          return mhchemParser.patterns.findObserveGroups(input, "_", "$", "$", "");
4382        },
4383        "_9": /^_([+\-]?[0-9]+|[^\\])/,
4384        "_\\x{}{}": function(input) {
4385          return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true);
4386        },
4387        "_\\x{}": function(input) {
4388          return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", "");
4389        },
4390        "_\\x": /^_(\\[a-zA-Z]+)\s*/,
4391        "^_": /^(?:\^(?=_)|\_(?=\^)|[\^_]$)/,
4392        "{}": /^\{\}/,
4393        "{...}": function(input) {
4394          return mhchemParser.patterns.findObserveGroups(input, "", "{", "}", "");
4395        },
4396        "{(...)}": function(input) {
4397          return mhchemParser.patterns.findObserveGroups(input, "{", "", "", "}");
4398        },
4399        "$...$": function(input) {
4400          return mhchemParser.patterns.findObserveGroups(input, "", "$", "$", "");
4401        },
4402        "${(...)}$": function(input) {
4403          return mhchemParser.patterns.findObserveGroups(input, "${", "", "", "}$");
4404        },
4405        "$(...)$": function(input) {
4406          return mhchemParser.patterns.findObserveGroups(input, "$", "", "", "$");
4407        },
4408        "=<>": /^[=<>]/,
4409        "#": /^[#\u2261]/,
4410        "+": /^\+/,
4411        "-$": /^-(?=[\s_},;\]/]|$|\([a-z]+\))/,
4412        // -space -, -; -] -/ -$ -state-of-aggregation
4413        "-9": /^-(?=[0-9])/,
4414        "- orbital overlap": /^-(?=(?:[spd]|sp)(?:$|[\s,;\)\]\}]))/,
4415        "-": /^-/,
4416        "pm-operator": /^(?:\\pm|\$\\pm\$|\+-|\+\/-)/,
4417        "operator": /^(?:\+|(?:[\-=<>]|<<|>>|\\approx|\$\\approx\$)(?=\s|$|-?[0-9]))/,
4418        "arrowUpDown": /^(?:v|\(v\)|\^|\(\^\))(?=$|[\s,;\)\]\}])/,
4419        "\\bond{(...)}": function(input) {
4420          return mhchemParser.patterns.findObserveGroups(input, "\\bond{", "", "", "}");
4421        },
4422        "->": /^(?:<->|<-->|->|<-|<=>>|<<=>|<=>|[\u2192\u27F6\u21CC])/,
4423        "CMT": /^[CMT](?=\[)/,
4424        "[(...)]": function(input) {
4425          return mhchemParser.patterns.findObserveGroups(input, "[", "", "", "]");
4426        },
4427        "1st-level escape": /^(&|\\\\|\\hline)\s*/,
4428        "\\,": /^(?:\\[,\ ;:])/,
4429        // \\x - but output no space before
4430        "\\x{}{}": function(input) {
4431          return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true);
4432        },
4433        "\\x{}": function(input) {
4434          return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", "");
4435        },
4436        "\\ca": /^\\ca(?:\s+|(?![a-zA-Z]))/,
4437        "\\x": /^(?:\\[a-zA-Z]+\s*|\\[_&{}%])/,
4438        "orbital": /^(?:[0-9]{1,2}[spdfgh]|[0-9]{0,2}sp)(?=$|[^a-zA-Z])/,
4439        // only those with numbers in front, because the others will be formatted correctly anyway
4440        "others": /^[\/~|]/,
4441        "\\frac{(...)}": function(input) {
4442          return mhchemParser.patterns.findObserveGroups(input, "\\frac{", "", "", "}", "{", "", "", "}");
4443        },
4444        "\\overset{(...)}": function(input) {
4445          return mhchemParser.patterns.findObserveGroups(input, "\\overset{", "", "", "}", "{", "", "", "}");
4446        },
4447        "\\underset{(...)}": function(input) {
4448          return mhchemParser.patterns.findObserveGroups(input, "\\underset{", "", "", "}", "{", "", "", "}");
4449        },
4450        "\\underbrace{(...)}": function(input) {
4451          return mhchemParser.patterns.findObserveGroups(input, "\\underbrace{", "", "", "}_", "{", "", "", "}");
4452        },
4453        "\\color{(...)}0": function(input) {
4454          return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}");
4455        },
4456        "\\color{(...)}{(...)}1": function(input) {
4457          return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}", "{", "", "", "}");
4458        },
4459        "\\color(...){(...)}2": function(input) {
4460          return mhchemParser.patterns.findObserveGroups(input, "\\color", "\\", "", /^(?=\{)/, "{", "", "", "}");
4461        },
4462        "\\ce{(...)}": function(input) {
4463          return mhchemParser.patterns.findObserveGroups(input, "\\ce{", "", "", "}");
4464        },
4465        "oxidation$": /^(?:[+-][IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/,
4466        "d-oxidation$": /^(?:[+-]?\s?[IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/,
4467        // 0 could be oxidation or charge
4468        "roman numeral": /^[IVX]+/,
4469        "1/2$": /^[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+(?:\$[a-z]\$|[a-z])?$/,
4470        "amount": function(input) {
4471          var match;
4472          match = input.match(/^(?:(?:(?:\([+\-]?[0-9]+\/[0-9]+\)|[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+|[+\-]?[0-9]+[.,][0-9]+|[+\-]?\.[0-9]+|[+\-]?[0-9]+)(?:[a-z](?=\s*[A-Z]))?)|[+\-]?[a-z](?=\s*[A-Z])|\+(?!\s))/);
4473          if (match) {
4474            return { match_: match[0], remainder: input.substr(match[0].length) };
4475          }
4476          var a = mhchemParser.patterns.findObserveGroups(input, "", "$", "$", "");
4477          if (a) {
4478            match = a.match_.match(/^\$(?:\(?[+\-]?(?:[0-9]*[a-z]?[+\-])?[0-9]*[a-z](?:[+\-][0-9]*[a-z]?)?\)?|\+|-)\$$/);
4479            if (match) {
4480              return { match_: match[0], remainder: input.substr(match[0].length) };
4481            }
4482          }
4483          return null;
4484        },
4485        "amount2": function(input) {
4486          return this["amount"](input);
4487        },
4488        "(KV letters),": /^(?:[A-Z][a-z]{0,2}|i)(?=,)/,
4489        "formula$": function(input) {
4490          if (input.match(/^\([a-z]+\)$/)) {
4491            return null;
4492          }
4493          var match = input.match(/^(?:[a-z]|(?:[0-9\ \+\-\,\.\(\)]+[a-z])+[0-9\ \+\-\,\.\(\)]*|(?:[a-z][0-9\ \+\-\,\.\(\)]+)+[a-z]?)$/);
4494          if (match) {
4495            return { match_: match[0], remainder: input.substr(match[0].length) };
4496          }
4497          return null;
4498        },
4499        "uprightEntities": /^(?:pH|pOH|pC|pK|iPr|iBu)(?=$|[^a-zA-Z])/,
4500        "/": /^\s*(\/)\s*/,
4501        "//": /^\s*(\/\/)\s*/,
4502        "*": /^\s*[*.]\s*/
4503      },
4504      findObserveGroups: function(input, begExcl, begIncl, endIncl, endExcl, beg2Excl, beg2Incl, end2Incl, end2Excl, combine) {
4505        var _match = function(input2, pattern) {
4506          if (typeof pattern === "string") {
4507            if (input2.indexOf(pattern) !== 0) {
4508              return null;
4509            }
4510            return pattern;
4511          } else {
4512            var match2 = input2.match(pattern);
4513            if (!match2) {
4514              return null;
4515            }
4516            return match2[0];
4517          }
4518        };
4519        var _findObserveGroups = function(input2, i, endChars) {
4520          var braces = 0;
4521          while (i < input2.length) {
4522            var a = input2.charAt(i);
4523            var match2 = _match(input2.substr(i), endChars);
4524            if (match2 !== null && braces === 0) {
4525              return { endMatchBegin: i, endMatchEnd: i + match2.length };
4526            } else if (a === "{") {
4527              braces++;
4528            } else if (a === "}") {
4529              if (braces === 0) {
4530                throw ["ExtraCloseMissingOpen", "Extra close brace or missing open brace"];
4531              } else {
4532                braces--;
4533              }
4534            }
4535            i++;
4536          }
4537          if (braces > 0) {
4538            return null;
4539          }
4540          return null;
4541        };
4542        var match = _match(input, begExcl);
4543        if (match === null) {
4544          return null;
4545        }
4546        input = input.substr(match.length);
4547        match = _match(input, begIncl);
4548        if (match === null) {
4549          return null;
4550        }
4551        var e = _findObserveGroups(input, match.length, endIncl || endExcl);
4552        if (e === null) {
4553          return null;
4554        }
4555        var match1 = input.substring(0, endIncl ? e.endMatchEnd : e.endMatchBegin);
4556        if (!(beg2Excl || beg2Incl)) {
4557          return {
4558            match_: match1,
4559            remainder: input.substr(e.endMatchEnd)
4560          };
4561        } else {
4562          var group2 = this.findObserveGroups(input.substr(e.endMatchEnd), beg2Excl, beg2Incl, end2Incl, end2Excl);
4563          if (group2 === null) {
4564            return null;
4565          }
4566          var matchRet = [match1, group2.match_];
4567          return {
4568            match_: combine ? matchRet.join("") : matchRet,
4569            remainder: group2.remainder
4570          };
4571        }
4572      },
4573      //
4574      // Matching function
4575      // e.g. match("a", input) will look for the regexp called "a" and see if it matches
4576      // returns null or {match_:"a", remainder:"bc"}
4577      //
4578      match_: function(m, input) {
4579        var pattern = mhchemParser.patterns.patterns[m];
4580        if (pattern === void 0) {
4581          throw ["MhchemBugP", "mhchem bug P. Please report. (" + m + ")"];
4582        } else if (typeof pattern === "function") {
4583          return mhchemParser.patterns.patterns[m](input);
4584        } else {
4585          var match = input.match(pattern);
4586          if (match) {
4587            var mm;
4588            if (match[2]) {
4589              mm = [match[1], match[2]];
4590            } else if (match[1]) {
4591              mm = match[1];
4592            } else {
4593              mm = match[0];
4594            }
4595            return { match_: mm, remainder: input.substr(match[0].length) };
4596          }
4597          return null;
4598        }
4599      }
4600    },
4601    //
4602    // Generic state machine actions
4603    //
4604    actions: {
4605      "a=": function(buffer, m) {
4606        buffer.a = (buffer.a || "") + m;
4607      },
4608      "b=": function(buffer, m) {
4609        buffer.b = (buffer.b || "") + m;
4610      },
4611      "p=": function(buffer, m) {
4612        buffer.p = (buffer.p || "") + m;
4613      },
4614      "o=": function(buffer, m) {
4615        buffer.o = (buffer.o || "") + m;
4616      },
4617      "q=": function(buffer, m) {
4618        buffer.q = (buffer.q || "") + m;
4619      },
4620      "d=": function(buffer, m) {
4621        buffer.d = (buffer.d || "") + m;
4622      },
4623      "rm=": function(buffer, m) {
4624        buffer.rm = (buffer.rm || "") + m;
4625      },
4626      "text=": function(buffer, m) {
4627        buffer.text_ = (buffer.text_ || "") + m;
4628      },
4629      "insert": function(buffer, m, a) {
4630        return { type_: a };
4631      },
4632      "insert+p1": function(buffer, m, a) {
4633        return { type_: a, p1: m };
4634      },
4635      "insert+p1+p2": function(buffer, m, a) {
4636        return { type_: a, p1: m[0], p2: m[1] };
4637      },
4638      "copy": function(buffer, m) {
4639        return m;
4640      },
4641      "rm": function(buffer, m) {
4642        return { type_: "rm", p1: m || "" };
4643      },
4644      "text": function(buffer, m) {
4645        return mhchemParser.go(m, "text");
4646      },
4647      "{text}": function(buffer, m) {
4648        var ret = ["{"];
4649        mhchemParser.concatArray(ret, mhchemParser.go(m, "text"));
4650        ret.push("}");
4651        return ret;
4652      },
4653      "tex-math": function(buffer, m) {
4654        return mhchemParser.go(m, "tex-math");
4655      },
4656      "tex-math tight": function(buffer, m) {
4657        return mhchemParser.go(m, "tex-math tight");
4658      },
4659      "bond": function(buffer, m, k) {
4660        return { type_: "bond", kind_: k || m };
4661      },
4662      "color0-output": function(buffer, m) {
4663        return { type_: "color0", color: m[0] };
4664      },
4665      "ce": function(buffer, m) {
4666        return mhchemParser.go(m);
4667      },
4668      "1/2": function(buffer, m) {
4669        var ret = [];
4670        if (m.match(/^[+\-]/)) {
4671          ret.push(m.substr(0, 1));
4672          m = m.substr(1);
4673        }
4674        var n = m.match(/^([0-9]+|\$[a-z]\$|[a-z])\/([0-9]+)(\$[a-z]\$|[a-z])?$/);
4675        n[1] = n[1].replace(/\$/g, "");
4676        ret.push({ type_: "frac", p1: n[1], p2: n[2] });
4677        if (n[3]) {
4678          n[3] = n[3].replace(/\$/g, "");
4679          ret.push({ type_: "tex-math", p1: n[3] });
4680        }
4681        return ret;
4682      },
4683      "9,9": function(buffer, m) {
4684        return mhchemParser.go(m, "9,9");
4685      }
4686    },
4687    //
4688    // createTransitions
4689    // convert  { 'letter': { 'state': { action_: 'output' } } }  to  { 'state' => [ { pattern: 'letter', task: { action_: [{type_: 'output'}] } } ] }
4690    // with expansion of 'a|b' to 'a' and 'b' (at 2 places)
4691    //
4692    createTransitions: function(o) {
4693      var pattern, state;
4694      var stateArray;
4695      var i;
4696      var transitions = {};
4697      for (pattern in o) {
4698        for (state in o[pattern]) {
4699          stateArray = state.split("|");
4700          o[pattern][state].stateArray = stateArray;
4701          for (i = 0; i < stateArray.length; i++) {
4702            transitions[stateArray[i]] = [];
4703          }
4704        }
4705      }
4706      for (pattern in o) {
4707        for (state in o[pattern]) {
4708          stateArray = o[pattern][state].stateArray || [];
4709          for (i = 0; i < stateArray.length; i++) {
4710            var p = o[pattern][state];
4711            if (p.action_) {
4712              p.action_ = [].concat(p.action_);
4713              for (var k = 0; k < p.action_.length; k++) {
4714                if (typeof p.action_[k] === "string") {
4715                  p.action_[k] = { type_: p.action_[k] };
4716                }
4717              }
4718            } else {
4719              p.action_ = [];
4720            }
4721            var patternArray = pattern.split("|");
4722            for (var j = 0; j < patternArray.length; j++) {
4723              if (stateArray[i] === "*") {
4724                for (var t in transitions) {
4725                  transitions[t].push({ pattern: patternArray[j], task: p });
4726                }
4727              } else {
4728                transitions[stateArray[i]].push({ pattern: patternArray[j], task: p });
4729              }
4730            }
4731          }
4732        }
4733      }
4734      return transitions;
4735    },
4736    stateMachines: {}
4737  };
4738  mhchemParser.stateMachines = {
4739    //
4740    // \ce state machines
4741    //
4742    //#region ce
4743    "ce": {
4744      // main parser
4745      transitions: mhchemParser.createTransitions({
4746        "empty": {
4747          "*": { action_: "output" }
4748        },
4749        "else": {
4750          "0|1|2": { action_: "beginsWithBond=false", revisit: true, toContinue: true }
4751        },
4752        "oxidation$": {
4753          "0": { action_: "oxidation-output" }
4754        },
4755        "CMT": {
4756          "r": { action_: "rdt=", nextState: "rt" },
4757          "rd": { action_: "rqt=", nextState: "rdt" }
4758        },
4759        "arrowUpDown": {
4760          "0|1|2|as": { action_: ["sb=false", "output", "operator"], nextState: "1" }
4761        },
4762        "uprightEntities": {
4763          "0|1|2": { action_: ["o=", "output"], nextState: "1" }
4764        },
4765        "orbital": {
4766          "0|1|2|3": { action_: "o=", nextState: "o" }
4767        },
4768        "->": {
4769          "0|1|2|3": { action_: "r=", nextState: "r" },
4770          "a|as": { action_: ["output", "r="], nextState: "r" },
4771          "*": { action_: ["output", "r="], nextState: "r" }
4772        },
4773        "+": {
4774          "o": { action_: "d= kv", nextState: "d" },
4775          "d|D": { action_: "d=", nextState: "d" },
4776          "q": { action_: "d=", nextState: "qd" },
4777          "qd|qD": { action_: "d=", nextState: "qd" },
4778          "dq": { action_: ["output", "d="], nextState: "d" },
4779          "3": { action_: ["sb=false", "output", "operator"], nextState: "0" }
4780        },
4781        "amount": {
4782          "0|2": { action_: "a=", nextState: "a" }
4783        },
4784        "pm-operator": {
4785          "0|1|2|a|as": { action_: ["sb=false", "output", { type_: "operator", option: "\\pm" }], nextState: "0" }
4786        },
4787        "operator": {
4788          "0|1|2|a|as": { action_: ["sb=false", "output", "operator"], nextState: "0" }
4789        },
4790        "-$": {
4791          "o|q": { action_: ["charge or bond", "output"], nextState: "qd" },
4792          "d": { action_: "d=", nextState: "d" },
4793          "D": { action_: ["output", { type_: "bond", option: "-" }], nextState: "3" },
4794          "q": { action_: "d=", nextState: "qd" },
4795          "qd": { action_: "d=", nextState: "qd" },
4796          "qD|dq": { action_: ["output", { type_: "bond", option: "-" }], nextState: "3" }
4797        },
4798        "-9": {
4799          "3|o": { action_: ["output", { type_: "insert", option: "hyphen" }], nextState: "3" }
4800        },
4801        "- orbital overlap": {
4802          "o": { action_: ["output", { type_: "insert", option: "hyphen" }], nextState: "2" },
4803          "d": { action_: ["output", { type_: "insert", option: "hyphen" }], nextState: "2" }
4804        },
4805        "-": {
4806          "0|1|2": { action_: [{ type_: "output", option: 1 }, "beginsWithBond=true", { type_: "bond", option: "-" }], nextState: "3" },
4807          "3": { action_: { type_: "bond", option: "-" } },
4808          "a": { action_: ["output", { type_: "insert", option: "hyphen" }], nextState: "2" },
4809          "as": { action_: [{ type_: "output", option: 2 }, { type_: "bond", option: "-" }], nextState: "3" },
4810          "b": { action_: "b=" },
4811          "o": { action_: { type_: "- after o/d", option: false }, nextState: "2" },
4812          "q": { action_: { type_: "- after o/d", option: false }, nextState: "2" },
4813          "d|qd|dq": { action_: { type_: "- after o/d", option: true }, nextState: "2" },
4814          "D|qD|p": { action_: ["output", { type_: "bond", option: "-" }], nextState: "3" }
4815        },
4816        "amount2": {
4817          "1|3": { action_: "a=", nextState: "a" }
4818        },
4819        "letters": {
4820          "0|1|2|3|a|as|b|p|bp|o": { action_: "o=", nextState: "o" },
4821          "q|dq": { action_: ["output", "o="], nextState: "o" },
4822          "d|D|qd|qD": { action_: "o after d", nextState: "o" }
4823        },
4824        "digits": {
4825          "o": { action_: "q=", nextState: "q" },
4826          "d|D": { action_: "q=", nextState: "dq" },
4827          "q": { action_: ["output", "o="], nextState: "o" },
4828          "a": { action_: "o=", nextState: "o" }
4829        },
4830        "space A": {
4831          "b|p|bp": {}
4832        },
4833        "space": {
4834          "a": { nextState: "as" },
4835          "0": { action_: "sb=false" },
4836          "1|2": { action_: "sb=true" },
4837          "r|rt|rd|rdt|rdq": { action_: "output", nextState: "0" },
4838          "*": { action_: ["output", "sb=true"], nextState: "1" }
4839        },
4840        "1st-level escape": {
4841          "1|2": { action_: ["output", { type_: "insert+p1", option: "1st-level escape" }] },
4842          "*": { action_: ["output", { type_: "insert+p1", option: "1st-level escape" }], nextState: "0" }
4843        },
4844        "[(...)]": {
4845          "r|rt": { action_: "rd=", nextState: "rd" },
4846          "rd|rdt": { action_: "rq=", nextState: "rdq" }
4847        },
4848        "...": {
4849          "o|d|D|dq|qd|qD": { action_: ["output", { type_: "bond", option: "..." }], nextState: "3" },
4850          "*": { action_: [{ type_: "output", option: 1 }, { type_: "insert", option: "ellipsis" }], nextState: "1" }
4851        },
4852        ". |* ": {
4853          "*": { action_: ["output", { type_: "insert", option: "addition compound" }], nextState: "1" }
4854        },
4855        "state of aggregation $": {
4856          "*": { action_: ["output", "state of aggregation"], nextState: "1" }
4857        },
4858        "{[(": {
4859          "a|as|o": { action_: ["o=", "output", "parenthesisLevel++"], nextState: "2" },
4860          "0|1|2|3": { action_: ["o=", "output", "parenthesisLevel++"], nextState: "2" },
4861          "*": { action_: ["output", "o=", "output", "parenthesisLevel++"], nextState: "2" }
4862        },
4863        ")]}": {
4864          "0|1|2|3|b|p|bp|o": { action_: ["o=", "parenthesisLevel--"], nextState: "o" },
4865          "a|as|d|D|q|qd|qD|dq": { action_: ["output", "o=", "parenthesisLevel--"], nextState: "o" }
4866        },
4867        ", ": {
4868          "*": { action_: ["output", "comma"], nextState: "0" }
4869        },
4870        "^_": {
4871          // ^ and _ without a sensible argument
4872          "*": {}
4873        },
4874        "^{(...)}|^($...$)": {
4875          "0|1|2|as": { action_: "b=", nextState: "b" },
4876          "p": { action_: "b=", nextState: "bp" },
4877          "3|o": { action_: "d= kv", nextState: "D" },
4878          "q": { action_: "d=", nextState: "qD" },
4879          "d|D|qd|qD|dq": { action_: ["output", "d="], nextState: "D" }
4880        },
4881        "^a|^\\x{}{}|^\\x{}|^\\x|'": {
4882          "0|1|2|as": { action_: "b=", nextState: "b" },
4883          "p": { action_: "b=", nextState: "bp" },
4884          "3|o": { action_: "d= kv", nextState: "d" },
4885          "q": { action_: "d=", nextState: "qd" },
4886          "d|qd|D|qD": { action_: "d=" },
4887          "dq": { action_: ["output", "d="], nextState: "d" }
4888        },
4889        "_{(state of aggregation)}$": {
4890          "d|D|q|qd|qD|dq": { action_: ["output", "q="], nextState: "q" }
4891        },
4892        "_{(...)}|_($...$)|_9|_\\x{}{}|_\\x{}|_\\x": {
4893          "0|1|2|as": { action_: "p=", nextState: "p" },
4894          "b": { action_: "p=", nextState: "bp" },
4895          "3|o": { action_: "q=", nextState: "q" },
4896          "d|D": { action_: "q=", nextState: "dq" },
4897          "q|qd|qD|dq": { action_: ["output", "q="], nextState: "q" }
4898        },
4899        "=<>": {
4900          "0|1|2|3|a|as|o|q|d|D|qd|qD|dq": { action_: [{ type_: "output", option: 2 }, "bond"], nextState: "3" }
4901        },
4902        "#": {
4903          "0|1|2|3|a|as|o": { action_: [{ type_: "output", option: 2 }, { type_: "bond", option: "#" }], nextState: "3" }
4904        },
4905        "{}": {
4906          "*": { action_: { type_: "output", option: 1 }, nextState: "1" }
4907        },
4908        "{...}": {
4909          "0|1|2|3|a|as|b|p|bp": { action_: "o=", nextState: "o" },
4910          "o|d|D|q|qd|qD|dq": { action_: ["output", "o="], nextState: "o" }
4911        },
4912        "$...$": {
4913          "a": { action_: "a=" },
4914          // 2$n$
4915          "0|1|2|3|as|b|p|bp|o": { action_: "o=", nextState: "o" },
4916          // not 'amount'
4917          "as|o": { action_: "o=" },
4918          "q|d|D|qd|qD|dq": { action_: ["output", "o="], nextState: "o" }
4919        },
4920        "\\bond{(...)}": {
4921          "*": { action_: [{ type_: "output", option: 2 }, "bond"], nextState: "3" }
4922        },
4923        "\\frac{(...)}": {
4924          "*": { action_: [{ type_: "output", option: 1 }, "frac-output"], nextState: "3" }
4925        },
4926        "\\overset{(...)}": {
4927          "*": { action_: [{ type_: "output", option: 2 }, "overset-output"], nextState: "3" }
4928        },
4929        "\\underset{(...)}": {
4930          "*": { action_: [{ type_: "output", option: 2 }, "underset-output"], nextState: "3" }
4931        },
4932        "\\underbrace{(...)}": {
4933          "*": { action_: [{ type_: "output", option: 2 }, "underbrace-output"], nextState: "3" }
4934        },
4935        "\\color{(...)}{(...)}1|\\color(...){(...)}2": {
4936          "*": { action_: [{ type_: "output", option: 2 }, "color-output"], nextState: "3" }
4937        },
4938        "\\color{(...)}0": {
4939          "*": { action_: [{ type_: "output", option: 2 }, "color0-output"] }
4940        },
4941        "\\ce{(...)}": {
4942          "*": { action_: [{ type_: "output", option: 2 }, "ce"], nextState: "3" }
4943        },
4944        "\\,": {
4945          "*": { action_: [{ type_: "output", option: 1 }, "copy"], nextState: "1" }
4946        },
4947        "\\x{}{}|\\x{}|\\x": {
4948          "0|1|2|3|a|as|b|p|bp|o|c0": { action_: ["o=", "output"], nextState: "3" },
4949          "*": { action_: ["output", "o=", "output"], nextState: "3" }
4950        },
4951        "others": {
4952          "*": { action_: [{ type_: "output", option: 1 }, "copy"], nextState: "3" }
4953        },
4954        "else2": {
4955          "a": { action_: "a to o", nextState: "o", revisit: true },
4956          "as": { action_: ["output", "sb=true"], nextState: "1", revisit: true },
4957          "r|rt|rd|rdt|rdq": { action_: ["output"], nextState: "0", revisit: true },
4958          "*": { action_: ["output", "copy"], nextState: "3" }
4959        }
4960      }),
4961      actions: {
4962        "o after d": function(buffer, m) {
4963          var ret;
4964          if ((buffer.d || "").match(/^[0-9]+$/)) {
4965            var tmp = buffer.d;
4966            buffer.d = void 0;
4967            ret = this["output"](buffer);
4968            buffer.b = tmp;
4969          } else {
4970            ret = this["output"](buffer);
4971          }
4972          mhchemParser.actions["o="](buffer, m);
4973          return ret;
4974        },
4975        "d= kv": function(buffer, m) {
4976          buffer.d = m;
4977          buffer.dType = "kv";
4978        },
4979        "charge or bond": function(buffer, m) {
4980          if (buffer["beginsWithBond"]) {
4981            var ret = [];
4982            mhchemParser.concatArray(ret, this["output"](buffer));
4983            mhchemParser.concatArray(ret, mhchemParser.actions["bond"](buffer, m, "-"));
4984            return ret;
4985          } else {
4986            buffer.d = m;
4987          }
4988        },
4989        "- after o/d": function(buffer, m, isAfterD) {
4990          var c1 = mhchemParser.patterns.match_("orbital", buffer.o || "");
4991          var c2 = mhchemParser.patterns.match_("one lowercase greek letter $", buffer.o || "");
4992          var c3 = mhchemParser.patterns.match_("one lowercase latin letter $", buffer.o || "");
4993          var c4 = mhchemParser.patterns.match_("$one lowercase latin letter$ $", buffer.o || "");
4994          var hyphenFollows = m === "-" && (c1 && c1.remainder === "" || c2 || c3 || c4);
4995          if (hyphenFollows && !buffer.a && !buffer.b && !buffer.p && !buffer.d && !buffer.q && !c1 && c3) {
4996            buffer.o = "$" + buffer.o + "$";
4997          }
4998          var ret = [];
4999          if (hyphenFollows) {
5000            mhchemParser.concatArray(ret, this["output"](buffer));
5001            ret.push({ type_: "hyphen" });
5002          } else {
5003            c1 = mhchemParser.patterns.match_("digits", buffer.d || "");
5004            if (isAfterD && c1 && c1.remainder === "") {
5005              mhchemParser.concatArray(ret, mhchemParser.actions["d="](buffer, m));
5006              mhchemParser.concatArray(ret, this["output"](buffer));
5007            } else {
5008              mhchemParser.concatArray(ret, this["output"](buffer));
5009              mhchemParser.concatArray(ret, mhchemParser.actions["bond"](buffer, m, "-"));
5010            }
5011          }
5012          return ret;
5013        },
5014        "a to o": function(buffer) {
5015          buffer.o = buffer.a;
5016          buffer.a = void 0;
5017        },
5018        "sb=true": function(buffer) {
5019          buffer.sb = true;
5020        },
5021        "sb=false": function(buffer) {
5022          buffer.sb = false;
5023        },
5024        "beginsWithBond=true": function(buffer) {
5025          buffer["beginsWithBond"] = true;
5026        },
5027        "beginsWithBond=false": function(buffer) {
5028          buffer["beginsWithBond"] = false;
5029        },
5030        "parenthesisLevel++": function(buffer) {
5031          buffer["parenthesisLevel"]++;
5032        },
5033        "parenthesisLevel--": function(buffer) {
5034          buffer["parenthesisLevel"]--;
5035        },
5036        "state of aggregation": function(buffer, m) {
5037          return { type_: "state of aggregation", p1: mhchemParser.go(m, "o") };
5038        },
5039        "comma": function(buffer, m) {
5040          var a = m.replace(/\s*$/, "");
5041          var withSpace = a !== m;
5042          if (withSpace && buffer["parenthesisLevel"] === 0) {
5043            return { type_: "comma enumeration L", p1: a };
5044          } else {
5045            return { type_: "comma enumeration M", p1: a };
5046          }
5047        },
5048        "output": function(buffer, m, entityFollows) {
5049          var ret;
5050          if (!buffer.r) {
5051            ret = [];
5052            if (!buffer.a && !buffer.b && !buffer.p && !buffer.o && !buffer.q && !buffer.d && !entityFollows) {
5053            } else {
5054              if (buffer.sb) {
5055                ret.push({ type_: "entitySkip" });
5056              }
5057              if (!buffer.o && !buffer.q && !buffer.d && !buffer.b && !buffer.p && entityFollows !== 2) {
5058                buffer.o = buffer.a;
5059                buffer.a = void 0;
5060              } else if (!buffer.o && !buffer.q && !buffer.d && (buffer.b || buffer.p)) {
5061                buffer.o = buffer.a;
5062                buffer.d = buffer.b;
5063                buffer.q = buffer.p;
5064                buffer.a = buffer.b = buffer.p = void 0;
5065              } else {
5066                if (buffer.o && buffer.dType === "kv" && mhchemParser.patterns.match_("d-oxidation$", buffer.d || "")) {
5067                  buffer.dType = "oxidation";
5068                } else if (buffer.o && buffer.dType === "kv" && !buffer.q) {
5069                  buffer.dType = void 0;
5070                }
5071              }
5072              ret.push({
5073                type_: "chemfive",
5074                a: mhchemParser.go(buffer.a, "a"),
5075                b: mhchemParser.go(buffer.b, "bd"),
5076                p: mhchemParser.go(buffer.p, "pq"),
5077                o: mhchemParser.go(buffer.o, "o"),
5078                q: mhchemParser.go(buffer.q, "pq"),
5079                d: mhchemParser.go(buffer.d, buffer.dType === "oxidation" ? "oxidation" : "bd"),
5080                dType: buffer.dType
5081              });
5082            }
5083          } else {
5084            var rd;
5085            if (buffer.rdt === "M") {
5086              rd = mhchemParser.go(buffer.rd, "tex-math");
5087            } else if (buffer.rdt === "T") {
5088              rd = [{ type_: "text", p1: buffer.rd || "" }];
5089            } else {
5090              rd = mhchemParser.go(buffer.rd);
5091            }
5092            var rq;
5093            if (buffer.rqt === "M") {
5094              rq = mhchemParser.go(buffer.rq, "tex-math");
5095            } else if (buffer.rqt === "T") {
5096              rq = [{ type_: "text", p1: buffer.rq || "" }];
5097            } else {
5098              rq = mhchemParser.go(buffer.rq);
5099            }
5100            ret = {
5101              type_: "arrow",
5102              r: buffer.r,
5103              rd,
5104              rq
5105            };
5106          }
5107          for (var p in buffer) {
5108            if (p !== "parenthesisLevel" && p !== "beginsWithBond") {
5109              delete buffer[p];
5110            }
5111          }
5112          return ret;
5113        },
5114        "oxidation-output": function(buffer, m) {
5115          var ret = ["{"];
5116          mhchemParser.concatArray(ret, mhchemParser.go(m, "oxidation"));
5117          ret.push("}");
5118          return ret;
5119        },
5120        "frac-output": function(buffer, m) {
5121          return { type_: "frac-ce", p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) };
5122        },
5123        "overset-output": function(buffer, m) {
5124          return { type_: "overset", p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) };
5125        },
5126        "underset-output": function(buffer, m) {
5127          return { type_: "underset", p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) };
5128        },
5129        "underbrace-output": function(buffer, m) {
5130          return { type_: "underbrace", p1: mhchemParser.go(m[0]), p2: mhchemParser.go(m[1]) };
5131        },
5132        "color-output": function(buffer, m) {
5133          return { type_: "color", color1: m[0], color2: mhchemParser.go(m[1]) };
5134        },
5135        "r=": function(buffer, m) {
5136          buffer.r = m;
5137        },
5138        "rdt=": function(buffer, m) {
5139          buffer.rdt = m;
5140        },
5141        "rd=": function(buffer, m) {
5142          buffer.rd = m;
5143        },
5144        "rqt=": function(buffer, m) {
5145          buffer.rqt = m;
5146        },
5147        "rq=": function(buffer, m) {
5148          buffer.rq = m;
5149        },
5150        "operator": function(buffer, m, p1) {
5151          return { type_: "operator", kind_: p1 || m };
5152        }
5153      }
5154    },
5155    "a": {
5156      transitions: mhchemParser.createTransitions({
5157        "empty": {
5158          "*": {}
5159        },
5160        "1/2$": {
5161          "0": { action_: "1/2" }
5162        },
5163        "else": {
5164          "0": { nextState: "1", revisit: true }
5165        },
5166        "$(...)$": {
5167          "*": { action_: "tex-math tight", nextState: "1" }
5168        },
5169        ",": {
5170          "*": { action_: { type_: "insert", option: "commaDecimal" } }
5171        },
5172        "else2": {
5173          "*": { action_: "copy" }
5174        }
5175      }),
5176      actions: {}
5177    },
5178    "o": {
5179      transitions: mhchemParser.createTransitions({
5180        "empty": {
5181          "*": {}
5182        },
5183        "1/2$": {
5184          "0": { action_: "1/2" }
5185        },
5186        "else": {
5187          "0": { nextState: "1", revisit: true }
5188        },
5189        "letters": {
5190          "*": { action_: "rm" }
5191        },
5192        "\\ca": {
5193          "*": { action_: { type_: "insert", option: "circa" } }
5194        },
5195        "\\x{}{}|\\x{}|\\x": {
5196          "*": { action_: "copy" }
5197        },
5198        "${(...)}$|$(...)$": {
5199          "*": { action_: "tex-math" }
5200        },
5201        "{(...)}": {
5202          "*": { action_: "{text}" }
5203        },
5204        "else2": {
5205          "*": { action_: "copy" }
5206        }
5207      }),
5208      actions: {}
5209    },
5210    "text": {
5211      transitions: mhchemParser.createTransitions({
5212        "empty": {
5213          "*": { action_: "output" }
5214        },
5215        "{...}": {
5216          "*": { action_: "text=" }
5217        },
5218        "${(...)}$|$(...)$": {
5219          "*": { action_: "tex-math" }
5220        },
5221        "\\greek": {
5222          "*": { action_: ["output", "rm"] }
5223        },
5224        "\\,|\\x{}{}|\\x{}|\\x": {
5225          "*": { action_: ["output", "copy"] }
5226        },
5227        "else": {
5228          "*": { action_: "text=" }
5229        }
5230      }),
5231      actions: {
5232        "output": function(buffer) {
5233          if (buffer.text_) {
5234            var ret = { type_: "text", p1: buffer.text_ };
5235            for (var p in buffer) {
5236              delete buffer[p];
5237            }
5238            return ret;
5239          }
5240        }
5241      }
5242    },
5243    "pq": {
5244      transitions: mhchemParser.createTransitions({
5245        "empty": {
5246          "*": {}
5247        },
5248        "state of aggregation $": {
5249          "*": { action_: "state of aggregation" }
5250        },
5251        "i$": {
5252          "0": { nextState: "!f", revisit: true }
5253        },
5254        "(KV letters),": {
5255          "0": { action_: "rm", nextState: "0" }
5256        },
5257        "formula$": {
5258          "0": { nextState: "f", revisit: true }
5259        },
5260        "1/2$": {
5261          "0": { action_: "1/2" }
5262        },
5263        "else": {
5264          "0": { nextState: "!f", revisit: true }
5265        },
5266        "${(...)}$|$(...)$": {
5267          "*": { action_: "tex-math" }
5268        },
5269        "{(...)}": {
5270          "*": { action_: "text" }
5271        },
5272        "a-z": {
5273          "f": { action_: "tex-math" }
5274        },
5275        "letters": {
5276          "*": { action_: "rm" }
5277        },
5278        "-9.,9": {
5279          "*": { action_: "9,9" }
5280        },
5281        ",": {
5282          "*": { action_: { type_: "insert+p1", option: "comma enumeration S" } }
5283        },
5284        "\\color{(...)}{(...)}1|\\color(...){(...)}2": {
5285          "*": { action_: "color-output" }
5286        },
5287        "\\color{(...)}0": {
5288          "*": { action_: "color0-output" }
5289        },
5290        "\\ce{(...)}": {
5291          "*": { action_: "ce" }
5292        },
5293        "\\,|\\x{}{}|\\x{}|\\x": {
5294          "*": { action_: "copy" }
5295        },
5296        "else2": {
5297          "*": { action_: "copy" }
5298        }
5299      }),
5300      actions: {
5301        "state of aggregation": function(buffer, m) {
5302          return { type_: "state of aggregation subscript", p1: mhchemParser.go(m, "o") };
5303        },
5304        "color-output": function(buffer, m) {
5305          return { type_: "color", color1: m[0], color2: mhchemParser.go(m[1], "pq") };
5306        }
5307      }
5308    },
5309    "bd": {
5310      transitions: mhchemParser.createTransitions({
5311        "empty": {
5312          "*": {}
5313        },
5314        "x$": {
5315          "0": { nextState: "!f", revisit: true }
5316        },
5317        "formula$": {
5318          "0": { nextState: "f", revisit: true }
5319        },
5320        "else": {
5321          "0": { nextState: "!f", revisit: true }
5322        },
5323        "-9.,9 no missing 0": {
5324          "*": { action_: "9,9" }
5325        },
5326        ".": {
5327          "*": { action_: { type_: "insert", option: "electron dot" } }
5328        },
5329        "a-z": {
5330          "f": { action_: "tex-math" }
5331        },
5332        "x": {
5333          "*": { action_: { type_: "insert", option: "KV x" } }
5334        },
5335        "letters": {
5336          "*": { action_: "rm" }
5337        },
5338        "'": {
5339          "*": { action_: { type_: "insert", option: "prime" } }
5340        },
5341        "${(...)}$|$(...)$": {
5342          "*": { action_: "tex-math" }
5343        },
5344        "{(...)}": {
5345          "*": { action_: "text" }
5346        },
5347        "\\color{(...)}{(...)}1|\\color(...){(...)}2": {
5348          "*": { action_: "color-output" }
5349        },
5350        "\\color{(...)}0": {
5351          "*": { action_: "color0-output" }
5352        },
5353        "\\ce{(...)}": {
5354          "*": { action_: "ce" }
5355        },
5356        "\\,|\\x{}{}|\\x{}|\\x": {
5357          "*": { action_: "copy" }
5358        },
5359        "else2": {
5360          "*": { action_: "copy" }
5361        }
5362      }),
5363      actions: {
5364        "color-output": function(buffer, m) {
5365          return { type_: "color", color1: m[0], color2: mhchemParser.go(m[1], "bd") };
5366        }
5367      }
5368    },
5369    "oxidation": {
5370      transitions: mhchemParser.createTransitions({
5371        "empty": {
5372          "*": {}
5373        },
5374        "roman numeral": {
5375          "*": { action_: "roman-numeral" }
5376        },
5377        "${(...)}$|$(...)$": {
5378          "*": { action_: "tex-math" }
5379        },
5380        "else": {
5381          "*": { action_: "copy" }
5382        }
5383      }),
5384      actions: {
5385        "roman-numeral": function(buffer, m) {
5386          return { type_: "roman numeral", p1: m || "" };
5387        }
5388      }
5389    },
5390    "tex-math": {
5391      transitions: mhchemParser.createTransitions({
5392        "empty": {
5393          "*": { action_: "output" }
5394        },
5395        "\\ce{(...)}": {
5396          "*": { action_: ["output", "ce"] }
5397        },
5398        "{...}|\\,|\\x{}{}|\\x{}|\\x": {
5399          "*": { action_: "o=" }
5400        },
5401        "else": {
5402          "*": { action_: "o=" }
5403        }
5404      }),
5405      actions: {
5406        "output": function(buffer) {
5407          if (buffer.o) {
5408            var ret = { type_: "tex-math", p1: buffer.o };
5409            for (var p in buffer) {
5410              delete buffer[p];
5411            }
5412            return ret;
5413          }
5414        }
5415      }
5416    },
5417    "tex-math tight": {
5418      transitions: mhchemParser.createTransitions({
5419        "empty": {
5420          "*": { action_: "output" }
5421        },
5422        "\\ce{(...)}": {
5423          "*": { action_: ["output", "ce"] }
5424        },
5425        "{...}|\\,|\\x{}{}|\\x{}|\\x": {
5426          "*": { action_: "o=" }
5427        },
5428        "-|+": {
5429          "*": { action_: "tight operator" }
5430        },
5431        "else": {
5432          "*": { action_: "o=" }
5433        }
5434      }),
5435      actions: {
5436        "tight operator": function(buffer, m) {
5437          buffer.o = (buffer.o || "") + "{" + m + "}";
5438        },
5439        "output": function(buffer) {
5440          if (buffer.o) {
5441            var ret = { type_: "tex-math", p1: buffer.o };
5442            for (var p in buffer) {
5443              delete buffer[p];
5444            }
5445            return ret;
5446          }
5447        }
5448      }
5449    },
5450    "9,9": {
5451      transitions: mhchemParser.createTransitions({
5452        "empty": {
5453          "*": {}
5454        },
5455        ",": {
5456          "*": { action_: "comma" }
5457        },
5458        "else": {
5459          "*": { action_: "copy" }
5460        }
5461      }),
5462      actions: {
5463        "comma": function() {
5464          return { type_: "commaDecimal" };
5465        }
5466      }
5467    },
5468    //#endregion
5469    //
5470    // \pu state machines
5471    //
5472    //#region pu
5473    "pu": {
5474      transitions: mhchemParser.createTransitions({
5475        "empty": {
5476          "*": { action_: "output" }
5477        },
5478        "space$": {
5479          "*": { action_: ["output", "space"] }
5480        },
5481        "{[(|)]}": {
5482          "0|a": { action_: "copy" }
5483        },
5484        "(-)(9)^(-9)": {
5485          "0": { action_: "number^", nextState: "a" }
5486        },
5487        "(-)(9.,9)(e)(99)": {
5488          "0": { action_: "enumber", nextState: "a" }
5489        },
5490        "space": {
5491          "0|a": {}
5492        },
5493        "pm-operator": {
5494          "0|a": { action_: { type_: "operator", option: "\\pm" }, nextState: "0" }
5495        },
5496        "operator": {
5497          "0|a": { action_: "copy", nextState: "0" }
5498        },
5499        "//": {
5500          "d": { action_: "o=", nextState: "/" }
5501        },
5502        "/": {
5503          "d": { action_: "o=", nextState: "/" }
5504        },
5505        "{...}|else": {
5506          "0|d": { action_: "d=", nextState: "d" },
5507          "a": { action_: ["space", "d="], nextState: "d" },
5508          "/|q": { action_: "q=", nextState: "q" }
5509        }
5510      }),
5511      actions: {
5512        "enumber": function(buffer, m) {
5513          var ret = [];
5514          if (m[0] === "+-" || m[0] === "+/-") {
5515            ret.push("\\pm ");
5516          } else if (m[0]) {
5517            ret.push(m[0]);
5518          }
5519          if (m[1]) {
5520            mhchemParser.concatArray(ret, mhchemParser.go(m[1], "pu-9,9"));
5521            if (m[2]) {
5522              if (m[2].match(/[,.]/)) {
5523                mhchemParser.concatArray(ret, mhchemParser.go(m[2], "pu-9,9"));
5524              } else {
5525                ret.push(m[2]);
5526              }
5527            }
5528            m[3] = m[4] || m[3];
5529            if (m[3]) {
5530              m[3] = m[3].trim();
5531              if (m[3] === "e" || m[3].substr(0, 1) === "*") {
5532                ret.push({ type_: "cdot" });
5533              } else {
5534                ret.push({ type_: "times" });
5535              }
5536            }
5537          }
5538          if (m[3]) {
5539            ret.push("10^{" + m[5] + "}");
5540          }
5541          return ret;
5542        },
5543        "number^": function(buffer, m) {
5544          var ret = [];
5545          if (m[0] === "+-" || m[0] === "+/-") {
5546            ret.push("\\pm ");
5547          } else if (m[0]) {
5548            ret.push(m[0]);
5549          }
5550          mhchemParser.concatArray(ret, mhchemParser.go(m[1], "pu-9,9"));
5551          ret.push("^{" + m[2] + "}");
5552          return ret;
5553        },
5554        "operator": function(buffer, m, p1) {
5555          return { type_: "operator", kind_: p1 || m };
5556        },
5557        "space": function() {
5558          return { type_: "pu-space-1" };
5559        },
5560        "output": function(buffer) {
5561          var ret;
5562          var md = mhchemParser.patterns.match_("{(...)}", buffer.d || "");
5563          if (md && md.remainder === "") {
5564            buffer.d = md.match_;
5565          }
5566          var mq = mhchemParser.patterns.match_("{(...)}", buffer.q || "");
5567          if (mq && mq.remainder === "") {
5568            buffer.q = mq.match_;
5569          }
5570          if (buffer.d) {
5571            buffer.d = buffer.d.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C");
5572            buffer.d = buffer.d.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F");
5573          }
5574          if (buffer.q) {
5575            buffer.q = buffer.q.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C");
5576            buffer.q = buffer.q.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F");
5577            var b5 = {
5578              d: mhchemParser.go(buffer.d, "pu"),
5579              q: mhchemParser.go(buffer.q, "pu")
5580            };
5581            if (buffer.o === "//") {
5582              ret = { type_: "pu-frac", p1: b5.d, p2: b5.q };
5583            } else {
5584              ret = b5.d;
5585              if (b5.d.length > 1 || b5.q.length > 1) {
5586                ret.push({ type_: " / " });
5587              } else {
5588                ret.push({ type_: "/" });
5589              }
5590              mhchemParser.concatArray(ret, b5.q);
5591            }
5592          } else {
5593            ret = mhchemParser.go(buffer.d, "pu-2");
5594          }
5595          for (var p in buffer) {
5596            delete buffer[p];
5597          }
5598          return ret;
5599        }
5600      }
5601    },
5602    "pu-2": {
5603      transitions: mhchemParser.createTransitions({
5604        "empty": {
5605          "*": { action_: "output" }
5606        },
5607        "*": {
5608          "*": { action_: ["output", "cdot"], nextState: "0" }
5609        },
5610        "\\x": {
5611          "*": { action_: "rm=" }
5612        },
5613        "space": {
5614          "*": { action_: ["output", "space"], nextState: "0" }
5615        },
5616        "^{(...)}|^(-1)": {
5617          "1": { action_: "^(-1)" }
5618        },
5619        "-9.,9": {
5620          "0": { action_: "rm=", nextState: "0" },
5621          "1": { action_: "^(-1)", nextState: "0" }
5622        },
5623        "{...}|else": {
5624          "*": { action_: "rm=", nextState: "1" }
5625        }
5626      }),
5627      actions: {
5628        "cdot": function() {
5629          return { type_: "tight cdot" };
5630        },
5631        "^(-1)": function(buffer, m) {
5632          buffer.rm += "^{" + m + "}";
5633        },
5634        "space": function() {
5635          return { type_: "pu-space-2" };
5636        },
5637        "output": function(buffer) {
5638          var ret = [];
5639          if (buffer.rm) {
5640            var mrm = mhchemParser.patterns.match_("{(...)}", buffer.rm || "");
5641            if (mrm && mrm.remainder === "") {
5642              ret = mhchemParser.go(mrm.match_, "pu");
5643            } else {
5644              ret = { type_: "rm", p1: buffer.rm };
5645            }
5646          }
5647          for (var p in buffer) {
5648            delete buffer[p];
5649          }
5650          return ret;
5651        }
5652      }
5653    },
5654    "pu-9,9": {
5655      transitions: mhchemParser.createTransitions({
5656        "empty": {
5657          "0": { action_: "output-0" },
5658          "o": { action_: "output-o" }
5659        },
5660        ",": {
5661          "0": { action_: ["output-0", "comma"], nextState: "o" }
5662        },
5663        ".": {
5664          "0": { action_: ["output-0", "copy"], nextState: "o" }
5665        },
5666        "else": {
5667          "*": { action_: "text=" }
5668        }
5669      }),
5670      actions: {
5671        "comma": function() {
5672          return { type_: "commaDecimal" };
5673        },
5674        "output-0": function(buffer) {
5675          var ret = [];
5676          buffer.text_ = buffer.text_ || "";
5677          if (buffer.text_.length > 4) {
5678            var a = buffer.text_.length % 3;
5679            if (a === 0) {
5680              a = 3;
5681            }
5682            for (var i = buffer.text_.length - 3; i > 0; i -= 3) {
5683              ret.push(buffer.text_.substr(i, 3));
5684              ret.push({ type_: "1000 separator" });
5685            }
5686            ret.push(buffer.text_.substr(0, a));
5687            ret.reverse();
5688          } else {
5689            ret.push(buffer.text_);
5690          }
5691          for (var p in buffer) {
5692            delete buffer[p];
5693          }
5694          return ret;
5695        },
5696        "output-o": function(buffer) {
5697          var ret = [];
5698          buffer.text_ = buffer.text_ || "";
5699          if (buffer.text_.length > 4) {
5700            var a = buffer.text_.length - 3;
5701            for (var i = 0; i < a; i += 3) {
5702              ret.push(buffer.text_.substr(i, 3));
5703              ret.push({ type_: "1000 separator" });
5704            }
5705            ret.push(buffer.text_.substr(i));
5706          } else {
5707            ret.push(buffer.text_);
5708          }
5709          for (var p in buffer) {
5710            delete buffer[p];
5711          }
5712          return ret;
5713        }
5714      }
5715    }
5716    //#endregion
5717  };
5718  var texify = {
5719    go: function(input, isInner) {
5720      if (!input) {
5721        return "";
5722      }
5723      var res = "";
5724      var cee = false;
5725      for (var i = 0; i < input.length; i++) {
5726        var inputi = input[i];
5727        if (typeof inputi === "string") {
5728          res += inputi;
5729        } else {
5730          res += texify._go2(inputi);
5731          if (inputi.type_ === "1st-level escape") {
5732            cee = true;
5733          }
5734        }
5735      }
5736      if (!isInner && !cee && res) {
5737        res = "{" + res + "}";
5738      }
5739      return res;
5740    },
5741    _goInner: function(input) {
5742      if (!input) {
5743        return input;
5744      }
5745      return texify.go(input, true);
5746    },
5747    _go2: function(buf) {
5748      var res;
5749      switch (buf.type_) {
5750        case "chemfive":
5751          res = "";
5752          var b5 = {
5753            a: texify._goInner(buf.a),
5754            b: texify._goInner(buf.b),
5755            p: texify._goInner(buf.p),
5756            o: texify._goInner(buf.o),
5757            q: texify._goInner(buf.q),
5758            d: texify._goInner(buf.d)
5759          };
5760          if (b5.a) {
5761            if (b5.a.match(/^[+\-]/)) {
5762              b5.a = "{" + b5.a + "}";
5763            }
5764            res += b5.a + "\\,";
5765          }
5766          if (b5.b || b5.p) {
5767            res += "{\\vphantom{X}}";
5768            res += "^{\\hphantom{" + (b5.b || "") + "}}_{\\hphantom{" + (b5.p || "") + "}}";
5769            res += "{\\vphantom{X}}";
5770            res += "^{\\vphantom{2}\\mathllap{" + (b5.b || "") + "}}";
5771            res += "_{\\vphantom{2}\\mathllap{" + (b5.p || "") + "}}";
5772          }
5773          if (b5.o) {
5774            if (b5.o.match(/^[+\-]/)) {
5775              b5.o = "{" + b5.o + "}";
5776            }
5777            res += b5.o;
5778          }
5779          if (buf.dType === "kv") {
5780            if (b5.d || b5.q) {
5781              res += "{\\vphantom{X}}";
5782            }
5783            if (b5.d) {
5784              res += "^{" + b5.d + "}";
5785            }
5786            if (b5.q) {
5787              res += "_{" + b5.q + "}";
5788            }
5789          } else if (buf.dType === "oxidation") {
5790            if (b5.d) {
5791              res += "{\\vphantom{X}}";
5792              res += "^{" + b5.d + "}";
5793            }
5794            if (b5.q) {
5795              res += "{{}}";
5796              res += "_{" + b5.q + "}";
5797            }
5798          } else {
5799            if (b5.q) {
5800              res += "{{}}";
5801              res += "_{" + b5.q + "}";
5802            }
5803            if (b5.d) {
5804              res += "{{}}";
5805              res += "^{" + b5.d + "}";
5806            }
5807          }
5808          break;
5809        case "rm":
5810          res = "\\mathrm{" + buf.p1 + "}";
5811          break;
5812        case "text":
5813          if (buf.p1.match(/[\^_]/)) {
5814            buf.p1 = buf.p1.replace(" ", "~").replace("-", "\\text{-}");
5815            res = "\\mathrm{" + buf.p1 + "}";
5816          } else {
5817            res = "\\text{" + buf.p1 + "}";
5818          }
5819          break;
5820        case "roman numeral":
5821          res = "\\mathrm{" + buf.p1 + "}";
5822          break;
5823        case "state of aggregation":
5824          res = "\\mskip2mu " + texify._goInner(buf.p1);
5825          break;
5826        case "state of aggregation subscript":
5827          res = "\\mskip1mu " + texify._goInner(buf.p1);
5828          break;
5829        case "bond":
5830          res = texify._getBond(buf.kind_);
5831          if (!res) {
5832            throw ["MhchemErrorBond", "mhchem Error. Unknown bond type (" + buf.kind_ + ")"];
5833          }
5834          break;
5835        case "frac":
5836          var c = "\\frac{" + buf.p1 + "}{" + buf.p2 + "}";
5837          res = "\\mathchoice{\\textstyle" + c + "}{" + c + "}{" + c + "}{" + c + "}";
5838          break;
5839        case "pu-frac":
5840          var d = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
5841          res = "\\mathchoice{\\textstyle" + d + "}{" + d + "}{" + d + "}{" + d + "}";
5842          break;
5843        case "tex-math":
5844          res = buf.p1 + " ";
5845          break;
5846        case "frac-ce":
5847          res = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
5848          break;
5849        case "overset":
5850          res = "\\overset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
5851          break;
5852        case "underset":
5853          res = "\\underset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
5854          break;
5855        case "underbrace":
5856          res = "\\underbrace{" + texify._goInner(buf.p1) + "}_{" + texify._goInner(buf.p2) + "}";
5857          break;
5858        case "color":
5859          res = "{\\color{" + buf.color1 + "}{" + texify._goInner(buf.color2) + "}}";
5860          break;
5861        case "color0":
5862          res = "\\color{" + buf.color + "}";
5863          break;
5864        case "arrow":
5865          var b6 = {
5866            rd: texify._goInner(buf.rd),
5867            rq: texify._goInner(buf.rq)
5868          };
5869          var arrow = texify._getArrow(buf.r);
5870          if (b6.rq) {
5871            arrow += "[{\\rm " + b6.rq + "}]";
5872          }
5873          if (b6.rd) {
5874            arrow += "{\\rm " + b6.rd + "}";
5875          } else {
5876            arrow += "{}";
5877          }
5878          res = arrow;
5879          break;
5880        case "operator":
5881          res = texify._getOperator(buf.kind_);
5882          break;
5883        case "1st-level escape":
5884          res = buf.p1 + " ";
5885          break;
5886        case "space":
5887          res = " ";
5888          break;
5889        case "entitySkip":
5890          res = "~";
5891          break;
5892        case "pu-space-1":
5893          res = "~";
5894          break;
5895        case "pu-space-2":
5896          res = "\\mkern3mu ";
5897          break;
5898        case "1000 separator":
5899          res = "\\mkern2mu ";
5900          break;
5901        case "commaDecimal":
5902          res = "{,}";
5903          break;
5904        case "comma enumeration L":
5905          res = "{" + buf.p1 + "}\\mkern6mu ";
5906          break;
5907        case "comma enumeration M":
5908          res = "{" + buf.p1 + "}\\mkern3mu ";
5909          break;
5910        case "comma enumeration S":
5911          res = "{" + buf.p1 + "}\\mkern1mu ";
5912          break;
5913        case "hyphen":
5914          res = "\\text{-}";
5915          break;
5916        case "addition compound":
5917          res = "\\,{\\cdot}\\,";
5918          break;
5919        case "electron dot":
5920          res = "\\mkern1mu \\text{\\textbullet}\\mkern1mu ";
5921          break;
5922        case "KV x":
5923          res = "{\\times}";
5924          break;
5925        case "prime":
5926          res = "\\prime ";
5927          break;
5928        case "cdot":
5929          res = "\\cdot ";
5930          break;
5931        case "tight cdot":
5932          res = "\\mkern1mu{\\cdot}\\mkern1mu ";
5933          break;
5934        case "times":
5935          res = "\\times ";
5936          break;
5937        case "circa":
5938          res = "{\\sim}";
5939          break;
5940        case "^":
5941          res = "uparrow";
5942          break;
5943        case "v":
5944          res = "downarrow";
5945          break;
5946        case "ellipsis":
5947          res = "\\ldots ";
5948          break;
5949        case "/":
5950          res = "/";
5951          break;
5952        case " / ":
5953          res = "\\,/\\,";
5954          break;
5955        default:
5956          assertNever(buf);
5957          throw ["MhchemBugT", "mhchem bug T. Please report."];
5958      }
5959      assertString(res);
5960      return res;
5961    },
5962    _getArrow: function(a) {
5963      switch (a) {
5964        case "->":
5965          return "\\yields";
5966        case "\u2192":
5967          return "\\yields";
5968        case "\u27F6":
5969          return "\\yields";
5970        case "<-":
5971          return "\\yieldsLeft";
5972        case "<->":
5973          return "\\mesomerism";
5974        case "<-->":
5975          return "\\yieldsLeftRight";
5976        case "<=>":
5977          return "\\equilibrium";
5978        case "\u21CC":
5979          return "\\equilibrium";
5980        case "<=>>":
5981          return "\\equilibriumRight";
5982        case "<<=>":
5983          return "\\equilibriumLeft";
5984        default:
5985          assertNever(a);
5986          throw ["MhchemBugT", "mhchem bug T. Please report."];
5987      }
5988    },
5989    _getBond: function(a) {
5990      switch (a) {
5991        case "-":
5992          return "{-}";
5993        case "1":
5994          return "{-}";
5995        case "=":
5996          return "{=}";
5997        case "2":
5998          return "{=}";
5999        case "#":
6000          return "{\\equiv}";
6001        case "3":
6002          return "{\\equiv}";
6003        case "~":
6004          return "{\\tripleDash}";
6005        case "~-":
6006          return "{\\tripleDashOverLine}";
6007        case "~=":
6008          return "{\\tripleDashOverDoubleLine}";
6009        case "~--":
6010          return "{\\tripleDashOverDoubleLine}";
6011        case "-~-":
6012          return "{\\tripleDashBetweenDoubleLine}";
6013        case "...":
6014          return "{{\\cdot}{\\cdot}{\\cdot}}";
6015        case "....":
6016          return "{{\\cdot}{\\cdot}{\\cdot}{\\cdot}}";
6017        case "->":
6018          return "{\\rightarrow}";
6019        case "<-":
6020          return "{\\leftarrow}";
6021        case "<":
6022          return "{<}";
6023        case ">":
6024          return "{>}";
6025        default:
6026          assertNever(a);
6027          throw ["MhchemBugT", "mhchem bug T. Please report."];
6028      }
6029    },
6030    _getOperator: function(a) {
6031      switch (a) {
6032        case "+":
6033          return " {}+{} ";
6034        case "-":
6035          return " {}-{} ";
6036        case "=":
6037          return " {}={} ";
6038        case "<":
6039          return " {}<{} ";
6040        case ">":
6041          return " {}>{} ";
6042        case "<<":
6043          return " {}\\ll{} ";
6044        case ">>":
6045          return " {}\\gg{} ";
6046        case "\\pm":
6047          return " {}\\pm{} ";
6048        case "\\approx":
6049          return " {}\\approx{} ";
6050        case "$\\approx$":
6051          return " {}\\approx{} ";
6052        case "v":
6053          return " \\downarrow{} ";
6054        case "(v)":
6055          return " \\downarrow{} ";
6056        case "^":
6057          return " \\uparrow{} ";
6058        case "(^)":
6059          return " \\uparrow{} ";
6060        default:
6061          assertNever(a);
6062          throw ["MhchemBugT", "mhchem bug T. Please report."];
6063      }
6064    }
6065  };
6066  function assertNever(a) {
6067  }
6068  function assertString(a) {
6069  }
6070  defineMacro("\\darr", "\\downarrow");
6071  defineMacro("\\dArr", "\\Downarrow");
6072  defineMacro("\\Darr", "\\Downarrow");
6073  defineMacro("\\lang", "\\langle");
6074  defineMacro("\\rang", "\\rangle");
6075  defineMacro("\\uarr", "\\uparrow");
6076  defineMacro("\\uArr", "\\Uparrow");
6077  defineMacro("\\Uarr", "\\Uparrow");
6078  defineMacro("\\N", "\\mathbb{N}");
6079  defineMacro("\\R", "\\mathbb{R}");
6080  defineMacro("\\Z", "\\mathbb{Z}");
6081  defineMacro("\\alef", "\\aleph");
6082  defineMacro("\\alefsym", "\\aleph");
6083  defineMacro("\\bull", "\\bullet");
6084  defineMacro("\\clubs", "\\clubsuit");
6085  defineMacro("\\cnums", "\\mathbb{C}");
6086  defineMacro("\\Complex", "\\mathbb{C}");
6087  defineMacro("\\Dagger", "\\ddagger");
6088  defineMacro("\\diamonds", "\\diamondsuit");
6089  defineMacro("\\empty", "\\emptyset");
6090  defineMacro("\\exist", "\\exists");
6091  defineMacro("\\harr", "\\leftrightarrow");
6092  defineMacro("\\hArr", "\\Leftrightarrow");
6093  defineMacro("\\Harr", "\\Leftrightarrow");
6094  defineMacro("\\hearts", "\\heartsuit");
6095  defineMacro("\\image", "\\Im");
6096  defineMacro("\\infin", "\\infty");
6097  defineMacro("\\isin", "\\in");
6098  defineMacro("\\larr", "\\leftarrow");
6099  defineMacro("\\lArr", "\\Leftarrow");
6100  defineMacro("\\Larr", "\\Leftarrow");
6101  defineMacro("\\lrarr", "\\leftrightarrow");
6102  defineMacro("\\lrArr", "\\Leftrightarrow");
6103  defineMacro("\\Lrarr", "\\Leftrightarrow");
6104  defineMacro("\\natnums", "\\mathbb{N}");
6105  defineMacro("\\plusmn", "\\pm");
6106  defineMacro("\\rarr", "\\rightarrow");
6107  defineMacro("\\rArr", "\\Rightarrow");
6108  defineMacro("\\Rarr", "\\Rightarrow");
6109  defineMacro("\\real", "\\Re");
6110  defineMacro("\\reals", "\\mathbb{R}");
6111  defineMacro("\\Reals", "\\mathbb{R}");
6112  defineMacro("\\sdot", "\\cdot");
6113  defineMacro("\\sect", "\\S");
6114  defineMacro("\\spades", "\\spadesuit");
6115  defineMacro("\\sub", "\\subset");
6116  defineMacro("\\sube", "\\subseteq");
6117  defineMacro("\\supe", "\\supseteq");
6118  defineMacro("\\thetasym", "\\vartheta");
6119  defineMacro("\\weierp", "\\wp");
6120  defineMacro("\\quantity", "{\\left\\{ #1 \\right\\}}");
6121  defineMacro("\\qty", "{\\left\\{ #1 \\right\\}}");
6122  defineMacro("\\pqty", "{\\left( #1 \\right)}");
6123  defineMacro("\\bqty", "{\\left[ #1 \\right]}");
6124  defineMacro("\\vqty", "{\\left\\vert #1 \\right\\vert}");
6125  defineMacro("\\Bqty", "{\\left\\{ #1 \\right\\}}");
6126  defineMacro("\\absolutevalue", "{\\left\\vert #1 \\right\\vert}");
6127  defineMacro("\\abs", "{\\left\\vert #1 \\right\\vert}");
6128  defineMacro("\\norm", "{\\left\\Vert #1 \\right\\Vert}");
6129  defineMacro("\\evaluated", "{\\left.#1 \\right\\vert}");
6130  defineMacro("\\eval", "{\\left.#1 \\right\\vert}");
6131  defineMacro("\\order", "{\\mathcal{O} \\left( #1 \\right)}");
6132  defineMacro("\\commutator", "{\\left[ #1 , #2 \\right]}");
6133  defineMacro("\\comm", "{\\left[ #1 , #2 \\right]}");
6134  defineMacro("\\anticommutator", "{\\left\\{ #1 , #2 \\right\\}}");
6135  defineMacro("\\acomm", "{\\left\\{ #1 , #2 \\right\\}}");
6136  defineMacro("\\poissonbracket", "{\\left\\{ #1 , #2 \\right\\}}");
6137  defineMacro("\\pb", "{\\left\\{ #1 , #2 \\right\\}}");
6138  defineMacro("\\vectorbold", "{\\boldsymbol{ #1 }}");
6139  defineMacro("\\vb", "{\\boldsymbol{ #1 }}");
6140  defineMacro("\\vectorarrow", "{\\vec{\\boldsymbol{ #1 }}}");
6141  defineMacro("\\va", "{\\vec{\\boldsymbol{ #1 }}}");
6142  defineMacro("\\vectorunit", "{{\\boldsymbol{\\hat{ #1 }}}}");
6143  defineMacro("\\vu", "{{\\boldsymbol{\\hat{ #1 }}}}");
6144  defineMacro("\\dotproduct", "\\mathbin{\\boldsymbol\\cdot}");
6145  defineMacro("\\vdot", "{\\boldsymbol\\cdot}");
6146  defineMacro("\\crossproduct", "\\mathbin{\\boldsymbol\\times}");
6147  defineMacro("\\cross", "\\mathbin{\\boldsymbol\\times}");
6148  defineMacro("\\cp", "\\mathbin{\\boldsymbol\\times}");
6149  defineMacro("\\gradient", "{\\boldsymbol\\nabla}");
6150  defineMacro("\\grad", "{\\boldsymbol\\nabla}");
6151  defineMacro("\\divergence", "{\\grad\\vdot}");
6152  defineMacro("\\curl", "{\\grad\\cross}");
6153  defineMacro("\\laplacian", "\\nabla^2");
6154  defineMacro("\\tr", "{\\operatorname{tr}}");
6155  defineMacro("\\Tr", "{\\operatorname{Tr}}");
6156  defineMacro("\\rank", "{\\operatorname{rank}}");
6157  defineMacro("\\erf", "{\\operatorname{erf}}");
6158  defineMacro("\\Res", "{\\operatorname{Res}}");
6159  defineMacro("\\principalvalue", "{\\mathcal{P}}");
6160  defineMacro("\\pv", "{\\mathcal{P}}");
6161  defineMacro("\\PV", "{\\operatorname{P.V.}}");
6162  defineMacro("\\qqtext", "{\\quad\\text{ #1 }\\quad}");
6163  defineMacro("\\qq", "{\\quad\\text{ #1 }\\quad}");
6164  defineMacro("\\qcomma", "{\\text{,}\\quad}");
6165  defineMacro("\\qc", "{\\text{,}\\quad}");
6166  defineMacro("\\qcc", "{\\quad\\text{c.c.}\\quad}");
6167  defineMacro("\\qif", "{\\quad\\text{if}\\quad}");
6168  defineMacro("\\qthen", "{\\quad\\text{then}\\quad}");
6169  defineMacro("\\qelse", "{\\quad\\text{else}\\quad}");
6170  defineMacro("\\qotherwise", "{\\quad\\text{otherwise}\\quad}");
6171  defineMacro("\\qunless", "{\\quad\\text{unless}\\quad}");
6172  defineMacro("\\qgiven", "{\\quad\\text{given}\\quad}");
6173  defineMacro("\\qusing", "{\\quad\\text{using}\\quad}");
6174  defineMacro("\\qassume", "{\\quad\\text{assume}\\quad}");
6175  defineMacro("\\qsince", "{\\quad\\text{since}\\quad}");
6176  defineMacro("\\qlet", "{\\quad\\text{let}\\quad}");
6177  defineMacro("\\qfor", "{\\quad\\text{for}\\quad}");
6178  defineMacro("\\qall", "{\\quad\\text{all}\\quad}");
6179  defineMacro("\\qeven", "{\\quad\\text{even}\\quad}");
6180  defineMacro("\\qodd", "{\\quad\\text{odd}\\quad}");
6181  defineMacro("\\qinteger", "{\\quad\\text{integer}\\quad}");
6182  defineMacro("\\qand", "{\\quad\\text{and}\\quad}");
6183  defineMacro("\\qor", "{\\quad\\text{or}\\quad}");
6184  defineMacro("\\qas", "{\\quad\\text{as}\\quad}");
6185  defineMacro("\\qin", "{\\quad\\text{in}\\quad}");
6186  defineMacro("\\differential", "{\\text{d}}");
6187  defineMacro("\\dd", "{\\text{d}}");
6188  defineMacro("\\derivative", "{\\frac{\\text{d}{ #1 }}{\\text{d}{ #2 }}}");
6189  defineMacro("\\dv", "{\\frac{\\text{d}{ #1 }}{\\text{d}{ #2 }}}");
6190  defineMacro("\\partialderivative", "{\\frac{\\partial{ #1 }}{\\partial{ #2 }}}");
6191  defineMacro("\\variation", "{\\delta}");
6192  defineMacro("\\var", "{\\delta}");
6193  defineMacro("\\functionalderivative", "{\\frac{\\delta{ #1 }}{\\delta{ #2 }}}");
6194  defineMacro("\\fdv", "{\\frac{\\delta{ #1 }}{\\delta{ #2 }}}");
6195  defineMacro("\\innerproduct", "{\\left\\langle {#1} \\mid { #2} \\right\\rangle}");
6196  defineMacro(
6197    "\\outerproduct",
6198    "{\\left\\vert { #1 } \\right\\rangle\\left\\langle { #2} \\right\\vert}"
6199  );
6200  defineMacro(
6201    "\\dyad",
6202    "{\\left\\vert { #1 } \\right\\rangle\\left\\langle { #2} \\right\\vert}"
6203  );
6204  defineMacro(
6205    "\\ketbra",
6206    "{\\left\\vert { #1 } \\right\\rangle\\left\\langle { #2} \\right\\vert}"
6207  );
6208  defineMacro(
6209    "\\op",
6210    "{\\left\\vert { #1 } \\right\\rangle\\left\\langle { #2} \\right\\vert}"
6211  );
6212  defineMacro("\\expectationvalue", "{\\left\\langle {#1 } \\right\\rangle}");
6213  defineMacro("\\expval", "{\\left\\langle {#1 } \\right\\rangle}");
6214  defineMacro("\\ev", "{\\left\\langle {#1 } \\right\\rangle}");
6215  defineMacro(
6216    "\\matrixelement",
6217    "{\\left\\langle{ #1 }\\right\\vert{ #2 }\\left\\vert{#3}\\right\\rangle}"
6218  );
6219  defineMacro(
6220    "\\matrixel",
6221    "{\\left\\langle{ #1 }\\right\\vert{ #2 }\\left\\vert{#3}\\right\\rangle}"
6222  );
6223  defineMacro(
6224    "\\mel",
6225    "{\\left\\langle{ #1 }\\right\\vert{ #2 }\\left\\vert{#3}\\right\\rangle}"
6226  );
6227  function getHLines(parser) {
6228    const hlineInfo = [];
6229    parser.consumeSpaces();
6230    let nxt = parser.fetch().text;
6231    if (nxt === "\\relax") {
6232      parser.consume();
6233      parser.consumeSpaces();
6234      nxt = parser.fetch().text;
6235    }
6236    while (nxt === "\\hline" || nxt === "\\hdashline") {
6237      parser.consume();
6238      hlineInfo.push(nxt === "\\hdashline");
6239      parser.consumeSpaces();
6240      nxt = parser.fetch().text;
6241    }
6242    return hlineInfo;
6243  }
6244  var validateAmsEnvironmentContext = (context) => {
6245    const settings = context.parser.settings;
6246    if (!settings.displayMode) {
6247      throw new ParseError(`{$context.envName}} can be used only in display mode.`);
6248    }
6249  };
6250  var sizeRegEx$1 = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/;
6251  var arrayGaps = (macros2) => {
6252    let arraystretch = macros2.get("\\arraystretch");
6253    if (typeof arraystretch !== "string") {
6254      arraystretch = stringFromArg(arraystretch.tokens);
6255    }
6256    arraystretch = isNaN(arraystretch) ? null : Number(arraystretch);
6257    let arraycolsepStr = macros2.get("\\arraycolsep");
6258    if (typeof arraycolsepStr !== "string") {
6259      arraycolsepStr = stringFromArg(arraycolsepStr.tokens);
6260    }
6261    const match = sizeRegEx$1.exec(arraycolsepStr);
6262    const arraycolsep = match ? { number: +(match[1] + match[2]), unit: match[3] } : null;
6263    return [arraystretch, arraycolsep];
6264  };
6265  var checkCellForLabels = (cell) => {
6266    let rowLabel = "";
6267    for (let i = 0; i < cell.length; i++) {
6268      if (cell[i].type === "label") {
6269        if (rowLabel) {
6270          throw new ParseError("Multiple \\labels in one row");
6271        }
6272        rowLabel = cell[i].string;
6273      }
6274    }
6275    return rowLabel;
6276  };
6277  function getAutoTag(name) {
6278    if (name.indexOf("ed") === -1) {
6279      return name.indexOf("*") === -1;
6280    }
6281  }
6282  function parseArray(parser, {
6283    cols,
6284    // [{ type: string , align: l|c|r|null }]
6285    envClasses,
6286    // align(ed|at|edat) | array | cases | cd | small | multline
6287    autoTag,
6288    // boolean
6289    singleRow,
6290    // boolean
6291    emptySingleRow,
6292    // boolean
6293    maxNumCols,
6294    // number
6295    leqno,
6296    // boolean
6297    arraystretch,
6298    // number  | null
6299    arraycolsep
6300    // size value | null
6301  }, scriptLevel2) {
6302    parser.gullet.beginGroup();
6303    if (!singleRow) {
6304      parser.gullet.macros.set("\\cr", "\\\\\\relax");
6305    }
6306    parser.gullet.beginGroup();
6307    let row = [];
6308    const body = [row];
6309    const rowGaps = [];
6310    const labels = [];
6311    const hLinesBeforeRow = [];
6312    const tags = autoTag != null ? [] : void 0;
6313    function beginRow() {
6314      if (autoTag) {
6315        parser.gullet.macros.set("\\@eqnsw", "1", true);
6316      }
6317    }
6318    function endRow() {
6319      if (tags) {
6320        if (parser.gullet.macros.get("\\df@tag")) {
6321          tags.push(parser.subparse([new Token("\\df@tag")]));
6322          parser.gullet.macros.set("\\df@tag", void 0, true);
6323        } else {
6324          tags.push(Boolean(autoTag) && parser.gullet.macros.get("\\@eqnsw") === "1");
6325        }
6326      }
6327    }
6328    beginRow();
6329    hLinesBeforeRow.push(getHLines(parser));
6330    while (true) {
6331      let cell = parser.parseExpression(false, singleRow ? "\\end" : "\\\\");
6332      parser.gullet.endGroup();
6333      parser.gullet.beginGroup();
6334      cell = {
6335        type: "ordgroup",
6336        mode: parser.mode,
6337        body: cell,
6338        semisimple: true
6339      };
6340      row.push(cell);
6341      const next = parser.fetch().text;
6342      if (next === "&") {
6343        if (maxNumCols && row.length === maxNumCols) {
6344          if (envClasses.includes("array")) {
6345            if (parser.settings.strict) {
6346              throw new ParseError(
6347                "Too few columns specified in the {array} column argument.",
6348                parser.nextToken
6349              );
6350            }
6351          } else if (maxNumCols === 2) {
6352            throw new ParseError(
6353              "The split environment accepts no more than two columns",
6354              parser.nextToken
6355            );
6356          } else {
6357            throw new ParseError(
6358              "The equation environment accepts only one column",
6359              parser.nextToken
6360            );
6361          }
6362        }
6363        parser.consume();
6364      } else if (next === "\\end") {
6365        endRow();
6366        if (row.length === 1 && cell.body.length === 0 && (body.length > 1 || !emptySingleRow)) {
6367          body.pop();
6368        }
6369        labels.push(checkCellForLabels(cell.body));
6370        if (hLinesBeforeRow.length < body.length + 1) {
6371          hLinesBeforeRow.push([]);
6372        }
6373        break;
6374      } else if (next === "\\\\") {
6375        parser.consume();
6376        let size;
6377        if (parser.gullet.future().text !== " ") {
6378          size = parser.parseSizeGroup(true);
6379        }
6380        rowGaps.push(size ? size.value : null);
6381        endRow();
6382        labels.push(checkCellForLabels(cell.body));
6383        hLinesBeforeRow.push(getHLines(parser));
6384        row = [];
6385        body.push(row);
6386        beginRow();
6387      } else {
6388        throw new ParseError("Expected & or \\\\ or \\cr or \\end", parser.nextToken);
6389      }
6390    }
6391    parser.gullet.endGroup();
6392    parser.gullet.endGroup();
6393    return {
6394      type: "array",
6395      mode: parser.mode,
6396      body,
6397      cols,
6398      rowGaps,
6399      hLinesBeforeRow,
6400      envClasses,
6401      autoTag,
6402      scriptLevel: scriptLevel2,
6403      tags,
6404      labels,
6405      leqno,
6406      arraystretch,
6407      arraycolsep
6408    };
6409  }
6410  function dCellStyle(envName) {
6411    return envName.slice(0, 1) === "d" ? "display" : "text";
6412  }
6413  var alignMap = {
6414    c: "center ",
6415    l: "left ",
6416    r: "right "
6417  };
6418  var glue = (group) => {
6419    const glueNode = new mathMLTree.MathNode("mtd", []);
6420    glueNode.style = { padding: "0", width: "50%" };
6421    if (group.envClasses.includes("multline")) {
6422      glueNode.style.width = "7.5%";
6423    }
6424    return glueNode;
6425  };
6426  var mathmlBuilder$7 = function(group, style) {
6427    const tbl = [];
6428    const numRows = group.body.length;
6429    const hlines = group.hLinesBeforeRow;
6430    for (let i = 0; i < numRows; i++) {
6431      const rw = group.body[i];
6432      const row = [];
6433      const cellLevel = group.scriptLevel === "text" ? StyleLevel.TEXT : group.scriptLevel === "script" ? StyleLevel.SCRIPT : StyleLevel.DISPLAY;
6434      for (let j = 0; j < rw.length; j++) {
6435        const mtd = new mathMLTree.MathNode(
6436          "mtd",
6437          [buildGroup$1(rw[j], style.withLevel(cellLevel))]
6438        );
6439        if (group.envClasses.includes("multline")) {
6440          const align2 = i === 0 ? "left" : i === numRows - 1 ? "right" : "center";
6441          mtd.setAttribute("columnalign", align2);
6442          if (align2 !== "center") {
6443            mtd.classes.push("tml-" + align2);
6444          }
6445        }
6446        row.push(mtd);
6447      }
6448      const numColumns = group.body[0].length;
6449      for (let k = 0; k < numColumns - rw.length; k++) {
6450        row.push(new mathMLTree.MathNode("mtd", [], style));
6451      }
6452      if (group.autoTag) {
6453        const tag = group.tags[i];
6454        let tagElement;
6455        if (tag === true) {
6456          tagElement = new mathMLTree.MathNode("mtext", [new Span(["tml-eqn"])]);
6457        } else if (tag === false) {
6458          tagElement = new mathMLTree.MathNode("mtext", [], []);
6459        } else {
6460          tagElement = buildExpressionRow(tag[0].body, style.withLevel(cellLevel), true);
6461          tagElement = consolidateText(tagElement);
6462          tagElement.classes = ["tml-tag"];
6463        }
6464        if (tagElement) {
6465          row.unshift(glue(group));
6466          row.push(glue(group));
6467          if (group.leqno) {
6468            row[0].children.push(tagElement);
6469            row[0].classes.push("tml-left");
6470          } else {
6471            row[row.length - 1].children.push(tagElement);
6472            row[row.length - 1].classes.push("tml-right");
6473          }
6474        }
6475      }
6476      const mtr = new mathMLTree.MathNode("mtr", row, []);
6477      const label = group.labels.shift();
6478      if (label && group.tags && group.tags[i]) {
6479        mtr.setAttribute("id", label);
6480        if (Array.isArray(group.tags[i])) {
6481          mtr.classes.push("tml-tageqn");
6482        }
6483      }
6484      if (i === 0 && hlines[0].length > 0) {
6485        if (hlines[0].length === 2) {
6486          mtr.children.forEach((cell) => {
6487            cell.style.borderTop = "0.15em double";
6488          });
6489        } else {
6490          mtr.children.forEach((cell) => {
6491            cell.style.borderTop = hlines[0][0] ? "0.06em dashed" : "0.06em solid";
6492          });
6493        }
6494      }
6495      if (hlines[i + 1].length > 0) {
6496        if (hlines[i + 1].length === 2) {
6497          mtr.children.forEach((cell) => {
6498            cell.style.borderBottom = "0.15em double";
6499          });
6500        } else {
6501          mtr.children.forEach((cell) => {
6502            cell.style.borderBottom = hlines[i + 1][0] ? "0.06em dashed" : "0.06em solid";
6503          });
6504        }
6505      }
6506      tbl.push(mtr);
6507    }
6508    if (group.envClasses.length > 0) {
6509      if (group.arraystretch && group.arraystretch !== 1) {
6510        const pad = String(1.4 * group.arraystretch - 0.8) + "ex";
6511        for (let i = 0; i < tbl.length; i++) {
6512          for (let j = 0; j < tbl[i].children.length; j++) {
6513            tbl[i].children[j].style.paddingTop = pad;
6514            tbl[i].children[j].style.paddingBottom = pad;
6515          }
6516        }
6517      }
6518      let sidePadding = group.envClasses.includes("abut") ? "0" : group.envClasses.includes("cases") ? "0" : group.envClasses.includes("small") ? "0.1389" : group.envClasses.includes("cd") ? "0.25" : "0.4";
6519      let sidePadUnit = "em";
6520      if (group.arraycolsep) {
6521        const arraySidePad = calculateSize(group.arraycolsep, style);
6522        sidePadding = arraySidePad.number.toFixed(4);
6523        sidePadUnit = arraySidePad.unit;
6524      }
6525      const numCols = tbl.length === 0 ? 0 : tbl[0].children.length;
6526      const sidePad = (j, hand) => {
6527        if (j === 0 && hand === 0) {
6528          return "0";
6529        }
6530        if (j === numCols - 1 && hand === 1) {
6531          return "0";
6532        }
6533        if (group.envClasses[0] !== "align") {
6534          return sidePadding;
6535        }
6536        if (hand === 1) {
6537          return "0";
6538        }
6539        if (group.autoTag) {
6540          return j % 2 ? "1" : "0";
6541        } else {
6542          return j % 2 ? "0" : "1";
6543        }
6544      };
6545      for (let i = 0; i < tbl.length; i++) {
6546        for (let j = 0; j < tbl[i].children.length; j++) {
6547          tbl[i].children[j].style.paddingLeft = `$sidePad(j, 0)}$sidePadUnit}`;
6548          tbl[i].children[j].style.paddingRight = `$sidePad(j, 1)}$sidePadUnit}`;
6549        }
6550      }
6551      const align2 = group.envClasses.includes("align") || group.envClasses.includes("alignat");
6552      for (let i = 0; i < tbl.length; i++) {
6553        const row = tbl[i];
6554        if (align2) {
6555          for (let j = 0; j < row.children.length; j++) {
6556            row.children[j].classes = ["tml-" + (j % 2 ? "left" : "right")];
6557          }
6558          if (group.autoTag) {
6559            const k = group.leqno ? 0 : row.children.length - 1;
6560            row.children[k].classes = ["tml-" + (group.leqno ? "left" : "right")];
6561          }
6562        }
6563        if (row.children.length > 1 && group.envClasses.includes("cases")) {
6564          row.children[1].style.paddingLeft = "1em";
6565        }
6566        if (group.envClasses.includes("cases") || group.envClasses.includes("subarray")) {
6567          for (const cell of row.children) {
6568            cell.classes.push("tml-left");
6569          }
6570        }
6571      }
6572    } else {
6573      for (let i = 0; i < tbl.length; i++) {
6574        tbl[i].children[0].style.paddingLeft = "0em";
6575        if (tbl[i].children.length === tbl[0].children.length) {
6576          tbl[i].children[tbl[i].children.length - 1].style.paddingRight = "0em";
6577        }
6578      }
6579    }
6580    let table = new mathMLTree.MathNode("mtable", tbl);
6581    if (group.envClasses.length > 0) {
6582      if (group.envClasses.includes("jot")) {
6583        table.classes.push("tml-jot");
6584      } else if (group.envClasses.includes("small")) {
6585        table.classes.push("tml-small");
6586      }
6587    }
6588    if (group.scriptLevel === "display") {
6589      table.setAttribute("displaystyle", "true");
6590    }
6591    if (group.autoTag || group.envClasses.includes("multline")) {
6592      table.style.width = "100%";
6593    }
6594    let align = "";
6595    if (group.cols && group.cols.length > 0) {
6596      const cols = group.cols;
6597      let prevTypeWasAlign = false;
6598      let iStart = 0;
6599      let iEnd = cols.length;
6600      while (cols[iStart].type === "separator") {
6601        iStart += 1;
6602      }
6603      while (cols[iEnd - 1].type === "separator") {
6604        iEnd -= 1;
6605      }
6606      if (cols[0].type === "separator") {
6607        const sep = cols[1].type === "separator" ? "0.15em double" : cols[0].separator === "|" ? "0.06em solid " : "0.06em dashed ";
6608        for (const row of table.children) {
6609          row.children[0].style.borderLeft = sep;
6610        }
6611      }
6612      let iCol = group.autoTag ? 0 : -1;
6613      for (let i = iStart; i < iEnd; i++) {
6614        if (cols[i].type === "align") {
6615          const colAlign = alignMap[cols[i].align];
6616          align += colAlign;
6617          iCol += 1;
6618          for (const row of table.children) {
6619            if (colAlign.trim() !== "center" && iCol < row.children.length) {
6620              row.children[iCol].classes = ["tml-" + colAlign.trim()];
6621            }
6622          }
6623          prevTypeWasAlign = true;
6624        } else if (cols[i].type === "separator") {
6625          if (prevTypeWasAlign) {
6626            const sep = cols[i + 1].type === "separator" ? "0.15em double" : cols[i].separator === "|" ? "0.06em solid" : "0.06em dashed";
6627            for (const row of table.children) {
6628              if (iCol < row.children.length) {
6629                row.children[iCol].style.borderRight = sep;
6630              }
6631            }
6632          }
6633          prevTypeWasAlign = false;
6634        }
6635      }
6636      if (cols[cols.length - 1].type === "separator") {
6637        const sep = cols[cols.length - 2].type === "separator" ? "0.15em double" : cols[cols.length - 1].separator === "|" ? "0.06em solid" : "0.06em dashed";
6638        for (const row of table.children) {
6639          row.children[row.children.length - 1].style.borderRight = sep;
6640          row.children[row.children.length - 1].style.paddingRight = "0.4em";
6641        }
6642      }
6643    }
6644    if (group.autoTag) {
6645      align = "left " + (align.length > 0 ? align : "center ") + "right ";
6646    }
6647    if (align) {
6648      table.setAttribute("columnalign", align.trim());
6649    }
6650    if (group.envClasses.includes("small")) {
6651      table = new mathMLTree.MathNode("mstyle", [table]);
6652      table.setAttribute("scriptlevel", "1");
6653    }
6654    return table;
6655  };
6656  var alignedHandler = function(context, args) {
6657    if (context.envName.indexOf("ed") === -1) {
6658      validateAmsEnvironmentContext(context);
6659    }
6660    const isSplit = context.envName === "split";
6661    const cols = [];
6662    const res = parseArray(
6663      context.parser,
6664      {
6665        cols,
6666        emptySingleRow: true,
6667        autoTag: isSplit ? void 0 : getAutoTag(context.envName),
6668        envClasses: ["abut", "jot"],
6669        // set row spacing & provisional column spacing
6670        maxNumCols: context.envName === "split" ? 2 : void 0,
6671        leqno: context.parser.settings.leqno
6672      },
6673      "display"
6674    );
6675    let numMaths;
6676    let numCols = 0;
6677    const isAlignedAt = context.envName.indexOf("at") > -1;
6678    if (args[0] && isAlignedAt) {
6679      let arg0 = "";
6680      for (let i = 0; i < args[0].body.length; i++) {
6681        const textord2 = assertNodeType(args[0].body[i], "textord");
6682        arg0 += textord2.text;
6683      }
6684      if (isNaN(arg0)) {
6685        throw new ParseError("The alignat enviroment requires a numeric first argument.");
6686      }
6687      numMaths = Number(arg0);
6688      numCols = numMaths * 2;
6689    }
6690    res.body.forEach(function(row) {
6691      if (isAlignedAt) {
6692        const curMaths = row.length / 2;
6693        if (numMaths < curMaths) {
6694          throw new ParseError(
6695            `Too many math in a row: expected $numMaths}, but got $curMaths}`,
6696            row[0]
6697          );
6698        }
6699      } else if (numCols < row.length) {
6700        numCols = row.length;
6701      }
6702    });
6703    for (let i = 0; i < numCols; ++i) {
6704      let align = "r";
6705      if (i % 2 === 1) {
6706        align = "l";
6707      }
6708      cols[i] = {
6709        type: "align",
6710        align
6711      };
6712    }
6713    if (context.envName === "split") ;
6714    else if (isAlignedAt) {
6715      res.envClasses.push("alignat");
6716    } else {
6717      res.envClasses[0] = "align";
6718    }
6719    return res;
6720  };
6721  defineEnvironment({
6722    type: "array",
6723    names: ["array", "darray"],
6724    props: {
6725      numArgs: 1
6726    },
6727    handler(context, args) {
6728      const symNode = checkSymbolNodeType(args[0]);
6729      const colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body;
6730      const cols = colalign.map(function(nde) {
6731        const node = assertSymbolNodeType(nde);
6732        const ca = node.text;
6733        if ("lcr".indexOf(ca) !== -1) {
6734          return {
6735            type: "align",
6736            align: ca
6737          };
6738        } else if (ca === "|") {
6739          return {
6740            type: "separator",
6741            separator: "|"
6742          };
6743        } else if (ca === ":") {
6744          return {
6745            type: "separator",
6746            separator: ":"
6747          };
6748        }
6749        throw new ParseError("Unknown column alignment: " + ca, nde);
6750      });
6751      const [arraystretch, arraycolsep] = arrayGaps(context.parser.gullet.macros);
6752      const res = {
6753        cols,
6754        envClasses: ["array"],
6755        maxNumCols: cols.length,
6756        arraystretch,
6757        arraycolsep
6758      };
6759      return parseArray(context.parser, res, dCellStyle(context.envName));
6760    },
6761    mathmlBuilder: mathmlBuilder$7
6762  });
6763  defineEnvironment({
6764    type: "array",
6765    names: [
6766      "matrix",
6767      "pmatrix",
6768      "bmatrix",
6769      "Bmatrix",
6770      "vmatrix",
6771      "Vmatrix",
6772      "matrix*",
6773      "pmatrix*",
6774      "bmatrix*",
6775      "Bmatrix*",
6776      "vmatrix*",
6777      "Vmatrix*"
6778    ],
6779    props: {
6780      numArgs: 0
6781    },
6782    handler(context) {
6783      const delimiters2 = {
6784        matrix: null,
6785        pmatrix: ["(", ")"],
6786        bmatrix: ["[", "]"],
6787        Bmatrix: ["\\{", "\\}"],
6788        vmatrix: ["|", "|"],
6789        Vmatrix: ["\\Vert", "\\Vert"]
6790      }[context.envName.replace("*", "")];
6791      let colAlign = "c";
6792      const payload = {
6793        envClasses: [],
6794        cols: []
6795      };
6796      if (context.envName.charAt(context.envName.length - 1) === "*") {
6797        const parser = context.parser;
6798        parser.consumeSpaces();
6799        if (parser.fetch().text === "[") {
6800          parser.consume();
6801          parser.consumeSpaces();
6802          colAlign = parser.fetch().text;
6803          if ("lcr".indexOf(colAlign) === -1) {
6804            throw new ParseError("Expected l or c or r", parser.nextToken);
6805          }
6806          parser.consume();
6807          parser.consumeSpaces();
6808          parser.expect("]");
6809          parser.consume();
6810          payload.cols = [];
6811        }
6812      }
6813      const res = parseArray(context.parser, payload, "text");
6814      res.cols = new Array(res.body[0].length).fill({ type: "align", align: colAlign });
6815      const [arraystretch, arraycolsep] = arrayGaps(context.parser.gullet.macros);
6816      return delimiters2 ? {
6817        type: "leftright",
6818        mode: context.mode,
6819        body: [res],
6820        left: delimiters2[0],
6821        right: delimiters2[1],
6822        rightColor: void 0,
6823        // \right uninfluenced by \color in array
6824        arraystretch,
6825        arraycolsep
6826      } : res;
6827    },
6828    mathmlBuilder: mathmlBuilder$7
6829  });
6830  defineEnvironment({
6831    type: "array",
6832    names: ["smallmatrix"],
6833    props: {
6834      numArgs: 0
6835    },
6836    handler(context) {
6837      const payload = { type: "small" };
6838      const res = parseArray(context.parser, payload, "script");
6839      res.envClasses = ["small"];
6840      return res;
6841    },
6842    mathmlBuilder: mathmlBuilder$7
6843  });
6844  defineEnvironment({
6845    type: "array",
6846    names: ["subarray"],
6847    props: {
6848      numArgs: 1
6849    },
6850    handler(context, args) {
6851      const symNode = checkSymbolNodeType(args[0]);
6852      const colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body;
6853      const cols = colalign.map(function(nde) {
6854        const node = assertSymbolNodeType(nde);
6855        const ca = node.text;
6856        if ("lc".indexOf(ca) !== -1) {
6857          return {
6858            type: "align",
6859            align: ca
6860          };
6861        }
6862        throw new ParseError("Unknown column alignment: " + ca, nde);
6863      });
6864      if (cols.length > 1) {
6865        throw new ParseError("{subarray} can contain only one column");
6866      }
6867      let res = {
6868        cols,
6869        envClasses: ["small"]
6870      };
6871      res = parseArray(context.parser, res, "script");
6872      if (res.body.length > 0 && res.body[0].length > 1) {
6873        throw new ParseError("{subarray} can contain only one column");
6874      }
6875      return res;
6876    },
6877    mathmlBuilder: mathmlBuilder$7
6878  });
6879  defineEnvironment({
6880    type: "array",
6881    names: ["cases", "dcases", "rcases", "drcases"],
6882    props: {
6883      numArgs: 0
6884    },
6885    handler(context) {
6886      const payload = {
6887        cols: [],
6888        envClasses: ["cases"]
6889      };
6890      const res = parseArray(context.parser, payload, dCellStyle(context.envName));
6891      return {
6892        type: "leftright",
6893        mode: context.mode,
6894        body: [res],
6895        left: context.envName.indexOf("r") > -1 ? "." : "\\{",
6896        right: context.envName.indexOf("r") > -1 ? "\\}" : ".",
6897        rightColor: void 0
6898      };
6899    },
6900    mathmlBuilder: mathmlBuilder$7
6901  });
6902  defineEnvironment({
6903    type: "array",
6904    names: ["align", "align*", "aligned", "split"],
6905    props: {
6906      numArgs: 0
6907    },
6908    handler: alignedHandler,
6909    mathmlBuilder: mathmlBuilder$7
6910  });
6911  defineEnvironment({
6912    type: "array",
6913    names: ["alignat", "alignat*", "alignedat"],
6914    props: {
6915      numArgs: 1
6916    },
6917    handler: alignedHandler,
6918    mathmlBuilder: mathmlBuilder$7
6919  });
6920  defineEnvironment({
6921    type: "array",
6922    names: ["gathered", "gather", "gather*"],
6923    props: {
6924      numArgs: 0
6925    },
6926    handler(context) {
6927      if (context.envName !== "gathered") {
6928        validateAmsEnvironmentContext(context);
6929      }
6930      const res = {
6931        cols: [],
6932        envClasses: ["abut", "jot"],
6933        autoTag: getAutoTag(context.envName),
6934        emptySingleRow: true,
6935        leqno: context.parser.settings.leqno
6936      };
6937      return parseArray(context.parser, res, "display");
6938    },
6939    mathmlBuilder: mathmlBuilder$7
6940  });
6941  defineEnvironment({
6942    type: "array",
6943    names: ["equation", "equation*"],
6944    props: {
6945      numArgs: 0
6946    },
6947    handler(context) {
6948      validateAmsEnvironmentContext(context);
6949      const res = {
6950        autoTag: getAutoTag(context.envName),
6951        emptySingleRow: true,
6952        singleRow: true,
6953        maxNumCols: 1,
6954        envClasses: ["align"],
6955        leqno: context.parser.settings.leqno
6956      };
6957      return parseArray(context.parser, res, "display");
6958    },
6959    mathmlBuilder: mathmlBuilder$7
6960  });
6961  defineEnvironment({
6962    type: "array",
6963    names: ["multline", "multline*"],
6964    props: {
6965      numArgs: 0
6966    },
6967    handler(context) {
6968      validateAmsEnvironmentContext(context);
6969      const res = {
6970        autoTag: context.envName === "multline",
6971        maxNumCols: 1,
6972        envClasses: ["jot", "multline"],
6973        leqno: context.parser.settings.leqno
6974      };
6975      return parseArray(context.parser, res, "display");
6976    },
6977    mathmlBuilder: mathmlBuilder$7
6978  });
6979  defineEnvironment({
6980    type: "array",
6981    names: ["CD"],
6982    props: {
6983      numArgs: 0
6984    },
6985    handler(context) {
6986      validateAmsEnvironmentContext(context);
6987      return parseCD(context.parser);
6988    },
6989    mathmlBuilder: mathmlBuilder$7
6990  });
6991  defineFunction({
6992    type: "text",
6993    // Doesn't matter what this is.
6994    names: ["\\hline", "\\hdashline"],
6995    props: {
6996      numArgs: 0,
6997      allowedInText: true,
6998      allowedInMath: true
6999    },
7000    handler(context, args) {
7001      throw new ParseError(`$context.funcName} valid only within array environment`);
7002    }
7003  });
7004  var environments = _environments;
7005  defineFunction({
7006    type: "environment",
7007    names: ["\\begin", "\\end"],
7008    props: {
7009      numArgs: 1,
7010      argTypes: ["text"]
7011    },
7012    handler({ parser, funcName }, args) {
7013      const nameGroup = args[0];
7014      if (nameGroup.type !== "ordgroup") {
7015        throw new ParseError("Invalid environment name", nameGroup);
7016      }
7017      let envName = "";
7018      for (let i = 0; i < nameGroup.body.length; ++i) {
7019        envName += assertNodeType(nameGroup.body[i], "textord").text;
7020      }
7021      if (funcName === "\\begin") {
7022        if (!Object.prototype.hasOwnProperty.call(environments, envName)) {
7023          throw new ParseError("No such environment: " + envName, nameGroup);
7024        }
7025        const env = environments[envName];
7026        const { args: args2, optArgs } = parser.parseArguments("\\begin{" + envName + "}", env);
7027        const context = {
7028          mode: parser.mode,
7029          envName,
7030          parser
7031        };
7032        const result = env.handler(context, args2, optArgs);
7033        parser.expect("\\end", false);
7034        const endNameToken = parser.nextToken;
7035        const end = assertNodeType(parser.parseFunction(), "environment");
7036        if (end.name !== envName) {
7037          throw new ParseError(
7038            `Mismatch: \\begin{$envName}} matched by \\end{$end.name}}`,
7039            endNameToken
7040          );
7041        }
7042        return result;
7043      }
7044      return {
7045        type: "environment",
7046        mode: parser.mode,
7047        name: envName,
7048        nameGroup
7049      };
7050    }
7051  });
7052  defineFunction({
7053    type: "envTag",
7054    names: ["\\env@tag"],
7055    props: {
7056      numArgs: 1,
7057      argTypes: ["math"]
7058    },
7059    handler({ parser }, args) {
7060      return {
7061        type: "envTag",
7062        mode: parser.mode,
7063        body: args[0]
7064      };
7065    },
7066    mathmlBuilder(group, style) {
7067      return new mathMLTree.MathNode("mrow");
7068    }
7069  });
7070  defineFunction({
7071    type: "noTag",
7072    names: ["\\env@notag"],
7073    props: {
7074      numArgs: 0
7075    },
7076    handler({ parser }) {
7077      return {
7078        type: "noTag",
7079        mode: parser.mode
7080      };
7081    },
7082    mathmlBuilder(group, style) {
7083      return new mathMLTree.MathNode("mrow");
7084    }
7085  });
7086  var isLongVariableName = (group, font) => {
7087    if (font !== "mathrm" || group.body.type !== "ordgroup" || group.body.body.length === 1) {
7088      return false;
7089    }
7090    if (group.body.body[0].type !== "mathord") {
7091      return false;
7092    }
7093    for (let i = 1; i < group.body.body.length; i++) {
7094      const parseNodeType = group.body.body[i].type;
7095      if (!(parseNodeType === "mathord" || parseNodeType === "textord" && !isNaN(group.body.body[i].text))) {
7096        return false;
7097      }
7098    }
7099    return true;
7100  };
7101  var mathmlBuilder$6 = (group, style) => {
7102    const font = group.font;
7103    const newStyle = style.withFont(font);
7104    const mathGroup = buildGroup$1(group.body, newStyle);
7105    if (mathGroup.children.length === 0) {
7106      return mathGroup;
7107    }
7108    if (font === "boldsymbol" && ["mo", "mpadded", "mrow"].includes(mathGroup.type)) {
7109      mathGroup.style.fontWeight = "bold";
7110      return mathGroup;
7111    }
7112    if (isLongVariableName(group, font)) {
7113      const mi2 = mathGroup.children[0].children[0];
7114      delete mi2.attributes.mathvariant;
7115      for (let i = 1; i < mathGroup.children.length; i++) {
7116        mi2.children[0].text += mathGroup.children[i].type === "mn" ? mathGroup.children[i].children[0].text : mathGroup.children[i].children[0].children[0].text;
7117      }
7118      const bogus = new mathMLTree.MathNode("mtext", new mathMLTree.TextNode("\u200B"));
7119      return new mathMLTree.MathNode("mrow", [bogus, mi2]);
7120    }
7121    let canConsolidate = mathGroup.children[0].type === "mo";
7122    for (let i = 1; i < mathGroup.children.length; i++) {
7123      if (mathGroup.children[i].type === "mo" && font === "boldsymbol") {
7124        mathGroup.children[i].style.fontWeight = "bold";
7125      }
7126      if (mathGroup.children[i].type !== "mi") {
7127        canConsolidate = false;
7128      }
7129      const localVariant = mathGroup.children[i].attributes && mathGroup.children[i].attributes.mathvariant || "";
7130      if (localVariant !== "normal") {
7131        canConsolidate = false;
7132      }
7133    }
7134    if (!canConsolidate) {
7135      return mathGroup;
7136    }
7137    const mi = mathGroup.children[0];
7138    for (let i = 1; i < mathGroup.children.length; i++) {
7139      mi.children.push(mathGroup.children[i].children[0]);
7140    }
7141    if (mi.attributes.mathvariant && mi.attributes.mathvariant === "normal") {
7142      const bogus = new mathMLTree.MathNode("mtext", new mathMLTree.TextNode("\u200B"));
7143      return new mathMLTree.MathNode("mrow", [bogus, mi]);
7144    }
7145    return mi;
7146  };
7147  var fontAliases = {
7148    "\\Bbb": "\\mathbb",
7149    "\\bold": "\\mathbf",
7150    "\\frak": "\\mathfrak",
7151    "\\bm": "\\boldsymbol"
7152  };
7153  defineFunction({
7154    type: "font",
7155    names: [
7156      // styles
7157      "\\mathrm",
7158      "\\mathit",
7159      "\\mathbf",
7160      "\\mathnormal",
7161      "\\up@greek",
7162      "\\boldsymbol",
7163      // families
7164      "\\mathbb",
7165      "\\mathcal",
7166      "\\mathfrak",
7167      "\\mathscr",
7168      "\\mathsf",
7169      "\\mathsfit",
7170      "\\mathtt",
7171      // aliases
7172      "\\Bbb",
7173      "\\bm",
7174      "\\bold",
7175      "\\frak"
7176    ],
7177    props: {
7178      numArgs: 1,
7179      allowedInArgument: true
7180    },
7181    handler: ({ parser, funcName }, args) => {
7182      const body = normalizeArgument(args[0]);
7183      let func = funcName;
7184      if (func in fontAliases) {
7185        func = fontAliases[func];
7186      }
7187      return {
7188        type: "font",
7189        mode: parser.mode,
7190        font: func.slice(1),
7191        body
7192      };
7193    },
7194    mathmlBuilder: mathmlBuilder$6
7195  });
7196  defineFunction({
7197    type: "font",
7198    names: ["\\rm", "\\sf", "\\tt", "\\bf", "\\it", "\\cal"],
7199    props: {
7200      numArgs: 0,
7201      allowedInText: true
7202    },
7203    handler: ({ parser, funcName, breakOnTokenText }, args) => {
7204      const { mode } = parser;
7205      const body = parser.parseExpression(true, breakOnTokenText, true);
7206      const fontStyle = `math$funcName.slice(1)}`;
7207      return {
7208        type: "font",
7209        mode,
7210        font: fontStyle,
7211        body: {
7212          type: "ordgroup",
7213          mode: parser.mode,
7214          body
7215        }
7216      };
7217    },
7218    mathmlBuilder: mathmlBuilder$6
7219  });
7220  var stylArray = ["display", "text", "script", "scriptscript"];
7221  var scriptLevel = { auto: -1, display: 0, text: 0, script: 1, scriptscript: 2 };
7222  var mathmlBuilder$5 = (group, style) => {
7223    const childOptions = group.scriptLevel === "auto" ? style.incrementLevel() : group.scriptLevel === "display" ? style.withLevel(StyleLevel.TEXT) : group.scriptLevel === "text" ? style.withLevel(StyleLevel.SCRIPT) : style.withLevel(StyleLevel.SCRIPTSCRIPT);
7224    const numer = buildGroup$1(group.numer, childOptions);
7225    const denom = buildGroup$1(group.denom, childOptions);
7226    if (style.level === 3) {
7227      numer.style.mathDepth = "2";
7228      numer.setAttribute("scriptlevel", "2");
7229      denom.style.mathDepth = "2";
7230      denom.setAttribute("scriptlevel", "2");
7231    }
7232    let node = new mathMLTree.MathNode("mfrac", [numer, denom]);
7233    if (!group.hasBarLine) {
7234      node.setAttribute("linethickness", "0px");
7235    } else if (group.barSize) {
7236      const ruleWidth = calculateSize(group.barSize, style);
7237      node.setAttribute("linethickness", ruleWidth.number + ruleWidth.unit);
7238    }
7239    if (group.leftDelim != null || group.rightDelim != null) {
7240      const withDelims = [];
7241      if (group.leftDelim != null) {
7242        const leftOp = new mathMLTree.MathNode("mo", [
7243          new mathMLTree.TextNode(group.leftDelim.replace("\\", ""))
7244        ]);
7245        leftOp.setAttribute("fence", "true");
7246        withDelims.push(leftOp);
7247      }
7248      withDelims.push(node);
7249      if (group.rightDelim != null) {
7250        const rightOp = new mathMLTree.MathNode("mo", [
7251          new mathMLTree.TextNode(group.rightDelim.replace("\\", ""))
7252        ]);
7253        rightOp.setAttribute("fence", "true");
7254        withDelims.push(rightOp);
7255      }
7256      node = makeRow(withDelims);
7257    }
7258    if (group.scriptLevel !== "auto") {
7259      node = new mathMLTree.MathNode("mstyle", [node]);
7260      node.setAttribute("displaystyle", String(group.scriptLevel === "display"));
7261      node.setAttribute("scriptlevel", scriptLevel[group.scriptLevel]);
7262    }
7263    return node;
7264  };
7265  defineFunction({
7266    type: "genfrac",
7267    names: [
7268      "\\dfrac",
7269      "\\frac",
7270      "\\tfrac",
7271      "\\dbinom",
7272      "\\binom",
7273      "\\tbinom",
7274      "\\\\atopfrac",
7275      // can’t be entered directly
7276      "\\\\bracefrac",
7277      "\\\\brackfrac"
7278      // ditto
7279    ],
7280    props: {
7281      numArgs: 2,
7282      allowedInArgument: true
7283    },
7284    handler: ({ parser, funcName }, args) => {
7285      const numer = args[0];
7286      const denom = args[1];
7287      let hasBarLine = false;
7288      let leftDelim = null;
7289      let rightDelim = null;
7290      let scriptLevel2 = "auto";
7291      switch (funcName) {
7292        case "\\dfrac":
7293        case "\\frac":
7294        case "\\tfrac":
7295          hasBarLine = true;
7296          break;
7297        case "\\\\atopfrac":
7298          hasBarLine = false;
7299          break;
7300        case "\\dbinom":
7301        case "\\binom":
7302        case "\\tbinom":
7303          leftDelim = "(";
7304          rightDelim = ")";
7305          break;
7306        case "\\\\bracefrac":
7307          leftDelim = "\\{";
7308          rightDelim = "\\}";
7309          break;
7310        case "\\\\brackfrac":
7311          leftDelim = "[";
7312          rightDelim = "]";
7313          break;
7314        default:
7315          throw new Error("Unrecognized genfrac command");
7316      }
7317      switch (funcName) {
7318        case "\\dfrac":
7319        case "\\dbinom":
7320          scriptLevel2 = "display";
7321          break;
7322        case "\\tfrac":
7323        case "\\tbinom":
7324          scriptLevel2 = "text";
7325          break;
7326      }
7327      return {
7328        type: "genfrac",
7329        mode: parser.mode,
7330        continued: false,
7331        numer,
7332        denom,
7333        hasBarLine,
7334        leftDelim,
7335        rightDelim,
7336        scriptLevel: scriptLevel2,
7337        barSize: null
7338      };
7339    },
7340    mathmlBuilder: mathmlBuilder$5
7341  });
7342  defineFunction({
7343    type: "genfrac",
7344    names: ["\\cfrac"],
7345    props: {
7346      numArgs: 2
7347    },
7348    handler: ({ parser, funcName }, args) => {
7349      const numer = args[0];
7350      const denom = args[1];
7351      return {
7352        type: "genfrac",
7353        mode: parser.mode,
7354        continued: true,
7355        numer,
7356        denom,
7357        hasBarLine: true,
7358        leftDelim: null,
7359        rightDelim: null,
7360        scriptLevel: "display",
7361        barSize: null
7362      };
7363    }
7364  });
7365  defineFunction({
7366    type: "infix",
7367    names: ["\\over", "\\choose", "\\atop", "\\brace", "\\brack"],
7368    props: {
7369      numArgs: 0,
7370      infix: true
7371    },
7372    handler({ parser, funcName, token }) {
7373      let replaceWith;
7374      switch (funcName) {
7375        case "\\over":
7376          replaceWith = "\\frac";
7377          break;
7378        case "\\choose":
7379          replaceWith = "\\binom";
7380          break;
7381        case "\\atop":
7382          replaceWith = "\\\\atopfrac";
7383          break;
7384        case "\\brace":
7385          replaceWith = "\\\\bracefrac";
7386          break;
7387        case "\\brack":
7388          replaceWith = "\\\\brackfrac";
7389          break;
7390        default:
7391          throw new Error("Unrecognized infix genfrac command");
7392      }
7393      return {
7394        type: "infix",
7395        mode: parser.mode,
7396        replaceWith,
7397        token
7398      };
7399    }
7400  });
7401  var delimFromValue = function(delimString) {
7402    let delim = null;
7403    if (delimString.length > 0) {
7404      delim = delimString;
7405      delim = delim === "." ? null : delim;
7406    }
7407    return delim;
7408  };
7409  defineFunction({
7410    type: "genfrac",
7411    names: ["\\genfrac"],
7412    props: {
7413      numArgs: 6,
7414      allowedInArgument: true,
7415      argTypes: ["math", "math", "size", "text", "math", "math"]
7416    },
7417    handler({ parser }, args) {
7418      const numer = args[4];
7419      const denom = args[5];
7420      const leftNode = normalizeArgument(args[0]);
7421      const leftDelim = leftNode.type === "atom" && leftNode.family === "open" ? delimFromValue(leftNode.text) : null;
7422      const rightNode = normalizeArgument(args[1]);
7423      const rightDelim = rightNode.type === "atom" && rightNode.family === "close" ? delimFromValue(rightNode.text) : null;
7424      const barNode = assertNodeType(args[2], "size");
7425      let hasBarLine;
7426      let barSize = null;
7427      if (barNode.isBlank) {
7428        hasBarLine = true;
7429      } else {
7430        barSize = barNode.value;
7431        hasBarLine = barSize.number > 0;
7432      }
7433      let scriptLevel2 = "auto";
7434      let styl = args[3];
7435      if (styl.type === "ordgroup") {
7436        if (styl.body.length > 0) {
7437          const textOrd = assertNodeType(styl.body[0], "textord");
7438          scriptLevel2 = stylArray[Number(textOrd.text)];
7439        }
7440      } else {
7441        styl = assertNodeType(styl, "textord");
7442        scriptLevel2 = stylArray[Number(styl.text)];
7443      }
7444      return {
7445        type: "genfrac",
7446        mode: parser.mode,
7447        numer,
7448        denom,
7449        continued: false,
7450        hasBarLine,
7451        barSize,
7452        leftDelim,
7453        rightDelim,
7454        scriptLevel: scriptLevel2
7455      };
7456    },
7457    mathmlBuilder: mathmlBuilder$5
7458  });
7459  defineFunction({
7460    type: "infix",
7461    names: ["\\above"],
7462    props: {
7463      numArgs: 1,
7464      argTypes: ["size"],
7465      infix: true
7466    },
7467    handler({ parser, funcName, token }, args) {
7468      return {
7469        type: "infix",
7470        mode: parser.mode,
7471        replaceWith: "\\\\abovefrac",
7472        barSize: assertNodeType(args[0], "size").value,
7473        token
7474      };
7475    }
7476  });
7477  defineFunction({
7478    type: "genfrac",
7479    names: ["\\\\abovefrac"],
7480    props: {
7481      numArgs: 3,
7482      argTypes: ["math", "size", "math"]
7483    },
7484    handler: ({ parser, funcName }, args) => {
7485      const numer = args[0];
7486      const barSize = assert(assertNodeType(args[1], "infix").barSize);
7487      const denom = args[2];
7488      const hasBarLine = barSize.number > 0;
7489      return {
7490        type: "genfrac",
7491        mode: parser.mode,
7492        numer,
7493        denom,
7494        continued: false,
7495        hasBarLine,
7496        barSize,
7497        leftDelim: null,
7498        rightDelim: null,
7499        scriptLevel: "auto"
7500      };
7501    },
7502    mathmlBuilder: mathmlBuilder$5
7503  });
7504  defineFunction({
7505    type: "hbox",
7506    names: ["\\hbox"],
7507    props: {
7508      numArgs: 1,
7509      argTypes: ["hbox"],
7510      allowedInArgument: true,
7511      allowedInText: false
7512    },
7513    handler({ parser }, args) {
7514      return {
7515        type: "hbox",
7516        mode: parser.mode,
7517        body: ordargument(args[0])
7518      };
7519    },
7520    mathmlBuilder(group, style) {
7521      const newStyle = style.withLevel(StyleLevel.TEXT);
7522      const mrow = buildExpressionRow(group.body, newStyle);
7523      return consolidateText(mrow);
7524    }
7525  });
7526  var mathmlBuilder$4 = (group, style) => {
7527    const accentNode2 = stretchy.mathMLnode(group.label);
7528    accentNode2.style["math-depth"] = 0;
7529    return new mathMLTree.MathNode(group.isOver ? "mover" : "munder", [
7530      buildGroup$1(group.base, style),
7531      accentNode2
7532    ]);
7533  };
7534  defineFunction({
7535    type: "horizBrace",
7536    names: ["\\overbrace", "\\underbrace"],
7537    props: {
7538      numArgs: 1
7539    },
7540    handler({ parser, funcName }, args) {
7541      return {
7542        type: "horizBrace",
7543        mode: parser.mode,
7544        label: funcName,
7545        isOver: /^\\over/.test(funcName),
7546        base: args[0]
7547      };
7548    },
7549    mathmlBuilder: mathmlBuilder$4
7550  });
7551  defineFunction({
7552    type: "href",
7553    names: ["\\href"],
7554    props: {
7555      numArgs: 2,
7556      argTypes: ["url", "original"],
7557      allowedInText: true
7558    },
7559    handler: ({ parser, token }, args) => {
7560      const body = args[1];
7561      const href = assertNodeType(args[0], "url").url;
7562      if (!parser.settings.isTrusted({
7563        command: "\\href",
7564        url: href
7565      })) {
7566        throw new ParseError(`Function "\\href" is not trusted`, token);
7567      }
7568      return {
7569        type: "href",
7570        mode: parser.mode,
7571        href,
7572        body: ordargument(body)
7573      };
7574    },
7575    mathmlBuilder: (group, style) => {
7576      const math2 = new MathNode("math", [buildExpressionRow(group.body, style)]);
7577      const anchorNode = new AnchorNode(group.href, [], [math2]);
7578      return anchorNode;
7579    }
7580  });
7581  defineFunction({
7582    type: "href",
7583    names: ["\\url"],
7584    props: {
7585      numArgs: 1,
7586      argTypes: ["url"],
7587      allowedInText: true
7588    },
7589    handler: ({ parser, token }, args) => {
7590      const href = assertNodeType(args[0], "url").url;
7591      if (!parser.settings.isTrusted({
7592        command: "\\url",
7593        url: href
7594      })) {
7595        throw new ParseError(`Function "\\url" is not trusted`, token);
7596      }
7597      const chars = [];
7598      for (let i = 0; i < href.length; i++) {
7599        let c = href[i];
7600        if (c === "~") {
7601          c = "\\textasciitilde";
7602        }
7603        chars.push({
7604          type: "textord",
7605          mode: "text",
7606          text: c
7607        });
7608      }
7609      const body = {
7610        type: "text",
7611        mode: parser.mode,
7612        font: "\\texttt",
7613        body: chars
7614      };
7615      return {
7616        type: "href",
7617        mode: parser.mode,
7618        href,
7619        body: ordargument(body)
7620      };
7621    }
7622  });
7623  defineFunction({
7624    type: "html",
7625    names: ["\\class", "\\id", "\\style", "\\data"],
7626    props: {
7627      numArgs: 2,
7628      argTypes: ["raw", "original"],
7629      allowedInText: true
7630    },
7631    handler: ({ parser, funcName, token }, args) => {
7632      const value = assertNodeType(args[0], "raw").string;
7633      const body = args[1];
7634      if (parser.settings.strict) {
7635        throw new ParseError(`Function "$funcName}" is disabled in strict mode`, token);
7636      }
7637      let trustContext;
7638      const attributes = {};
7639      switch (funcName) {
7640        case "\\class":
7641          attributes.class = value;
7642          trustContext = {
7643            command: "\\class",
7644            class: value
7645          };
7646          break;
7647        case "\\id":
7648          attributes.id = value;
7649          trustContext = {
7650            command: "\\id",
7651            id: value
7652          };
7653          break;
7654        case "\\style":
7655          attributes.style = value;
7656          trustContext = {
7657            command: "\\style",
7658            style: value
7659          };
7660          break;
7661        case "\\data": {
7662          const data = value.split(",");
7663          for (let i = 0; i < data.length; i++) {
7664            const keyVal = data[i].split("=");
7665            if (keyVal.length !== 2) {
7666              throw new ParseError("Error parsing key-value for \\data");
7667            }
7668            attributes["data-" + keyVal[0].trim()] = keyVal[1].trim();
7669          }
7670          trustContext = {
7671            command: "\\data",
7672            attributes
7673          };
7674          break;
7675        }
7676        default:
7677          throw new Error("Unrecognized html command");
7678      }
7679      if (!parser.settings.isTrusted(trustContext)) {
7680        throw new ParseError(`Function "$funcName}" is not trusted`, token);
7681      }
7682      return {
7683        type: "html",
7684        mode: parser.mode,
7685        attributes,
7686        body: ordargument(body)
7687      };
7688    },
7689    mathmlBuilder: (group, style) => {
7690      const element = buildExpressionRow(group.body, style);
7691      const classes = [];
7692      if (group.attributes.class) {
7693        classes.push(...group.attributes.class.trim().split(/\s+/));
7694      }
7695      element.classes = classes;
7696      for (const attr in group.attributes) {
7697        if (attr !== "class" && Object.prototype.hasOwnProperty.call(group.attributes, attr)) {
7698          element.setAttribute(attr, group.attributes[attr]);
7699        }
7700      }
7701      return element;
7702    }
7703  });
7704  var sizeData = function(str) {
7705    if (/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(str)) {
7706      return { number: +str, unit: "bp" };
7707    } else {
7708      const match = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(str);
7709      if (!match) {
7710        throw new ParseError("Invalid size: '" + str + "' in \\includegraphics");
7711      }
7712      const data = {
7713        number: +(match[1] + match[2]),
7714        // sign + magnitude, cast to number
7715        unit: match[3]
7716      };
7717      if (!validUnit(data)) {
7718        throw new ParseError("Invalid unit: '" + data.unit + "' in \\includegraphics.");
7719      }
7720      return data;
7721    }
7722  };
7723  defineFunction({
7724    type: "includegraphics",
7725    names: ["\\includegraphics"],
7726    props: {
7727      numArgs: 1,
7728      numOptionalArgs: 1,
7729      argTypes: ["raw", "url"],
7730      allowedInText: false
7731    },
7732    handler: ({ parser, token }, args, optArgs) => {
7733      let width = { number: 0, unit: "em" };
7734      let height = { number: 0.9, unit: "em" };
7735      let totalheight = { number: 0, unit: "em" };
7736      let alt = "";
7737      if (optArgs[0]) {
7738        const attributeStr = assertNodeType(optArgs[0], "raw").string;
7739        const attributes = attributeStr.split(",");
7740        for (let i = 0; i < attributes.length; i++) {
7741          const keyVal = attributes[i].split("=");
7742          if (keyVal.length === 2) {
7743            const str = keyVal[1].trim();
7744            switch (keyVal[0].trim()) {
7745              case "alt":
7746                alt = str;
7747                break;
7748              case "width":
7749                width = sizeData(str);
7750                break;
7751              case "height":
7752                height = sizeData(str);
7753                break;
7754              case "totalheight":
7755                totalheight = sizeData(str);
7756                break;
7757              default:
7758                throw new ParseError("Invalid key: '" + keyVal[0] + "' in \\includegraphics.");
7759            }
7760          }
7761        }
7762      }
7763      const src = assertNodeType(args[0], "url").url;
7764      if (alt === "") {
7765        alt = src;
7766        alt = alt.replace(/^.*[\\/]/, "");
7767        alt = alt.substring(0, alt.lastIndexOf("."));
7768      }
7769      if (!parser.settings.isTrusted({
7770        command: "\\includegraphics",
7771        url: src
7772      })) {
7773        throw new ParseError(`Function "\\includegraphics" is not trusted`, token);
7774      }
7775      return {
7776        type: "includegraphics",
7777        mode: parser.mode,
7778        alt,
7779        width,
7780        height,
7781        totalheight,
7782        src
7783      };
7784    },
7785    mathmlBuilder: (group, style) => {
7786      const height = calculateSize(group.height, style);
7787      const depth = { number: 0, unit: "em" };
7788      if (group.totalheight.number > 0) {
7789        if (group.totalheight.unit === height.unit && group.totalheight.number > height.number) {
7790          depth.number = group.totalheight.number - height.number;
7791          depth.unit = height.unit;
7792        }
7793      }
7794      let width = 0;
7795      if (group.width.number > 0) {
7796        width = calculateSize(group.width, style);
7797      }
7798      const graphicStyle = { height: height.number + depth.number + "em" };
7799      if (width.number > 0) {
7800        graphicStyle.width = width.number + width.unit;
7801      }
7802      if (depth.number > 0) {
7803        graphicStyle.verticalAlign = -depth.number + depth.unit;
7804      }
7805      const node = new Img(group.src, group.alt, graphicStyle);
7806      node.height = height;
7807      node.depth = depth;
7808      return new mathMLTree.MathNode("mtext", [node]);
7809    }
7810  });
7811  defineFunction({
7812    type: "kern",
7813    names: ["\\kern", "\\mkern", "\\hskip", "\\mskip"],
7814    props: {
7815      numArgs: 1,
7816      argTypes: ["size"],
7817      primitive: true,
7818      allowedInText: true
7819    },
7820    handler({ parser, funcName, token }, args) {
7821      const size = assertNodeType(args[0], "size");
7822      if (parser.settings.strict) {
7823        const mathFunction = funcName[1] === "m";
7824        const muUnit = size.value.unit === "mu";
7825        if (mathFunction) {
7826          if (!muUnit) {
7827            throw new ParseError(`LaTeX's $funcName} supports only mu units, not $size.value.unit} units`, token);
7828          }
7829          if (parser.mode !== "math") {
7830            throw new ParseError(`LaTeX's $funcName} works only in math mode`, token);
7831          }
7832        } else {
7833          if (muUnit) {
7834            throw new ParseError(`LaTeX's $funcName} doesn't support mu units`, token);
7835          }
7836        }
7837      }
7838      return {
7839        type: "kern",
7840        mode: parser.mode,
7841        dimension: size.value
7842      };
7843    },
7844    mathmlBuilder(group, style) {
7845      const dimension = calculateSize(group.dimension, style);
7846      const ch = dimension.unit === "em" ? spaceCharacter(dimension.number) : "";
7847      if (group.mode === "text" && ch.length > 0) {
7848        const character = new mathMLTree.TextNode(ch);
7849        return new mathMLTree.MathNode("mtext", [character]);
7850      } else {
7851        const node = new mathMLTree.MathNode("mspace");
7852        node.setAttribute("width", dimension.number + dimension.unit);
7853        if (dimension.number < 0) {
7854          node.style.marginLeft = dimension.number + dimension.unit;
7855        }
7856        return node;
7857      }
7858    }
7859  });
7860  var spaceCharacter = function(width) {
7861    if (width >= 0.05555 && width <= 0.05556) {
7862      return "\u200A";
7863    } else if (width >= 0.1666 && width <= 0.1667) {
7864      return "\u2009";
7865    } else if (width >= 0.2222 && width <= 0.2223) {
7866      return "\u2005";
7867    } else if (width >= 0.2777 && width <= 0.2778) {
7868      return "\u2005\u200A";
7869    } else {
7870      return "";
7871    }
7872  };
7873  var invalidIdRegEx = /[^A-Za-z_0-9-]/g;
7874  defineFunction({
7875    type: "label",
7876    names: ["\\label"],
7877    props: {
7878      numArgs: 1,
7879      argTypes: ["raw"]
7880    },
7881    handler({ parser }, args) {
7882      return {
7883        type: "label",
7884        mode: parser.mode,
7885        string: args[0].string.replace(invalidIdRegEx, "")
7886      };
7887    },
7888    mathmlBuilder(group, style) {
7889      const node = new mathMLTree.MathNode("mrow", [], ["tml-label"]);
7890      if (group.string.length > 0) {
7891        node.setLabel(group.string);
7892      }
7893      return node;
7894    }
7895  });
7896  var textModeLap = ["\\clap", "\\llap", "\\rlap"];
7897  defineFunction({
7898    type: "lap",
7899    names: ["\\mathllap", "\\mathrlap", "\\mathclap", "\\clap", "\\llap", "\\rlap"],
7900    props: {
7901      numArgs: 1,
7902      allowedInText: true
7903    },
7904    handler: ({ parser, funcName, token }, args) => {
7905      if (textModeLap.includes(funcName)) {
7906        if (parser.settings.strict && parser.mode !== "text") {
7907          throw new ParseError(`{$funcName}} can be used only in text mode.
7908   Try \\math$funcName.slice(1)}`, token);
7909        }
7910        funcName = funcName.slice(1);
7911      } else {
7912        funcName = funcName.slice(5);
7913      }
7914      const body = args[0];
7915      return {
7916        type: "lap",
7917        mode: parser.mode,
7918        alignment: funcName,
7919        body
7920      };
7921    },
7922    mathmlBuilder: (group, style) => {
7923      let strut;
7924      if (group.alignment === "llap") {
7925        const phantomInner = buildExpression(ordargument(group.body), style);
7926        const phantom = new mathMLTree.MathNode("mphantom", phantomInner);
7927        strut = new mathMLTree.MathNode("mpadded", [phantom]);
7928        strut.setAttribute("width", "0px");
7929      }
7930      const inner2 = buildGroup$1(group.body, style);
7931      let node;
7932      if (group.alignment === "llap") {
7933        inner2.style.position = "absolute";
7934        inner2.style.right = "0";
7935        inner2.style.bottom = `0`;
7936        node = new mathMLTree.MathNode("mpadded", [strut, inner2]);
7937      } else {
7938        node = new mathMLTree.MathNode("mpadded", [inner2]);
7939      }
7940      if (group.alignment === "rlap") {
7941        if (group.body.body.length > 0 && group.body.body[0].type === "genfrac") {
7942          node.setAttribute("lspace", "0.16667em");
7943        }
7944      } else {
7945        const offset2 = group.alignment === "llap" ? "-1" : "-0.5";
7946        node.setAttribute("lspace", offset2 + "width");
7947        if (group.alignment === "llap") {
7948          node.style.position = "relative";
7949        } else {
7950          node.style.display = "flex";
7951          node.style.justifyContent = "center";
7952        }
7953      }
7954      node.setAttribute("width", "0px");
7955      return node;
7956    }
7957  });
7958  defineFunction({
7959    type: "ordgroup",
7960    names: ["\\(", "$"],
7961    props: {
7962      numArgs: 0,
7963      allowedInText: true,
7964      allowedInMath: false
7965    },
7966    handler({ funcName, parser }, args) {
7967      const outerMode = parser.mode;
7968      parser.switchMode("math");
7969      const close2 = funcName === "\\(" ? "\\)" : "$";
7970      const body = parser.parseExpression(false, close2);
7971      parser.expect(close2);
7972      parser.switchMode(outerMode);
7973      return {
7974        type: "ordgroup",
7975        mode: parser.mode,
7976        body
7977      };
7978    }
7979  });
7980  defineFunction({
7981    type: "text",
7982    // Doesn't matter what this is.
7983    names: ["\\)", "\\]"],
7984    props: {
7985      numArgs: 0,
7986      allowedInText: true,
7987      allowedInMath: false
7988    },
7989    handler(context, token) {
7990      throw new ParseError(`Mismatched $context.funcName}`, token);
7991    }
7992  });
7993  var chooseStyle = (group, style) => {
7994    switch (style.level) {
7995      case StyleLevel.DISPLAY:
7996        return group.display;
7997      case StyleLevel.TEXT:
7998        return group.text;
7999      case StyleLevel.SCRIPT:
8000        return group.script;
8001      case StyleLevel.SCRIPTSCRIPT:
8002        return group.scriptscript;
8003      default:
8004        return group.text;
8005    }
8006  };
8007  defineFunction({
8008    type: "mathchoice",
8009    names: ["\\mathchoice"],
8010    props: {
8011      numArgs: 4,
8012      primitive: true
8013    },
8014    handler: ({ parser }, args) => {
8015      return {
8016        type: "mathchoice",
8017        mode: parser.mode,
8018        display: ordargument(args[0]),
8019        text: ordargument(args[1]),
8020        script: ordargument(args[2]),
8021        scriptscript: ordargument(args[3])
8022      };
8023    },
8024    mathmlBuilder: (group, style) => {
8025      const body = chooseStyle(group, style);
8026      return buildExpressionRow(body, style);
8027    }
8028  });
8029  var textAtomTypes = ["text", "textord", "mathord", "atom"];
8030  var padding = (width) => {
8031    const node = new mathMLTree.MathNode("mspace");
8032    node.setAttribute("width", width + "em");
8033    return node;
8034  };
8035  function mathmlBuilder$3(group, style) {
8036    let node;
8037    const inner2 = buildExpression(group.body, style);
8038    if (group.mclass === "minner") {
8039      node = new mathMLTree.MathNode("mpadded", inner2);
8040    } else if (group.mclass === "mord") {
8041      if (group.isCharacterBox || inner2[0].type === "mathord") {
8042        node = inner2[0];
8043        node.type = "mi";
8044        if (node.children.length === 1 && node.children[0].text && node.children[0].text === "\u2207") {
8045          node.setAttribute("mathvariant", "normal");
8046        }
8047      } else {
8048        node = new mathMLTree.MathNode("mi", inner2);
8049      }
8050    } else {
8051      node = new mathMLTree.MathNode("mrow", inner2);
8052      if (group.mustPromote) {
8053        node = inner2[0];
8054        node.type = "mo";
8055        if (group.isCharacterBox && group.body[0].text && /[A-Za-z]/.test(group.body[0].text)) {
8056          node.setAttribute("mathvariant", "italic");
8057        }
8058      } else {
8059        node = new mathMLTree.MathNode("mrow", inner2);
8060      }
8061      const doSpacing = style.level < 2;
8062      if (node.type === "mrow") {
8063        if (doSpacing) {
8064          if (group.mclass === "mbin") {
8065            node.children.unshift(padding(0.2222));
8066            node.children.push(padding(0.2222));
8067          } else if (group.mclass === "mrel") {
8068            node.children.unshift(padding(0.2778));
8069            node.children.push(padding(0.2778));
8070          } else if (group.mclass === "mpunct") {
8071            node.children.push(padding(0.1667));
8072          } else if (group.mclass === "minner") {
8073            node.children.unshift(padding(0.0556));
8074            node.children.push(padding(0.0556));
8075          }
8076        }
8077      } else {
8078        if (group.mclass === "mbin") {
8079          node.attributes.lspace = doSpacing ? "0.2222em" : "0";
8080          node.attributes.rspace = doSpacing ? "0.2222em" : "0";
8081        } else if (group.mclass === "mrel") {
8082          node.attributes.lspace = doSpacing ? "0.2778em" : "0";
8083          node.attributes.rspace = doSpacing ? "0.2778em" : "0";
8084        } else if (group.mclass === "mpunct") {
8085          node.attributes.lspace = "0em";
8086          node.attributes.rspace = doSpacing ? "0.1667em" : "0";
8087        } else if (group.mclass === "mopen" || group.mclass === "mclose") {
8088          node.attributes.lspace = "0em";
8089          node.attributes.rspace = "0em";
8090        } else if (group.mclass === "minner" && doSpacing) {
8091          node.attributes.lspace = "0.0556em";
8092          node.attributes.width = "+0.1111em";
8093        }
8094      }
8095      if (!(group.mclass === "mopen" || group.mclass === "mclose")) {
8096        delete node.attributes.stretchy;
8097        delete node.attributes.form;
8098      }
8099    }
8100    return node;
8101  }
8102  defineFunction({
8103    type: "mclass",
8104    names: [
8105      "\\mathord",
8106      "\\mathbin",
8107      "\\mathrel",
8108      "\\mathopen",
8109      "\\mathclose",
8110      "\\mathpunct",
8111      "\\mathinner"
8112    ],
8113    props: {
8114      numArgs: 1,
8115      primitive: true
8116    },
8117    handler({ parser, funcName }, args) {
8118      const body = args[0];
8119      const isCharacterBox2 = utils.isCharacterBox(body);
8120      let mustPromote = true;
8121      const mord = { type: "mathord", text: "", mode: parser.mode };
8122      const arr = body.body ? body.body : [body];
8123      for (const arg of arr) {
8124        if (textAtomTypes.includes(arg.type)) {
8125          if (symbols[parser.mode][arg.text]) {
8126            mord.text += symbols[parser.mode][arg.text].replace;
8127          } else if (arg.text) {
8128            mord.text += arg.text;
8129          } else if (arg.body) {
8130            arg.body.map((e) => {
8131              mord.text += e.text;
8132            });
8133          }
8134        } else {
8135          mustPromote = false;
8136          break;
8137        }
8138      }
8139      return {
8140        type: "mclass",
8141        mode: parser.mode,
8142        mclass: "m" + funcName.slice(5),
8143        body: ordargument(mustPromote ? mord : body),
8144        isCharacterBox: isCharacterBox2,
8145        mustPromote
8146      };
8147    },
8148    mathmlBuilder: mathmlBuilder$3
8149  });
8150  var binrelClass = (arg) => {
8151    const atom = arg.type === "ordgroup" && arg.body.length ? arg.body[0] : arg;
8152    if (atom.type === "atom" && (atom.family === "bin" || atom.family === "rel")) {
8153      return "m" + atom.family;
8154    } else {
8155      return "mord";
8156    }
8157  };
8158  defineFunction({
8159    type: "mclass",
8160    names: ["\\@binrel"],
8161    props: {
8162      numArgs: 2
8163    },
8164    handler({ parser }, args) {
8165      return {
8166        type: "mclass",
8167        mode: parser.mode,
8168        mclass: binrelClass(args[0]),
8169        body: ordargument(args[1]),
8170        isCharacterBox: utils.isCharacterBox(args[1])
8171      };
8172    }
8173  });
8174  defineFunction({
8175    type: "mclass",
8176    names: ["\\stackrel", "\\overset", "\\underset"],
8177    props: {
8178      numArgs: 2
8179    },
8180    handler({ parser, funcName }, args) {
8181      const baseArg = args[1];
8182      const shiftedArg = args[0];
8183      const baseOp = {
8184        type: "op",
8185        mode: baseArg.mode,
8186        limits: true,
8187        alwaysHandleSupSub: true,
8188        parentIsSupSub: false,
8189        symbol: false,
8190        stack: true,
8191        suppressBaseShift: funcName !== "\\stackrel",
8192        body: ordargument(baseArg)
8193      };
8194      return {
8195        type: "supsub",
8196        mode: shiftedArg.mode,
8197        base: baseOp,
8198        sup: funcName === "\\underset" ? null : shiftedArg,
8199        sub: funcName === "\\underset" ? shiftedArg : null
8200      };
8201    },
8202    mathmlBuilder: mathmlBuilder$3
8203  });
8204  var buildGroup = (el, style, noneNode) => {
8205    if (!el) {
8206      return noneNode;
8207    }
8208    const node = buildGroup$1(el, style);
8209    if (node.type === "mrow" && node.children.length === 0) {
8210      return noneNode;
8211    }
8212    return node;
8213  };
8214  defineFunction({
8215    type: "multiscript",
8216    names: ["\\sideset", "\\pres@cript"],
8217    // See macros.js for \prescript
8218    props: {
8219      numArgs: 3
8220    },
8221    handler({ parser, funcName, token }, args) {
8222      if (args[2].body.length === 0) {
8223        throw new ParseError(funcName + `cannot parse an empty base.`);
8224      }
8225      const base = args[2].body[0];
8226      if (parser.settings.strict && funcName === "\\sideset" && !base.symbol) {
8227        throw new ParseError(`The base of \\sideset must be a big operator. Try \\prescript.`);
8228      }
8229      if (args[0].body.length > 0 && args[0].body[0].type !== "supsub" || args[1].body.length > 0 && args[1].body[0].type !== "supsub") {
8230        throw new ParseError("\\sideset can parse only subscripts and superscripts in its first two arguments", token);
8231      }
8232      const prescripts = args[0].body.length > 0 ? args[0].body[0] : null;
8233      const postscripts = args[1].body.length > 0 ? args[1].body[0] : null;
8234      if (!prescripts && !postscripts) {
8235        return base;
8236      } else if (!prescripts) {
8237        return {
8238          type: "styling",
8239          mode: parser.mode,
8240          scriptLevel: "text",
8241          body: [{
8242            type: "supsub",
8243            mode: parser.mode,
8244            base,
8245            sup: postscripts.sup,
8246            sub: postscripts.sub
8247          }]
8248        };
8249      } else {
8250        return {
8251          type: "multiscript",
8252          mode: parser.mode,
8253          isSideset: funcName === "\\sideset",
8254          prescripts,
8255          postscripts,
8256          base
8257        };
8258      }
8259    },
8260    mathmlBuilder(group, style) {
8261      const base = buildGroup$1(group.base, style);
8262      const prescriptsNode = new mathMLTree.MathNode("mprescripts");
8263      const noneNode = new mathMLTree.MathNode("none");
8264      let children = [];
8265      const preSub = buildGroup(group.prescripts.sub, style, noneNode);
8266      const preSup = buildGroup(group.prescripts.sup, style, noneNode);
8267      if (group.isSideset) {
8268        preSub.setAttribute("style", "text-align: left;");
8269        preSup.setAttribute("style", "text-align: left;");
8270      }
8271      if (group.postscripts) {
8272        const postSub = buildGroup(group.postscripts.sub, style, noneNode);
8273        const postSup = buildGroup(group.postscripts.sup, style, noneNode);
8274        children = [base, postSub, postSup, prescriptsNode, preSub, preSup];
8275      } else {
8276        children = [base, prescriptsNode, preSub, preSup];
8277      }
8278      return new mathMLTree.MathNode("mmultiscripts", children);
8279    }
8280  });
8281  defineFunction({
8282    type: "not",
8283    names: ["\\not"],
8284    props: {
8285      numArgs: 1,
8286      primitive: true,
8287      allowedInText: false
8288    },
8289    handler({ parser }, args) {
8290      const isCharacterBox2 = utils.isCharacterBox(args[0]);
8291      let body;
8292      if (isCharacterBox2) {
8293        body = ordargument(args[0]);
8294        if (body[0].text.charAt(0) === "\\") {
8295          body[0].text = symbols.math[body[0].text].replace;
8296        }
8297        body[0].text = body[0].text.slice(0, 1) + "\u0338" + body[0].text.slice(1);
8298      } else {
8299        const notNode = { type: "textord", mode: "math", text: "\u0338" };
8300        const kernNode = { type: "kern", mode: "math", dimension: { number: -0.6, unit: "em" } };
8301        body = [notNode, kernNode, args[0]];
8302      }
8303      return {
8304        type: "not",
8305        mode: parser.mode,
8306        body,
8307        isCharacterBox: isCharacterBox2
8308      };
8309    },
8310    mathmlBuilder(group, style) {
8311      if (group.isCharacterBox) {
8312        const inner2 = buildExpression(group.body, style, true);
8313        return inner2[0];
8314      } else {
8315        return buildExpressionRow(group.body, style);
8316      }
8317    }
8318  });
8319  var ordAtomTypes = ["textord", "mathord", "atom"];
8320  var noSuccessor = ["\\smallint"];
8321  var ordTypes = ["textord", "mathord", "ordgroup", "close", "leftright", "font"];
8322  var setSpacing = (node) => {
8323    node.attributes.lspace = "0.1667em";
8324    node.attributes.rspace = "0.1667em";
8325  };
8326  var mathmlBuilder$2 = (group, style) => {
8327    let node;
8328    if (group.symbol) {
8329      node = new MathNode("mo", [makeText(group.name, group.mode)]);
8330      if (noSuccessor.includes(group.name)) {
8331        node.setAttribute("largeop", "false");
8332      } else {
8333        node.setAttribute("movablelimits", "false");
8334      }
8335      if (group.fromMathOp) {
8336        setSpacing(node);
8337      }
8338    } else if (group.body) {
8339      node = new MathNode("mo", buildExpression(group.body, style));
8340      if (group.fromMathOp) {
8341        setSpacing(node);
8342      }
8343    } else {
8344      node = new MathNode("mi", [new TextNode2(group.name.slice(1))]);
8345      if (!group.parentIsSupSub) {
8346        const operator = new MathNode("mo", [makeText("\u2061", "text")]);
8347        const row = [node, operator];
8348        if (group.needsLeadingSpace) {
8349          const lead = new MathNode("mspace");
8350          lead.setAttribute("width", "0.1667em");
8351          row.unshift(lead);
8352        }
8353        if (!group.isFollowedByDelimiter) {
8354          const trail = new MathNode("mspace");
8355          trail.setAttribute("width", "0.1667em");
8356          row.push(trail);
8357        }
8358        node = new MathNode("mrow", row);
8359      }
8360    }
8361    return node;
8362  };
8363  var singleCharBigOps = {
8364    "\u220F": "\\prod",
8365    "\u2210": "\\coprod",
8366    "\u2211": "\\sum",
8367    "\u22C0": "\\bigwedge",
8368    "\u22C1": "\\bigvee",
8369    "\u22C2": "\\bigcap",
8370    "\u22C3": "\\bigcup",
8371    "\u2A00": "\\bigodot",
8372    "\u2A01": "\\bigoplus",
8373    "\u2A02": "\\bigotimes",
8374    "\u2A04": "\\biguplus",
8375    "\u2A05": "\\bigsqcap",
8376    "\u2A06": "\\bigsqcup",
8377    "\u2A03": "\\bigcupdot",
8378    "\u2A07": "\\bigdoublevee",
8379    "\u2A08": "\\bigdoublewedge",
8380    "\u2A09": "\\bigtimes"
8381  };
8382  defineFunction({
8383    type: "op",
8384    names: [
8385      "\\coprod",
8386      "\\bigvee",
8387      "\\bigwedge",
8388      "\\biguplus",
8389      "\\bigcupplus",
8390      "\\bigcupdot",
8391      "\\bigcap",
8392      "\\bigcup",
8393      "\\bigdoublevee",
8394      "\\bigdoublewedge",
8395      "\\intop",
8396      "\\prod",
8397      "\\sum",
8398      "\\bigotimes",
8399      "\\bigoplus",
8400      "\\bigodot",
8401      "\\bigsqcap",
8402      "\\bigsqcup",
8403      "\\bigtimes",
8404      "\\smallint",
8405      "\u220F",
8406      "\u2210",
8407      "\u2211",
8408      "\u22C0",
8409      "\u22C1",
8410      "\u22C2",
8411      "\u22C3",
8412      "\u2A00",
8413      "\u2A01",
8414      "\u2A02",
8415      "\u2A04",
8416      "\u2A06"
8417    ],
8418    props: {
8419      numArgs: 0
8420    },
8421    handler: ({ parser, funcName }, args) => {
8422      let fName = funcName;
8423      if (fName.length === 1) {
8424        fName = singleCharBigOps[fName];
8425      }
8426      return {
8427        type: "op",
8428        mode: parser.mode,
8429        limits: true,
8430        parentIsSupSub: false,
8431        symbol: true,
8432        stack: false,
8433        // This is true for \stackrel{}, not here.
8434        name: fName
8435      };
8436    },
8437    mathmlBuilder: mathmlBuilder$2
8438  });
8439  defineFunction({
8440    type: "op",
8441    names: ["\\mathop"],
8442    props: {
8443      numArgs: 1,
8444      primitive: true
8445    },
8446    handler: ({ parser }, args) => {
8447      const body = args[0];
8448      const arr = body.body ? body.body : [body];
8449      const isSymbol = arr.length === 1 && ordAtomTypes.includes(arr[0].type);
8450      return {
8451        type: "op",
8452        mode: parser.mode,
8453        limits: true,
8454        parentIsSupSub: false,
8455        symbol: isSymbol,
8456        fromMathOp: true,
8457        stack: false,
8458        name: isSymbol ? arr[0].text : null,
8459        body: isSymbol ? null : ordargument(body)
8460      };
8461    },
8462    mathmlBuilder: mathmlBuilder$2
8463  });
8464  var singleCharIntegrals = {
8465    "\u222B": "\\int",
8466    "\u222C": "\\iint",
8467    "\u222D": "\\iiint",
8468    "\u222E": "\\oint",
8469    "\u222F": "\\oiint",
8470    "\u2230": "\\oiiint",
8471    "\u2231": "\\intclockwise",
8472    "\u2232": "\\varointclockwise",
8473    "\u2A0C": "\\iiiint",
8474    "\u2A0D": "\\intbar",
8475    "\u2A0E": "\\intBar",
8476    "\u2A0F": "\\fint",
8477    "\u2A12": "\\rppolint",
8478    "\u2A13": "\\scpolint",
8479    "\u2A15": "\\pointint",
8480    "\u2A16": "\\sqint",
8481    "\u2A17": "\\intlarhk",
8482    "\u2A18": "\\intx",
8483    "\u2A19": "\\intcap",
8484    "\u2A1A": "\\intcup"
8485  };
8486  defineFunction({
8487    type: "op",
8488    names: [
8489      "\\arcsin",
8490      "\\arccos",
8491      "\\arctan",
8492      "\\arctg",
8493      "\\arcctg",
8494      "\\arg",
8495      "\\ch",
8496      "\\cos",
8497      "\\cosec",
8498      "\\cosh",
8499      "\\cot",
8500      "\\cotg",
8501      "\\coth",
8502      "\\csc",
8503      "\\ctg",
8504      "\\cth",
8505      "\\deg",
8506      "\\dim",
8507      "\\exp",
8508      "\\hom",
8509      "\\ker",
8510      "\\lg",
8511      "\\ln",
8512      "\\log",
8513      "\\sec",
8514      "\\sin",
8515      "\\sinh",
8516      "\\sh",
8517      "\\sgn",
8518      "\\tan",
8519      "\\tanh",
8520      "\\tg",
8521      "\\th"
8522    ],
8523    props: {
8524      numArgs: 0
8525    },
8526    handler({ parser, funcName }) {
8527      const prevAtomType = parser.prevAtomType;
8528      const next = parser.gullet.future().text;
8529      return {
8530        type: "op",
8531        mode: parser.mode,
8532        limits: false,
8533        parentIsSupSub: false,
8534        symbol: false,
8535        stack: false,
8536        isFollowedByDelimiter: isDelimiter(next),
8537        needsLeadingSpace: prevAtomType.length > 0 && ordTypes.includes(prevAtomType),
8538        name: funcName
8539      };
8540    },
8541    mathmlBuilder: mathmlBuilder$2
8542  });
8543  defineFunction({
8544    type: "op",
8545    names: ["\\det", "\\gcd", "\\inf", "\\lim", "\\max", "\\min", "\\Pr", "\\sup"],
8546    props: {
8547      numArgs: 0
8548    },
8549    handler({ parser, funcName }) {
8550      const prevAtomType = parser.prevAtomType;
8551      const next = parser.gullet.future().text;
8552      return {
8553        type: "op",
8554        mode: parser.mode,
8555        limits: true,
8556        parentIsSupSub: false,
8557        symbol: false,
8558        stack: false,
8559        isFollowedByDelimiter: isDelimiter(next),
8560        needsLeadingSpace: prevAtomType.length > 0 && ordTypes.includes(prevAtomType),
8561        name: funcName
8562      };
8563    },
8564    mathmlBuilder: mathmlBuilder$2
8565  });
8566  defineFunction({
8567    type: "op",
8568    names: [
8569      "\\int",
8570      "\\iint",
8571      "\\iiint",
8572      "\\iiiint",
8573      "\\oint",
8574      "\\oiint",
8575      "\\oiiint",
8576      "\\intclockwise",
8577      "\\varointclockwise",
8578      "\\intbar",
8579      "\\intBar",
8580      "\\fint",
8581      "\\rppolint",
8582      "\\scpolint",
8583      "\\pointint",
8584      "\\sqint",
8585      "\\intlarhk",
8586      "\\intx",
8587      "\\intcap",
8588      "\\intcup",
8589      "\u222B",
8590      "\u222C",
8591      "\u222D",
8592      "\u222E",
8593      "\u222F",
8594      "\u2230",
8595      "\u2231",
8596      "\u2232",
8597      "\u2A0C",
8598      "\u2A0D",
8599      "\u2A0E",
8600      "\u2A0F",
8601      "\u2A12",
8602      "\u2A13",
8603      "\u2A15",
8604      "\u2A16",
8605      "\u2A17",
8606      "\u2A18",
8607      "\u2A19",
8608      "\u2A1A"
8609    ],
8610    props: {
8611      numArgs: 0
8612    },
8613    handler({ parser, funcName }) {
8614      let fName = funcName;
8615      if (fName.length === 1) {
8616        fName = singleCharIntegrals[fName];
8617      }
8618      return {
8619        type: "op",
8620        mode: parser.mode,
8621        limits: false,
8622        parentIsSupSub: false,
8623        symbol: true,
8624        stack: false,
8625        name: fName
8626      };
8627    },
8628    mathmlBuilder: mathmlBuilder$2
8629  });
8630  var mathmlBuilder$1 = (group, style) => {
8631    let expression = buildExpression(group.body, style.withFont("mathrm"));
8632    let isAllString = true;
8633    for (let i = 0; i < expression.length; i++) {
8634      let node = expression[i];
8635      if (node instanceof mathMLTree.MathNode) {
8636        if (node.type === "mrow" && node.children.length === 1 && node.children[0] instanceof mathMLTree.MathNode) {
8637          node = node.children[0];
8638        }
8639        switch (node.type) {
8640          case "mi":
8641          case "mn":
8642          case "ms":
8643          case "mtext":
8644            break;
8645          // Do nothing yet.
8646          case "mspace":
8647            {
8648              if (node.attributes.width) {
8649                const width = node.attributes.width.replace("em", "");
8650                const ch = spaceCharacter(Number(width));
8651                if (ch === "") {
8652                  isAllString = false;
8653                } else {
8654                  expression[i] = new mathMLTree.MathNode("mtext", [new mathMLTree.TextNode(ch)]);
8655                }
8656              }
8657            }
8658            break;
8659          case "mo": {
8660            const child = node.children[0];
8661            if (node.children.length === 1 && child instanceof mathMLTree.TextNode) {
8662              child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*");
8663            } else {
8664              isAllString = false;
8665            }
8666            break;
8667          }
8668          default:
8669            isAllString = false;
8670        }
8671      } else {
8672        isAllString = false;
8673      }
8674    }
8675    if (isAllString) {
8676      const word = expression.map((node) => node.toText()).join("");
8677      expression = [new mathMLTree.TextNode(word)];
8678    } else if (expression.length === 1 && ["mover", "munder"].includes(expression[0].type) && (expression[0].children[0].type === "mi" || expression[0].children[0].type === "mtext")) {
8679      expression[0].children[0].type = "mi";
8680      if (group.parentIsSupSub) {
8681        return new mathMLTree.MathNode("mrow", expression);
8682      } else {
8683        const operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]);
8684        return mathMLTree.newDocumentFragment([expression[0], operator]);
8685      }
8686    }
8687    let wrapper;
8688    if (isAllString) {
8689      wrapper = new mathMLTree.MathNode("mi", expression);
8690      if (expression[0].text.length === 1) {
8691        wrapper.setAttribute("mathvariant", "normal");
8692      }
8693    } else {
8694      wrapper = new mathMLTree.MathNode("mrow", expression);
8695    }
8696    if (!group.parentIsSupSub) {
8697      const operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]);
8698      const fragment = [wrapper, operator];
8699      if (group.needsLeadingSpace) {
8700        const space = new mathMLTree.MathNode("mspace");
8701        space.setAttribute("width", "0.1667em");
8702        fragment.unshift(space);
8703      }
8704      if (!group.isFollowedByDelimiter) {
8705        const trail = new mathMLTree.MathNode("mspace");
8706        trail.setAttribute("width", "0.1667em");
8707        fragment.push(trail);
8708      }
8709      return mathMLTree.newDocumentFragment(fragment);
8710    }
8711    return wrapper;
8712  };
8713  defineFunction({
8714    type: "operatorname",
8715    names: ["\\operatorname@", "\\operatornamewithlimits"],
8716    props: {
8717      numArgs: 1,
8718      allowedInArgument: true
8719    },
8720    handler: ({ parser, funcName }, args) => {
8721      const body = args[0];
8722      const prevAtomType = parser.prevAtomType;
8723      const next = parser.gullet.future().text;
8724      return {
8725        type: "operatorname",
8726        mode: parser.mode,
8727        body: ordargument(body),
8728        alwaysHandleSupSub: funcName === "\\operatornamewithlimits",
8729        limits: false,
8730        parentIsSupSub: false,
8731        isFollowedByDelimiter: isDelimiter(next),
8732        needsLeadingSpace: prevAtomType.length > 0 && ordTypes.includes(prevAtomType)
8733      };
8734    },
8735    mathmlBuilder: mathmlBuilder$1
8736  });
8737  defineMacro(
8738    "\\operatorname",
8739    "\\@ifstar\\operatornamewithlimits\\operatorname@"
8740  );
8741  defineFunctionBuilders({
8742    type: "ordgroup",
8743    mathmlBuilder(group, style) {
8744      return buildExpressionRow(group.body, style, group.semisimple);
8745    }
8746  });
8747  defineFunction({
8748    type: "phantom",
8749    names: ["\\phantom"],
8750    props: {
8751      numArgs: 1,
8752      allowedInText: true
8753    },
8754    handler: ({ parser }, args) => {
8755      const body = args[0];
8756      return {
8757        type: "phantom",
8758        mode: parser.mode,
8759        body: ordargument(body)
8760      };
8761    },
8762    mathmlBuilder: (group, style) => {
8763      const inner2 = buildExpression(group.body, style);
8764      return new mathMLTree.MathNode("mphantom", inner2);
8765    }
8766  });
8767  defineFunction({
8768    type: "hphantom",
8769    names: ["\\hphantom"],
8770    props: {
8771      numArgs: 1,
8772      allowedInText: true
8773    },
8774    handler: ({ parser }, args) => {
8775      const body = args[0];
8776      return {
8777        type: "hphantom",
8778        mode: parser.mode,
8779        body
8780      };
8781    },
8782    mathmlBuilder: (group, style) => {
8783      const inner2 = buildExpression(ordargument(group.body), style);
8784      const phantom = new mathMLTree.MathNode("mphantom", inner2);
8785      const node = new mathMLTree.MathNode("mpadded", [phantom]);
8786      node.setAttribute("height", "0px");
8787      node.setAttribute("depth", "0px");
8788      return node;
8789    }
8790  });
8791  defineFunction({
8792    type: "vphantom",
8793    names: ["\\vphantom"],
8794    props: {
8795      numArgs: 1,
8796      allowedInText: true
8797    },
8798    handler: ({ parser }, args) => {
8799      const body = args[0];
8800      return {
8801        type: "vphantom",
8802        mode: parser.mode,
8803        body
8804      };
8805    },
8806    mathmlBuilder: (group, style) => {
8807      const inner2 = buildExpression(ordargument(group.body), style);
8808      const phantom = new mathMLTree.MathNode("mphantom", inner2);
8809      const node = new mathMLTree.MathNode("mpadded", [phantom]);
8810      node.setAttribute("width", "0px");
8811      return node;
8812    }
8813  });
8814  defineFunction({
8815    type: "pmb",
8816    names: ["\\pmb"],
8817    props: {
8818      numArgs: 1,
8819      allowedInText: true
8820    },
8821    handler({ parser }, args) {
8822      return {
8823        type: "pmb",
8824        mode: parser.mode,
8825        body: ordargument(args[0])
8826      };
8827    },
8828    mathmlBuilder(group, style) {
8829      const inner2 = buildExpression(group.body, style);
8830      const node = wrapWithMstyle(inner2);
8831      node.setAttribute("style", "font-weight:bold");
8832      return node;
8833    }
8834  });
8835  var mathmlBuilder = (group, style) => {
8836    const newStyle = style.withLevel(StyleLevel.TEXT);
8837    const node = new mathMLTree.MathNode("mpadded", [buildGroup$1(group.body, newStyle)]);
8838    const dy = calculateSize(group.dy, style);
8839    node.setAttribute("voffset", dy.number + dy.unit);
8840    if (dy.number > 0) {
8841      node.style.padding = dy.number + dy.unit + " 0 0 0";
8842    } else {
8843      node.style.padding = "0 0 " + Math.abs(dy.number) + dy.unit + " 0";
8844    }
8845    return node;
8846  };
8847  defineFunction({
8848    type: "raise",
8849    names: ["\\raise", "\\lower"],
8850    props: {
8851      numArgs: 2,
8852      argTypes: ["size", "primitive"],
8853      primitive: true
8854    },
8855    handler({ parser, funcName }, args) {
8856      const amount = assertNodeType(args[0], "size").value;
8857      if (funcName === "\\lower") {
8858        amount.number *= -1;
8859      }
8860      const body = args[1];
8861      return {
8862        type: "raise",
8863        mode: parser.mode,
8864        dy: amount,
8865        body
8866      };
8867    },
8868    mathmlBuilder
8869  });
8870  defineFunction({
8871    type: "raise",
8872    names: ["\\raisebox"],
8873    props: {
8874      numArgs: 2,
8875      argTypes: ["size", "hbox"],
8876      allowedInText: true
8877    },
8878    handler({ parser, funcName }, args) {
8879      const amount = assertNodeType(args[0], "size").value;
8880      const body = args[1];
8881      return {
8882        type: "raise",
8883        mode: parser.mode,
8884        dy: amount,
8885        body
8886      };
8887    },
8888    mathmlBuilder
8889  });
8890  defineFunction({
8891    type: "ref",
8892    names: ["\\ref", "\\eqref"],
8893    props: {
8894      numArgs: 1,
8895      argTypes: ["raw"]
8896    },
8897    handler({ parser, funcName }, args) {
8898      return {
8899        type: "ref",
8900        mode: parser.mode,
8901        funcName,
8902        string: args[0].string.replace(invalidIdRegEx, "")
8903      };
8904    },
8905    mathmlBuilder(group, style) {
8906      const classes = group.funcName === "\\ref" ? ["tml-ref"] : ["tml-ref", "tml-eqref"];
8907      return new AnchorNode("#" + group.string, classes, null);
8908    }
8909  });
8910  defineFunction({
8911    type: "reflect",
8912    names: ["\\reflectbox"],
8913    props: {
8914      numArgs: 1,
8915      argTypes: ["hbox"],
8916      allowedInText: true
8917    },
8918    handler({ parser }, args) {
8919      return {
8920        type: "reflect",
8921        mode: parser.mode,
8922        body: args[0]
8923      };
8924    },
8925    mathmlBuilder(group, style) {
8926      const node = buildGroup$1(group.body, style);
8927      node.style.transform = "scaleX(-1)";
8928      return node;
8929    }
8930  });
8931  defineFunction({
8932    type: "internal",
8933    names: ["\\relax"],
8934    props: {
8935      numArgs: 0,
8936      allowedInText: true
8937    },
8938    handler({ parser }) {
8939      return {
8940        type: "internal",
8941        mode: parser.mode
8942      };
8943    }
8944  });
8945  defineFunction({
8946    type: "rule",
8947    names: ["\\rule"],
8948    props: {
8949      numArgs: 2,
8950      numOptionalArgs: 1,
8951      allowedInText: true,
8952      allowedInMath: true,
8953      argTypes: ["size", "size", "size"]
8954    },
8955    handler({ parser }, args, optArgs) {
8956      const shift = optArgs[0];
8957      const width = assertNodeType(args[0], "size");
8958      const height = assertNodeType(args[1], "size");
8959      return {
8960        type: "rule",
8961        mode: parser.mode,
8962        shift: shift && assertNodeType(shift, "size").value,
8963        width: width.value,
8964        height: height.value
8965      };
8966    },
8967    mathmlBuilder(group, style) {
8968      const width = calculateSize(group.width, style);
8969      const height = calculateSize(group.height, style);
8970      const shift = group.shift ? calculateSize(group.shift, style) : { number: 0, unit: "em" };
8971      const color = style.color && style.getColor() || "black";
8972      const rule = new mathMLTree.MathNode("mspace");
8973      if (width.number > 0 && height.number > 0) {
8974        rule.setAttribute("mathbackground", color);
8975      }
8976      rule.setAttribute("width", width.number + width.unit);
8977      rule.setAttribute("height", height.number + height.unit);
8978      if (shift.number === 0) {
8979        return rule;
8980      }
8981      const wrapper = new mathMLTree.MathNode("mpadded", [rule]);
8982      if (shift.number >= 0) {
8983        wrapper.setAttribute("height", "+" + shift.number + shift.unit);
8984      } else {
8985        wrapper.setAttribute("height", shift.number + shift.unit);
8986        wrapper.setAttribute("depth", "+" + -shift.number + shift.unit);
8987      }
8988      wrapper.setAttribute("voffset", shift.number + shift.unit);
8989      return wrapper;
8990    }
8991  });
8992  var sizeMap = {
8993    "\\tiny": 0.5,
8994    "\\sixptsize": 0.6,
8995    "\\Tiny": 0.6,
8996    "\\scriptsize": 0.7,
8997    "\\footnotesize": 0.8,
8998    "\\small": 0.9,
8999    "\\normalsize": 1,
9000    "\\large": 1.2,
9001    "\\Large": 1.44,
9002    "\\LARGE": 1.728,
9003    "\\huge": 2.074,
9004    "\\Huge": 2.488
9005  };
9006  defineFunction({
9007    type: "sizing",
9008    names: [
9009      "\\tiny",
9010      "\\sixptsize",
9011      "\\Tiny",
9012      "\\scriptsize",
9013      "\\footnotesize",
9014      "\\small",
9015      "\\normalsize",
9016      "\\large",
9017      "\\Large",
9018      "\\LARGE",
9019      "\\huge",
9020      "\\Huge"
9021    ],
9022    props: {
9023      numArgs: 0,
9024      allowedInText: true
9025    },
9026    handler: ({ breakOnTokenText, funcName, parser }, args) => {
9027      if (parser.settings.strict && parser.mode === "math") {
9028        console.log(`Temml strict-mode warning: Command $funcName} is invalid in math mode.`);
9029      }
9030      const body = parser.parseExpression(false, breakOnTokenText, true);
9031      return {
9032        type: "sizing",
9033        mode: parser.mode,
9034        funcName,
9035        body
9036      };
9037    },
9038    mathmlBuilder: (group, style) => {
9039      const newStyle = style.withFontSize(sizeMap[group.funcName]);
9040      const inner2 = buildExpression(group.body, newStyle);
9041      const node = wrapWithMstyle(inner2);
9042      const factor = (sizeMap[group.funcName] / style.fontSize).toFixed(4);
9043      node.setAttribute("mathsize", factor + "em");
9044      return node;
9045    }
9046  });
9047  defineFunction({
9048    type: "smash",
9049    names: ["\\smash"],
9050    props: {
9051      numArgs: 1,
9052      numOptionalArgs: 1,
9053      allowedInText: true
9054    },
9055    handler: ({ parser }, args, optArgs) => {
9056      let smashHeight = false;
9057      let smashDepth = false;
9058      const tbArg = optArgs[0] && assertNodeType(optArgs[0], "ordgroup");
9059      if (tbArg) {
9060        let letter = "";
9061        for (let i = 0; i < tbArg.body.length; ++i) {
9062          const node = tbArg.body[i];
9063          letter = node.text;
9064          if (letter === "t") {
9065            smashHeight = true;
9066          } else if (letter === "b") {
9067            smashDepth = true;
9068          } else {
9069            smashHeight = false;
9070            smashDepth = false;
9071            break;
9072          }
9073        }
9074      } else {
9075        smashHeight = true;
9076        smashDepth = true;
9077      }
9078      const body = args[0];
9079      return {
9080        type: "smash",
9081        mode: parser.mode,
9082        body,
9083        smashHeight,
9084        smashDepth
9085      };
9086    },
9087    mathmlBuilder: (group, style) => {
9088      const node = new mathMLTree.MathNode("mpadded", [buildGroup$1(group.body, style)]);
9089      if (group.smashHeight) {
9090        node.setAttribute("height", "0px");
9091      }
9092      if (group.smashDepth) {
9093        node.setAttribute("depth", "0px");
9094      }
9095      return node;
9096    }
9097  });
9098  defineFunction({
9099    type: "sqrt",
9100    names: ["\\sqrt"],
9101    props: {
9102      numArgs: 1,
9103      numOptionalArgs: 1
9104    },
9105    handler({ parser }, args, optArgs) {
9106      const index = optArgs[0];
9107      const body = args[0];
9108      return {
9109        type: "sqrt",
9110        mode: parser.mode,
9111        body,
9112        index
9113      };
9114    },
9115    mathmlBuilder(group, style) {
9116      const { body, index } = group;
9117      return index ? new mathMLTree.MathNode("mroot", [
9118        buildGroup$1(body, style),
9119        buildGroup$1(index, style.incrementLevel())
9120      ]) : new mathMLTree.MathNode("msqrt", [buildGroup$1(body, style)]);
9121    }
9122  });
9123  var styleMap = {
9124    display: 0,
9125    text: 1,
9126    script: 2,
9127    scriptscript: 3
9128  };
9129  var styleAttributes = {
9130    display: ["0", "true"],
9131    text: ["0", "false"],
9132    script: ["1", "false"],
9133    scriptscript: ["2", "false"]
9134  };
9135  defineFunction({
9136    type: "styling",
9137    names: ["\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle"],
9138    props: {
9139      numArgs: 0,
9140      allowedInText: true,
9141      primitive: true
9142    },
9143    handler({ breakOnTokenText, funcName, parser }, args) {
9144      const body = parser.parseExpression(true, breakOnTokenText, true);
9145      const scriptLevel2 = funcName.slice(1, funcName.length - 5);
9146      return {
9147        type: "styling",
9148        mode: parser.mode,
9149        // Figure out what scriptLevel to use by pulling out the scriptLevel from
9150        // the function name
9151        scriptLevel: scriptLevel2,
9152        body
9153      };
9154    },
9155    mathmlBuilder(group, style) {
9156      const newStyle = style.withLevel(styleMap[group.scriptLevel]);
9157      const inner2 = buildExpression(group.body, newStyle);
9158      const node = wrapWithMstyle(inner2);
9159      const attr = styleAttributes[group.scriptLevel];
9160      node.setAttribute("scriptlevel", attr[0]);
9161      node.setAttribute("displaystyle", attr[1]);
9162      return node;
9163    }
9164  });
9165  var symbolRegEx = /^m(over|under|underover)$/;
9166  defineFunctionBuilders({
9167    type: "supsub",
9168    mathmlBuilder(group, style) {
9169      let isBrace = false;
9170      let isOver;
9171      let isSup;
9172      let appendApplyFunction = false;
9173      let appendSpace = false;
9174      let needsLeadingSpace = false;
9175      if (group.base && group.base.type === "horizBrace") {
9176        isSup = !!group.sup;
9177        if (isSup === group.base.isOver) {
9178          isBrace = true;
9179          isOver = group.base.isOver;
9180        }
9181      }
9182      if (group.base && !group.base.stack && (group.base.type === "op" || group.base.type === "operatorname")) {
9183        group.base.parentIsSupSub = true;
9184        appendApplyFunction = !group.base.symbol;
9185        appendSpace = appendApplyFunction && !group.isFollowedByDelimiter;
9186        needsLeadingSpace = group.base.needsLeadingSpace;
9187      }
9188      const children = group.base && group.base.stack ? [buildGroup$1(group.base.body[0], style)] : [buildGroup$1(group.base, style)];
9189      const childStyle = style.inSubOrSup();
9190      if (group.sub) {
9191        const sub = buildGroup$1(group.sub, childStyle);
9192        if (style.level === 3) {
9193          sub.setAttribute("scriptlevel", "2");
9194        }
9195        children.push(sub);
9196      }
9197      if (group.sup) {
9198        const sup = buildGroup$1(group.sup, childStyle);
9199        if (style.level === 3) {
9200          sup.setAttribute("scriptlevel", "2");
9201        }
9202        const testNode = sup.type === "mrow" ? sup.children[0] : sup;
9203        if (testNode && testNode.type === "mo" && testNode.classes.includes("tml-prime") && group.base && group.base.text && "fF".indexOf(group.base.text) > -1) {
9204          testNode.classes.push("prime-pad");
9205        }
9206        children.push(sup);
9207      }
9208      let nodeType;
9209      if (isBrace) {
9210        nodeType = isOver ? "mover" : "munder";
9211      } else if (!group.sub) {
9212        const base = group.base;
9213        if (base && base.type === "op" && base.limits && (style.level === StyleLevel.DISPLAY || base.alwaysHandleSupSub)) {
9214          nodeType = "mover";
9215        } else if (base && base.type === "operatorname" && base.alwaysHandleSupSub && (base.limits || style.level === StyleLevel.DISPLAY)) {
9216          nodeType = "mover";
9217        } else {
9218          nodeType = "msup";
9219        }
9220      } else if (!group.sup) {
9221        const base = group.base;
9222        if (base && base.type === "op" && base.limits && (style.level === StyleLevel.DISPLAY || base.alwaysHandleSupSub)) {
9223          nodeType = "munder";
9224        } else if (base && base.type === "operatorname" && base.alwaysHandleSupSub && (base.limits || style.level === StyleLevel.DISPLAY)) {
9225          nodeType = "munder";
9226        } else {
9227          nodeType = "msub";
9228        }
9229      } else {
9230        const base = group.base;
9231        if (base && (base.type === "op" && base.limits || base.type === "multiscript") && (style.level === StyleLevel.DISPLAY || base.alwaysHandleSupSub)) {
9232          nodeType = "munderover";
9233        } else if (base && base.type === "operatorname" && base.alwaysHandleSupSub && (style.level === StyleLevel.DISPLAY || base.limits)) {
9234          nodeType = "munderover";
9235        } else {
9236          nodeType = "msubsup";
9237        }
9238      }
9239      let node = new mathMLTree.MathNode(nodeType, children);
9240      if (appendApplyFunction) {
9241        const operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]);
9242        if (needsLeadingSpace) {
9243          const space = new mathMLTree.MathNode("mspace");
9244          space.setAttribute("width", "0.1667em");
9245          node = mathMLTree.newDocumentFragment([space, node, operator]);
9246        } else {
9247          node = mathMLTree.newDocumentFragment([node, operator]);
9248        }
9249        if (appendSpace) {
9250          const space = new mathMLTree.MathNode("mspace");
9251          space.setAttribute("width", "0.1667em");
9252          node.children.push(space);
9253        }
9254      } else if (symbolRegEx.test(nodeType)) {
9255        node = new mathMLTree.MathNode("mrow", [node]);
9256      }
9257      return node;
9258    }
9259  });
9260  var short = [
9261    "\\shortmid",
9262    "\\nshortmid",
9263    "\\shortparallel",
9264    "\\nshortparallel",
9265    "\\smallsetminus"
9266  ];
9267  var arrows = ["\\Rsh", "\\Lsh", "\\restriction"];
9268  var isArrow = (str) => {
9269    if (str.length === 1) {
9270      const codePoint = str.codePointAt(0);
9271      return 8591 < codePoint && codePoint < 8704;
9272    }
9273    return str.indexOf("arrow") > -1 || str.indexOf("harpoon") > -1 || arrows.includes(str);
9274  };
9275  defineFunctionBuilders({
9276    type: "atom",
9277    mathmlBuilder(group, style) {
9278      const node = new mathMLTree.MathNode("mo", [makeText(group.text, group.mode)]);
9279      if (group.family === "punct") {
9280        node.setAttribute("separator", "true");
9281      } else if (group.family === "open" || group.family === "close") {
9282        if (group.family === "open") {
9283          node.setAttribute("form", "prefix");
9284          node.setAttribute("stretchy", "false");
9285        } else if (group.family === "close") {
9286          node.setAttribute("form", "postfix");
9287          node.setAttribute("stretchy", "false");
9288        }
9289      } else if (group.text === "\\mid") {
9290        node.setAttribute("lspace", "0.22em");
9291        node.setAttribute("rspace", "0.22em");
9292        node.setAttribute("stretchy", "false");
9293      } else if (group.family === "rel" && isArrow(group.text)) {
9294        node.setAttribute("stretchy", "false");
9295      } else if (short.includes(group.text)) {
9296        node.setAttribute("mathsize", "70%");
9297      } else if (group.text === ":") {
9298        node.attributes.lspace = "0.2222em";
9299        node.attributes.rspace = "0.2222em";
9300      }
9301      return node;
9302    }
9303  });
9304  var fontMap = {
9305    // styles
9306    mathbf: "bold",
9307    mathrm: "normal",
9308    textit: "italic",
9309    mathit: "italic",
9310    mathnormal: "italic",
9311    // families
9312    mathbb: "double-struck",
9313    mathcal: "script",
9314    mathfrak: "fraktur",
9315    mathscr: "script",
9316    mathsf: "sans-serif",
9317    mathtt: "monospace"
9318  };
9319  var getVariant = function(group, style) {
9320    if (style.fontFamily === "texttt") {
9321      return "monospace";
9322    } else if (style.fontFamily === "textsc") {
9323      return "normal";
9324    } else if (style.fontFamily === "textsf") {
9325      if (style.fontShape === "textit" && style.fontWeight === "textbf") {
9326        return "sans-serif-bold-italic";
9327      } else if (style.fontShape === "textit") {
9328        return "sans-serif-italic";
9329      } else if (style.fontWeight === "textbf") {
9330        return "sans-serif-bold";
9331      } else {
9332        return "sans-serif";
9333      }
9334    } else if (style.fontShape === "textit" && style.fontWeight === "textbf") {
9335      return "bold-italic";
9336    } else if (style.fontShape === "textit") {
9337      return "italic";
9338    } else if (style.fontWeight === "textbf") {
9339      return "bold";
9340    }
9341    const font = style.font;
9342    if (!font || font === "mathnormal") {
9343      return null;
9344    }
9345    const mode = group.mode;
9346    switch (font) {
9347      case "mathit":
9348        return "italic";
9349      case "mathrm": {
9350        const codePoint = group.text.codePointAt(0);
9351        return 939 < codePoint && codePoint < 975 ? "italic" : "normal";
9352      }
9353      case "greekItalic":
9354        return "italic";
9355      case "up@greek":
9356        return "normal";
9357      case "boldsymbol":
9358      case "mathboldsymbol":
9359        return "bold-italic";
9360      case "mathbf":
9361        return "bold";
9362      case "mathbb":
9363        return "double-struck";
9364      case "mathfrak":
9365        return "fraktur";
9366      case "mathscr":
9367      case "mathcal":
9368        return "script";
9369      case "mathsf":
9370        return "sans-serif";
9371      case "mathsfit":
9372        return "sans-serif-italic";
9373      case "mathtt":
9374        return "monospace";
9375    }
9376    let text2 = group.text;
9377    if (symbols[mode][text2] && symbols[mode][text2].replace) {
9378      text2 = symbols[mode][text2].replace;
9379    }
9380    return Object.prototype.hasOwnProperty.call(fontMap, font) ? fontMap[font] : null;
9381  };
9382  var script = Object.freeze({
9383    B: 8426,
9384    // Offset from ASCII B to Unicode script B
9385    E: 8427,
9386    F: 8427,
9387    H: 8387,
9388    I: 8391,
9389    L: 8390,
9390    M: 8422,
9391    R: 8393,
9392    e: 8394,
9393    g: 8355,
9394    o: 8389
9395  });
9396  var frak = Object.freeze({
9397    C: 8426,
9398    H: 8388,
9399    I: 8392,
9400    R: 8394,
9401    Z: 8398
9402  });
9403  var bbb = Object.freeze({
9404    C: 8383,
9405    // blackboard bold
9406    H: 8389,
9407    N: 8391,
9408    P: 8393,
9409    Q: 8393,
9410    R: 8395,
9411    Z: 8394
9412  });
9413  var bold = Object.freeze({
9414    "\u03F5": 119527,
9415    // lunate epsilon
9416    "\u03D1": 119564,
9417    // vartheta
9418    "\u03F0": 119534,
9419    // varkappa
9420    "\u03C6": 119577,
9421    // varphi
9422    "\u03F1": 119535,
9423    // varrho
9424    "\u03D6": 119563
9425    // varpi
9426  });
9427  var boldItalic = Object.freeze({
9428    "\u03F5": 119643,
9429    // lunate epsilon
9430    "\u03D1": 119680,
9431    // vartheta
9432    "\u03F0": 119650,
9433    // varkappa
9434    "\u03C6": 119693,
9435    // varphi
9436    "\u03F1": 119651,
9437    // varrho
9438    "\u03D6": 119679
9439    // varpi
9440  });
9441  var boldsf = Object.freeze({
9442    "\u03F5": 119701,
9443    // lunate epsilon
9444    "\u03D1": 119738,
9445    // vartheta
9446    "\u03F0": 119708,
9447    // varkappa
9448    "\u03C6": 119751,
9449    // varphi
9450    "\u03F1": 119709,
9451    // varrho
9452    "\u03D6": 119737
9453    // varpi
9454  });
9455  var bisf = Object.freeze({
9456    "\u03F5": 119759,
9457    // lunate epsilon
9458    "\u03D1": 119796,
9459    // vartheta
9460    "\u03F0": 119766,
9461    // varkappa
9462    "\u03C6": 119809,
9463    // varphi
9464    "\u03F1": 119767,
9465    // varrho
9466    "\u03D6": 119795
9467    // varpi
9468  });
9469  var offset = Object.freeze({
9470    upperCaseLatin: {
9471      // A-Z
9472      "normal": (ch) => {
9473        return 0;
9474      },
9475      "bold": (ch) => {
9476        return 119743;
9477      },
9478      "italic": (ch) => {
9479        return 119795;
9480      },
9481      "bold-italic": (ch) => {
9482        return 119847;
9483      },
9484      "script": (ch) => {
9485        return script[ch] || 119899;
9486      },
9487      "script-bold": (ch) => {
9488        return 119951;
9489      },
9490      "fraktur": (ch) => {
9491        return frak[ch] || 120003;
9492      },
9493      "fraktur-bold": (ch) => {
9494        return 120107;
9495      },
9496      "double-struck": (ch) => {
9497        return bbb[ch] || 120055;
9498      },
9499      "sans-serif": (ch) => {
9500        return 120159;
9501      },
9502      "sans-serif-bold": (ch) => {
9503        return 120211;
9504      },
9505      "sans-serif-italic": (ch) => {
9506        return 120263;
9507      },
9508      "sans-serif-bold-italic": (ch) => {
9509        return 120380;
9510      },
9511      "monospace": (ch) => {
9512        return 120367;
9513      }
9514    },
9515    lowerCaseLatin: {
9516      // a-z
9517      "normal": (ch) => {
9518        return 0;
9519      },
9520      "bold": (ch) => {
9521        return 119737;
9522      },
9523      "italic": (ch) => {
9524        return ch === "h" ? 8358 : 119789;
9525      },
9526      "bold-italic": (ch) => {
9527        return 119841;
9528      },
9529      "script": (ch) => {
9530        return script[ch] || 119893;
9531      },
9532      "script-bold": (ch) => {
9533        return 119945;
9534      },
9535      "fraktur": (ch) => {
9536        return 119997;
9537      },
9538      "fraktur-bold": (ch) => {
9539        return 120101;
9540      },
9541      "double-struck": (ch) => {
9542        return 120049;
9543      },
9544      "sans-serif": (ch) => {
9545        return 120153;
9546      },
9547      "sans-serif-bold": (ch) => {
9548        return 120205;
9549      },
9550      "sans-serif-italic": (ch) => {
9551        return 120257;
9552      },
9553      "sans-serif-bold-italic": (ch) => {
9554        return 120309;
9555      },
9556      "monospace": (ch) => {
9557        return 120361;
9558      }
9559    },
9560    upperCaseGreek: {
9561      // A-Ω
9562      "normal": (ch) => {
9563        return 0;
9564      },
9565      "bold": (ch) => {
9566        return 119575;
9567      },
9568      "italic": (ch) => {
9569        return 119633;
9570      },
9571      // \boldsymbol actually returns upright bold for upperCaseGreek
9572      "bold-italic": (ch) => {
9573        return 119575;
9574      },
9575      "script": (ch) => {
9576        return 0;
9577      },
9578      "script-bold": (ch) => {
9579        return 0;
9580      },
9581      "fraktur": (ch) => {
9582        return 0;
9583      },
9584      "fraktur-bold": (ch) => {
9585        return 0;
9586      },
9587      "double-struck": (ch) => {
9588        return 0;
9589      },
9590      // Unicode has no code points for regular-weight san-serif Greek. Use bold.
9591      "sans-serif": (ch) => {
9592        return 119749;
9593      },
9594      "sans-serif-bold": (ch) => {
9595        return 119749;
9596      },
9597      "sans-serif-italic": (ch) => {
9598        return 0;
9599      },
9600      "sans-serif-bold-italic": (ch) => {
9601        return 119807;
9602      },
9603      "monospace": (ch) => {
9604        return 0;
9605      }
9606    },
9607    lowerCaseGreek: {
9608      // α-ω
9609      "normal": (ch) => {
9610        return 0;
9611      },
9612      "bold": (ch) => {
9613        return 119569;
9614      },
9615      "italic": (ch) => {
9616        return 119627;
9617      },
9618      "bold-italic": (ch) => {
9619        return ch === "\u03D5" ? 119678 : 119685;
9620      },
9621      "script": (ch) => {
9622        return 0;
9623      },
9624      "script-bold": (ch) => {
9625        return 0;
9626      },
9627      "fraktur": (ch) => {
9628        return 0;
9629      },
9630      "fraktur-bold": (ch) => {
9631        return 0;
9632      },
9633      "double-struck": (ch) => {
9634        return 0;
9635      },
9636      // Unicode has no code points for regular-weight san-serif Greek. Use bold.
9637      "sans-serif": (ch) => {
9638        return 119743;
9639      },
9640      "sans-serif-bold": (ch) => {
9641        return 119743;
9642      },
9643      "sans-serif-italic": (ch) => {
9644        return 0;
9645      },
9646      "sans-serif-bold-italic": (ch) => {
9647        return 119801;
9648      },
9649      "monospace": (ch) => {
9650        return 0;
9651      }
9652    },
9653    varGreek: {
9654      // \varGamma, etc
9655      "normal": (ch) => {
9656        return 0;
9657      },
9658      "bold": (ch) => {
9659        return bold[ch] || -51;
9660      },
9661      "italic": (ch) => {
9662        return 0;
9663      },
9664      "bold-italic": (ch) => {
9665        return boldItalic[ch] || 58;
9666      },
9667      "script": (ch) => {
9668        return 0;
9669      },
9670      "script-bold": (ch) => {
9671        return 0;
9672      },
9673      "fraktur": (ch) => {
9674        return 0;
9675      },
9676      "fraktur-bold": (ch) => {
9677        return 0;
9678      },
9679      "double-struck": (ch) => {
9680        return 0;
9681      },
9682      "sans-serif": (ch) => {
9683        return boldsf[ch] || 116;
9684      },
9685      "sans-serif-bold": (ch) => {
9686        return boldsf[ch] || 116;
9687      },
9688      "sans-serif-italic": (ch) => {
9689        return 0;
9690      },
9691      "sans-serif-bold-italic": (ch) => {
9692        return bisf[ch] || 174;
9693      },
9694      "monospace": (ch) => {
9695        return 0;
9696      }
9697    },
9698    numeral: {
9699      // 0-9
9700      "normal": (ch) => {
9701        return 0;
9702      },
9703      "bold": (ch) => {
9704        return 120734;
9705      },
9706      "italic": (ch) => {
9707        return 0;
9708      },
9709      "bold-italic": (ch) => {
9710        return 0;
9711      },
9712      "script": (ch) => {
9713        return 0;
9714      },
9715      "script-bold": (ch) => {
9716        return 0;
9717      },
9718      "fraktur": (ch) => {
9719        return 0;
9720      },
9721      "fraktur-bold": (ch) => {
9722        return 0;
9723      },
9724      "double-struck": (ch) => {
9725        return 120744;
9726      },
9727      "sans-serif": (ch) => {
9728        return 120754;
9729      },
9730      "sans-serif-bold": (ch) => {
9731        return 120764;
9732      },
9733      "sans-serif-italic": (ch) => {
9734        return 0;
9735      },
9736      "sans-serif-bold-italic": (ch) => {
9737        return 0;
9738      },
9739      "monospace": (ch) => {
9740        return 120774;
9741      }
9742    }
9743  });
9744  var variantChar = (ch, variant) => {
9745    const codePoint = ch.codePointAt(0);
9746    const block = 64 < codePoint && codePoint < 91 ? "upperCaseLatin" : 96 < codePoint && codePoint < 123 ? "lowerCaseLatin" : 912 < codePoint && codePoint < 938 ? "upperCaseGreek" : 944 < codePoint && codePoint < 970 || ch === "\u03D5" ? "lowerCaseGreek" : 120545 < codePoint && codePoint < 120572 || bold[ch] ? "varGreek" : 47 < codePoint && codePoint < 58 ? "numeral" : "other";
9747    return block === "other" ? ch : String.fromCodePoint(codePoint + offset[block][variant](ch));
9748  };
9749  var smallCaps = Object.freeze({
9750    a: "\u1D00",
9751    b: "\u0299",
9752    c: "\u1D04",
9753    d: "\u1D05",
9754    e: "\u1D07",
9755    f: "\uA730",
9756    g: "\u0262",
9757    h: "\u029C",
9758    i: "\u026A",
9759    j: "\u1D0A",
9760    k: "\u1D0B",
9761    l: "\u029F",
9762    m: "\u1D0D",
9763    n: "\u0274",
9764    o: "\u1D0F",
9765    p: "\u1D18",
9766    q: "\u01EB",
9767    r: "\u0280",
9768    s: "s",
9769    t: "\u1D1B",
9770    u: "\u1D1C",
9771    v: "\u1D20",
9772    w: "\u1D21",
9773    x: "x",
9774    y: "\u028F",
9775    z: "\u1D22"
9776  });
9777  var numberRegEx = /^\d(?:[\d,.]*\d)?$/;
9778  var latinRegEx = /[A-Ba-z]/;
9779  var primes = /* @__PURE__ */ new Set([
9780    "\\prime",
9781    "\\dprime",
9782    "\\trprime",
9783    "\\qprime",
9784    "\\backprime",
9785    "\\backdprime",
9786    "\\backtrprime"
9787  ]);
9788  var italicNumber = (text2, variant, tag) => {
9789    const mn = new mathMLTree.MathNode(tag, [text2]);
9790    const wrapper = new mathMLTree.MathNode("mstyle", [mn]);
9791    wrapper.style["font-style"] = "italic";
9792    wrapper.style["font-family"] = "Cambria, 'Times New Roman', serif";
9793    if (variant === "bold-italic") {
9794      wrapper.style["font-weight"] = "bold";
9795    }
9796    return wrapper;
9797  };
9798  defineFunctionBuilders({
9799    type: "mathord",
9800    mathmlBuilder(group, style) {
9801      const text2 = makeText(group.text, group.mode, style);
9802      const codePoint = text2.text.codePointAt(0);
9803      const defaultVariant = 912 < codePoint && codePoint < 938 ? "normal" : "italic";
9804      const variant = getVariant(group, style) || defaultVariant;
9805      if (variant === "script") {
9806        text2.text = variantChar(text2.text, variant);
9807        return new mathMLTree.MathNode("mi", [text2], [style.font]);
9808      } else if (variant !== "italic") {
9809        text2.text = variantChar(text2.text, variant);
9810      }
9811      let node = new mathMLTree.MathNode("mi", [text2]);
9812      if (variant === "normal") {
9813        node.setAttribute("mathvariant", "normal");
9814        if (text2.text.length === 1) {
9815          node = new mathMLTree.MathNode("mrow", [node]);
9816        }
9817      }
9818      return node;
9819    }
9820  });
9821  defineFunctionBuilders({
9822    type: "textord",
9823    mathmlBuilder(group, style) {
9824      let ch = group.text;
9825      const codePoint = ch.codePointAt(0);
9826      if (style.fontFamily === "textsc") {
9827        if (96 < codePoint && codePoint < 123) {
9828          ch = smallCaps[ch];
9829        }
9830      }
9831      const text2 = makeText(ch, group.mode, style);
9832      const variant = getVariant(group, style) || "normal";
9833      let node;
9834      if (numberRegEx.test(group.text)) {
9835        const tag = group.mode === "text" ? "mtext" : "mn";
9836        if (variant === "italic" || variant === "bold-italic") {
9837          return italicNumber(text2, variant, tag);
9838        } else {
9839          if (variant !== "normal") {
9840            text2.text = text2.text.split("").map((c) => variantChar(c, variant)).join("");
9841          }
9842          node = new mathMLTree.MathNode(tag, [text2]);
9843        }
9844      } else if (group.mode === "text") {
9845        if (variant !== "normal") {
9846          text2.text = variantChar(text2.text, variant);
9847        }
9848        node = new mathMLTree.MathNode("mtext", [text2]);
9849      } else if (primes.has(group.text)) {
9850        node = new mathMLTree.MathNode("mo", [text2]);
9851        node.classes.push("tml-prime");
9852      } else {
9853        const origText = text2.text;
9854        if (variant !== "italic") {
9855          text2.text = variantChar(text2.text, variant);
9856        }
9857        node = new mathMLTree.MathNode("mi", [text2]);
9858        if (text2.text === origText && latinRegEx.test(origText)) {
9859          node.setAttribute("mathvariant", "italic");
9860        }
9861      }
9862      return node;
9863    }
9864  });
9865  var cssSpace = {
9866    "\\nobreak": "nobreak",
9867    "\\allowbreak": "allowbreak"
9868  };
9869  var regularSpace = {
9870    " ": {},
9871    "\\ ": {},
9872    "~": {
9873      className: "nobreak"
9874    },
9875    "\\space": {},
9876    "\\nobreakspace": {
9877      className: "nobreak"
9878    }
9879  };
9880  defineFunctionBuilders({
9881    type: "spacing",
9882    mathmlBuilder(group, style) {
9883      let node;
9884      if (Object.prototype.hasOwnProperty.call(regularSpace, group.text)) {
9885        node = new mathMLTree.MathNode("mtext", [new mathMLTree.TextNode("\xA0")]);
9886      } else if (Object.prototype.hasOwnProperty.call(cssSpace, group.text)) {
9887        node = new mathMLTree.MathNode("mo");
9888        if (group.text === "\\nobreak") {
9889          node.setAttribute("linebreak", "nobreak");
9890        }
9891      } else {
9892        throw new ParseError(`Unknown type of space "$group.text}"`);
9893      }
9894      return node;
9895    }
9896  });
9897  defineFunctionBuilders({
9898    type: "tag"
9899  });
9900  var textFontFamilies = {
9901    "\\text": void 0,
9902    "\\textrm": "textrm",
9903    "\\textsf": "textsf",
9904    "\\texttt": "texttt",
9905    "\\textnormal": "textrm",
9906    "\\textsc": "textsc"
9907    // small caps
9908  };
9909  var textFontWeights = {
9910    "\\textbf": "textbf",
9911    "\\textmd": "textmd"
9912  };
9913  var textFontShapes = {
9914    "\\textit": "textit",
9915    "\\textup": "textup"
9916  };
9917  var styleWithFont = (group, style) => {
9918    const font = group.font;
9919    if (!font) {
9920      return style;
9921    } else if (textFontFamilies[font]) {
9922      return style.withTextFontFamily(textFontFamilies[font]);
9923    } else if (textFontWeights[font]) {
9924      return style.withTextFontWeight(textFontWeights[font]);
9925    } else if (font === "\\emph") {
9926      return style.fontShape === "textit" ? style.withTextFontShape("textup") : style.withTextFontShape("textit");
9927    }
9928    return style.withTextFontShape(textFontShapes[font]);
9929  };
9930  defineFunction({
9931    type: "text",
9932    names: [
9933      // Font families
9934      "\\text",
9935      "\\textrm",
9936      "\\textsf",
9937      "\\texttt",
9938      "\\textnormal",
9939      "\\textsc",
9940      // Font weights
9941      "\\textbf",
9942      "\\textmd",
9943      // Font Shapes
9944      "\\textit",
9945      "\\textup",
9946      "\\emph"
9947    ],
9948    props: {
9949      numArgs: 1,
9950      argTypes: ["text"],
9951      allowedInArgument: true,
9952      allowedInText: true
9953    },
9954    handler({ parser, funcName }, args) {
9955      const body = args[0];
9956      return {
9957        type: "text",
9958        mode: parser.mode,
9959        body: ordargument(body),
9960        font: funcName
9961      };
9962    },
9963    mathmlBuilder(group, style) {
9964      const newStyle = styleWithFont(group, style);
9965      const mrow = buildExpressionRow(group.body, newStyle);
9966      return consolidateText(mrow);
9967    }
9968  });
9969  defineFunction({
9970    type: "vcenter",
9971    names: ["\\vcenter"],
9972    props: {
9973      numArgs: 1,
9974      argTypes: ["original"],
9975      allowedInText: false
9976    },
9977    handler({ parser }, args) {
9978      return {
9979        type: "vcenter",
9980        mode: parser.mode,
9981        body: args[0]
9982      };
9983    },
9984    mathmlBuilder(group, style) {
9985      const mtd = new mathMLTree.MathNode("mtd", [buildGroup$1(group.body, style)]);
9986      mtd.style.padding = "0";
9987      const mtr = new mathMLTree.MathNode("mtr", [mtd]);
9988      return new mathMLTree.MathNode("mtable", [mtr]);
9989    }
9990  });
9991  defineFunction({
9992    type: "verb",
9993    names: ["\\verb"],
9994    props: {
9995      numArgs: 0,
9996      allowedInText: true
9997    },
9998    handler(context, args, optArgs) {
9999      throw new ParseError("\\verb ended by end of line instead of matching delimiter");
10000    },
10001    mathmlBuilder(group, style) {
10002      const text2 = new mathMLTree.TextNode(makeVerb(group));
10003      const node = new mathMLTree.MathNode("mtext", [text2]);
10004      node.setAttribute("mathvariant", "monospace");
10005      return node;
10006    }
10007  });
10008  var makeVerb = (group) => group.body.replace(/ /g, group.star ? "\u2423" : "\xA0");
10009  var functions = _functions;
10010  var spaceRegexString = "[ \r\n    ]";
10011  var controlWordRegexString = "\\\\[a-zA-Z@]+";
10012  var controlSymbolRegexString = "\\\\[^\uD800-\uDFFF]";
10013  var controlWordWhitespaceRegexString = `($controlWordRegexString})$spaceRegexString}*`;
10014  var controlSpaceRegexString = "\\\\(\n|[ \r    ]+\n?)[ \r    ]*";
10015  var combiningDiacriticalMarkString = "[\u0300-\u036F]";
10016  var combiningDiacriticalMarksEndRegex = new RegExp(`$combiningDiacriticalMarkString}+$`);
10017  var tokenRegexString = `($spaceRegexString}+)|$controlSpaceRegexString}|([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]$combiningDiacriticalMarkString}*|[\uD800-\uDBFF][\uDC00-\uDFFF]$combiningDiacriticalMarkString}*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|$controlWordWhitespaceRegexString}|$controlSymbolRegexString})`;
10018  var Lexer = class {
10019    constructor(input, settings) {
10020      this.input = input;
10021      this.settings = settings;
10022      this.tokenRegex = new RegExp(tokenRegexString, "g");
10023      this.catcodes = {
10024        "%": 14,
10025        // comment character
10026        "~": 13
10027        // active character
10028      };
10029    }
10030    setCatcode(char, code) {
10031      this.catcodes[char] = code;
10032    }
10033    /**
10034     * This function lexes a single token.
10035     */
10036    lex() {
10037      const input = this.input;
10038      const pos = this.tokenRegex.lastIndex;
10039      if (pos === input.length) {
10040        return new Token("EOF", new SourceLocation(this, pos, pos));
10041      }
10042      const match = this.tokenRegex.exec(input);
10043      if (match === null || match.index !== pos) {
10044        throw new ParseError(
10045          `Unexpected character: '$input[pos]}'`,
10046          new Token(input[pos], new SourceLocation(this, pos, pos + 1))
10047        );
10048      }
10049      const text2 = match[6] || match[3] || (match[2] ? "\\ " : " ");
10050      if (this.catcodes[text2] === 14) {
10051        const nlIndex = input.indexOf("\n", this.tokenRegex.lastIndex);
10052        if (nlIndex === -1) {
10053          this.tokenRegex.lastIndex = input.length;
10054          if (this.settings.strict) {
10055            throw new ParseError("% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode");
10056          }
10057        } else {
10058          this.tokenRegex.lastIndex = nlIndex + 1;
10059        }
10060        return this.lex();
10061      }
10062      return new Token(text2, new SourceLocation(this, pos, this.tokenRegex.lastIndex));
10063    }
10064  };
10065  var Namespace = class {
10066    /**
10067     * Both arguments are optional.  The first argument is an object of
10068     * built-in mappings which never change.  The second argument is an object
10069     * of initial (global-level) mappings, which will constantly change
10070     * according to any global/top-level `set`s done.
10071     */
10072    constructor(builtins = {}, globalMacros = {}) {
10073      this.current = globalMacros;
10074      this.builtins = builtins;
10075      this.undefStack = [];
10076    }
10077    /**
10078     * Start a new nested group, affecting future local `set`s.
10079     */
10080    beginGroup() {
10081      this.undefStack.push({});
10082    }
10083    /**
10084     * End current nested group, restoring values before the group began.
10085     */
10086    endGroup() {
10087      if (this.undefStack.length === 0) {
10088        throw new ParseError(
10089          "Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug"
10090        );
10091      }
10092      const undefs = this.undefStack.pop();
10093      for (const undef in undefs) {
10094        if (Object.prototype.hasOwnProperty.call(undefs, undef)) {
10095          if (undefs[undef] === void 0) {
10096            delete this.current[undef];
10097          } else {
10098            this.current[undef] = undefs[undef];
10099          }
10100        }
10101      }
10102    }
10103    /**
10104     * Detect whether `name` has a definition.  Equivalent to
10105     * `get(name) != null`.
10106     */
10107    has(name) {
10108      return Object.prototype.hasOwnProperty.call(this.current, name) || Object.prototype.hasOwnProperty.call(this.builtins, name);
10109    }
10110    /**
10111     * Get the current value of a name, or `undefined` if there is no value.
10112     *
10113     * Note: Do not use `if (namespace.get(...))` to detect whether a macro
10114     * is defined, as the definition may be the empty string which evaluates
10115     * to `false` in JavaScript.  Use `if (namespace.get(...) != null)` or
10116     * `if (namespace.has(...))`.
10117     */
10118    get(name) {
10119      if (Object.prototype.hasOwnProperty.call(this.current, name)) {
10120        return this.current[name];
10121      } else {
10122        return this.builtins[name];
10123      }
10124    }
10125    /**
10126     * Set the current value of a name, and optionally set it globally too.
10127     * Local set() sets the current value and (when appropriate) adds an undo
10128     * operation to the undo stack.  Global set() may change the undo
10129     * operation at every level, so takes time linear in their number.
10130     */
10131    set(name, value, global = false) {
10132      if (global) {
10133        for (let i = 0; i < this.undefStack.length; i++) {
10134          delete this.undefStack[i][name];
10135        }
10136        if (this.undefStack.length > 0) {
10137          this.undefStack[this.undefStack.length - 1][name] = value;
10138        }
10139      } else {
10140        const top = this.undefStack[this.undefStack.length - 1];
10141        if (top && !Object.prototype.hasOwnProperty.call(top, name)) {
10142          top[name] = this.current[name];
10143        }
10144      }
10145      this.current[name] = value;
10146    }
10147  };
10148  var implicitCommands = {
10149    "^": true,
10150    // Parser.js
10151    _: true,
10152    // Parser.js
10153    "\\limits": true,
10154    // Parser.js
10155    "\\nolimits": true
10156    // Parser.js
10157  };
10158  var MacroExpander = class {
10159    constructor(input, settings, mode) {
10160      this.settings = settings;
10161      this.expansionCount = 0;
10162      this.feed(input);
10163      this.macros = new Namespace(macros, settings.macros);
10164      this.mode = mode;
10165      this.stack = [];
10166    }
10167    /**
10168     * Feed a new input string to the same MacroExpander
10169     * (with existing macros etc.).
10170     */
10171    feed(input) {
10172      this.lexer = new Lexer(input, this.settings);
10173    }
10174    /**
10175     * Switches between "text" and "math" modes.
10176     */
10177    switchMode(newMode) {
10178      this.mode = newMode;
10179    }
10180    /**
10181     * Start a new group nesting within all namespaces.
10182     */
10183    beginGroup() {
10184      this.macros.beginGroup();
10185    }
10186    /**
10187     * End current group nesting within all namespaces.
10188     */
10189    endGroup() {
10190      this.macros.endGroup();
10191    }
10192    /**
10193     * Returns the topmost token on the stack, without expanding it.
10194     * Similar in behavior to TeX's `\futurelet`.
10195     */
10196    future() {
10197      if (this.stack.length === 0) {
10198        this.pushToken(this.lexer.lex());
10199      }
10200      return this.stack[this.stack.length - 1];
10201    }
10202    /**
10203     * Remove and return the next unexpanded token.
10204     */
10205    popToken() {
10206      this.future();
10207      return this.stack.pop();
10208    }
10209    /**
10210     * Add a given token to the token stack.  In particular, this get be used
10211     * to put back a token returned from one of the other methods.
10212     */
10213    pushToken(token) {
10214      this.stack.push(token);
10215    }
10216    /**
10217     * Append an array of tokens to the token stack.
10218     */
10219    pushTokens(tokens) {
10220      this.stack.push(...tokens);
10221    }
10222    /**
10223     * Find an macro argument without expanding tokens and append the array of
10224     * tokens to the token stack. Uses Token as a container for the result.
10225     */
10226    scanArgument(isOptional) {
10227      let start;
10228      let end;
10229      let tokens;
10230      if (isOptional) {
10231        this.consumeSpaces();
10232        if (this.future().text !== "[") {
10233          return null;
10234        }
10235        start = this.popToken();
10236        ({ tokens, end } = this.consumeArg(["]"]));
10237      } else {
10238        ({ tokens, start, end } = this.consumeArg());
10239      }
10240      this.pushToken(new Token("EOF", end.loc));
10241      this.pushTokens(tokens);
10242      return start.range(end, "");
10243    }
10244    /**
10245     * Consume all following space tokens, without expansion.
10246     */
10247    consumeSpaces() {
10248      for (; ; ) {
10249        const token = this.future();
10250        if (token.text === " ") {
10251          this.stack.pop();
10252        } else {
10253          break;
10254        }
10255      }
10256    }
10257    /**
10258     * Consume an argument from the token stream, and return the resulting array
10259     * of tokens and start/end token.
10260     */
10261    consumeArg(delims) {
10262      const tokens = [];
10263      const isDelimited = delims && delims.length > 0;
10264      if (!isDelimited) {
10265        this.consumeSpaces();
10266      }
10267      const start = this.future();
10268      let tok;
10269      let depth = 0;
10270      let match = 0;
10271      do {
10272        tok = this.popToken();
10273        tokens.push(tok);
10274        if (tok.text === "{") {
10275          ++depth;
10276        } else if (tok.text === "}") {
10277          --depth;
10278          if (depth === -1) {
10279            throw new ParseError("Extra }", tok);
10280          }
10281        } else if (tok.text === "EOF") {
10282          throw new ParseError(
10283            "Unexpected end of input in a macro argument, expected '" + (delims && isDelimited ? delims[match] : "}") + "'",
10284            tok
10285          );
10286        }
10287        if (delims && isDelimited) {
10288          if ((depth === 0 || depth === 1 && delims[match] === "{") && tok.text === delims[match]) {
10289            ++match;
10290            if (match === delims.length) {
10291              tokens.splice(-match, match);
10292              break;
10293            }
10294          } else {
10295            match = 0;
10296          }
10297        }
10298      } while (depth !== 0 || isDelimited);
10299      if (start.text === "{" && tokens[tokens.length - 1].text === "}") {
10300        tokens.pop();
10301        tokens.shift();
10302      }
10303      tokens.reverse();
10304      return { tokens, start, end: tok };
10305    }
10306    /**
10307     * Consume the specified number of (delimited) arguments from the token
10308     * stream and return the resulting array of arguments.
10309     */
10310    consumeArgs(numArgs, delimiters2) {
10311      if (delimiters2) {
10312        if (delimiters2.length !== numArgs + 1) {
10313          throw new ParseError("The length of delimiters doesn't match the number of args!");
10314        }
10315        const delims = delimiters2[0];
10316        for (let i = 0; i < delims.length; i++) {
10317          const tok = this.popToken();
10318          if (delims[i] !== tok.text) {
10319            throw new ParseError("Use of the macro doesn't match its definition", tok);
10320          }
10321        }
10322      }
10323      const args = [];
10324      for (let i = 0; i < numArgs; i++) {
10325        args.push(this.consumeArg(delimiters2 && delimiters2[i + 1]).tokens);
10326      }
10327      return args;
10328    }
10329    /**
10330     * Expand the next token only once if possible.
10331     *
10332     * If the token is expanded, the resulting tokens will be pushed onto
10333     * the stack in reverse order, and the number of such tokens will be
10334     * returned.  This number might be zero or positive.
10335     *
10336     * If not, the return value is `false`, and the next token remains at the
10337     * top of the stack.
10338     *
10339     * In either case, the next token will be on the top of the stack,
10340     * or the stack will be empty (in case of empty expansion
10341     * and no other tokens).
10342     *
10343     * Used to implement `expandAfterFuture` and `expandNextToken`.
10344     *
10345     * If expandableOnly, only expandable tokens are expanded and
10346     * an undefined control sequence results in an error.
10347     */
10348    expandOnce(expandableOnly) {
10349      const topToken = this.popToken();
10350      const name = topToken.text;
10351      const expansion = !topToken.noexpand ? this._getExpansion(name) : null;
10352      if (expansion == null || expandableOnly && expansion.unexpandable) {
10353        if (expandableOnly && expansion == null && name[0] === "\\" && !this.isDefined(name)) {
10354          throw new ParseError("Undefined control sequence: " + name);
10355        }
10356        this.pushToken(topToken);
10357        return false;
10358      }
10359      this.expansionCount++;
10360      if (this.expansionCount > this.settings.maxExpand) {
10361        throw new ParseError(
10362          "Too many expansions: infinite loop or need to increase maxExpand setting"
10363        );
10364      }
10365      let tokens = expansion.tokens;
10366      const args = this.consumeArgs(expansion.numArgs, expansion.delimiters);
10367      if (expansion.numArgs) {
10368        tokens = tokens.slice();
10369        for (let i = tokens.length - 1; i >= 0; --i) {
10370          let tok = tokens[i];
10371          if (tok.text === "#") {
10372            if (i === 0) {
10373              throw new ParseError("Incomplete placeholder at end of macro body", tok);
10374            }
10375            tok = tokens[--i];
10376            if (tok.text === "#") {
10377              tokens.splice(i + 1, 1);
10378            } else if (/^[1-9]$/.test(tok.text)) {
10379              tokens.splice(i, 2, ...args[+tok.text - 1]);
10380            } else {
10381              throw new ParseError("Not a valid argument number", tok);
10382            }
10383          }
10384        }
10385      }
10386      this.pushTokens(tokens);
10387      return tokens.length;
10388    }
10389    /**
10390     * Expand the next token only once (if possible), and return the resulting
10391     * top token on the stack (without removing anything from the stack).
10392     * Similar in behavior to TeX's `\expandafter\futurelet`.
10393     * Equivalent to expandOnce() followed by future().
10394     */
10395    expandAfterFuture() {
10396      this.expandOnce();
10397      return this.future();
10398    }
10399    /**
10400     * Recursively expand first token, then return first non-expandable token.
10401     */
10402    expandNextToken() {
10403      for (; ; ) {
10404        if (this.expandOnce() === false) {
10405          const token = this.stack.pop();
10406          if (token.treatAsRelax) {
10407            token.text = "\\relax";
10408          }
10409          return token;
10410        }
10411      }
10412      throw new Error();
10413    }
10414    /**
10415     * Fully expand the given macro name and return the resulting list of
10416     * tokens, or return `undefined` if no such macro is defined.
10417     */
10418    expandMacro(name) {
10419      return this.macros.has(name) ? this.expandTokens([new Token(name)]) : void 0;
10420    }
10421    /**
10422     * Fully expand the given token stream and return the resulting list of
10423     * tokens.  Note that the input tokens are in reverse order, but the
10424     * output tokens are in forward order.
10425     */
10426    expandTokens(tokens) {
10427      const output = [];
10428      const oldStackLength = this.stack.length;
10429      this.pushTokens(tokens);
10430      while (this.stack.length > oldStackLength) {
10431        if (this.expandOnce(true) === false) {
10432          const token = this.stack.pop();
10433          if (token.treatAsRelax) {
10434            token.noexpand = false;
10435            token.treatAsRelax = false;
10436          }
10437          output.push(token);
10438        }
10439      }
10440      return output;
10441    }
10442    /**
10443     * Fully expand the given macro name and return the result as a string,
10444     * or return `undefined` if no such macro is defined.
10445     */
10446    expandMacroAsText(name) {
10447      const tokens = this.expandMacro(name);
10448      if (tokens) {
10449        return tokens.map((token) => token.text).join("");
10450      } else {
10451        return tokens;
10452      }
10453    }
10454    /**
10455     * Returns the expanded macro as a reversed array of tokens and a macro
10456     * argument count.  Or returns `null` if no such macro.
10457     */
10458    _getExpansion(name) {
10459      const definition = this.macros.get(name);
10460      if (definition == null) {
10461        return definition;
10462      }
10463      if (name.length === 1) {
10464        const catcode = this.lexer.catcodes[name];
10465        if (catcode != null && catcode !== 13) {
10466          return;
10467        }
10468      }
10469      const expansion = typeof definition === "function" ? definition(this) : definition;
10470      if (typeof expansion === "string") {
10471        let numArgs = 0;
10472        if (expansion.indexOf("#") !== -1) {
10473          const stripped = expansion.replace(/##/g, "");
10474          while (stripped.indexOf("#" + (numArgs + 1)) !== -1) {
10475            ++numArgs;
10476          }
10477        }
10478        const bodyLexer = new Lexer(expansion, this.settings);
10479        const tokens = [];
10480        let tok = bodyLexer.lex();
10481        while (tok.text !== "EOF") {
10482          tokens.push(tok);
10483          tok = bodyLexer.lex();
10484        }
10485        tokens.reverse();
10486        const expanded = { tokens, numArgs };
10487        return expanded;
10488      }
10489      return expansion;
10490    }
10491    /**
10492     * Determine whether a command is currently "defined" (has some
10493     * functionality), meaning that it's a macro (in the current group),
10494     * a function, a symbol, or one of the special commands listed in
10495     * `implicitCommands`.
10496     */
10497    isDefined(name) {
10498      return this.macros.has(name) || Object.prototype.hasOwnProperty.call(functions, name) || Object.prototype.hasOwnProperty.call(symbols.math, name) || Object.prototype.hasOwnProperty.call(symbols.text, name) || Object.prototype.hasOwnProperty.call(implicitCommands, name);
10499    }
10500    /**
10501     * Determine whether a command is expandable.
10502     */
10503    isExpandable(name) {
10504      const macro = this.macros.get(name);
10505      return macro != null ? typeof macro === "string" || typeof macro === "function" || !macro.unexpandable : Object.prototype.hasOwnProperty.call(functions, name) && !functions[name].primitive;
10506    }
10507  };
10508  var unicodeSubRegEx = /^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/;
10509  var uSubsAndSups = Object.freeze({
10510    "\u208A": "+",
10511    "\u208B": "-",
10512    "\u208C": "=",
10513    "\u208D": "(",
10514    "\u208E": ")",
10515    "\u2080": "0",
10516    "\u2081": "1",
10517    "\u2082": "2",
10518    "\u2083": "3",
10519    "\u2084": "4",
10520    "\u2085": "5",
10521    "\u2086": "6",
10522    "\u2087": "7",
10523    "\u2088": "8",
10524    "\u2089": "9",
10525    "\u2090": "a",
10526    "\u2091": "e",
10527    "\u2095": "h",
10528    "\u1D62": "i",
10529    "\u2C7C": "j",
10530    "\u2096": "k",
10531    "\u2097": "l",
10532    "\u2098": "m",
10533    "\u2099": "n",
10534    "\u2092": "o",
10535    "\u209A": "p",
10536    "\u1D63": "r",
10537    "\u209B": "s",
10538    "\u209C": "t",
10539    "\u1D64": "u",
10540    "\u1D65": "v",
10541    "\u2093": "x",
10542    "\u1D66": "\u03B2",
10543    "\u1D67": "\u03B3",
10544    "\u1D68": "\u03C1",
10545    "\u1D69": "\u03D5",
10546    "\u1D6A": "\u03C7",
10547    "\u207A": "+",
10548    "\u207B": "-",
10549    "\u207C": "=",
10550    "\u207D": "(",
10551    "\u207E": ")",
10552    "\u2070": "0",
10553    "\xB9": "1",
10554    "\xB2": "2",
10555    "\xB3": "3",
10556    "\u2074": "4",
10557    "\u2075": "5",
10558    "\u2076": "6",
10559    "\u2077": "7",
10560    "\u2078": "8",
10561    "\u2079": "9",
10562    "\u1D2C": "A",
10563    "\u1D2E": "B",
10564    "\u1D30": "D",
10565    "\u1D31": "E",
10566    "\u1D33": "G",
10567    "\u1D34": "H",
10568    "\u1D35": "I",
10569    "\u1D36": "J",
10570    "\u1D37": "K",
10571    "\u1D38": "L",
10572    "\u1D39": "M",
10573    "\u1D3A": "N",
10574    "\u1D3C": "O",
10575    "\u1D3E": "P",
10576    "\u1D3F": "R",
10577    "\u1D40": "T",
10578    "\u1D41": "U",
10579    "\u2C7D": "V",
10580    "\u1D42": "W",
10581    "\u1D43": "a",
10582    "\u1D47": "b",
10583    "\u1D9C": "c",
10584    "\u1D48": "d",
10585    "\u1D49": "e",
10586    "\u1DA0": "f",
10587    "\u1D4D": "g",
10588    "\u02B0": "h",
10589    "\u2071": "i",
10590    "\u02B2": "j",
10591    "\u1D4F": "k",
10592    "\u02E1": "l",
10593    "\u1D50": "m",
10594    "\u207F": "n",
10595    "\u1D52": "o",
10596    "\u1D56": "p",
10597    "\u02B3": "r",
10598    "\u02E2": "s",
10599    "\u1D57": "t",
10600    "\u1D58": "u",
10601    "\u1D5B": "v",
10602    "\u02B7": "w",
10603    "\u02E3": "x",
10604    "\u02B8": "y",
10605    "\u1DBB": "z",
10606    "\u1D5D": "\u03B2",
10607    "\u1D5E": "\u03B3",
10608    "\u1D5F": "\u03B4",
10609    "\u1D60": "\u03D5",
10610    "\u1D61": "\u03C7",
10611    "\u1DBF": "\u03B8"
10612  });
10613  var asciiFromScript = Object.freeze({
10614    "\u{1D49C}": "A",
10615    "\u212C": "B",
10616    "\u{1D49E}": "C",
10617    "\u{1D49F}": "D",
10618    "\u2130": "E",
10619    "\u2131": "F",
10620    "\u{1D4A2}": "G",
10621    "\u210B": "H",
10622    "\u2110": "I",
10623    "\u{1D4A5}": "J",
10624    "\u{1D4A6}": "K",
10625    "\u2112": "L",
10626    "\u2133": "M",
10627    "\u{1D4A9}": "N",
10628    "\u{1D4AA}": "O",
10629    "\u{1D4AB}": "P",
10630    "\u{1D4AC}": "Q",
10631    "\u211B": "R",
10632    "\u{1D4AE}": "S",
10633    "\u{1D4AF}": "T",
10634    "\u{1D4B0}": "U",
10635    "\u{1D4B1}": "V",
10636    "\u{1D4B2}": "W",
10637    "\u{1D4B3}": "X",
10638    "\u{1D4B4}": "Y",
10639    "\u{1D4B5}": "Z"
10640  });
10641  var unicodeAccents = {
10642    "\u0301": { text: "\\'", math: "\\acute" },
10643    "\u0300": { text: "\\`", math: "\\grave" },
10644    "\u0308": { text: '\\"', math: "\\ddot" },
10645    "\u0303": { text: "\\~", math: "\\tilde" },
10646    "\u0304": { text: "\\=", math: "\\bar" },
10647    "\u0306": { text: "\\u", math: "\\breve" },
10648    "\u030C": { text: "\\v", math: "\\check" },
10649    "\u0302": { text: "\\^", math: "\\hat" },
10650    "\u0307": { text: "\\.", math: "\\dot" },
10651    "\u030A": { text: "\\r", math: "\\mathring" },
10652    "\u030B": { text: "\\H" },
10653    "\u0327": { text: "\\c" }
10654  };
10655  var unicodeSymbols = {
10656    "\xE1": "a\u0301",
10657    "\xE0": "a\u0300",
10658    "\xE4": "a\u0308",
10659    "\u01DF": "a\u0308\u0304",
10660    "\xE3": "a\u0303",
10661    "\u0101": "a\u0304",
10662    "\u0103": "a\u0306",
10663    "\u1EAF": "a\u0306\u0301",
10664    "\u1EB1": "a\u0306\u0300",
10665    "\u1EB5": "a\u0306\u0303",
10666    "\u01CE": "a\u030C",
10667    "\xE2": "a\u0302",
10668    "\u1EA5": "a\u0302\u0301",
10669    "\u1EA7": "a\u0302\u0300",
10670    "\u1EAB": "a\u0302\u0303",
10671    "\u0227": "a\u0307",
10672    "\u01E1": "a\u0307\u0304",
10673    "\xE5": "a\u030A",
10674    "\u01FB": "a\u030A\u0301",
10675    "\u1E03": "b\u0307",
10676    "\u0107": "c\u0301",
10677    "\u010D": "c\u030C",
10678    "\u0109": "c\u0302",
10679    "\u010B": "c\u0307",
10680    "\u010F": "d\u030C",
10681    "\u1E0B": "d\u0307",
10682    "\xE9": "e\u0301",
10683    "\xE8": "e\u0300",
10684    "\xEB": "e\u0308",
10685    "\u1EBD": "e\u0303",
10686    "\u0113": "e\u0304",
10687    "\u1E17": "e\u0304\u0301",
10688    "\u1E15": "e\u0304\u0300",
10689    "\u0115": "e\u0306",
10690    "\u011B": "e\u030C",
10691    "\xEA": "e\u0302",
10692    "\u1EBF": "e\u0302\u0301",
10693    "\u1EC1": "e\u0302\u0300",
10694    "\u1EC5": "e\u0302\u0303",
10695    "\u0117": "e\u0307",
10696    "\u1E1F": "f\u0307",
10697    "\u01F5": "g\u0301",
10698    "\u1E21": "g\u0304",
10699    "\u011F": "g\u0306",
10700    "\u01E7": "g\u030C",
10701    "\u011D": "g\u0302",
10702    "\u0121": "g\u0307",
10703    "\u1E27": "h\u0308",
10704    "\u021F": "h\u030C",
10705    "\u0125": "h\u0302",
10706    "\u1E23": "h\u0307",
10707    "\xED": "i\u0301",
10708    "\xEC": "i\u0300",
10709    "\xEF": "i\u0308",
10710    "\u1E2F": "i\u0308\u0301",
10711    "\u0129": "i\u0303",
10712    "\u012B": "i\u0304",
10713    "\u012D": "i\u0306",
10714    "\u01D0": "i\u030C",
10715    "\xEE": "i\u0302",
10716    "\u01F0": "j\u030C",
10717    "\u0135": "j\u0302",
10718    "\u1E31": "k\u0301",
10719    "\u01E9": "k\u030C",
10720    "\u013A": "l\u0301",
10721    "\u013E": "l\u030C",
10722    "\u1E3F": "m\u0301",
10723    "\u1E41": "m\u0307",
10724    "\u0144": "n\u0301",
10725    "\u01F9": "n\u0300",
10726    "\xF1": "n\u0303",
10727    "\u0148": "n\u030C",
10728    "\u1E45": "n\u0307",
10729    "\xF3": "o\u0301",
10730    "\xF2": "o\u0300",
10731    "\xF6": "o\u0308",
10732    "\u022B": "o\u0308\u0304",
10733    "\xF5": "o\u0303",
10734    "\u1E4D": "o\u0303\u0301",
10735    "\u1E4F": "o\u0303\u0308",
10736    "\u022D": "o\u0303\u0304",
10737    "\u014D": "o\u0304",
10738    "\u1E53": "o\u0304\u0301",
10739    "\u1E51": "o\u0304\u0300",
10740    "\u014F": "o\u0306",
10741    "\u01D2": "o\u030C",
10742    "\xF4": "o\u0302",
10743    "\u1ED1": "o\u0302\u0301",
10744    "\u1ED3": "o\u0302\u0300",
10745    "\u1ED7": "o\u0302\u0303",
10746    "\u022F": "o\u0307",
10747    "\u0231": "o\u0307\u0304",
10748    "\u0151": "o\u030B",
10749    "\u1E55": "p\u0301",
10750    "\u1E57": "p\u0307",
10751    "\u0155": "r\u0301",
10752    "\u0159": "r\u030C",
10753    "\u1E59": "r\u0307",
10754    "\u015B": "s\u0301",
10755    "\u1E65": "s\u0301\u0307",
10756    "\u0161": "s\u030C",
10757    "\u1E67": "s\u030C\u0307",
10758    "\u015D": "s\u0302",
10759    "\u1E61": "s\u0307",
10760    "\u1E97": "t\u0308",
10761    "\u0165": "t\u030C",
10762    "\u1E6B": "t\u0307",
10763    "\xFA": "u\u0301",
10764    "\xF9": "u\u0300",
10765    "\xFC": "u\u0308",
10766    "\u01D8": "u\u0308\u0301",
10767    "\u01DC": "u\u0308\u0300",
10768    "\u01D6": "u\u0308\u0304",
10769    "\u01DA": "u\u0308\u030C",
10770    "\u0169": "u\u0303",
10771    "\u1E79": "u\u0303\u0301",
10772    "\u016B": "u\u0304",
10773    "\u1E7B": "u\u0304\u0308",
10774    "\u016D": "u\u0306",
10775    "\u01D4": "u\u030C",
10776    "\xFB": "u\u0302",
10777    "\u016F": "u\u030A",
10778    "\u0171": "u\u030B",
10779    "\u1E7D": "v\u0303",
10780    "\u1E83": "w\u0301",
10781    "\u1E81": "w\u0300",
10782    "\u1E85": "w\u0308",
10783    "\u0175": "w\u0302",
10784    "\u1E87": "w\u0307",
10785    "\u1E98": "w\u030A",
10786    "\u1E8D": "x\u0308",
10787    "\u1E8B": "x\u0307",
10788    "\xFD": "y\u0301",
10789    "\u1EF3": "y\u0300",
10790    "\xFF": "y\u0308",
10791    "\u1EF9": "y\u0303",
10792    "\u0233": "y\u0304",
10793    "\u0177": "y\u0302",
10794    "\u1E8F": "y\u0307",
10795    "\u1E99": "y\u030A",
10796    "\u017A": "z\u0301",
10797    "\u017E": "z\u030C",
10798    "\u1E91": "z\u0302",
10799    "\u017C": "z\u0307",
10800    "\xC1": "A\u0301",
10801    "\xC0": "A\u0300",
10802    "\xC4": "A\u0308",
10803    "\u01DE": "A\u0308\u0304",
10804    "\xC3": "A\u0303",
10805    "\u0100": "A\u0304",
10806    "\u0102": "A\u0306",
10807    "\u1EAE": "A\u0306\u0301",
10808    "\u1EB0": "A\u0306\u0300",
10809    "\u1EB4": "A\u0306\u0303",
10810    "\u01CD": "A\u030C",
10811    "\xC2": "A\u0302",
10812    "\u1EA4": "A\u0302\u0301",
10813    "\u1EA6": "A\u0302\u0300",
10814    "\u1EAA": "A\u0302\u0303",
10815    "\u0226": "A\u0307",
10816    "\u01E0": "A\u0307\u0304",
10817    "\xC5": "A\u030A",
10818    "\u01FA": "A\u030A\u0301",
10819    "\u1E02": "B\u0307",
10820    "\u0106": "C\u0301",
10821    "\u010C": "C\u030C",
10822    "\u0108": "C\u0302",
10823    "\u010A": "C\u0307",
10824    "\u010E": "D\u030C",
10825    "\u1E0A": "D\u0307",
10826    "\xC9": "E\u0301",
10827    "\xC8": "E\u0300",
10828    "\xCB": "E\u0308",
10829    "\u1EBC": "E\u0303",
10830    "\u0112": "E\u0304",
10831    "\u1E16": "E\u0304\u0301",
10832    "\u1E14": "E\u0304\u0300",
10833    "\u0114": "E\u0306",
10834    "\u011A": "E\u030C",
10835    "\xCA": "E\u0302",
10836    "\u1EBE": "E\u0302\u0301",
10837    "\u1EC0": "E\u0302\u0300",
10838    "\u1EC4": "E\u0302\u0303",
10839    "\u0116": "E\u0307",
10840    "\u1E1E": "F\u0307",
10841    "\u01F4": "G\u0301",
10842    "\u1E20": "G\u0304",
10843    "\u011E": "G\u0306",
10844    "\u01E6": "G\u030C",
10845    "\u011C": "G\u0302",
10846    "\u0120": "G\u0307",
10847    "\u1E26": "H\u0308",
10848    "\u021E": "H\u030C",
10849    "\u0124": "H\u0302",
10850    "\u1E22": "H\u0307",
10851    "\xCD": "I\u0301",
10852    "\xCC": "I\u0300",
10853    "\xCF": "I\u0308",
10854    "\u1E2E": "I\u0308\u0301",
10855    "\u0128": "I\u0303",
10856    "\u012A": "I\u0304",
10857    "\u012C": "I\u0306",
10858    "\u01CF": "I\u030C",
10859    "\xCE": "I\u0302",
10860    "\u0130": "I\u0307",
10861    "\u0134": "J\u0302",
10862    "\u1E30": "K\u0301",
10863    "\u01E8": "K\u030C",
10864    "\u0139": "L\u0301",
10865    "\u013D": "L\u030C",
10866    "\u1E3E": "M\u0301",
10867    "\u1E40": "M\u0307",
10868    "\u0143": "N\u0301",
10869    "\u01F8": "N\u0300",
10870    "\xD1": "N\u0303",
10871    "\u0147": "N\u030C",
10872    "\u1E44": "N\u0307",
10873    "\xD3": "O\u0301",
10874    "\xD2": "O\u0300",
10875    "\xD6": "O\u0308",
10876    "\u022A": "O\u0308\u0304",
10877    "\xD5": "O\u0303",
10878    "\u1E4C": "O\u0303\u0301",
10879    "\u1E4E": "O\u0303\u0308",
10880    "\u022C": "O\u0303\u0304",
10881    "\u014C": "O\u0304",
10882    "\u1E52": "O\u0304\u0301",
10883    "\u1E50": "O\u0304\u0300",
10884    "\u014E": "O\u0306",
10885    "\u01D1": "O\u030C",
10886    "\xD4": "O\u0302",
10887    "\u1ED0": "O\u0302\u0301",
10888    "\u1ED2": "O\u0302\u0300",
10889    "\u1ED6": "O\u0302\u0303",
10890    "\u022E": "O\u0307",
10891    "\u0230": "O\u0307\u0304",
10892    "\u0150": "O\u030B",
10893    "\u1E54": "P\u0301",
10894    "\u1E56": "P\u0307",
10895    "\u0154": "R\u0301",
10896    "\u0158": "R\u030C",
10897    "\u1E58": "R\u0307",
10898    "\u015A": "S\u0301",
10899    "\u1E64": "S\u0301\u0307",
10900    "\u0160": "S\u030C",
10901    "\u1E66": "S\u030C\u0307",
10902    "\u015C": "S\u0302",
10903    "\u1E60": "S\u0307",
10904    "\u0164": "T\u030C",
10905    "\u1E6A": "T\u0307",
10906    "\xDA": "U\u0301",
10907    "\xD9": "U\u0300",
10908    "\xDC": "U\u0308",
10909    "\u01D7": "U\u0308\u0301",
10910    "\u01DB": "U\u0308\u0300",
10911    "\u01D5": "U\u0308\u0304",
10912    "\u01D9": "U\u0308\u030C",
10913    "\u0168": "U\u0303",
10914    "\u1E78": "U\u0303\u0301",
10915    "\u016A": "U\u0304",
10916    "\u1E7A": "U\u0304\u0308",
10917    "\u016C": "U\u0306",
10918    "\u01D3": "U\u030C",
10919    "\xDB": "U\u0302",
10920    "\u016E": "U\u030A",
10921    "\u0170": "U\u030B",
10922    "\u1E7C": "V\u0303",
10923    "\u1E82": "W\u0301",
10924    "\u1E80": "W\u0300",
10925    "\u1E84": "W\u0308",
10926    "\u0174": "W\u0302",
10927    "\u1E86": "W\u0307",
10928    "\u1E8C": "X\u0308",
10929    "\u1E8A": "X\u0307",
10930    "\xDD": "Y\u0301",
10931    "\u1EF2": "Y\u0300",
10932    "\u0178": "Y\u0308",
10933    "\u1EF8": "Y\u0303",
10934    "\u0232": "Y\u0304",
10935    "\u0176": "Y\u0302",
10936    "\u1E8E": "Y\u0307",
10937    "\u0179": "Z\u0301",
10938    "\u017D": "Z\u030C",
10939    "\u1E90": "Z\u0302",
10940    "\u017B": "Z\u0307",
10941    "\u03AC": "\u03B1\u0301",
10942    "\u1F70": "\u03B1\u0300",
10943    "\u1FB1": "\u03B1\u0304",
10944    "\u1FB0": "\u03B1\u0306",
10945    "\u03AD": "\u03B5\u0301",
10946    "\u1F72": "\u03B5\u0300",
10947    "\u03AE": "\u03B7\u0301",
10948    "\u1F74": "\u03B7\u0300",
10949    "\u03AF": "\u03B9\u0301",
10950    "\u1F76": "\u03B9\u0300",
10951    "\u03CA": "\u03B9\u0308",
10952    "\u0390": "\u03B9\u0308\u0301",
10953    "\u1FD2": "\u03B9\u0308\u0300",
10954    "\u1FD1": "\u03B9\u0304",
10955    "\u1FD0": "\u03B9\u0306",
10956    "\u03CC": "\u03BF\u0301",
10957    "\u1F78": "\u03BF\u0300",
10958    "\u03CD": "\u03C5\u0301",
10959    "\u1F7A": "\u03C5\u0300",
10960    "\u03CB": "\u03C5\u0308",
10961    "\u03B0": "\u03C5\u0308\u0301",
10962    "\u1FE2": "\u03C5\u0308\u0300",
10963    "\u1FE1": "\u03C5\u0304",
10964    "\u1FE0": "\u03C5\u0306",
10965    "\u03CE": "\u03C9\u0301",
10966    "\u1F7C": "\u03C9\u0300",
10967    "\u038E": "\u03A5\u0301",
10968    "\u1FEA": "\u03A5\u0300",
10969    "\u03AB": "\u03A5\u0308",
10970    "\u1FE9": "\u03A5\u0304",
10971    "\u1FE8": "\u03A5\u0306",
10972    "\u038F": "\u03A9\u0301",
10973    "\u1FFA": "\u03A9\u0300"
10974  };
10975  var binLeftCancellers = ["bin", "op", "open", "punct", "rel"];
10976  var sizeRegEx = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/;
10977  var Parser = class _Parser {
10978    constructor(input, settings, isPreamble = false) {
10979      this.mode = "math";
10980      this.gullet = new MacroExpander(input, settings, this.mode);
10981      this.settings = settings;
10982      this.isPreamble = isPreamble;
10983      this.leftrightDepth = 0;
10984      this.prevAtomType = "";
10985    }
10986    /**
10987     * Checks a result to make sure it has the right type, and throws an
10988     * appropriate error otherwise.
10989     */
10990    expect(text2, consume = true) {
10991      if (this.fetch().text !== text2) {
10992        throw new ParseError(`Expected '$text2}', got '$this.fetch().text}'`, this.fetch());
10993      }
10994      if (consume) {
10995        this.consume();
10996      }
10997    }
10998    /**
10999     * Discards the current lookahead token, considering it consumed.
11000     */
11001    consume() {
11002      this.nextToken = null;
11003    }
11004    /**
11005     * Return the current lookahead token, or if there isn't one (at the
11006     * beginning, or if the previous lookahead token was consume()d),
11007     * fetch the next token as the new lookahead token and return it.
11008     */
11009    fetch() {
11010      if (this.nextToken == null) {
11011        this.nextToken = this.gullet.expandNextToken();
11012      }
11013      return this.nextToken;
11014    }
11015    /**
11016     * Switches between "text" and "math" modes.
11017     */
11018    switchMode(newMode) {
11019      this.mode = newMode;
11020      this.gullet.switchMode(newMode);
11021    }
11022    /**
11023     * Main parsing function, which parses an entire input.
11024     */
11025    parse() {
11026      this.gullet.beginGroup();
11027      if (this.settings.colorIsTextColor) {
11028        this.gullet.macros.set("\\color", "\\textcolor");
11029      }
11030      const parse = this.parseExpression(false);
11031      this.expect("EOF");
11032      if (this.isPreamble) {
11033        const macros2 = /* @__PURE__ */ Object.create(null);
11034        Object.entries(this.gullet.macros.current).forEach(([key, value]) => {
11035          macros2[key] = value;
11036        });
11037        this.gullet.endGroup();
11038        return macros2;
11039      }
11040      const tag = this.gullet.macros.get("\\df@tag");
11041      this.gullet.endGroup();
11042      if (tag) {
11043        this.gullet.macros.current["\\df@tag"] = tag;
11044      }
11045      return parse;
11046    }
11047    static get endOfExpression() {
11048      return ["}", "\\endgroup", "\\end", "\\right", "\\endtoggle", "&"];
11049    }
11050    /**
11051     * Fully parse a separate sequence of tokens as a separate job.
11052     * Tokens should be specified in reverse order, as in a MacroDefinition.
11053     */
11054    subparse(tokens) {
11055      const oldToken = this.nextToken;
11056      this.consume();
11057      this.gullet.pushToken(new Token("}"));
11058      this.gullet.pushTokens(tokens);
11059      const parse = this.parseExpression(false);
11060      this.expect("}");
11061      this.nextToken = oldToken;
11062      return parse;
11063    }
11064    /**
11065       * Parses an "expression", which is a list of atoms.
11066       *
11067       * `breakOnInfix`: Should the parsing stop when we hit infix nodes? This
11068       *                 happens when functions have higher precedence han infix
11069       *                 nodes in implicit parses.
11070       *
11071       * `breakOnTokenText`: The text of the token that the expression should end
11072       *                     with, or `null` if something else should end the
11073       *                     expression.
11074       *
11075       * `breakOnMiddle`: \color, \over, and old styling functions work on an implicit group.
11076       *                  These groups end just before the usual tokens, but they also
11077       *                  end just before `\middle`.
11078       */
11079    parseExpression(breakOnInfix, breakOnTokenText, breakOnMiddle) {
11080      const body = [];
11081      this.prevAtomType = "";
11082      while (true) {
11083        if (this.mode === "math") {
11084          this.consumeSpaces();
11085        }
11086        const lex = this.fetch();
11087        if (_Parser.endOfExpression.indexOf(lex.text) !== -1) {
11088          break;
11089        }
11090        if (breakOnTokenText && lex.text === breakOnTokenText) {
11091          break;
11092        }
11093        if (breakOnMiddle && lex.text === "\\middle") {
11094          break;
11095        }
11096        if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) {
11097          break;
11098        }
11099        const atom = this.parseAtom(breakOnTokenText);
11100        if (!atom) {
11101          break;
11102        } else if (atom.type === "internal") {
11103          continue;
11104        }
11105        body.push(atom);
11106        this.prevAtomType = atom.type === "atom" ? atom.family : atom.type;
11107      }
11108      if (this.mode === "text") {
11109        this.formLigatures(body);
11110      }
11111      return this.handleInfixNodes(body);
11112    }
11113    /**
11114     * Rewrites infix operators such as \over with corresponding commands such
11115     * as \frac.
11116     *
11117     * There can only be one infix operator per group.  If there's more than one
11118     * then the expression is ambiguous.  This can be resolved by adding {}.
11119     */
11120    handleInfixNodes(body) {
11121      let overIndex = -1;
11122      let funcName;
11123      for (let i = 0; i < body.length; i++) {
11124        if (body[i].type === "infix") {
11125          if (overIndex !== -1) {
11126            throw new ParseError("only one infix operator per group", body[i].token);
11127          }
11128          overIndex = i;
11129          funcName = body[i].replaceWith;
11130        }
11131      }
11132      if (overIndex !== -1 && funcName) {
11133        let numerNode;
11134        let denomNode;
11135        const numerBody = body.slice(0, overIndex);
11136        const denomBody = body.slice(overIndex + 1);
11137        if (numerBody.length === 1 && numerBody[0].type === "ordgroup") {
11138          numerNode = numerBody[0];
11139        } else {
11140          numerNode = { type: "ordgroup", mode: this.mode, body: numerBody };
11141        }
11142        if (denomBody.length === 1 && denomBody[0].type === "ordgroup") {
11143          denomNode = denomBody[0];
11144        } else {
11145          denomNode = { type: "ordgroup", mode: this.mode, body: denomBody };
11146        }
11147        let node;
11148        if (funcName === "\\\\abovefrac") {
11149          node = this.callFunction(funcName, [numerNode, body[overIndex], denomNode], []);
11150        } else {
11151          node = this.callFunction(funcName, [numerNode, denomNode], []);
11152        }
11153        return [node];
11154      } else {
11155        return body;
11156      }
11157    }
11158    /**
11159     * Handle a subscript or superscript with nice errors.
11160     */
11161    handleSupSubscript(name) {
11162      const symbolToken = this.fetch();
11163      const symbol = symbolToken.text;
11164      this.consume();
11165      this.consumeSpaces();
11166      const group = this.parseGroup(name);
11167      if (!group) {
11168        throw new ParseError("Expected group after '" + symbol + "'", symbolToken);
11169      }
11170      return group;
11171    }
11172    /**
11173     * Converts the textual input of an unsupported command into a text node
11174     * contained within a color node whose color is determined by errorColor
11175     */
11176    formatUnsupportedCmd(text2) {
11177      const textordArray = [];
11178      for (let i = 0; i < text2.length; i++) {
11179        textordArray.push({ type: "textord", mode: "text", text: text2[i] });
11180      }
11181      const textNode = {
11182        type: "text",
11183        mode: this.mode,
11184        body: textordArray
11185      };
11186      const colorNode = {
11187        type: "color",
11188        mode: this.mode,
11189        color: this.settings.errorColor,
11190        body: [textNode]
11191      };
11192      return colorNode;
11193    }
11194    /**
11195     * Parses a group with optional super/subscripts.
11196     */
11197    parseAtom(breakOnTokenText) {
11198      const base = this.parseGroup("atom", breakOnTokenText);
11199      if (this.mode === "text") {
11200        return base;
11201      }
11202      let superscript;
11203      let subscript;
11204      while (true) {
11205        this.consumeSpaces();
11206        const lex = this.fetch();
11207        if (lex.text === "\\limits" || lex.text === "\\nolimits") {
11208          if (base && base.type === "op") {
11209            const limits = lex.text === "\\limits";
11210            base.limits = limits;
11211            base.alwaysHandleSupSub = true;
11212          } else if (base && base.type === "operatorname") {
11213            if (base.alwaysHandleSupSub) {
11214              base.limits = lex.text === "\\limits";
11215            }
11216          } else {
11217            throw new ParseError("Limit controls must follow a math operator", lex);
11218          }
11219          this.consume();
11220        } else if (lex.text === "^") {
11221          if (superscript) {
11222            throw new ParseError("Double superscript", lex);
11223          }
11224          superscript = this.handleSupSubscript("superscript");
11225        } else if (lex.text === "_") {
11226          if (subscript) {
11227            throw new ParseError("Double subscript", lex);
11228          }
11229          subscript = this.handleSupSubscript("subscript");
11230        } else if (lex.text === "'") {
11231          if (superscript) {
11232            throw new ParseError("Double superscript", lex);
11233          }
11234          const prime = { type: "textord", mode: this.mode, text: "\\prime" };
11235          const primes2 = [prime];
11236          this.consume();
11237          while (this.fetch().text === "'") {
11238            primes2.push(prime);
11239            this.consume();
11240          }
11241          if (this.fetch().text === "^") {
11242            primes2.push(this.handleSupSubscript("superscript"));
11243          }
11244          superscript = { type: "ordgroup", mode: this.mode, body: primes2 };
11245        } else if (uSubsAndSups[lex.text]) {
11246          const isSub = unicodeSubRegEx.test(lex.text);
11247          const subsupTokens = [];
11248          subsupTokens.push(new Token(uSubsAndSups[lex.text]));
11249          this.consume();
11250          while (true) {
11251            const token = this.fetch().text;
11252            if (!uSubsAndSups[token]) {
11253              break;
11254            }
11255            if (unicodeSubRegEx.test(token) !== isSub) {
11256              break;
11257            }
11258            subsupTokens.unshift(new Token(uSubsAndSups[token]));
11259            this.consume();
11260          }
11261          const body = this.subparse(subsupTokens);
11262          if (isSub) {
11263            subscript = { type: "ordgroup", mode: "math", body };
11264          } else {
11265            superscript = { type: "ordgroup", mode: "math", body };
11266          }
11267        } else {
11268          break;
11269        }
11270      }
11271      if (superscript || subscript) {
11272        if (base && base.type === "multiscript" && !base.postscripts) {
11273          base.postscripts = { sup: superscript, sub: subscript };
11274          return base;
11275        } else {
11276          const isFollowedByDelimiter = !base || base.type !== "op" && base.type !== "operatorname" ? void 0 : isDelimiter(this.nextToken.text);
11277          return {
11278            type: "supsub",
11279            mode: this.mode,
11280            base,
11281            sup: superscript,
11282            sub: subscript,
11283            isFollowedByDelimiter
11284          };
11285        }
11286      } else {
11287        return base;
11288      }
11289    }
11290    /**
11291     * Parses an entire function, including its base and all of its arguments.
11292     */
11293    parseFunction(breakOnTokenText, name) {
11294      const token = this.fetch();
11295      const func = token.text;
11296      const funcData = functions[func];
11297      if (!funcData) {
11298        return null;
11299      }
11300      this.consume();
11301      if (name && name !== "atom" && !funcData.allowedInArgument) {
11302        throw new ParseError(
11303          "Got function '" + func + "' with no arguments" + (name ? " as " + name : ""),
11304          token
11305        );
11306      } else if (this.mode === "text" && !funcData.allowedInText) {
11307        throw new ParseError("Can't use function '" + func + "' in text mode", token);
11308      } else if (this.mode === "math" && funcData.allowedInMath === false) {
11309        throw new ParseError("Can't use function '" + func + "' in math mode", token);
11310      }
11311      const prevAtomType = this.prevAtomType;
11312      const { args, optArgs } = this.parseArguments(func, funcData);
11313      this.prevAtomType = prevAtomType;
11314      return this.callFunction(func, args, optArgs, token, breakOnTokenText);
11315    }
11316    /**
11317     * Call a function handler with a suitable context and arguments.
11318     */
11319    callFunction(name, args, optArgs, token, breakOnTokenText) {
11320      const context = {
11321        funcName: name,
11322        parser: this,
11323        token,
11324        breakOnTokenText
11325      };
11326      const func = functions[name];
11327      if (func && func.handler) {
11328        return func.handler(context, args, optArgs);
11329      } else {
11330        throw new ParseError(`No function handler for $name}`);
11331      }
11332    }
11333    /**
11334     * Parses the arguments of a function or environment
11335     */
11336    parseArguments(func, funcData) {
11337      const totalArgs = funcData.numArgs + funcData.numOptionalArgs;
11338      if (totalArgs === 0) {
11339        return { args: [], optArgs: [] };
11340      }
11341      const args = [];
11342      const optArgs = [];
11343      for (let i = 0; i < totalArgs; i++) {
11344        let argType = funcData.argTypes && funcData.argTypes[i];
11345        const isOptional = i < funcData.numOptionalArgs;
11346        if (funcData.primitive && argType == null || // \sqrt expands into primitive if optional argument doesn't exist
11347        funcData.type === "sqrt" && i === 1 && optArgs[0] == null) {
11348          argType = "primitive";
11349        }
11350        const arg = this.parseGroupOfType(`argument to '$func}'`, argType, isOptional);
11351        if (isOptional) {
11352          optArgs.push(arg);
11353        } else if (arg != null) {
11354          args.push(arg);
11355        } else {
11356          throw new ParseError("Null argument, please report this as a bug");
11357        }
11358      }
11359      return { args, optArgs };
11360    }
11361    /**
11362     * Parses a group when the mode is changing.
11363     */
11364    parseGroupOfType(name, type, optional) {
11365      switch (type) {
11366        case "size":
11367          return this.parseSizeGroup(optional);
11368        case "url":
11369          return this.parseUrlGroup(optional);
11370        case "math":
11371        case "text":
11372          return this.parseArgumentGroup(optional, type);
11373        case "hbox": {
11374          const group = this.parseArgumentGroup(optional, "text");
11375          return group != null ? {
11376            type: "styling",
11377            mode: group.mode,
11378            body: [group],
11379            scriptLevel: "text"
11380            // simulate \textstyle
11381          } : null;
11382        }
11383        case "raw": {
11384          const token = this.parseStringGroup("raw", optional);
11385          return token != null ? {
11386            type: "raw",
11387            mode: "text",
11388            string: token.text
11389          } : null;
11390        }
11391        case "primitive": {
11392          if (optional) {
11393            throw new ParseError("A primitive argument cannot be optional");
11394          }
11395          const group = this.parseGroup(name);
11396          if (group == null) {
11397            throw new ParseError("Expected group as " + name, this.fetch());
11398          }
11399          return group;
11400        }
11401        case "original":
11402        case null:
11403        case void 0:
11404          return this.parseArgumentGroup(optional);
11405        default:
11406          throw new ParseError("Unknown group type as " + name, this.fetch());
11407      }
11408    }
11409    /**
11410     * Discard any space tokens, fetching the next non-space token.
11411     */
11412    consumeSpaces() {
11413      while (true) {
11414        const ch = this.fetch().text;
11415        if (ch === " " || ch === "\xA0" || ch === "\uFE0E") {
11416          this.consume();
11417        } else {
11418          break;
11419        }
11420      }
11421    }
11422    /**
11423     * Parses a group, essentially returning the string formed by the
11424     * brace-enclosed tokens plus some position information.
11425     */
11426    parseStringGroup(modeName, optional) {
11427      const argToken = this.gullet.scanArgument(optional);
11428      if (argToken == null) {
11429        return null;
11430      }
11431      let str = "";
11432      let nextToken;
11433      while ((nextToken = this.fetch()).text !== "EOF") {
11434        str += nextToken.text;
11435        this.consume();
11436      }
11437      this.consume();
11438      argToken.text = str;
11439      return argToken;
11440    }
11441    /**
11442     * Parses a regex-delimited group: the largest sequence of tokens
11443     * whose concatenated strings match `regex`. Returns the string
11444     * formed by the tokens plus some position information.
11445     */
11446    parseRegexGroup(regex, modeName) {
11447      const firstToken = this.fetch();
11448      let lastToken = firstToken;
11449      let str = "";
11450      let nextToken;
11451      while ((nextToken = this.fetch()).text !== "EOF" && regex.test(str + nextToken.text)) {
11452        lastToken = nextToken;
11453        str += lastToken.text;
11454        this.consume();
11455      }
11456      if (str === "") {
11457        throw new ParseError("Invalid " + modeName + ": '" + firstToken.text + "'", firstToken);
11458      }
11459      return firstToken.range(lastToken, str);
11460    }
11461    /**
11462     * Parses a size specification, consisting of magnitude and unit.
11463     */
11464    parseSizeGroup(optional) {
11465      let res;
11466      let isBlank = false;
11467      this.gullet.consumeSpaces();
11468      if (!optional && this.gullet.future().text !== "{") {
11469        res = this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/, "size");
11470      } else {
11471        res = this.parseStringGroup("size", optional);
11472      }
11473      if (!res) {
11474        return null;
11475      }
11476      if (!optional && res.text.length === 0) {
11477        res.text = "0pt";
11478        isBlank = true;
11479      }
11480      const match = sizeRegEx.exec(res.text);
11481      if (!match) {
11482        throw new ParseError("Invalid size: '" + res.text + "'", res);
11483      }
11484      const data = {
11485        number: +(match[1] + match[2]),
11486        // sign + magnitude, cast to number
11487        unit: match[3]
11488      };
11489      if (!validUnit(data)) {
11490        throw new ParseError("Invalid unit: '" + data.unit + "'", res);
11491      }
11492      return {
11493        type: "size",
11494        mode: this.mode,
11495        value: data,
11496        isBlank
11497      };
11498    }
11499    /**
11500     * Parses an URL, checking escaped letters and allowed protocols,
11501     * and setting the catcode of % as an active character (as in \hyperref).
11502     */
11503    parseUrlGroup(optional) {
11504      this.gullet.lexer.setCatcode("%", 13);
11505      this.gullet.lexer.setCatcode("~", 12);
11506      const res = this.parseStringGroup("url", optional);
11507      this.gullet.lexer.setCatcode("%", 14);
11508      this.gullet.lexer.setCatcode("~", 13);
11509      if (res == null) {
11510        return null;
11511      }
11512      let url = res.text.replace(/\\([#$%&~_^{}])/g, "$1");
11513      url = res.text.replace(/{\u2044}/g, "/");
11514      return {
11515        type: "url",
11516        mode: this.mode,
11517        url
11518      };
11519    }
11520    /**
11521     * Parses an argument with the mode specified.
11522     */
11523    parseArgumentGroup(optional, mode) {
11524      const argToken = this.gullet.scanArgument(optional);
11525      if (argToken == null) {
11526        return null;
11527      }
11528      const outerMode = this.mode;
11529      if (mode) {
11530        this.switchMode(mode);
11531      }
11532      this.gullet.beginGroup();
11533      const expression = this.parseExpression(false, "EOF");
11534      this.expect("EOF");
11535      this.gullet.endGroup();
11536      const result = {
11537        type: "ordgroup",
11538        mode: this.mode,
11539        loc: argToken.loc,
11540        body: expression
11541      };
11542      if (mode) {
11543        this.switchMode(outerMode);
11544      }
11545      return result;
11546    }
11547    /**
11548     * Parses an ordinary group, which is either a single nucleus (like "x")
11549     * or an expression in braces (like "{x+y}") or an implicit group, a group
11550     * that starts at the current position, and ends right before a higher explicit
11551     * group ends, or at EOF.
11552     */
11553    parseGroup(name, breakOnTokenText) {
11554      const firstToken = this.fetch();
11555      const text2 = firstToken.text;
11556      let result;
11557      if (text2 === "{" || text2 === "\\begingroup" || text2 === "\\toggle") {
11558        this.consume();
11559        const groupEnd = text2 === "{" ? "}" : text2 === "\\begingroup" ? "\\endgroup" : "\\endtoggle";
11560        this.gullet.beginGroup();
11561        const expression = this.parseExpression(false, groupEnd);
11562        const lastToken = this.fetch();
11563        this.expect(groupEnd);
11564        this.gullet.endGroup();
11565        result = {
11566          type: lastToken.text === "\\endtoggle" ? "toggle" : "ordgroup",
11567          mode: this.mode,
11568          loc: SourceLocation.range(firstToken, lastToken),
11569          body: expression,
11570          // A group formed by \begingroup...\endgroup is a semi-simple group
11571          // which doesn't affect spacing in math mode, i.e., is transparent.
11572          // https://tex.stackexchange.com/questions/1930/
11573          semisimple: text2 === "\\begingroup" || void 0
11574        };
11575      } else {
11576        result = this.parseFunction(breakOnTokenText, name) || this.parseSymbol();
11577        if (result == null && text2[0] === "\\" && !Object.prototype.hasOwnProperty.call(implicitCommands, text2)) {
11578          result = this.formatUnsupportedCmd(text2);
11579          this.consume();
11580        }
11581      }
11582      return result;
11583    }
11584    /**
11585     * Form ligature-like combinations of characters for text mode.
11586     * This includes inputs like "--", "---", "``" and "''".
11587     * The result will simply replace multiple textord nodes with a single
11588     * character in each value by a single textord node having multiple
11589     * characters in its value.  The representation is still ASCII source.
11590     * The group will be modified in place.
11591     */
11592    formLigatures(group) {
11593      let n = group.length - 1;
11594      for (let i = 0; i < n; ++i) {
11595        const a = group[i];
11596        const v = a.text;
11597        if (v === "-" && group[i + 1].text === "-") {
11598          if (i + 1 < n && group[i + 2].text === "-") {
11599            group.splice(i, 3, {
11600              type: "textord",
11601              mode: "text",
11602              loc: SourceLocation.range(a, group[i + 2]),
11603              text: "---"
11604            });
11605            n -= 2;
11606          } else {
11607            group.splice(i, 2, {
11608              type: "textord",
11609              mode: "text",
11610              loc: SourceLocation.range(a, group[i + 1]),
11611              text: "--"
11612            });
11613            n -= 1;
11614          }
11615        }
11616        if ((v === "'" || v === "`") && group[i + 1].text === v) {
11617          group.splice(i, 2, {
11618            type: "textord",
11619            mode: "text",
11620            loc: SourceLocation.range(a, group[i + 1]),
11621            text: v + v
11622          });
11623          n -= 1;
11624        }
11625      }
11626    }
11627    /**
11628     * Parse a single symbol out of the string. Here, we handle single character
11629     * symbols and special functions like \verb.
11630     */
11631    parseSymbol() {
11632      const nucleus = this.fetch();
11633      let text2 = nucleus.text;
11634      if (/^\\verb[^a-zA-Z]/.test(text2)) {
11635        this.consume();
11636        let arg = text2.slice(5);
11637        const star = arg.charAt(0) === "*";
11638        if (star) {
11639          arg = arg.slice(1);
11640        }
11641        if (arg.length < 2 || arg.charAt(0) !== arg.slice(-1)) {
11642          throw new ParseError(`\\verb assertion failed --
11643                      please report what input caused this bug`);
11644        }
11645        arg = arg.slice(1, -1);
11646        return {
11647          type: "verb",
11648          mode: "text",
11649          body: arg,
11650          star
11651        };
11652      }
11653      if (Object.prototype.hasOwnProperty.call(unicodeSymbols, text2[0]) && this.mode === "math" && !symbols[this.mode][text2[0]]) {
11654        if (this.settings.strict && this.mode === "math") {
11655          throw new ParseError(
11656            `Accented Unicode text character "$text2[0]}" used in math mode`,
11657            nucleus
11658          );
11659        }
11660        text2 = unicodeSymbols[text2[0]] + text2.slice(1);
11661      }
11662      const match = this.mode === "math" ? combiningDiacriticalMarksEndRegex.exec(text2) : null;
11663      if (match) {
11664        text2 = text2.substring(0, match.index);
11665        if (text2 === "i") {
11666          text2 = "\u0131";
11667        } else if (text2 === "j") {
11668          text2 = "\u0237";
11669        }
11670      }
11671      let symbol;
11672      if (symbols[this.mode][text2]) {
11673        let group = symbols[this.mode][text2].group;
11674        if (group === "bin" && binLeftCancellers.includes(this.prevAtomType)) {
11675          group = "open";
11676        }
11677        const loc = SourceLocation.range(nucleus);
11678        let s;
11679        if (Object.prototype.hasOwnProperty.call(ATOMS, group)) {
11680          const family = group;
11681          s = {
11682            type: "atom",
11683            mode: this.mode,
11684            family,
11685            loc,
11686            text: text2
11687          };
11688        } else {
11689          if (asciiFromScript[text2]) {
11690            this.consume();
11691            const nextCode = this.fetch().text.charCodeAt(0);
11692            const font = nextCode === 65025 ? "mathscr" : "mathcal";
11693            if (nextCode === 65024 || nextCode === 65025) {
11694              this.consume();
11695            }
11696            return {
11697              type: "font",
11698              mode: "math",
11699              font,
11700              body: { type: "mathord", mode: "math", loc, text: asciiFromScript[text2] }
11701            };
11702          }
11703          s = {
11704            type: group,
11705            mode: this.mode,
11706            loc,
11707            text: text2
11708          };
11709        }
11710        symbol = s;
11711      } else if (text2.charCodeAt(0) >= 128 || combiningDiacriticalMarksEndRegex.exec(text2)) {
11712        if (this.settings.strict && this.mode === "math") {
11713          throw new ParseError(`Unicode text character "$text2[0]}" used in math mode`, nucleus);
11714        }
11715        symbol = {
11716          type: "textord",
11717          mode: "text",
11718          loc: SourceLocation.range(nucleus),
11719          text: text2
11720        };
11721      } else {
11722        return null;
11723      }
11724      this.consume();
11725      if (match) {
11726        for (let i = 0; i < match[0].length; i++) {
11727          const accent2 = match[0][i];
11728          if (!unicodeAccents[accent2]) {
11729            throw new ParseError(`Unknown accent ' $accent2}'`, nucleus);
11730          }
11731          const command = unicodeAccents[accent2][this.mode] || unicodeAccents[accent2].text;
11732          if (!command) {
11733            throw new ParseError(`Accent $accent2} unsupported in $this.mode} mode`, nucleus);
11734          }
11735          symbol = {
11736            type: "accent",
11737            mode: this.mode,
11738            loc: SourceLocation.range(nucleus),
11739            label: command,
11740            isStretchy: false,
11741            base: symbol
11742          };
11743        }
11744      }
11745      return symbol;
11746    }
11747  };
11748  var parseTree = function(toParse, settings) {
11749    if (!(typeof toParse === "string" || toParse instanceof String)) {
11750      throw new TypeError("Temml can only parse string typed expression");
11751    }
11752    const parser = new Parser(toParse, settings);
11753    delete parser.gullet.macros.current["\\df@tag"];
11754    let tree = parser.parse();
11755    if (!(tree.length > 0 && tree[0].type && tree[0].type === "array" && tree[0].addEqnNum)) {
11756      if (parser.gullet.macros.get("\\df@tag")) {
11757        if (!settings.displayMode) {
11758          throw new ParseError("\\tag works only in display mode");
11759        }
11760        parser.gullet.feed("\\df@tag");
11761        tree = [
11762          {
11763            type: "tag",
11764            mode: "text",
11765            body: tree,
11766            tag: parser.parse()
11767          }
11768        ];
11769      }
11770    }
11771    return tree;
11772  };
11773  var subOrSupLevel = [2, 2, 3, 3];
11774  var Style = class _Style {
11775    constructor(data) {
11776      this.level = data.level;
11777      this.color = data.color;
11778      this.font = data.font || "";
11779      this.fontFamily = data.fontFamily || "";
11780      this.fontSize = data.fontSize || 1;
11781      this.fontWeight = data.fontWeight || "";
11782      this.fontShape = data.fontShape || "";
11783      this.maxSize = data.maxSize;
11784    }
11785    /**
11786     * Returns a new style object with the same properties as "this".  Properties
11787     * from "extension" will be copied to the new style object.
11788     */
11789    extend(extension) {
11790      const data = {
11791        level: this.level,
11792        color: this.color,
11793        font: this.font,
11794        fontFamily: this.fontFamily,
11795        fontSize: this.fontSize,
11796        fontWeight: this.fontWeight,
11797        fontShape: this.fontShape,
11798        maxSize: this.maxSize
11799      };
11800      for (const key in extension) {
11801        if (Object.prototype.hasOwnProperty.call(extension, key)) {
11802          data[key] = extension[key];
11803        }
11804      }
11805      return new _Style(data);
11806    }
11807    withLevel(n) {
11808      return this.extend({
11809        level: n
11810      });
11811    }
11812    incrementLevel() {
11813      return this.extend({
11814        level: Math.min(this.level + 1, 3)
11815      });
11816    }
11817    inSubOrSup() {
11818      return this.extend({
11819        level: subOrSupLevel[this.level]
11820      });
11821    }
11822    /**
11823     * Create a new style object with the given color.
11824     */
11825    withColor(color) {
11826      return this.extend({
11827        color
11828      });
11829    }
11830    /**
11831     * Creates a new style object with the given math font or old text font.
11832     * @type {[type]}
11833     */
11834    withFont(font) {
11835      return this.extend({
11836        font
11837      });
11838    }
11839    /**
11840     * Create a new style objects with the given fontFamily.
11841     */
11842    withTextFontFamily(fontFamily) {
11843      return this.extend({
11844        fontFamily,
11845        font: ""
11846      });
11847    }
11848    /**
11849     * Creates a new style object with the given font size
11850     */
11851    withFontSize(num) {
11852      return this.extend({
11853        fontSize: num
11854      });
11855    }
11856    /**
11857     * Creates a new style object with the given font weight
11858     */
11859    withTextFontWeight(fontWeight) {
11860      return this.extend({
11861        fontWeight,
11862        font: ""
11863      });
11864    }
11865    /**
11866     * Creates a new style object with the given font weight
11867     */
11868    withTextFontShape(fontShape) {
11869      return this.extend({
11870        fontShape,
11871        font: ""
11872      });
11873    }
11874    /**
11875     * Gets the CSS color of the current style object
11876     */
11877    getColor() {
11878      return this.color;
11879    }
11880  };
11881  var version = "0.10.34";
11882  function postProcess(block) {
11883    const labelMap = {};
11884    let i = 0;
11885    const amsEqns = document.getElementsByClassName("tml-eqn");
11886    for (let parent of amsEqns) {
11887      i += 1;
11888      parent.setAttribute("id", "tml-eqn-" + String(i));
11889      while (true) {
11890        if (parent.tagName === "mtable") {
11891          break;
11892        }
11893        const labels = parent.getElementsByClassName("tml-label");
11894        if (labels.length > 0) {
11895          const id = parent.attributes.id.value;
11896          labelMap[id] = String(i);
11897          break;
11898        } else {
11899          parent = parent.parentElement;
11900        }
11901      }
11902    }
11903    const taggedEqns = document.getElementsByClassName("tml-tageqn");
11904    for (const parent of taggedEqns) {
11905      const labels = parent.getElementsByClassName("tml-label");
11906      if (labels.length > 0) {
11907        const tags = parent.getElementsByClassName("tml-tag");
11908        if (tags.length > 0) {
11909          const id = parent.attributes.id.value;
11910          labelMap[id] = tags[0].textContent;
11911        }
11912      }
11913    }
11914    const refs = block.getElementsByClassName("tml-ref");
11915    [...refs].forEach((ref) => {
11916      const attr = ref.getAttribute("href");
11917      let str = labelMap[attr.slice(1)];
11918      if (ref.className.indexOf("tml-eqref") === -1) {
11919        str = str.replace(/^\(/, "");
11920        str = str.replace(/\)$/, "");
11921      } else {
11922        if (str.charAt(0) !== "(") {
11923          str = "(" + str;
11924        }
11925        if (str.slice(-1) !== ")") {
11926          str = str + ")";
11927        }
11928      }
11929      const mtext = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mtext");
11930      mtext.appendChild(document.createTextNode(str));
11931      const math2 = document.createElementNS("http://www.w3.org/1998/Math/MathML", "math");
11932      math2.appendChild(mtext);
11933      ref.appendChild(math2);
11934    });
11935  }
11936  var render = function(expression, baseNode, options = {}) {
11937    baseNode.textContent = "";
11938    const alreadyInMathElement = baseNode.tagName.toLowerCase() === "math";
11939    if (alreadyInMathElement) {
11940      options.wrap = "none";
11941    }
11942    const math2 = renderToMathMLTree(expression, options);
11943    if (alreadyInMathElement) {
11944      baseNode.textContent = "";
11945      math2.children.forEach((e) => {
11946        baseNode.appendChild(e.toNode());
11947      });
11948    } else if (math2.children.length > 1) {
11949      baseNode.textContent = "";
11950      math2.children.forEach((e) => {
11951        baseNode.appendChild(e.toNode());
11952      });
11953    } else {
11954      baseNode.appendChild(math2.toNode());
11955    }
11956  };
11957  if (typeof document !== "undefined") {
11958    if (document.compatMode !== "CSS1Compat") {
11959      typeof console !== "undefined" && console.warn(
11960        "Warning: Temml doesn't work in quirks mode. Make sure your website has a suitable doctype."
11961      );
11962      render = function() {
11963        throw new ParseError("Temml doesn't work in quirks mode.");
11964      };
11965    }
11966  }
11967  var renderToString = function(expression, options) {
11968    const markup = renderToMathMLTree(expression, options).toMarkup();
11969    return markup;
11970  };
11971  var generateParseTree = function(expression, options) {
11972    const settings = new Settings(options);
11973    return parseTree(expression, settings);
11974  };
11975  var definePreamble = function(expression, options) {
11976    const settings = new Settings(options);
11977    settings.macros = {};
11978    if (!(typeof expression === "string" || expression instanceof String)) {
11979      throw new TypeError("Temml can only parse string typed expression");
11980    }
11981    const parser = new Parser(expression, settings, true);
11982    delete parser.gullet.macros.current["\\df@tag"];
11983    const macros2 = parser.parse();
11984    return macros2;
11985  };
11986  var renderError = function(error, expression, options) {
11987    if (options.throwOnError || !(error instanceof ParseError)) {
11988      throw error;
11989    }
11990    const node = new Span(["temml-error"], [new TextNode$1(expression + "\n" + error.toString())]);
11991    node.style.color = options.errorColor;
11992    node.style.whiteSpace = "pre-line";
11993    return node;
11994  };
11995  var renderToMathMLTree = function(expression, options) {
11996    const settings = new Settings(options);
11997    try {
11998      const tree = parseTree(expression, settings);
11999      const style = new Style({
12000        level: settings.displayMode ? StyleLevel.DISPLAY : StyleLevel.TEXT,
12001        maxSize: settings.maxSize
12002      });
12003      return buildMathML(tree, expression, style, settings);
12004    } catch (error) {
12005      return renderError(error, expression, settings);
12006    }
12007  };
12008  var temml = {
12009    /**
12010     * Current Temml version
12011     */
12012    version,
12013    /**
12014     * Renders the given LaTeX into MathML, and adds
12015     * it as a child to the specified DOM node.
12016     */
12017    render,
12018    /**
12019     * Renders the given LaTeX into MathML string,
12020     * for sending to the client.
12021     */
12022    renderToString,
12023    /**
12024     * Post-process an entire HTML block.
12025     * Writes AMS auto-numbers and implements \ref{}.
12026     * Typcally called once, after a loop has rendered many individual spans.
12027     */
12028    postProcess,
12029    /**
12030     * Temml error, usually during parsing.
12031     */
12032    ParseError,
12033    /**
12034     * Creates a set of macros with document-wide scope.
12035     */
12036    definePreamble,
12037    /**
12038     * Parses the given LaTeX into Temml's internal parse tree structure,
12039     * without rendering to HTML or MathML.
12040     *
12041     * NOTE: This method is not currently recommended for public use.
12042     * The internal tree representation is unstable and is very likely
12043     * to change. Use at your own risk.
12044     */
12045    __parse: generateParseTree,
12046    /**
12047     * Renders the given LaTeX into a MathML internal DOM tree
12048     * representation, without flattening that representation to a string.
12049     *
12050     * NOTE: This method is not currently recommended for public use.
12051     * The internal tree representation is unstable and is very likely
12052     * to change. Use at your own risk.
12053     */
12054    __renderToMathMLTree: renderToMathMLTree,
12055    /**
12056     * adds a new symbol to builtin symbols table
12057     */
12058    __defineSymbol: defineSymbol,
12059    /**
12060     * adds a new macro to builtin macro list
12061     */
12062    __defineMacro: defineMacro
12063  };
12064  
12065  // packages/latex-to-mathml/build-module/index.js
12066  function latexToMathML(latex, { displayMode = true } = {}) {
12067    const mathML = temml.renderToString(latex, {
12068      displayMode,
12069      annotate: true,
12070      throwOnError: true
12071    });
12072    const doc = document.implementation.createHTMLDocument("");
12073    doc.body.innerHTML = mathML;
12074    return doc.body.querySelector("math")?.innerHTML ?? "";
12075  }
12076  export {
12077    latexToMathML as default
12078  };


Generated : Wed Apr 15 08:20:10 2026 Cross-referenced by PHPXref