PageSourceSearch

https://longchuc.vercel.app/_next/static/chunks/175675d1.899832eaabee9476.js

js longchuc.vercel.app collected 2026-10-03 07:15:18 UTC 609,902 bytes, 18,549 lines download raw bytes

vendor: 5,509 bytes, lines 1-183
1"use strict";
2(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([[1265],{
3
4/***/ 1008:
5/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
6
7/* harmony export */ __webpack_require__.d(__webpack_exports__, {
8/* harmony export */   "ZP": function() { return /* binding */ katex; }
9/* harmony export */ });
10/* unused harmony exports ParseError, SETTINGS_SCHEMA, __defineFunction, __defineMacro, __defineSymbol, __domTree, __parse, __renderToDomTree, __renderToHTMLTree, __setFontMetrics, render, renderToString, version */
11/**
12 * Lexing or parsing positional information for error reporting.
13 * This object is immutable.
14 */
15class SourceLocation {
16  // The + prefix indicates that these fields aren't writeable
17  // Lexer holding the input string.
18  // Start offset, zero-based inclusive.
19  // End offset, zero-based exclusive.
20  constructor(lexer, start, end) {
21    this.lexer = void 0;
22    this.start = void 0;
23    this.end = void 0;
24    this.lexer = lexer;
25    this.start = start;
26    this.end = end;
27  }
28  /**
29   * Merges two `SourceLocation`s from location providers, given they are
30   * provided in order of appearance.
31   * - Returns the first one's location if only the first is provided.
32   * - Returns a merged range of the first and the last if both are provided
33   *   and their lexers match.
34   * - Otherwise, returns null.
35   */
36
37
38  static range(first, second) {
39    if (!second) {
40      return first && first.loc;
41    } else if (!first || !first.loc || !second.loc || first.loc.lexer !== second.loc.lexer) {
42      return null;
43    } else {
44      return new SourceLocation(first.loc.lexer, first.loc.start, second.loc.end);
45    }
46  }
47
48}
49
50/**
51 * Interface required to break circular dependency between Token, Lexer, and
52 * ParseError.
53 */
54
55/**
56 * The resulting token returned from `lex`.
57 *
58 * It consists of the token text plus some position information.
59 * The position information is essentially a range in an input string,
60 * but instead of referencing the bare input string, we refer to the lexer.
61 * That way it is possible to attach extra metadata to the input string,
62 * like for example a file name or similar.
63 *
64 * The position information is optional, so it is OK to construct synthetic
65 * tokens if appropriate. Not providing available position information may
66 * lead to degraded error reporting, though.
67 */
68class Token {
69  // don't expand the token
70  // used in \noexpand
71  constructor(text, // the text of this token
72  loc) {
73    this.text = void 0;
74    this.loc = void 0;
75    this.noexpand = void 0;
76    this.treatAsRelax = void 0;
77    this.text = text;
78    this.loc = loc;
79  }
80  /**
81   * Given a pair of tokens (this and endToken), compute a `Token` encompassing
82   * the whole input range enclosed by these two.
83   */
84
85
86  range(endToken, // last token of the range, inclusive
87  text // the text of the newly constructed token
88  ) {
89    return new Token(text, SourceLocation.range(this, endToken));
90  }
91
92}
93
94/**
95 * This is the ParseError class, which is the main error thrown by KaTeX
96 * functions when something has gone wrong. This is used to distinguish internal
97 * errors from errors in the expression that the user provided.
98 *
99 * If possible, a caller should provide a Token or ParseNode with information
100 * about where in the source string the problem occurred.
101 */
102class ParseError {
103  // Error start position based on passed-in Token or ParseNode.
104  // Length of affected text based on passed-in Token or ParseNode.
105  // The underlying error message without any context added.
106  constructor(message, // The error message
107  token // An object providing position information
108  ) {
109    this.name = void 0;
110    this.position = void 0;
111    this.length = void 0;
112    this.rawMessage = void 0;
113    var error = "KaTeX parse error: " + message;
114    var start;
115    var end;
116    var loc = token && token.loc;
117
118    if (loc && loc.start <= loc.end) {
119      // If we have the input and a position, make the error a bit fancier
120      // Get the input
121      var input = loc.lexer.input; // Prepend some information
122
123      start = loc.start;
124      end = loc.end;
125
126      if (start === input.length) {
127        error += " at end of input: ";
128      } else {
129        error += " at position " + (start + 1) + ": ";
130      } // Underline token in question using combining underscores
131
132
133      var underlined = input.slice(start, end).replace(/[^]/g, "$&\u0332"); // Extract some context from the input and add it to the error
134
135      var left;
136
137      if (start > 15) {
138        left = "…" + input.slice(start - 15, start);
139      } else {
140        left = input.slice(0, start);
141      }
142
143      var right;
144
145      if (end + 15 < input.length) {
146        right = input.slice(end, end + 15) + "…";
147      } else {
148        right = input.slice(end);
149      }
150
151      error += left + underlined + right;
152    } // Some hackery to make ParseError a prototype of Error
153    // See http://stackoverflow.com/a/8460753
154    // $FlowFixMe
155
156
157    var self = new Error(error);
158    self.name = "ParseError"; // $FlowFixMe
159
160    self.__proto__ = ParseError.prototype;
161    self.position = start;
162
163    if (start != null && end != null) {
164      self.length = end - start;
165    }
166
167    self.rawMessage = message;
168    return self;
169  }
170
171} // $FlowFixMe More hackery
172
173
174ParseError.prototype.__proto__ = Error.prototype;
175
176/**
177 * This file contains a list of utility functions which are useful in other
178 * files.
179 */
180
181/**
182 * Return whether an element is contained in a list
183 */
184var contains = function contains(list, elem) {
185  return list.indexOf(elem) !== -1;
186};
187/**
188 * Provide a default value if a setting is undefined
189 * NOTE: Couldn't use `T` as the output type due to facebook/flow#5022.
190 */
191
192
193var deflt = function deflt(setting, defaultIfUndefined) {
194  return setting === undefined ? defaultIfUndefined : setting;
195}; // hyphenate and escape adapted from Facebook's React under Apache 2 license
196
197
198var uppercase = /([A-Z])/g;
199
200var hyphenate = function hyphenate(str) {
201  return str.replace(uppercase, "-$1").toLowerCase();
202};
203
204var ESCAPE_LOOKUP = {
205  "&": "&amp;",
206  ">": "&gt;",
207  "<": "&lt;",
208  "\"": "&quot;",
209  "'": "&#x27;"
210};
211var ESCAPE_REGEX = /[&><"']/g;
212/**
213 * Escapes text to prevent scripting attacks.
214 */
215
216function escape(text) {
217  return String(text).replace(ESCAPE_REGEX, match => ESCAPE_LOOKUP[match]);
218}
219/**
220 * Sometimes we want to pull out the innermost element of a group. In most
221 * cases, this will just be the group itself, but when ordgroups and colors have
222 * a single element, we want to pull that out.
223 */
224
225
226var getBaseElem = function getBaseElem(group) {
227  if (group.type === "ordgroup") {
228    if (group.body.length === 1) {
229      return getBaseElem(group.body[0]);
230    } else {
231      return group;
232    }
233  } else if (group.type === "color") {
234    if (group.body.length === 1) {
235      return getBaseElem(group.body[0]);
236    } else {
237      return group;
238    }
239  } else if (group.type === "font") {
240    return getBaseElem(group.body);
241  } else {
242    return group;
243  }
244};
245/**
246 * TeXbook algorithms often reference "character boxes", which are simply groups
247 * with a single character in them. To decide if something is a character box,
248 * we find its innermost group, and see if it is a single character.
249 */
250
251
252var isCharacterBox = function isCharacterBox(group) {
253  var baseElem = getBaseElem(group); // These are all they types of groups which hold single characters
254
255  return baseElem.type === "mathord" || baseElem.type === "textord" || baseElem.type === "atom";
256};
257
258var assert = function assert(value) {
259  if (!value) {
260    throw new Error('Expected non-null, but got ' + String(value));
261  }
262
263  return value;
264};
265/**
266 * Return the protocol of a URL, or "_relative" if the URL does not specify a
267 * protocol (and thus is relative), or `null` if URL has invalid protocol
268 * (so should be outright rejected).
269 */
270
271var protocolFromUrl = function protocolFromUrl(url) {
272  // Check for possible leading protocol.
273  // https://url.spec.whatwg.org/#url-parsing strips leading whitespace
274  // (U+20) or C0 control (U+00-U+1F) characters.
275  // eslint-disable-next-line no-control-regex
276  var protocol = /^[\x00-\x20]*([^\\/#?]*?)(:|&#0*58|&#x0*3a|&colon)/i.exec(url);
277
278  if (!protocol) {
279    return "_relative";
280  } // Reject weird colons
281
282
283  if (protocol[2] !== ":") {
284    return null;
285  } // Reject invalid characters in scheme according to
286  // https://datatracker.ietf.org/doc/html/rfc3986#section-3.1
287
288
289  if (!/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(protocol[1])) {
290    return null;
291  } // Lowercase the protocol
292
293
294  return protocol[1].toLowerCase();
295};
296var utils = {
297  contains,
298  deflt,
299  escape,
300  hyphenate,
301  getBaseElem,
302  isCharacterBox,
303  protocolFromUrl
304};
305
306/* eslint no-console:0 */
307// TODO: automatically generate documentation
308// TODO: check all properties on Settings exist
309// TODO: check the type of a property on Settings matches
310var SETTINGS_SCHEMA = {
311  displayMode: {
312    type: "boolean",
313    description: "Render math in display mode, which puts the math in " + "display style (so \\int and \\sum are large, for example), and " + "centers the math on the page on its own line.",
314    cli: "-d, --display-mode"
315  },
316  output: {
317    type: {
318      enum: ["htmlAndMathml", "html", "mathml"]
319    },
320    description: "Determines the markup language of the output.",
321    cli: "-F, --format <type>"
322  },
323  leqno: {
324    type: "boolean",
325    description: "Render display math in leqno style (left-justified tags)."
326  },
327  fleqn: {
328    type: "boolean",
329    description: "Render display math flush left."
330  },
331  throwOnError: {
332    type: "boolean",
333    default: true,
334    cli: "-t, --no-throw-on-error",
335    cliDescription: "Render errors (in the color given by --error-color) ins" + "tead of throwing a ParseError exception when encountering an error."
336  },
337  errorColor: {
338    type: "string",
339    default: "#cc0000",
340    cli: "-c, --error-color <color>",
341    cliDescription: "A color string given in the format 'rgb' or 'rrggbb' " + "(no #). This option determines the color of errors rendered by the " + "-t option.",
342    cliProcessor: color => "#" + color
343  },
344  macros: {
345    type: "object",
346    cli: "-m, --macro <def>",
347    cliDescription: "Define custom macro of the form '\\foo:expansion' (use " + "multiple -m arguments for multiple macros).",
348    cliDefault: [],
349    cliProcessor: (def, defs) => {
350      defs.push(def);
351      return defs;
352    }
353  },
354  minRuleThickness: {
355    type: "number",
356    description: "Specifies a minimum thickness, in ems, for fraction lines," + " `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, " + "`\\hdashline`, `\\underline`, `\\overline`, and the borders of " + "`\\fbox`, `\\boxed`, and `\\fcolorbox`.",
357    processor: t => Math.max(0, t),
358    cli: "--min-rule-thickness <size>",
359    cliProcessor: parseFloat
360  },
361  colorIsTextColor: {
362    type: "boolean",
363    description: "Makes \\color behave like LaTeX's 2-argument \\textcolor, " + "instead of LaTeX's one-argument \\color mode change.",
364    cli: "-b, --color-is-text-color"
365  },
366  strict: {
367    type: [{
368      enum: ["warn", "ignore", "error"]
369    }, "boolean", "function"],
370    description: "Turn on strict / LaTeX faithfulness mode, which throws an " + "error if the input uses features that are not supported by LaTeX.",
371    cli: "-S, --strict",
372    cliDefault: false
373  },
374  trust: {
375    type: ["boolean", "function"],
376    description: "Trust the input, enabling all HTML features such as \\url.",
377    cli: "-T, --trust"
378  },
379  maxSize: {
380    type: "number",
381    default: Infinity,
382    description: "If non-zero, all user-specified sizes, e.g. in " + "\\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, " + "elements and spaces can be arbitrarily large",
383    processor: s => Math.max(0, s),
384    cli: "-s, --max-size <n>",
385    cliProcessor: parseInt
386  },
387  maxExpand: {
388    type: "number",
389    default: 1000,
390    description: "Limit the number of macro expansions to the specified " + "number, to prevent e.g. infinite macro loops. If set to Infinity, " + "the macro expander will try to fully expand as in LaTeX.",
391    processor: n => Math.max(0, n),
392    cli: "-e, --max-expand <n>",
393    cliProcessor: n => n === "Infinity" ? Infinity : parseInt(n)
394  },
395  globalGroup: {
396    type: "boolean",
397    cli: false
398  }
399};
400
401function getDefaultValue(schema) {
402  if (schema.default) {
403    return schema.default;
404  }
405
406  var type = schema.type;
407  var defaultType = Array.isArray(type) ? type[0] : type;
408
409  if (typeof defaultType !== 'string') {
410    return defaultType.enum[0];
411  }
412
413  switch (defaultType) {
414    case 'boolean':
415      return false;
vendor: 4,712 bytes, lines 416-547
416
417    case 'string':
418      return '';
419
420    case 'number':
421      return 0;
422
423    case 'object':
424      return {};
425  }
426}
427/**
428 * The main Settings object
429 *
430 * The current options stored are:
431 *  - displayMode: Whether the expression should be typeset as inline math
432 *                 (false, the default), meaning that the math starts in
433 *                 \textstyle and is placed in an inline-block); or as display
434 *                 math (true), meaning that the math starts in \displaystyle
435 *                 and is placed in a block with vertical margin.
436 */
437
438
439class Settings {
440  constructor(options) {
441    this.displayMode = void 0;
442    this.output = void 0;
443    this.leqno = void 0;
444    this.fleqn = void 0;
445    this.throwOnError = void 0;
446    this.errorColor = void 0;
447    this.macros = void 0;
448    this.minRuleThickness = void 0;
449    this.colorIsTextColor = void 0;
450    this.strict = void 0;
451    this.trust = void 0;
452    this.maxSize = void 0;
453    this.maxExpand = void 0;
454    this.globalGroup = void 0;
455    // allow null options
456    options = options || {};
457
458    for (var prop in SETTINGS_SCHEMA) {
459      if (SETTINGS_SCHEMA.hasOwnProperty(prop)) {
460        // $FlowFixMe
461        var schema = SETTINGS_SCHEMA[prop]; // TODO: validate options
462        // $FlowFixMe
463
464        this[prop] = options[prop] !== undefined ? schema.processor ? schema.processor(options[prop]) : options[prop] : getDefaultValue(schema);
465      }
466    }
467  }
468  /**
469   * Report nonstrict (non-LaTeX-compatible) input.
470   * Can safely not be called if `this.strict` is false in JavaScript.
471   */
472
473
474  reportNonstrict(errorCode, errorMsg, token) {
475    var strict = this.strict;
476
477    if (typeof strict === "function") {
478      // Allow return value of strict function to be boolean or string
479      // (or null/undefined, meaning no further processing).
480      strict = strict(errorCode, errorMsg, token);
481    }
482
483    if (!strict || strict === "ignore") {
484      return;
485    } else if (strict === true || strict === "error") {
486      throw new ParseError("LaTeX-incompatible input and strict mode is set to 'error': " + (errorMsg + " [" + errorCode + "]"), token);
487    } else if (strict === "warn") {
488      typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]"));
489    } else {
490      // won't happen in type-safe code
491      typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]"));
492    }
493  }
494  /**
495   * Check whether to apply strict (LaTeX-adhering) behavior for unusual
496   * input (like `\\`).  Unlike `nonstrict`, will not throw an error;
497   * instead, "error" translates to a return value of `true`, while "ignore"
498   * translates to a return value of `false`.  May still print a warning:
499   * "warn" prints a warning and returns `false`.
500   * This is for the second category of `errorCode`s listed in the README.
501   */
502
503
504  useStrictBehavior(errorCode, errorMsg, token) {
505    var strict = this.strict;
506
507    if (typeof strict === "function") {
508      // Allow return value of strict function to be boolean or string
509      // (or null/undefined, meaning no further processing).
510      // But catch any exceptions thrown by function, treating them
511      // like "error".
512      try {
513        strict = strict(errorCode, errorMsg, token);
514      } catch (error) {
515        strict = "error";
516      }
517    }
518
519    if (!strict || strict === "ignore") {
520      return false;
521    } else if (strict === true || strict === "error") {
522      return true;
523    } else if (strict === "warn") {
524      typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + (errorMsg + " [" + errorCode + "]"));
525      return false;
526    } else {
527      // won't happen in type-safe code
528      typeof console !== "undefined" && console.warn("LaTeX-incompatible input and strict mode is set to " + ("unrecognized '" + strict + "': " + errorMsg + " [" + errorCode + "]"));
529      return false;
530    }
531  }
532  /**
533   * Check whether to test potentially dangerous input, and return
534   * `true` (trusted) or `false` (untrusted).  The sole argument `context`
535   * should be an object with `command` field specifying the relevant LaTeX
536   * command (as a string starting with `\`), and any other arguments, etc.
537   * If `context` has a `url` field, a `protocol` field will automatically
538   * get added by this function (changing the specified object).
539   */
540
541
542  isTrusted(context) {
543    if (context.url && !context.protocol) {
544      var protocol = utils.protocolFromUrl(context.url);
545
546      if (protocol == null) {
547        return false;
vendor: 9,826 bytes, lines 548-822
548      }
549
550      context.protocol = protocol;
551    }
552
553    var trust = typeof this.trust === "function" ? this.trust(context) : this.trust;
554    return Boolean(trust);
555  }
556
557}
558
559/**
560 * This file contains information and classes for the various kinds of styles
561 * used in TeX. It provides a generic `Style` class, which holds information
562 * about a specific style. It then provides instances of all the different kinds
563 * of styles possible, and provides functions to move between them and get
564 * information about them.
565 */
566
567/**
568 * The main style class. Contains a unique id for the style, a size (which is
569 * the same for cramped and uncramped version of a style), and a cramped flag.
570 */
571class Style {
572  constructor(id, size, cramped) {
573    this.id = void 0;
574    this.size = void 0;
575    this.cramped = void 0;
576    this.id = id;
577    this.size = size;
578    this.cramped = cramped;
579  }
580  /**
581   * Get the style of a superscript given a base in the current style.
582   */
583
584
585  sup() {
586    return styles[sup[this.id]];
587  }
588  /**
589   * Get the style of a subscript given a base in the current style.
590   */
591
592
593  sub() {
594    return styles[sub[this.id]];
595  }
596  /**
597   * Get the style of a fraction numerator given the fraction in the current
598   * style.
599   */
600
601
602  fracNum() {
603    return styles[fracNum[this.id]];
604  }
605  /**
606   * Get the style of a fraction denominator given the fraction in the current
607   * style.
608   */
609
610
611  fracDen() {
612    return styles[fracDen[this.id]];
613  }
614  /**
615   * Get the cramped version of a style (in particular, cramping a cramped style
616   * doesn't change the style).
617   */
618
619
620  cramp() {
621    return styles[cramp[this.id]];
622  }
623  /**
624   * Get a text or display version of this style.
625   */
626
627
628  text() {
629    return styles[text$1[this.id]];
630  }
631  /**
632   * Return true if this style is tightly spaced (scriptstyle/scriptscriptstyle)
633   */
634
635
636  isTight() {
637    return this.size >= 2;
638  }
639
640} // Export an interface for type checking, but don't expose the implementation.
641// This way, no more styles can be generated.
642
643
644// IDs of the different styles
645var D = 0;
646var Dc = 1;
647var T = 2;
648var Tc = 3;
649var S = 4;
650var Sc = 5;
651var SS = 6;
652var SSc = 7; // Instances of the different styles
653
654var styles = [new Style(D, 0, false), new Style(Dc, 0, true), new Style(T, 1, false), new Style(Tc, 1, true), new Style(S, 2, false), new Style(Sc, 2, true), new Style(SS, 3, false), new Style(SSc, 3, true)]; // Lookup tables for switching from one style to another
655
656var sup = [S, Sc, S, Sc, SS, SSc, SS, SSc];
657var sub = [Sc, Sc, Sc, Sc, SSc, SSc, SSc, SSc];
658var fracNum = [T, Tc, S, Sc, SS, SSc, SS, SSc];
659var fracDen = [Tc, Tc, Sc, Sc, SSc, SSc, SSc, SSc];
660var cramp = [Dc, Dc, Tc, Tc, Sc, Sc, SSc, SSc];
661var text$1 = [D, Dc, T, Tc, T, Tc, T, Tc]; // We only export some of the styles.
662
663var Style$1 = {
664  DISPLAY: styles[D],
665  TEXT: styles[T],
666  SCRIPT: styles[S],
667  SCRIPTSCRIPT: styles[SS]
668};
669
670/*
671 * This file defines the Unicode scripts and script families that we
672 * support. To add new scripts or families, just add a new entry to the
673 * scriptData array below. Adding scripts to the scriptData array allows
674 * characters from that script to appear in \text{} environments.
675 */
676
677/**
678 * Each script or script family has a name and an array of blocks.
679 * Each block is an array of two numbers which specify the start and
680 * end points (inclusive) of a block of Unicode codepoints.
681 */
682
683/**
684 * Unicode block data for the families of scripts we support in \text{}.
685 * Scripts only need to appear here if they do not have font metrics.
686 */
687var scriptData = [{
688  // Latin characters beyond the Latin-1 characters we have metrics for.
689  // Needed for Czech, Hungarian and Turkish text, for example.
690  name: 'latin',
691  blocks: [[0x0100, 0x024f], // Latin Extended-A and Latin Extended-B
692  [0x0300, 0x036f] // Combining Diacritical marks
693  ]
694}, {
695  // The Cyrillic script used by Russian and related languages.
696  // A Cyrillic subset used to be supported as explicitly defined
697  // symbols in symbols.js
698  name: 'cyrillic',
699  blocks: [[0x0400, 0x04ff]]
700}, {
701  // Armenian
702  name: 'armenian',
703  blocks: [[0x0530, 0x058F]]
704}, {
705  // The Brahmic scripts of South and Southeast Asia
706  // Devanagari (0900–097F)
707  // Bengali (0980–09FF)
708  // Gurmukhi (0A00–0A7F)
709  // Gujarati (0A80–0AFF)
710  // Oriya (0B00–0B7F)
711  // Tamil (0B80–0BFF)
712  // Telugu (0C00–0C7F)
713  // Kannada (0C80–0CFF)
714  // Malayalam (0D00–0D7F)
715  // Sinhala (0D80–0DFF)
716  // Thai (0E00–0E7F)
717  // Lao (0E80–0EFF)
718  // Tibetan (0F00–0FFF)
719  // Myanmar (1000–109F)
720  name: 'brahmic',
721  blocks: [[0x0900, 0x109F]]
722}, {
723  name: 'georgian',
724  blocks: [[0x10A0, 0x10ff]]
725}, {
726  // Chinese and Japanese.
727  // The "k" in cjk is for Korean, but we've separated Korean out
728  name: "cjk",
729  blocks: [[0x3000, 0x30FF], // CJK symbols and punctuation, Hiragana, Katakana
730  [0x4E00, 0x9FAF], // CJK ideograms
731  [0xFF00, 0xFF60] // Fullwidth punctuation
732  // TODO: add halfwidth Katakana and Romanji glyphs
733  ]
734}, {
735  // Korean
736  name: 'hangul',
737  blocks: [[0xAC00, 0xD7AF]]
738}];
739/**
740 * Given a codepoint, return the name of the script or script family
741 * it is from, or null if it is not part of a known block
742 */
743
744function scriptFromCodepoint(codepoint) {
745  for (var i = 0; i < scriptData.length; i++) {
746    var script = scriptData[i];
747
748    for (var _i = 0; _i < script.blocks.length; _i++) {
749      var block = script.blocks[_i];
750
751      if (codepoint >= block[0] && codepoint <= block[1]) {
752        return script.name;
753      }
754    }
755  }
756
757  return null;
758}
759/**
760 * A flattened version of all the supported blocks in a single array.
761 * This is an optimization to make supportedCodepoint() fast.
762 */
763
764var allBlocks = [];
765scriptData.forEach(s => s.blocks.forEach(b => allBlocks.push(...b)));
766/**
767 * Given a codepoint, return true if it falls within one of the
768 * scripts or script families defined above and false otherwise.
769 *
770 * Micro benchmarks shows that this is faster than
771 * /[\u3000-\u30FF\u4E00-\u9FAF\uFF00-\uFF60\uAC00-\uD7AF\u0900-\u109F]/.test()
772 * in Firefox, Chrome and Node.
773 */
774
775function supportedCodepoint(codepoint) {
776  for (var i = 0; i < allBlocks.length; i += 2) {
777    if (codepoint >= allBlocks[i] && codepoint <= allBlocks[i + 1]) {
778      return true;
779    }
780  }
781
782  return false;
783}
784
785/**
786 * This file provides support to domTree.js and delimiter.js.
787 * It's a storehouse of path geometry for SVG images.
788 */
789// In all paths below, the viewBox-to-em scale is 1000:1.
790var hLinePad = 80; // padding above a sqrt vinculum. Prevents image cropping.
791// The vinculum of a \sqrt can be made thicker by a KaTeX rendering option.
792// Think of variable extraVinculum as two detours in the SVG path.
793// The detour begins at the lower left of the area labeled extraVinculum below.
794// The detour proceeds one extraVinculum distance up and slightly to the right,
795// displacing the radiused corner between surd and vinculum. The radius is
796// traversed as usual, then the detour resumes. It goes right, to the end of
797// the very long vinculum, then down one extraVinculum distance,
798// after which it resumes regular path geometry for the radical.
799
800/*                                                  vinculum
801                                                   /
802         /▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒←extraVinculum
803        / █████████████████████←0.04em (40 unit) std vinculum thickness
804       / /
805      / /
806     / /\
807    / / surd
808*/
809
810var sqrtMain = function sqrtMain(extraVinculum, hLinePad) {
811  // sqrtMain path geometry is from glyph U221A in the font KaTeX Main
812  return "M95," + (622 + extraVinculum + hLinePad) + "\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl" + extraVinculum / 2.075 + " -" + extraVinculum + "\nc5.3,-9.3,12,-14,20,-14\nH400000v" + (40 + extraVinculum) + "H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM" + (834 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "h-400000z";
813};
814
815var sqrtSize1 = function sqrtSize1(extraVinculum, hLinePad) {
816  // size1 is from glyph U221A in the font KaTeX_Size1-Regular
817  return "M263," + (601 + extraVinculum + hLinePad) + "c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl" + extraVinculum / 2.084 + " -" + extraVinculum + "\nc4.7,-7.3,11,-11,19,-11\nH40000v" + (40 + extraVinculum) + "H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM" + (1001 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "h-400000z";
818};
819
820var sqrtSize2 = function sqrtSize2(extraVinculum, hLinePad) {
821  // size2 is from glyph U221A in the font KaTeX_Size2-Regular
822  return "M983 " + (10 + extraVinculum + hLinePad) + "\nl" + extraVinculum / 3.13 + " -" + extraVinculum + "\nc4,-6.7,10,-10,18,-10 H400000v" + (40 + extraVinculum) + "\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\
vendor: 4,637 bytes, lines 822-910
822nM" + (1001 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "h-400000z";
823};
824
825var sqrtSize3 = function sqrtSize3(extraVinculum, hLinePad) {
826  // size3 is from glyph U221A in the font KaTeX_Size3-Regular
827  return "M424," + (2398 + extraVinculum + hLinePad) + "\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl" + extraVinculum / 4.223 + " -" + extraVinculum + "c4,-6.7,10,-10,18,-10 H400000\nv" + (40 + extraVinculum) + "H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M" + (1001 + extraVinculum) + " " + hLinePad + "\nh400000v" + (40 + extraVinculum) + "h-400000z";
828};
829
830var sqrtSize4 = function sqrtSize4(extraVinculum, hLinePad) {
831  // size4 is from glyph U221A in the font KaTeX_Size4-Regular
832  return "M473," + (2713 + extraVinculum + hLinePad) + "\nc339.3,-1799.3,509.3,-2700,510,-2702 l" + extraVinculum / 5.298 + " -" + extraVinculum + "\nc3.3,-7.3,9.3,-11,18,-11 H400000v" + (40 + extraVinculum) + "H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM" + (1001 + extraVinculum) + " " + hLinePad + "h400000v" + (40 + extraVinculum) + "H1017.7z";
833};
834
835var phasePath = function phasePath(y) {
836  var x = y / 2; // x coordinate at top of angle
837
838  return "M400000 " + y + " H0 L" + x + " 0 l65 45 L145 " + (y - 80) + " H400000z";
839};
840
841var sqrtTall = function sqrtTall(extraVinculum, hLinePad, viewBoxHeight) {
842  // sqrtTall is from glyph U23B7 in the font KaTeX_Size4-Regular
843  // One path edge has a variable length. It runs vertically from the vinculum
844  // to a point near (14 units) the bottom of the surd. The vinculum
845  // is normally 40 units thick. So the length of the line in question is:
846  var vertSegment = viewBoxHeight - 54 - hLinePad - extraVinculum;
847  return "M702 " + (extraVinculum + hLinePad) + "H400000" + (40 + extraVinculum) + "\nH742v" + vertSegment + "l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 " + hLinePad + "H400000v" + (40 + extraVinculum) + "H742z";
848};
849
850var sqrtPath = function sqrtPath(size, extraVinculum, viewBoxHeight) {
851  extraVinculum = 1000 * extraVinculum; // Convert from document ems to viewBox.
852
853  var path = "";
854
855  switch (size) {
856    case "sqrtMain":
857      path = sqrtMain(extraVinculum, hLinePad);
858      break;
859
860    case "sqrtSize1":
861      path = sqrtSize1(extraVinculum, hLinePad);
862      break;
863
864    case "sqrtSize2":
865      path = sqrtSize2(extraVinculum, hLinePad);
866      break;
867
868    case "sqrtSize3":
869      path = sqrtSize3(extraVinculum, hLinePad);
870      break;
871
872    case "sqrtSize4":
873      path = sqrtSize4(extraVinculum, hLinePad);
874      break;
875
876    case "sqrtTall":
877      path = sqrtTall(extraVinculum, hLinePad, viewBoxHeight);
878  }
879
880  return path;
881};
882var innerPath = function innerPath(name, height) {
883  // The inner part of stretchy tall delimiters
884  switch (name) {
885    case "\u239c":
886      return "M291 0 H417 V" + height + " H291z M291 0 H417 V" + height + " H291z";
887
888    case "\u2223":
889      return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z";
890
891    case "\u2225":
892      return "M145 0 H188 V" + height + " H145z M145 0 H188 V" + height + " H145z" + ("M367 0 H410 V" + height + " H367z M367 0 H410 V" + height + " H367z");
893
894    case "\u239f":
895      return "M457 0 H583 V" + height + " H457z M457 0 H583 V" + height + " H457z";
896
897    case "\u23a2":
898      return "M319 0 H403 V" + height + " H319z M319 0 H403 V" + height + " H319z";
899
900    case "\u23a5":
901      return "M263 0 H347 V" + height + " H263z M263 0 H347 V" + height + " H263z";
902
903    case "\u23aa":
904      return "M384 0 H504 V" + height + " H384z M384 0 H504 V" + height + " H384z";
905
906    case "\u23d0":
907      return "M312 0 H355 V" + height + " H312z M312 0 H355 V" + height + " H312z";
908
909    case "\u2016":
910      return "M257 0 H300 V" + height + " H257z M257 0 H300 V" + height + " H257z" + ("M478 0 H521 V" + height + " H478z M478 0 H521 V" + height + " H478z");
vendor: 17,177 bytes, lines 911-994
911
912    default:
913      return "";
914  }
915};
916var path = {
917  // The doubleleftarrow geometry is from glyph U+21D0 in the font KaTeX Main
918  doubleleftarrow: "M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",
919  // doublerightarrow is from glyph U+21D2 in font KaTeX Main
920  doublerightarrow: "M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",
921  // leftarrow is from glyph U+2190 in font KaTeX Main
922  leftarrow: "M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",
923  // overbrace is from glyphs U+23A9/23A8/23A7 in font KaTeX_Size4-Regular
924  leftbrace: "M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",
925  leftbraceunder: "M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",
926  // overgroup is from the MnSymbol package (public domain)
927  leftgroup: "M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",
928  leftgroupunder: "M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",
929  // Harpoons are from glyph U+21BD in font KaTeX Main
930  leftharpoon: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",
931  leftharpoonplus: "M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",
932  leftharpoondown: "M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",
933  leftharpoondownplus: "M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",
934  // hook is from glyph U+21A9 in font KaTeX Main
935  lefthook: "M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",
936  leftlinesegment: "M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",
937  leftmapsto: "M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",
938  // tofrom is from glyph U+21C4 in font KaTeX AMS Regular
939  leftToFrom: "M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",
940  longequal: "M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",
941  midbrace: "M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",
942  midbraceunder: "M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",
943  oiintSize1: "M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",
944  oiintSize2: "M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",
945  oiiintSize1: "M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",
946  oiiintSize2: "M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",
947  rightarrow: "M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",
948  rightbrace: "M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",
949  rightbraceunder: "M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",
950  rightgroup: "M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",
951  rightgroupunder: "M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",
952  rightharpoon: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",
953  rightharpoonplus: "M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",
954  rightharpoondown: "M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",
955  rightharpoondownplus: "M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",
956  righthook: "M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",
957  rightlinesegment: "M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",
958  rightToFrom: "M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",
959  // twoheadleftarrow is from glyph U+219E in font KaTeX AMS Regular
960  twoheadleftarrow: "M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",
961  twoheadrightarrow: "M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",
962  // tilde1 is a modified version of a glyph from the MnSymbol package
963  tilde1: "M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",
964  // ditto tilde2, tilde3, & tilde4
965  tilde2: "M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",
966  tilde3: "M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",
967  tilde4: "M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",
968  // vec is from glyph U+20D7 in font KaTeX Main
969  vec: "M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",
970  // widehat1 is a modified version of a glyph from the MnSymbol package
971  widehat1: "M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",
972  // ditto widehat2, widehat3, & widehat4
973  widehat2: "M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",
974  widehat3: "M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",
975  widehat4: "M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",
976  // widecheck paths are all inverted versions of widehat
977  widecheck1: "M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",
978  widecheck2: "M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",
979  widecheck3: "M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",
980  widecheck4: "M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",
981  // The next ten paths support reaction arrows from the mhchem package.
982  // Arrows for \ce{<-->} are offset from xAxis by 0.22ex, per mhchem in LaTeX
983  // baraboveleftarrow is mostly from glyph U+2190 in font KaTeX Main
984  baraboveleftarrow: "M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",
985  // rightarrowabovebar is mostly from glyph U+2192, KaTeX Main
986  rightarrowabovebar: "M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",
987  // The short left harpoon has 0.5em (i.e. 500 units) kern on the left end.
988  // Ref from mhchem.sty: \rlap{\raisebox{-.22ex}{$\kern0.5em
989  baraboveshortleftharpoon: "M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",
990  rightharpoonaboveshortbar: "M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",
991  shortbaraboveleftharpoon: "M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",
992  shortrightharpoonabovebar: "M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"
993};
994var tallDelim = function tallDelim
vendor: 3,900 bytes, lines 994-1057
994(label, midHeight) {
995  switch (label) {
996    case "lbrack":
997      return "M403 1759 V84 H666 V0 H319 V1759 v" + midHeight + " v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v" + midHeight + " v1759 h84z";
998
999    case "rbrack":
1000      return "M347 1759 V0 H0 V84 H263 V1759 v" + midHeight + " v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v" + midHeight + " v1759 h84z";
1001
1002    case "vert":
1003      return "M145 15 v585 v" + midHeight + " v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v" + -midHeight + " v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v" + midHeight + " v585 h43z";
1004
1005    case "doublevert":
1006      return "M145 15 v585 v" + midHeight + " v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v" + -midHeight + " v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v" + midHeight + " v585 h43z\nM367 15 v585 v" + midHeight + " v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v" + -midHeight + " v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v" + midHeight + " v585 h43z";
1007
1008    case "lfloor":
1009      return "M319 602 V0 H403 V602 v" + midHeight + " v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v" + midHeight + " v1715 H319z";
1010
1011    case "rfloor":
1012      return "M319 602 V0 H403 V602 v" + midHeight + " v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v" + midHeight + " v1715 H319z";
1013
1014    case "lceil":
1015      return "M403 1759 V84 H666 V0 H319 V1759 v" + midHeight + " v602 h84z\nM403 1759 V0 H319 V1759 v" + midHeight + " v602 h84z";
1016
1017    case "rceil":
1018      return "M347 1759 V0 H0 V84 H263 V1759 v" + midHeight + " v602 h84z\nM347 1759 V0 h-84 V1759 v" + midHeight + " v602 h84z";
1019
1020    case "lparen":
1021      return "M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0," + (midHeight + 84) + "c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-" + (midHeight + 92) + "c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z";
1022
1023    case "rparen":
1024      return "M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0," + (midHeight + 9) + "\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-" + (midHeight + 144) + "c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z";
1025
1026    default:
1027      // We should not ever get here.
1028      throw new Error("Unknown stretchy delimiter.");
1029  }
1030};
1031
1032/**
1033 * This node represents a document fragment, which contains elements, but when
1034 * placed into the DOM doesn't have any representation itself. It only contains
1035 * children and doesn't have any DOM node properties.
1036 */
1037class DocumentFragment {
1038  // HtmlDomNode
1039  // Never used; needed for satisfying interface.
1040  constructor(children) {
1041    this.children = void 0;
1042    this.classes = void 0;
1043    this.height = void 0;
1044    this.depth = void 0;
1045    this.maxFontSize = void 0;
1046    this.style = void 0;
1047    this.children = children;
1048    this.classes = [];
1049    this.height = 0;
1050    this.depth = 0;
1051    this.maxFontSize = 0;
1052    this.style = {};
1053  }
1054
1055  hasClass(className) {
1056    return utils.contains(this.classes, className);
1057  }
1058  /** Convert the fragment into a node. */
1059
1060
1061  toNode() {
1062    var frag = document.createDocumentFragment();
1063
1064    for (var i = 0; i < this.children.length; i++) {
1065      frag.appendChild(this.children[i].toNode());
1066    }
1067
1068    return frag;
1069  }
1070  /** Convert the fragment into HTML markup. */
1071
1072
1073  toMarkup() {
1074    var markup = ""; // Simply concatenate the markup for the children together.
1075
1076    for (var i = 0; i < this.children.length; i++) {
1077      markup += this.children[i].toMarkup();
1078    }
1079
1080    return markup;
1081  }
1082  /**
1083   * Converts the math node into a string, similar to innerText. Applies to
1084   * MathDomNode's only.
1085   */
1086
1087
1088  toText() {
1089    // To avoid this, we would subclass documentFragment separately for
1090    // MathML, but polyfills for subclassing is expensive per PR 1469.
1091    // $FlowFixMe: Only works for ChildType = MathDomNode.
1092    var toText = child => child.toText();
1093
1094    return this.children.map(toText).join("");
1095  }
1096
1097}
vendor: 16,782 bytes, lines 1097-1487
1097
1098
1099// This file is GENERATED by buildMetrics.sh. DO NOT MODIFY.
1100var fontMetricsData = {
1101  "AMS-Regular": {
1102    "32": [0, 0, 0, 0, 0.25],
1103    "65": [0, 0.68889, 0, 0, 0.72222],
1104    "66": [0, 0.68889, 0, 0, 0.66667],
1105    "67": [0, 0.68889, 0, 0, 0.72222],
1106    "68": [0, 0.68889, 0, 0, 0.72222],
1107    "69": [0, 0.68889, 0, 0, 0.66667],
1108    "70": [0, 0.68889, 0, 0, 0.61111],
1109    "71": [0, 0.68889, 0, 0, 0.77778],
1110    "72": [0, 0.68889, 0, 0, 0.77778],
1111    "73": [0, 0.68889, 0, 0, 0.38889],
1112    "74": [0.16667, 0.68889, 0, 0, 0.5],
1113    "75": [0, 0.68889, 0, 0, 0.77778],
1114    "76": [0, 0.68889, 0, 0, 0.66667],
1115    "77": [0, 0.68889, 0, 0, 0.94445],
1116    "78": [0, 0.68889, 0, 0, 0.72222],
1117    "79": [0.16667, 0.68889, 0, 0, 0.77778],
1118    "80": [0, 0.68889, 0, 0, 0.61111],
1119    "81": [0.16667, 0.68889, 0, 0, 0.77778],
1120    "82": [0, 0.68889, 0, 0, 0.72222],
1121    "83": [0, 0.68889, 0, 0, 0.55556],
1122    "84": [0, 0.68889, 0, 0, 0.66667],
1123    "85": [0, 0.68889, 0, 0, 0.72222],
1124    "86": [0, 0.68889, 0, 0, 0.72222],
1125    "87": [0, 0.68889, 0, 0, 1.0],
1126    "88": [0, 0.68889, 0, 0, 0.72222],
1127    "89": [0, 0.68889, 0, 0, 0.72222],
1128    "90": [0, 0.68889, 0, 0, 0.66667],
1129    "107": [0, 0.68889, 0, 0, 0.55556],
1130    "160": [0, 0, 0, 0, 0.25],
1131    "165": [0, 0.675, 0.025, 0, 0.75],
1132    "174": [0.15559, 0.69224, 0, 0, 0.94666],
1133    "240": [0, 0.68889, 0, 0, 0.55556],
1134    "295": [0, 0.68889, 0, 0, 0.54028],
1135    "710": [0, 0.825, 0, 0, 2.33334],
1136    "732": [0, 0.9, 0, 0, 2.33334],
1137    "770": [0, 0.825, 0, 0, 2.33334],
1138    "771": [0, 0.9, 0, 0, 2.33334],
1139    "989": [0.08167, 0.58167, 0, 0, 0.77778],
1140    "1008": [0, 0.43056, 0.04028, 0, 0.66667],
1141    "8245": [0, 0.54986, 0, 0, 0.275],
1142    "8463": [0, 0.68889, 0, 0, 0.54028],
1143    "8487": [0, 0.68889, 0, 0, 0.72222],
1144    "8498": [0, 0.68889, 0, 0, 0.55556],
1145    "8502": [0, 0.68889, 0, 0, 0.66667],
1146    "8503": [0, 0.68889, 0, 0, 0.44445],
1147    "8504": [0, 0.68889, 0, 0, 0.66667],
1148    "8513": [0, 0.68889, 0, 0, 0.63889],
1149    "8592": [-0.03598, 0.46402, 0, 0, 0.5],
1150    "8594": [-0.03598, 0.46402, 0, 0, 0.5],
1151    "8602": [-0.13313, 0.36687, 0, 0, 1.0],
1152    "8603": [-0.13313, 0.36687, 0, 0, 1.0],
1153    "8606": [0.01354, 0.52239, 0, 0, 1.0],
1154    "8608": [0.01354, 0.52239, 0, 0, 1.0],
1155    "8610": [0.01354, 0.52239, 0, 0, 1.11111],
1156    "8611": [0.01354, 0.52239, 0, 0, 1.11111],
1157    "8619": [0, 0.54986, 0, 0, 1.0],
1158    "8620": [0, 0.54986, 0, 0, 1.0],
1159    "8621": [-0.13313, 0.37788, 0, 0, 1.38889],
1160    "8622": [-0.13313, 0.36687, 0, 0, 1.0],
1161    "8624": [0, 0.69224, 0, 0, 0.5],
1162    "8625": [0, 0.69224, 0, 0, 0.5],
1163    "8630": [0, 0.43056, 0, 0, 1.0],
1164    "8631": [0, 0.43056, 0, 0, 1.0],
1165    "8634": [0.08198, 0.58198, 0, 0, 0.77778],
1166    "8635": [0.08198, 0.58198, 0, 0, 0.77778],
1167    "8638": [0.19444, 0.69224, 0, 0, 0.41667],
1168    "8639": [0.19444, 0.69224, 0, 0, 0.41667],
1169    "8642": [0.19444, 0.69224, 0, 0, 0.41667],
1170    "8643": [0.19444, 0.69224, 0, 0, 0.41667],
1171    "8644": [0.1808, 0.675, 0, 0, 1.0],
1172    "8646": [0.1808, 0.675, 0, 0, 1.0],
1173    "8647": [0.1808, 0.675, 0, 0, 1.0],
1174    "8648": [0.19444, 0.69224, 0, 0, 0.83334],
1175    "8649": [0.1808, 0.675, 0, 0, 1.0],
1176    "8650": [0.19444, 0.69224, 0, 0, 0.83334],
1177    "8651": [0.01354, 0.52239, 0, 0, 1.0],
1178    "8652": [0.01354, 0.52239, 0, 0, 1.0],
1179    "8653": [-0.13313, 0.36687, 0, 0, 1.0],
1180    "8654": [-0.13313, 0.36687, 0, 0, 1.0],
1181    "8655": [-0.13313, 0.36687, 0, 0, 1.0],
1182    "8666": [0.13667, 0.63667, 0, 0, 1.0],
1183    "8667": [0.13667, 0.63667, 0, 0, 1.0],
1184    "8669": [-0.13313, 0.37788, 0, 0, 1.0],
1185    "8672": [-0.064, 0.437, 0, 0, 1.334],
1186    "8674": [-0.064, 0.437, 0, 0, 1.334],
1187    "8705": [0, 0.825, 0, 0, 0.5],
1188    "8708": [0, 0.68889, 0, 0, 0.55556],
1189    "8709": [0.08167, 0.58167, 0, 0, 0.77778],
1190    "8717": [0, 0.43056, 0, 0, 0.42917],
1191    "8722": [-0.03598, 0.46402, 0, 0, 0.5],
1192    "8724": [0.08198, 0.69224, 0, 0, 0.77778],
1193    "8726": [0.08167, 0.58167, 0, 0, 0.77778],
1194    "8733": [0, 0.69224, 0, 0, 0.77778],
1195    "8736": [0, 0.69224, 0, 0, 0.72222],
1196    "8737": [0, 0.69224, 0, 0, 0.72222],
1197    "8738": [0.03517, 0.52239, 0, 0, 0.72222],
1198    "8739": [0.08167, 0.58167, 0, 0, 0.22222],
1199    "8740": [0.25142, 0.74111, 0, 0, 0.27778],
1200    "8741": [0.08167, 0.58167, 0, 0, 0.38889],
1201    "8742": [0.25142, 0.74111, 0, 0, 0.5],
1202    "8756": [0, 0.69224, 0, 0, 0.66667],
1203    "8757": [0, 0.69224, 0, 0, 0.66667],
1204    "8764": [-0.13313, 0.36687, 0, 0, 0.77778],
1205    "8765": [-0.13313, 0.37788, 0, 0, 0.77778],
1206    "8769": [-0.13313, 0.36687, 0, 0, 0.77778],
1207    "8770": [-0.03625, 0.46375, 0, 0, 0.77778],
1208    "8774": [0.30274, 0.79383, 0, 0, 0.77778],
1209    "8776": [-0.01688, 0.48312, 0, 0, 0.77778],
1210    "8778": [0.08167, 0.58167, 0, 0, 0.77778],
1211    "8782": [0.06062, 0.54986, 0, 0, 0.77778],
1212    "8783": [0.06062, 0.54986, 0, 0, 0.77778],
1213    "8785": [0.08198, 0.58198, 0, 0, 0.77778],
1214    "8786": [0.08198, 0.58198, 0, 0, 0.77778],
1215    "8787": [0.08198, 0.58198, 0, 0, 0.77778],
1216    "8790": [0, 0.69224, 0, 0, 0.77778],
1217    "8791": [0.22958, 0.72958, 0, 0, 0.77778],
1218    "8796": [0.08198, 0.91667, 0, 0, 0.77778],
1219    "8806": [0.25583, 0.75583, 0, 0, 0.77778],
1220    "8807": [0.25583, 0.75583, 0, 0, 0.77778],
1221    "8808": [0.25142, 0.75726, 0, 0, 0.77778],
1222    "8809": [0.25142, 0.75726, 0, 0, 0.77778],
1223    "8812": [0.25583, 0.75583, 0, 0, 0.5],
1224    "8814": [0.20576, 0.70576, 0, 0, 0.77778],
1225    "8815": [0.20576, 0.70576, 0, 0, 0.77778],
1226    "8816": [0.30274, 0.79383, 0, 0, 0.77778],
1227    "8817": [0.30274, 0.79383, 0, 0, 0.77778],
1228    "8818": [0.22958, 0.72958, 0, 0, 0.77778],
1229    "8819": [0.22958, 0.72958, 0, 0, 0.77778],
1230    "8822": [0.1808, 0.675, 0, 0, 0.77778],
1231    "8823": [0.1808, 0.675, 0, 0, 0.77778],
1232    "8828": [0.13667, 0.63667, 0, 0, 0.77778],
1233    "8829": [0.13667, 0.63667, 0, 0, 0.77778],
1234    "8830": [0.22958, 0.72958, 0, 0, 0.77778],
1235    "8831": [0.22958, 0.72958, 0, 0, 0.77778],
1236    "8832": [0.20576, 0.70576, 0, 0, 0.77778],
1237    "8833": [0.20576, 0.70576, 0, 0, 0.77778],
1238    "8840": [0.30274, 0.79383, 0, 0, 0.77778],
1239    "8841": [0.30274, 0.79383, 0, 0, 0.77778],
1240    "8842": [0.13597, 0.63597, 0, 0, 0.77778],
1241    "8843": [0.13597, 0.63597, 0, 0, 0.77778],
1242    "8847": [0.03517, 0.54986, 0, 0, 0.77778],
1243    "8848": [0.03517, 0.54986, 0, 0, 0.77778],
1244    "8858": [0.08198, 0.58198, 0, 0, 0.77778],
1245    "8859": [0.08198, 0.58198, 0, 0, 0.77778],
1246    "8861": [0.08198, 0.58198, 0, 0, 0.77778],
1247    "8862": [0, 0.675, 0, 0, 0.77778],
1248    "8863": [0, 0.675, 0, 0, 0.77778],
1249    "8864": [0, 0.675, 0, 0, 0.77778],
1250    "8865": [0, 0.675, 0, 0, 0.77778],
1251    "8872": [0, 0.69224, 0, 0, 0.61111],
1252    "8873": [0, 0.69224, 0, 0, 0.72222],
1253    "8874": [0, 0.69224, 0, 0, 0.88889],
1254    "8876": [0, 0.68889, 0, 0, 0.61111],
1255    "8877": [0, 0.68889, 0, 0, 0.61111],
1256    "8878": [0, 0.68889, 0, 0, 0.72222],
1257    "8879": [0, 0.68889, 0, 0, 0.72222],
1258    "8882": [0.03517, 0.54986, 0, 0, 0.77778],
1259    "8883": [0.03517, 0.54986, 0, 0, 0.77778],
1260    "8884": [0.13667, 0.63667, 0, 0, 0.77778],
1261    "8885": [0.13667, 0.63667, 0, 0, 0.77778],
1262    "8888": [0, 0.54986, 0, 0, 1.11111],
1263    "8890": [0.19444, 0.43056, 0, 0, 0.55556],
1264    "8891": [0.19444, 0.69224, 0, 0, 0.61111],
1265    "8892": [0.19444, 0.69224, 0, 0, 0.61111],
1266    "8901": [0, 0.54986, 0, 0, 0.27778],
1267    "8903": [0.08167, 0.58167, 0, 0, 0.77778],
1268    "8905": [0.08167, 0.58167, 0, 0, 0.77778],
1269    "8906": [0.08167, 0.58167, 0, 0, 0.77778],
1270    "8907": [0, 0.69224, 0, 0, 0.77778],
1271    "8908": [0, 0.69224, 0, 0, 0.77778],
1272    "8909": [-0.03598, 0.46402, 0, 0, 0.77778],
1273    "8910": [0, 0.54986, 0, 0, 0.76042],
1274    "8911": [0, 0.54986, 0, 0, 0.76042],
1275    "8912": [0.03517, 0.54986, 0, 0, 0.77778],
1276    "8913": [0.03517, 0.54986, 0, 0, 0.77778],
1277    "8914": [0, 0.54986, 0, 0, 0.66667],
1278    "8915": [0, 0.54986, 0, 0, 0.66667],
1279    "8916": [0, 0.69224, 0, 0, 0.66667],
1280    "8918": [0.0391, 0.5391, 0, 0, 0.77778],
1281    "8919": [0.0391, 0.5391, 0, 0, 0.77778],
1282    "8920": [0.03517, 0.54986, 0, 0, 1.33334],
1283    "8921": [0.03517, 0.54986, 0, 0, 1.33334],
1284    "8922": [0.38569, 0.88569, 0, 0, 0.77778],
1285    "8923": [0.38569, 0.88569, 0, 0, 0.77778],
1286    "8926": [0.13667, 0.63667, 0, 0, 0.77778],
1287    "8927": [0.13667, 0.63667, 0, 0, 0.77778],
1288    "8928": [0.30274, 0.79383, 0, 0, 0.77778],
1289    "8929": [0.30274, 0.79383, 0, 0, 0.77778],
1290    "8934": [0.23222, 0.74111, 0, 0, 0.77778],
1291    "8935": [0.23222, 0.74111, 0, 0, 0.77778],
1292    "8936": [0.23222, 0.74111, 0, 0, 0.77778],
1293    "8937": [0.23222, 0.74111, 0, 0, 0.77778],
1294    "8938": [0.20576, 0.70576, 0, 0, 0.77778],
1295    "8939": [0.20576, 0.70576, 0, 0, 0.77778],
1296    "8940": [0.30274, 0.79383, 0, 0, 0.77778],
1297    "8941": [0.30274, 0.79383, 0, 0, 0.77778],
1298    "8994": [0.19444, 0.69224, 0, 0, 0.77778],
1299    "8995": [0.19444, 0.69224, 0, 0, 0.77778],
1300    "9416": [0.15559, 0.69224, 0, 0, 0.90222],
1301    "9484": [0, 0.69224, 0, 0, 0.5],
1302    "9488": [0, 0.69224, 0, 0, 0.5],
1303    "9492": [0, 0.37788, 0, 0, 0.5],
1304    "9496": [0, 0.37788, 0, 0, 0.5],
1305    "9585": [0.19444, 0.68889, 0, 0, 0.88889],
1306    "9586": [0.19444, 0.74111, 0, 0, 0.88889],
1307    "9632": [0, 0.675, 0, 0, 0.77778],
1308    "9633": [0, 0.675, 0, 0, 0.77778],
1309    "9650": [0, 0.54986, 0, 0, 0.72222],
1310    "9651": [0, 0.54986, 0, 0, 0.72222],
1311    "9654": [0.03517, 0.54986, 0, 0, 0.77778],
1312    "9660": [0, 0.54986, 0, 0, 0.72222],
1313    "9661": [0, 0.54986, 0, 0, 0.72222],
1314    "9664": [0.03517, 0.54986, 0, 0, 0.77778],
1315    "9674": [0.11111, 0.69224, 0, 0, 0.66667],
1316    "9733": [0.19444, 0.69224, 0, 0, 0.94445],
1317    "10003": [0, 0.69224, 0, 0, 0.83334],
1318    "10016": [0, 0.69224, 0, 0, 0.83334],
1319    "10731": [0.11111, 0.69224, 0, 0, 0.66667],
1320    "10846": [0.19444, 0.75583, 0, 0, 0.61111],
1321    "10877": [0.13667, 0.63667, 0, 0, 0.77778],
1322    "10878": [0.13667, 0.63667, 0, 0, 0.77778],
1323    "10885": [0.25583, 0.75583, 0, 0, 0.77778],
1324    "10886": [0.25583, 0.75583, 0, 0, 0.77778],
1325    "10887": [0.13597, 0.63597, 0, 0, 0.77778],
1326    "10888": [0.13597, 0.63597, 0, 0, 0.77778],
1327    "10889": [0.26167, 0.75726, 0, 0, 0.77778],
1328    "10890": [0.26167, 0.75726, 0, 0, 0.77778],
1329    "10891": [0.48256, 0.98256, 0, 0, 0.77778],
1330    "10892": [0.48256, 0.98256, 0, 0, 0.77778],
1331    "10901": [0.13667, 0.63667, 0, 0, 0.77778],
1332    "10902": [0.13667, 0.63667, 0, 0, 0.77778],
1333    "10933": [0.25142, 0.75726, 0, 0, 0.77778],
1334    "10934": [0.25142, 0.75726, 0, 0, 0.77778],
1335    "10935": [0.26167, 0.75726, 0, 0, 0.77778],
1336    "10936": [0.26167, 0.75726, 0, 0, 0.77778],
1337    "10937": [0.26167, 0.75726, 0, 0, 0.77778],
1338    "10938": [0.26167, 0.75726, 0, 0, 0.77778],
1339    "10949": [0.25583, 0.75583, 0, 0, 0.77778],
1340    "10950": [0.25583, 0.75583, 0, 0, 0.77778],
1341    "10955": [0.28481, 0.79383, 0, 0, 0.77778],
1342    "10956": [0.28481, 0.79383, 0, 0, 0.77778],
1343    "57350": [0.08167, 0.58167, 0, 0, 0.22222],
1344    "57351": [0.08167, 0.58167, 0, 0, 0.38889],
1345    "57352": [0.08167, 0.58167, 0, 0, 0.77778],
1346    "57353": [0, 0.43056, 0.04028, 0, 0.66667],
1347    "57356": [0.25142, 0.75726, 0, 0, 0.77778],
1348    "57357": [0.25142, 0.75726, 0, 0, 0.77778],
1349    "57358": [0.41951, 0.91951, 0, 0, 0.77778],
1350    "57359": [0.30274, 0.79383, 0, 0, 0.77778],
1351    "57360": [0.30274, 0.79383, 0, 0, 0.77778],
1352    "57361": [0.41951, 0.91951, 0, 0, 0.77778],
1353    "57366": [0.25142, 0.75726, 0, 0, 0.77778],
1354    "57367": [0.25142, 0.75726, 0, 0, 0.77778],
1355    "57368": [0.25142, 0.75726, 0, 0, 0.77778],
1356    "57369": [0.25142, 0.75726, 0, 0, 0.77778],
1357    "57370": [0.13597, 0.63597, 0, 0, 0.77778],
1358    "57371": [0.13597, 0.63597, 0, 0, 0.77778]
1359  },
1360  "Caligraphic-Regular": {
1361    "32": [0, 0, 0, 0, 0.25],
1362    "65": [0, 0.68333, 0, 0.19445, 0.79847],
1363    "66": [0, 0.68333, 0.03041, 0.13889, 0.65681],
1364    "67": [0, 0.68333, 0.05834, 0.13889, 0.52653],
1365    "68": [0, 0.68333, 0.02778, 0.08334, 0.77139],
1366    "69": [0, 0.68333, 0.08944, 0.11111, 0.52778],
1367    "70": [0, 0.68333, 0.09931, 0.11111, 0.71875],
1368    "71": [0.09722, 0.68333, 0.0593, 0.11111, 0.59487],
1369    "72": [0, 0.68333, 0.00965, 0.11111, 0.84452],
1370    "73": [0, 0.68333, 0.07382, 0, 0.54452],
1371    "74": [0.09722, 0.68333, 0.18472, 0.16667, 0.67778],
1372    "75": [0, 0.68333, 0.01445, 0.05556, 0.76195],
1373    "76": [0, 0.68333, 0, 0.13889, 0.68972],
1374    "77": [0, 0.68333, 0, 0.13889, 1.2009],
1375    "78": [0, 0.68333, 0.14736, 0.08334, 0.82049],
1376    "79": [0, 0.68333, 0.02778, 0.11111, 0.79611],
1377    "80": [0, 0.68333, 0.08222, 0.08334, 0.69556],
1378    "81": [0.09722, 0.68333, 0, 0.11111, 0.81667],
1379    "82": [0, 0.68333, 0, 0.08334, 0.8475],
1380    "83": [0, 0.68333, 0.075, 0.13889, 0.60556],
1381    "84": [0, 0.68333, 0.25417, 0, 0.54464],
1382    "85": [0, 0.68333, 0.09931, 0.08334, 0.62583],
1383    "86": [0, 0.68333, 0.08222, 0, 0.61278],
1384    "87": [0, 0.68333, 0.08222, 0.08334, 0.98778],
1385    "88": [0, 0.68333, 0.14643, 0.13889, 0.7133],
1386    "89": [0.09722, 0.68333, 0.08222, 0.08334, 0.66834],
1387    "90": [0, 0.68333, 0.07944, 0.13889, 0.72473],
1388    "160": [0, 0, 0, 0, 0.25]
1389  },
1390  "Fraktur-Regular": {
1391    "32": [0, 0, 0, 0, 0.25],
1392    "33": [0, 0.69141, 0, 0, 0.29574],
1393    "34": [0, 0.69141, 0, 0, 0.21471],
1394    "38": [0, 0.69141, 0, 0, 0.73786],
1395    "39": [0, 0.69141, 0, 0, 0.21201],
1396    "40": [0.24982, 0.74947, 0, 0, 0.38865],
1397    "41": [0.24982, 0.74947, 0, 0, 0.38865],
1398    "42": [0, 0.62119, 0, 0, 0.27764],
1399    "43": [0.08319, 0.58283, 0, 0, 0.75623],
1400    "44": [0, 0.10803, 0, 0, 0.27764],
1401    "45": [0.08319, 0.58283, 0, 0, 0.75623],
1402    "46": [0, 0.10803, 0, 0, 0.27764],
1403    "47": [0.24982, 0.74947, 0, 0, 0.50181],
1404    "48": [0, 0.47534, 0, 0, 0.50181],
1405    "49": [0, 0.47534, 0, 0, 0.50181],
1406    "50": [0, 0.47534, 0, 0, 0.50181],
1407    "51": [0.18906, 0.47534, 0, 0, 0.50181],
1408    "52": [0.18906, 0.47534, 0, 0, 0.50181],
1409    "53": [0.18906, 0.47534, 0, 0, 0.50181],
1410    "54": [0, 0.69141, 0, 0, 0.50181],
1411    "55": [0.18906, 0.47534, 0, 0, 0.50181],
1412    "56": [0, 0.69141, 0, 0, 0.50181],
1413    "57": [0.18906, 0.47534, 0, 0, 0.50181],
1414    "58": [0, 0.47534, 0, 0, 0.21606],
1415    "59": [0.12604, 0.47534, 0, 0, 0.21606],
1416    "61": [-0.13099, 0.36866, 0, 0, 0.75623],
1417    "63": [0, 0.69141, 0, 0, 0.36245],
1418    "65": [0, 0.69141, 0, 0, 0.7176],
1419    "66": [0, 0.69141, 0, 0, 0.88397],
1420    "67": [0, 0.69141, 0, 0, 0.61254],
1421    "68": [0, 0.69141, 0, 0, 0.83158],
1422    "69": [0, 0.69141, 0, 0, 0.66278],
1423    "70": [0.12604, 0.69141, 0, 0, 0.61119],
1424    "71": [0, 0.69141, 0, 0, 0.78539],
1425    "72": [0.06302, 0.69141, 0, 0, 0.7203],
1426    "73": [0, 0.69141, 0, 0, 0.55448],
1427    "74": [0.12604, 0.69141, 0, 0, 0.55231],
1428    "75": [0, 0.69141, 0, 0, 0.66845],
1429    "76": [0, 0.69141, 0, 0, 0.66602],
1430    "77": [0, 0.69141, 0, 0, 1.04953],
1431    "78": [0, 0.69141, 0, 0, 0.83212],
1432    "79": [0, 0.69141, 0, 0, 0.82699],
1433    "80": [0.18906, 0.69141, 0, 0, 0.82753],
1434    "81": [0.03781, 0.69141, 0, 0, 0.82699],
1435    "82": [0, 0.69141, 0, 0, 0.82807],
1436    "83": [0, 0.69141, 0, 0, 0.82861],
1437    "84": [0, 0.69141, 0, 0, 0.66899],
1438    "85": [0, 0.69141, 0, 0, 0.64576],
1439    "86": [0, 0.69141, 0, 0, 0.83131],
1440    "87": [0, 0.69141, 0, 0, 1.04602],
1441    "88": [0, 0.69141, 0, 0, 0.71922],
1442    "89": [0.18906, 0.69141, 0, 0, 0.83293],
1443    "90": [0.12604, 0.69141, 0, 0, 0.60201],
1444    "91": [0.24982, 0.74947, 0, 0, 0.27764],
1445    "93": [0.24982, 0.74947, 0, 0, 0.27764],
1446    "94": [0, 0.69141, 0, 0, 0.49965],
1447    "97": [0, 0.47534, 0, 0, 0.50046],
1448    "98": [0, 0.69141, 0, 0, 0.51315],
1449    "99": [0, 0.47534, 0, 0, 0.38946],
1450    "100": [0, 0.62119, 0, 0, 0.49857],
1451    "101": [0, 0.47534, 0, 0, 0.40053],
1452    "102": [0.18906, 0.69141, 0, 0, 0.32626],
1453    "103": [0.18906, 0.47534, 0, 0, 0.5037],
1454    "104": [0.18906, 0.69141, 0, 0, 0.52126],
1455    "105": [0, 0.69141, 0, 0, 0.27899],
1456    "106": [0, 0.69141, 0, 0, 0.28088],
1457    "107": [0, 0.69141, 0, 0, 0.38946],
1458    "108": [0, 0.69141, 0, 0, 0.27953],
1459    "109": [0, 0.47534, 0, 0, 0.76676],
1460    "110": [0, 0.47534, 0, 0, 0.52666],
1461    "111": [0, 0.47534, 0, 0, 0.48885],
1462    "112": [0.18906, 0.52396, 0, 0, 0.50046],
1463    "113": [0.18906, 0.47534, 0, 0, 0.48912],
1464    "114": [0, 0.47534, 0, 0, 0.38919],
1465    "115": [0, 0.47534, 0, 0, 0.44266],
1466    "116": [0, 0.62119, 0, 0, 0.33301],
1467    "117": [0, 0.47534, 0, 0, 0.5172],
1468    "118": [0, 0.52396, 0, 0, 0.5118],
1469    "119": [0, 0.52396, 0, 0, 0.77351],
1470    "120": [0.18906, 0.47534, 0, 0, 0.38865],
1471    "121": [0.18906, 0.47534, 0, 0, 0.49884],
1472    "122": [0.18906, 0.47534, 0, 0, 0.39054],
1473    "160": [0, 0, 0, 0, 0.25],
1474    "8216": [0, 0.69141, 0, 0, 0.21471],
1475    "8217": [0, 0.69141, 0, 0, 0.21471],
1476    "58112": [0, 0.62119, 0, 0, 0.49749],
1477    "58113": [0, 0.62119, 0, 0, 0.4983],
1478    "58114": [0.18906, 0.69141, 0, 0, 0.33328],
1479    "58115": [0.18906, 0.69141, 0, 0, 0.32923],
1480    "58116": [0.18906, 0.47534, 0, 0, 0.50343],
1481    "58117": [0, 0.69141, 0, 0, 0.33301],
1482    "58118": [0, 0.62119, 0, 0, 0.33409],
1483    "58119": [0, 0.47534, 0, 0, 0.50073]
1484  },
1485  "Main-Bold": {
1486    "32": [0, 0, 0, 0, 0.25],
1487    "33": [0, 0.69444, 0, 0, 0.35],
vendor: 2,406 bytes, lines 1488-1548
1488    "34": [0, 0.69444, 0, 0, 0.60278],
1489    "35": [0.19444, 0.69444, 0, 0, 0.95833],
1490    "36": [0.05556, 0.75, 0, 0, 0.575],
1491    "37": [0.05556, 0.75, 0, 0, 0.95833],
1492    "38": [0, 0.69444, 0, 0, 0.89444],
1493    "39": [0, 0.69444, 0, 0, 0.31944],
1494    "40": [0.25, 0.75, 0, 0, 0.44722],
1495    "41": [0.25, 0.75, 0, 0, 0.44722],
1496    "42": [0, 0.75, 0, 0, 0.575],
1497    "43": [0.13333, 0.63333, 0, 0, 0.89444],
1498    "44": [0.19444, 0.15556, 0, 0, 0.31944],
1499    "45": [0, 0.44444, 0, 0, 0.38333],
1500    "46": [0, 0.15556, 0, 0, 0.31944],
1501    "47": [0.25, 0.75, 0, 0, 0.575],
1502    "48": [0, 0.64444, 0, 0, 0.575],
1503    "49": [0, 0.64444, 0, 0, 0.575],
1504    "50": [0, 0.64444, 0, 0, 0.575],
1505    "51": [0, 0.64444, 0, 0, 0.575],
1506    "52": [0, 0.64444, 0, 0, 0.575],
1507    "53": [0, 0.64444, 0, 0, 0.575],
1508    "54": [0, 0.64444, 0, 0, 0.575],
1509    "55": [0, 0.64444, 0, 0, 0.575],
1510    "56": [0, 0.64444, 0, 0, 0.575],
1511    "57": [0, 0.64444, 0, 0, 0.575],
1512    "58": [0, 0.44444, 0, 0, 0.31944],
1513    "59": [0.19444, 0.44444, 0, 0, 0.31944],
1514    "60": [0.08556, 0.58556, 0, 0, 0.89444],
1515    "61": [-0.10889, 0.39111, 0, 0, 0.89444],
1516    "62": [0.08556, 0.58556, 0, 0, 0.89444],
1517    "63": [0, 0.69444, 0, 0, 0.54305],
1518    "64": [0, 0.69444, 0, 0, 0.89444],
1519    "65": [0, 0.68611, 0, 0, 0.86944],
1520    "66": [0, 0.68611, 0, 0, 0.81805],
1521    "67": [0, 0.68611, 0, 0, 0.83055],
1522    "68": [0, 0.68611, 0, 0, 0.88194],
1523    "69": [0, 0.68611, 0, 0, 0.75555],
1524    "70": [0, 0.68611, 0, 0, 0.72361],
1525    "71": [0, 0.68611, 0, 0, 0.90416],
1526    "72": [0, 0.68611, 0, 0, 0.9],
1527    "73": [0, 0.68611, 0, 0, 0.43611],
1528    "74": [0, 0.68611, 0, 0, 0.59444],
1529    "75": [0, 0.68611, 0, 0, 0.90138],
1530    "76": [0, 0.68611, 0, 0, 0.69166],
1531    "77": [0, 0.68611, 0, 0, 1.09166],
1532    "78": [0, 0.68611, 0, 0, 0.9],
1533    "79": [0, 0.68611, 0, 0, 0.86388],
1534    "80": [0, 0.68611, 0, 0, 0.78611],
1535    "81": [0.19444, 0.68611, 0, 0, 0.86388],
1536    "82": [0, 0.68611, 0, 0, 0.8625],
1537    "83": [0, 0.68611, 0, 0, 0.63889],
1538    "84": [0, 0.68611, 0, 0, 0.8],
1539    "85": [0, 0.68611, 0, 0, 0.88472],
1540    "86": [0, 0.68611, 0.01597, 0, 0.86944],
1541    "87": [0, 0.68611, 0.01597, 0, 1.18888],
1542    "88": [0, 0.68611, 0, 0, 0.86944],
1543    "89": [0, 0.68611, 0.02875, 0, 0.86944],
1544    "90": [0, 0.68611, 0, 0, 0.70277],
1545    "91": [0.25, 0.75, 0, 0, 0.31944],
1546    "92": [0.25, 0.75, 0, 0, 0.575],
1547    "93": [0.25, 0.75, 0, 0, 0.31944],
1548    "94": [0, 0.69444, 0, 0, 0.575],
vendor: 8,281 bytes, lines 1549-1741
1549    "95": [0.31, 0.13444, 0.03194, 0, 0.575],
1550    "97": [0, 0.44444, 0, 0, 0.55902],
1551    "98": [0, 0.69444, 0, 0, 0.63889],
1552    "99": [0, 0.44444, 0, 0, 0.51111],
1553    "100": [0, 0.69444, 0, 0, 0.63889],
1554    "101": [0, 0.44444, 0, 0, 0.52708],
1555    "102": [0, 0.69444, 0.10903, 0, 0.35139],
1556    "103": [0.19444, 0.44444, 0.01597, 0, 0.575],
1557    "104": [0, 0.69444, 0, 0, 0.63889],
1558    "105": [0, 0.69444, 0, 0, 0.31944],
1559    "106": [0.19444, 0.69444, 0, 0, 0.35139],
1560    "107": [0, 0.69444, 0, 0, 0.60694],
1561    "108": [0, 0.69444, 0, 0, 0.31944],
1562    "109": [0, 0.44444, 0, 0, 0.95833],
1563    "110": [0, 0.44444, 0, 0, 0.63889],
1564    "111": [0, 0.44444, 0, 0, 0.575],
1565    "112": [0.19444, 0.44444, 0, 0, 0.63889],
1566    "113": [0.19444, 0.44444, 0, 0, 0.60694],
1567    "114": [0, 0.44444, 0, 0, 0.47361],
1568    "115": [0, 0.44444, 0, 0, 0.45361],
1569    "116": [0, 0.63492, 0, 0, 0.44722],
1570    "117": [0, 0.44444, 0, 0, 0.63889],
1571    "118": [0, 0.44444, 0.01597, 0, 0.60694],
1572    "119": [0, 0.44444, 0.01597, 0, 0.83055],
1573    "120": [0, 0.44444, 0, 0, 0.60694],
1574    "121": [0.19444, 0.44444, 0.01597, 0, 0.60694],
1575    "122": [0, 0.44444, 0, 0, 0.51111],
1576    "123": [0.25, 0.75, 0, 0, 0.575],
1577    "124": [0.25, 0.75, 0, 0, 0.31944],
1578    "125": [0.25, 0.75, 0, 0, 0.575],
1579    "126": [0.35, 0.34444, 0, 0, 0.575],
1580    "160": [0, 0, 0, 0, 0.25],
1581    "163": [0, 0.69444, 0, 0, 0.86853],
1582    "168": [0, 0.69444, 0, 0, 0.575],
1583    "172": [0, 0.44444, 0, 0, 0.76666],
1584    "176": [0, 0.69444, 0, 0, 0.86944],
1585    "177": [0.13333, 0.63333, 0, 0, 0.89444],
1586    "184": [0.17014, 0, 0, 0, 0.51111],
1587    "198": [0, 0.68611, 0, 0, 1.04166],
1588    "215": [0.13333, 0.63333, 0, 0, 0.89444],
1589    "216": [0.04861, 0.73472, 0, 0, 0.89444],
1590    "223": [0, 0.69444, 0, 0, 0.59722],
1591    "230": [0, 0.44444, 0, 0, 0.83055],
1592    "247": [0.13333, 0.63333, 0, 0, 0.89444],
1593    "248": [0.09722, 0.54167, 0, 0, 0.575],
1594    "305": [0, 0.44444, 0, 0, 0.31944],
1595    "338": [0, 0.68611, 0, 0, 1.16944],
1596    "339": [0, 0.44444, 0, 0, 0.89444],
1597    "567": [0.19444, 0.44444, 0, 0, 0.35139],
1598    "710": [0, 0.69444, 0, 0, 0.575],
1599    "711": [0, 0.63194, 0, 0, 0.575],
1600    "713": [0, 0.59611, 0, 0, 0.575],
1601    "714": [0, 0.69444, 0, 0, 0.575],
1602    "715": [0, 0.69444, 0, 0, 0.575],
1603    "728": [0, 0.69444, 0, 0, 0.575],
1604    "729": [0, 0.69444, 0, 0, 0.31944],
1605    "730": [0, 0.69444, 0, 0, 0.86944],
1606    "732": [0, 0.69444, 0, 0, 0.575],
1607    "733": [0, 0.69444, 0, 0, 0.575],
1608    "915": [0, 0.68611, 0, 0, 0.69166],
1609    "916": [0, 0.68611, 0, 0, 0.95833],
1610    "920": [0, 0.68611, 0, 0, 0.89444],
1611    "923": [0, 0.68611, 0, 0, 0.80555],
1612    "926": [0, 0.68611, 0, 0, 0.76666],
1613    "928": [0, 0.68611, 0, 0, 0.9],
1614    "931": [0, 0.68611, 0, 0, 0.83055],
1615    "933": [0, 0.68611, 0, 0, 0.89444],
1616    "934": [0, 0.68611, 0, 0, 0.83055],
1617    "936": [0, 0.68611, 0, 0, 0.89444],
1618    "937": [0, 0.68611, 0, 0, 0.83055],
1619    "8211": [0, 0.44444, 0.03194, 0, 0.575],
1620    "8212": [0, 0.44444, 0.03194, 0, 1.14999],
1621    "8216": [0, 0.69444, 0, 0, 0.31944],
1622    "8217": [0, 0.69444, 0, 0, 0.31944],
1623    "8220": [0, 0.69444, 0, 0, 0.60278],
1624    "8221": [0, 0.69444, 0, 0, 0.60278],
1625    "8224": [0.19444, 0.69444, 0, 0, 0.51111],
1626    "8225": [0.19444, 0.69444, 0, 0, 0.51111],
1627    "8242": [0, 0.55556, 0, 0, 0.34444],
1628    "8407": [0, 0.72444, 0.15486, 0, 0.575],
1629    "8463": [0, 0.69444, 0, 0, 0.66759],
1630    "8465": [0, 0.69444, 0, 0, 0.83055],
1631    "8467": [0, 0.69444, 0, 0, 0.47361],
1632    "8472": [0.19444, 0.44444, 0, 0, 0.74027],
1633    "8476": [0, 0.69444, 0, 0, 0.83055],
1634    "8501": [0, 0.69444, 0, 0, 0.70277],
1635    "8592": [-0.10889, 0.39111, 0, 0, 1.14999],
1636    "8593": [0.19444, 0.69444, 0, 0, 0.575],
1637    "8594": [-0.10889, 0.39111, 0, 0, 1.14999],
1638    "8595": [0.19444, 0.69444, 0, 0, 0.575],
1639    "8596": [-0.10889, 0.39111, 0, 0, 1.14999],
1640    "8597": [0.25, 0.75, 0, 0, 0.575],
1641    "8598": [0.19444, 0.69444, 0, 0, 1.14999],
1642    "8599": [0.19444, 0.69444, 0, 0, 1.14999],
1643    "8600": [0.19444, 0.69444, 0, 0, 1.14999],
1644    "8601": [0.19444, 0.69444, 0, 0, 1.14999],
1645    "8636": [-0.10889, 0.39111, 0, 0, 1.14999],
1646    "8637": [-0.10889, 0.39111, 0, 0, 1.14999],
1647    "8640": [-0.10889, 0.39111, 0, 0, 1.14999],
1648    "8641": [-0.10889, 0.39111, 0, 0, 1.14999],
1649    "8656": [-0.10889, 0.39111, 0, 0, 1.14999],
1650    "8657": [0.19444, 0.69444, 0, 0, 0.70277],
1651    "8658": [-0.10889, 0.39111, 0, 0, 1.14999],
1652    "8659": [0.19444, 0.69444, 0, 0, 0.70277],
1653    "8660": [-0.10889, 0.39111, 0, 0, 1.14999],
1654    "8661": [0.25, 0.75, 0, 0, 0.70277],
1655    "8704": [0, 0.69444, 0, 0, 0.63889],
1656    "8706": [0, 0.69444, 0.06389, 0, 0.62847],
1657    "8707": [0, 0.69444, 0, 0, 0.63889],
1658    "8709": [0.05556, 0.75, 0, 0, 0.575],
1659    "8711": [0, 0.68611, 0, 0, 0.95833],
1660    "8712": [0.08556, 0.58556, 0, 0, 0.76666],
1661    "8715": [0.08556, 0.58556, 0, 0, 0.76666],
1662    "8722": [0.13333, 0.63333, 0, 0, 0.89444],
1663    "8723": [0.13333, 0.63333, 0, 0, 0.89444],
1664    "8725": [0.25, 0.75, 0, 0, 0.575],
1665    "8726": [0.25, 0.75, 0, 0, 0.575],
1666    "8727": [-0.02778, 0.47222, 0, 0, 0.575],
1667    "8728": [-0.02639, 0.47361, 0, 0, 0.575],
1668    "8729": [-0.02639, 0.47361, 0, 0, 0.575],
1669    "8730": [0.18, 0.82, 0, 0, 0.95833],
1670    "8733": [0, 0.44444, 0, 0, 0.89444],
1671    "8734": [0, 0.44444, 0, 0, 1.14999],
1672    "8736": [0, 0.69224, 0, 0, 0.72222],
1673    "8739": [0.25, 0.75, 0, 0, 0.31944],
1674    "8741": [0.25, 0.75, 0, 0, 0.575],
1675    "8743": [0, 0.55556, 0, 0, 0.76666],
1676    "8744": [0, 0.55556, 0, 0, 0.76666],
1677    "8745": [0, 0.55556, 0, 0, 0.76666],
1678    "8746": [0, 0.55556, 0, 0, 0.76666],
1679    "8747": [0.19444, 0.69444, 0.12778, 0, 0.56875],
1680    "8764": [-0.10889, 0.39111, 0, 0, 0.89444],
1681    "8768": [0.19444, 0.69444, 0, 0, 0.31944],
1682    "8771": [0.00222, 0.50222, 0, 0, 0.89444],
1683    "8773": [0.027, 0.638, 0, 0, 0.894],
1684    "8776": [0.02444, 0.52444, 0, 0, 0.89444],
1685    "8781": [0.00222, 0.50222, 0, 0, 0.89444],
1686    "8801": [0.00222, 0.50222, 0, 0, 0.89444],
1687    "8804": [0.19667, 0.69667, 0, 0, 0.89444],
1688    "8805": [0.19667, 0.69667, 0, 0, 0.89444],
1689    "8810": [0.08556, 0.58556, 0, 0, 1.14999],
1690    "8811": [0.08556, 0.58556, 0, 0, 1.14999],
1691    "8826": [0.08556, 0.58556, 0, 0, 0.89444],
1692    "8827": [0.08556, 0.58556, 0, 0, 0.89444],
1693    "8834": [0.08556, 0.58556, 0, 0, 0.89444],
1694    "8835": [0.08556, 0.58556, 0, 0, 0.89444],
1695    "8838": [0.19667, 0.69667, 0, 0, 0.89444],
1696    "8839": [0.19667, 0.69667, 0, 0, 0.89444],
1697    "8846": [0, 0.55556, 0, 0, 0.76666],
1698    "8849": [0.19667, 0.69667, 0, 0, 0.89444],
1699    "8850": [0.19667, 0.69667, 0, 0, 0.89444],
1700    "8851": [0, 0.55556, 0, 0, 0.76666],
1701    "8852": [0, 0.55556, 0, 0, 0.76666],
1702    "8853": [0.13333, 0.63333, 0, 0, 0.89444],
1703    "8854": [0.13333, 0.63333, 0, 0, 0.89444],
1704    "8855": [0.13333, 0.63333, 0, 0, 0.89444],
1705    "8856": [0.13333, 0.63333, 0, 0, 0.89444],
1706    "8857": [0.13333, 0.63333, 0, 0, 0.89444],
1707    "8866": [0, 0.69444, 0, 0, 0.70277],
1708    "8867": [0, 0.69444, 0, 0, 0.70277],
1709    "8868": [0, 0.69444, 0, 0, 0.89444],
1710    "8869": [0, 0.69444, 0, 0, 0.89444],
1711    "8900": [-0.02639, 0.47361, 0, 0, 0.575],
1712    "8901": [-0.02639, 0.47361, 0, 0, 0.31944],
1713    "8902": [-0.02778, 0.47222, 0, 0, 0.575],
1714    "8968": [0.25, 0.75, 0, 0, 0.51111],
1715    "8969": [0.25, 0.75, 0, 0, 0.51111],
1716    "8970": [0.25, 0.75, 0, 0, 0.51111],
1717    "8971": [0.25, 0.75, 0, 0, 0.51111],
1718    "8994": [-0.13889, 0.36111, 0, 0, 1.14999],
1719    "8995": [-0.13889, 0.36111, 0, 0, 1.14999],
1720    "9651": [0.19444, 0.69444, 0, 0, 1.02222],
1721    "9657": [-0.02778, 0.47222, 0, 0, 0.575],
1722    "9661": [0.19444, 0.69444, 0, 0, 1.02222],
1723    "9667": [-0.02778, 0.47222, 0, 0, 0.575],
1724    "9711": [0.19444, 0.69444, 0, 0, 1.14999],
1725    "9824": [0.12963, 0.69444, 0, 0, 0.89444],
1726    "9825": [0.12963, 0.69444, 0, 0, 0.89444],
1727    "9826": [0.12963, 0.69444, 0, 0, 0.89444],
1728    "9827": [0.12963, 0.69444, 0, 0, 0.89444],
1729    "9837": [0, 0.75, 0, 0, 0.44722],
1730    "9838": [0.19444, 0.69444, 0, 0, 0.44722],
1731    "9839": [0.19444, 0.69444, 0, 0, 0.44722],
1732    "10216": [0.25, 0.75, 0, 0, 0.44722],
1733    "10217": [0.25, 0.75, 0, 0, 0.44722],
1734    "10815": [0, 0.68611, 0, 0, 0.9],
1735    "10927": [0.19667, 0.69667, 0, 0, 0.89444],
1736    "10928": [0.19667, 0.69667, 0, 0, 0.89444],
1737    "57376": [0.19444, 0.69444, 0, 0, 0]
1738  },
1739  "Main-BoldItalic": {
1740    "32": [0, 0, 0, 0, 0.25],
1741    "33": [0, 0.69444, 0.11417, 0, 0.38611],
vendor: 15,788 bytes, lines 1742-2105
1742    "34": [0, 0.69444, 0.07939, 0, 0.62055],
1743    "35": [0.19444, 0.69444, 0.06833, 0, 0.94444],
1744    "37": [0.05556, 0.75, 0.12861, 0, 0.94444],
1745    "38": [0, 0.69444, 0.08528, 0, 0.88555],
1746    "39": [0, 0.69444, 0.12945, 0, 0.35555],
1747    "40": [0.25, 0.75, 0.15806, 0, 0.47333],
1748    "41": [0.25, 0.75, 0.03306, 0, 0.47333],
1749    "42": [0, 0.75, 0.14333, 0, 0.59111],
1750    "43": [0.10333, 0.60333, 0.03306, 0, 0.88555],
1751    "44": [0.19444, 0.14722, 0, 0, 0.35555],
1752    "45": [0, 0.44444, 0.02611, 0, 0.41444],
1753    "46": [0, 0.14722, 0, 0, 0.35555],
1754    "47": [0.25, 0.75, 0.15806, 0, 0.59111],
1755    "48": [0, 0.64444, 0.13167, 0, 0.59111],
1756    "49": [0, 0.64444, 0.13167, 0, 0.59111],
1757    "50": [0, 0.64444, 0.13167, 0, 0.59111],
1758    "51": [0, 0.64444, 0.13167, 0, 0.59111],
1759    "52": [0.19444, 0.64444, 0.13167, 0, 0.59111],
1760    "53": [0, 0.64444, 0.13167, 0, 0.59111],
1761    "54": [0, 0.64444, 0.13167, 0, 0.59111],
1762    "55": [0.19444, 0.64444, 0.13167, 0, 0.59111],
1763    "56": [0, 0.64444, 0.13167, 0, 0.59111],
1764    "57": [0, 0.64444, 0.13167, 0, 0.59111],
1765    "58": [0, 0.44444, 0.06695, 0, 0.35555],
1766    "59": [0.19444, 0.44444, 0.06695, 0, 0.35555],
1767    "61": [-0.10889, 0.39111, 0.06833, 0, 0.88555],
1768    "63": [0, 0.69444, 0.11472, 0, 0.59111],
1769    "64": [0, 0.69444, 0.09208, 0, 0.88555],
1770    "65": [0, 0.68611, 0, 0, 0.86555],
1771    "66": [0, 0.68611, 0.0992, 0, 0.81666],
1772    "67": [0, 0.68611, 0.14208, 0, 0.82666],
1773    "68": [0, 0.68611, 0.09062, 0, 0.87555],
1774    "69": [0, 0.68611, 0.11431, 0, 0.75666],
1775    "70": [0, 0.68611, 0.12903, 0, 0.72722],
1776    "71": [0, 0.68611, 0.07347, 0, 0.89527],
1777    "72": [0, 0.68611, 0.17208, 0, 0.8961],
1778    "73": [0, 0.68611, 0.15681, 0, 0.47166],
1779    "74": [0, 0.68611, 0.145, 0, 0.61055],
1780    "75": [0, 0.68611, 0.14208, 0, 0.89499],
1781    "76": [0, 0.68611, 0, 0, 0.69777],
1782    "77": [0, 0.68611, 0.17208, 0, 1.07277],
1783    "78": [0, 0.68611, 0.17208, 0, 0.8961],
1784    "79": [0, 0.68611, 0.09062, 0, 0.85499],
1785    "80": [0, 0.68611, 0.0992, 0, 0.78721],
1786    "81": [0.19444, 0.68611, 0.09062, 0, 0.85499],
1787    "82": [0, 0.68611, 0.02559, 0, 0.85944],
1788    "83": [0, 0.68611, 0.11264, 0, 0.64999],
1789    "84": [0, 0.68611, 0.12903, 0, 0.7961],
1790    "85": [0, 0.68611, 0.17208, 0, 0.88083],
1791    "86": [0, 0.68611, 0.18625, 0, 0.86555],
1792    "87": [0, 0.68611, 0.18625, 0, 1.15999],
1793    "88": [0, 0.68611, 0.15681, 0, 0.86555],
1794    "89": [0, 0.68611, 0.19803, 0, 0.86555],
1795    "90": [0, 0.68611, 0.14208, 0, 0.70888],
1796    "91": [0.25, 0.75, 0.1875, 0, 0.35611],
1797    "93": [0.25, 0.75, 0.09972, 0, 0.35611],
1798    "94": [0, 0.69444, 0.06709, 0, 0.59111],
1799    "95": [0.31, 0.13444, 0.09811, 0, 0.59111],
1800    "97": [0, 0.44444, 0.09426, 0, 0.59111],
1801    "98": [0, 0.69444, 0.07861, 0, 0.53222],
1802    "99": [0, 0.44444, 0.05222, 0, 0.53222],
1803    "100": [0, 0.69444, 0.10861, 0, 0.59111],
1804    "101": [0, 0.44444, 0.085, 0, 0.53222],
1805    "102": [0.19444, 0.69444, 0.21778, 0, 0.4],
1806    "103": [0.19444, 0.44444, 0.105, 0, 0.53222],
1807    "104": [0, 0.69444, 0.09426, 0, 0.59111],
1808    "105": [0, 0.69326, 0.11387, 0, 0.35555],
1809    "106": [0.19444, 0.69326, 0.1672, 0, 0.35555],
1810    "107": [0, 0.69444, 0.11111, 0, 0.53222],
1811    "108": [0, 0.69444, 0.10861, 0, 0.29666],
1812    "109": [0, 0.44444, 0.09426, 0, 0.94444],
1813    "110": [0, 0.44444, 0.09426, 0, 0.64999],
1814    "111": [0, 0.44444, 0.07861, 0, 0.59111],
1815    "112": [0.19444, 0.44444, 0.07861, 0, 0.59111],
1816    "113": [0.19444, 0.44444, 0.105, 0, 0.53222],
1817    "114": [0, 0.44444, 0.11111, 0, 0.50167],
1818    "115": [0, 0.44444, 0.08167, 0, 0.48694],
1819    "116": [0, 0.63492, 0.09639, 0, 0.385],
1820    "117": [0, 0.44444, 0.09426, 0, 0.62055],
1821    "118": [0, 0.44444, 0.11111, 0, 0.53222],
1822    "119": [0, 0.44444, 0.11111, 0, 0.76777],
1823    "120": [0, 0.44444, 0.12583, 0, 0.56055],
1824    "121": [0.19444, 0.44444, 0.105, 0, 0.56166],
1825    "122": [0, 0.44444, 0.13889, 0, 0.49055],
1826    "126": [0.35, 0.34444, 0.11472, 0, 0.59111],
1827    "160": [0, 0, 0, 0, 0.25],
1828    "168": [0, 0.69444, 0.11473, 0, 0.59111],
1829    "176": [0, 0.69444, 0, 0, 0.94888],
1830    "184": [0.17014, 0, 0, 0, 0.53222],
1831    "198": [0, 0.68611, 0.11431, 0, 1.02277],
1832    "216": [0.04861, 0.73472, 0.09062, 0, 0.88555],
1833    "223": [0.19444, 0.69444, 0.09736, 0, 0.665],
1834    "230": [0, 0.44444, 0.085, 0, 0.82666],
1835    "248": [0.09722, 0.54167, 0.09458, 0, 0.59111],
1836    "305": [0, 0.44444, 0.09426, 0, 0.35555],
1837    "338": [0, 0.68611, 0.11431, 0, 1.14054],
1838    "339": [0, 0.44444, 0.085, 0, 0.82666],
1839    "567": [0.19444, 0.44444, 0.04611, 0, 0.385],
1840    "710": [0, 0.69444, 0.06709, 0, 0.59111],
1841    "711": [0, 0.63194, 0.08271, 0, 0.59111],
1842    "713": [0, 0.59444, 0.10444, 0, 0.59111],
1843    "714": [0, 0.69444, 0.08528, 0, 0.59111],
1844    "715": [0, 0.69444, 0, 0, 0.59111],
1845    "728": [0, 0.69444, 0.10333, 0, 0.59111],
1846    "729": [0, 0.69444, 0.12945, 0, 0.35555],
1847    "730": [0, 0.69444, 0, 0, 0.94888],
1848    "732": [0, 0.69444, 0.11472, 0, 0.59111],
1849    "733": [0, 0.69444, 0.11472, 0, 0.59111],
1850    "915": [0, 0.68611, 0.12903, 0, 0.69777],
1851    "916": [0, 0.68611, 0, 0, 0.94444],
1852    "920": [0, 0.68611, 0.09062, 0, 0.88555],
1853    "923": [0, 0.68611, 0, 0, 0.80666],
1854    "926": [0, 0.68611, 0.15092, 0, 0.76777],
1855    "928": [0, 0.68611, 0.17208, 0, 0.8961],
1856    "931": [0, 0.68611, 0.11431, 0, 0.82666],
1857    "933": [0, 0.68611, 0.10778, 0, 0.88555],
1858    "934": [0, 0.68611, 0.05632, 0, 0.82666],
1859    "936": [0, 0.68611, 0.10778, 0, 0.88555],
1860    "937": [0, 0.68611, 0.0992, 0, 0.82666],
1861    "8211": [0, 0.44444, 0.09811, 0, 0.59111],
1862    "8212": [0, 0.44444, 0.09811, 0, 1.18221],
1863    "8216": [0, 0.69444, 0.12945, 0, 0.35555],
1864    "8217": [0, 0.69444, 0.12945, 0, 0.35555],
1865    "8220": [0, 0.69444, 0.16772, 0, 0.62055],
1866    "8221": [0, 0.69444, 0.07939, 0, 0.62055]
1867  },
1868  "Main-Italic": {
1869    "32": [0, 0, 0, 0, 0.25],
1870    "33": [0, 0.69444, 0.12417, 0, 0.30667],
1871    "34": [0, 0.69444, 0.06961, 0, 0.51444],
1872    "35": [0.19444, 0.69444, 0.06616, 0, 0.81777],
1873    "37": [0.05556, 0.75, 0.13639, 0, 0.81777],
1874    "38": [0, 0.69444, 0.09694, 0, 0.76666],
1875    "39": [0, 0.69444, 0.12417, 0, 0.30667],
1876    "40": [0.25, 0.75, 0.16194, 0, 0.40889],
1877    "41": [0.25, 0.75, 0.03694, 0, 0.40889],
1878    "42": [0, 0.75, 0.14917, 0, 0.51111],
1879    "43": [0.05667, 0.56167, 0.03694, 0, 0.76666],
1880    "44": [0.19444, 0.10556, 0, 0, 0.30667],
1881    "45": [0, 0.43056, 0.02826, 0, 0.35778],
1882    "46": [0, 0.10556, 0, 0, 0.30667],
1883    "47": [0.25, 0.75, 0.16194, 0, 0.51111],
1884    "48": [0, 0.64444, 0.13556, 0, 0.51111],
1885    "49": [0, 0.64444, 0.13556, 0, 0.51111],
1886    "50": [0, 0.64444, 0.13556, 0, 0.51111],
1887    "51": [0, 0.64444, 0.13556, 0, 0.51111],
1888    "52": [0.19444, 0.64444, 0.13556, 0, 0.51111],
1889    "53": [0, 0.64444, 0.13556, 0, 0.51111],
1890    "54": [0, 0.64444, 0.13556, 0, 0.51111],
1891    "55": [0.19444, 0.64444, 0.13556, 0, 0.51111],
1892    "56": [0, 0.64444, 0.13556, 0, 0.51111],
1893    "57": [0, 0.64444, 0.13556, 0, 0.51111],
1894    "58": [0, 0.43056, 0.0582, 0, 0.30667],
1895    "59": [0.19444, 0.43056, 0.0582, 0, 0.30667],
1896    "61": [-0.13313, 0.36687, 0.06616, 0, 0.76666],
1897    "63": [0, 0.69444, 0.1225, 0, 0.51111],
1898    "64": [0, 0.69444, 0.09597, 0, 0.76666],
1899    "65": [0, 0.68333, 0, 0, 0.74333],
1900    "66": [0, 0.68333, 0.10257, 0, 0.70389],
1901    "67": [0, 0.68333, 0.14528, 0, 0.71555],
1902    "68": [0, 0.68333, 0.09403, 0, 0.755],
1903    "69": [0, 0.68333, 0.12028, 0, 0.67833],
1904    "70": [0, 0.68333, 0.13305, 0, 0.65277],
1905    "71": [0, 0.68333, 0.08722, 0, 0.77361],
1906    "72": [0, 0.68333, 0.16389, 0, 0.74333],
1907    "73": [0, 0.68333, 0.15806, 0, 0.38555],
1908    "74": [0, 0.68333, 0.14028, 0, 0.525],
1909    "75": [0, 0.68333, 0.14528, 0, 0.76888],
1910    "76": [0, 0.68333, 0, 0, 0.62722],
1911    "77": [0, 0.68333, 0.16389, 0, 0.89666],
1912    "78": [0, 0.68333, 0.16389, 0, 0.74333],
1913    "79": [0, 0.68333, 0.09403, 0, 0.76666],
1914    "80": [0, 0.68333, 0.10257, 0, 0.67833],
1915    "81": [0.19444, 0.68333, 0.09403, 0, 0.76666],
1916    "82": [0, 0.68333, 0.03868, 0, 0.72944],
1917    "83": [0, 0.68333, 0.11972, 0, 0.56222],
1918    "84": [0, 0.68333, 0.13305, 0, 0.71555],
1919    "85": [0, 0.68333, 0.16389, 0, 0.74333],
1920    "86": [0, 0.68333, 0.18361, 0, 0.74333],
1921    "87": [0, 0.68333, 0.18361, 0, 0.99888],
1922    "88": [0, 0.68333, 0.15806, 0, 0.74333],
1923    "89": [0, 0.68333, 0.19383, 0, 0.74333],
1924    "90": [0, 0.68333, 0.14528, 0, 0.61333],
1925    "91": [0.25, 0.75, 0.1875, 0, 0.30667],
1926    "93": [0.25, 0.75, 0.10528, 0, 0.30667],
1927    "94": [0, 0.69444, 0.06646, 0, 0.51111],
1928    "95": [0.31, 0.12056, 0.09208, 0, 0.51111],
1929    "97": [0, 0.43056, 0.07671, 0, 0.51111],
1930    "98": [0, 0.69444, 0.06312, 0, 0.46],
1931    "99": [0, 0.43056, 0.05653, 0, 0.46],
1932    "100": [0, 0.69444, 0.10333, 0, 0.51111],
1933    "101": [0, 0.43056, 0.07514, 0, 0.46],
1934    "102": [0.19444, 0.69444, 0.21194, 0, 0.30667],
1935    "103": [0.19444, 0.43056, 0.08847, 0, 0.46],
1936    "104": [0, 0.69444, 0.07671, 0, 0.51111],
1937    "105": [0, 0.65536, 0.1019, 0, 0.30667],
1938    "106": [0.19444, 0.65536, 0.14467, 0, 0.30667],
1939    "107": [0, 0.69444, 0.10764, 0, 0.46],
1940    "108": [0, 0.69444, 0.10333, 0, 0.25555],
1941    "109": [0, 0.43056, 0.07671, 0, 0.81777],
1942    "110": [0, 0.43056, 0.07671, 0, 0.56222],
1943    "111": [0, 0.43056, 0.06312, 0, 0.51111],
1944    "112": [0.19444, 0.43056, 0.06312, 0, 0.51111],
1945    "113": [0.19444, 0.43056, 0.08847, 0, 0.46],
1946    "114": [0, 0.43056, 0.10764, 0, 0.42166],
1947    "115": [0, 0.43056, 0.08208, 0, 0.40889],
1948    "116": [0, 0.61508, 0.09486, 0, 0.33222],
1949    "117": [0, 0.43056, 0.07671, 0, 0.53666],
1950    "118": [0, 0.43056, 0.10764, 0, 0.46],
1951    "119": [0, 0.43056, 0.10764, 0, 0.66444],
1952    "120": [0, 0.43056, 0.12042, 0, 0.46389],
1953    "121": [0.19444, 0.43056, 0.08847, 0, 0.48555],
1954    "122": [0, 0.43056, 0.12292, 0, 0.40889],
1955    "126": [0.35, 0.31786, 0.11585, 0, 0.51111],
1956    "160": [0, 0, 0, 0, 0.25],
1957    "168": [0, 0.66786, 0.10474, 0, 0.51111],
1958    "176": [0, 0.69444, 0, 0, 0.83129],
1959    "184": [0.17014, 0, 0, 0, 0.46],
1960    "198": [0, 0.68333, 0.12028, 0, 0.88277],
1961    "216": [0.04861, 0.73194, 0.09403, 0, 0.76666],
1962    "223": [0.19444, 0.69444, 0.10514, 0, 0.53666],
1963    "230": [0, 0.43056, 0.07514, 0, 0.71555],
1964    "248": [0.09722, 0.52778, 0.09194, 0, 0.51111],
1965    "338": [0, 0.68333, 0.12028, 0, 0.98499],
1966    "339": [0, 0.43056, 0.07514, 0, 0.71555],
1967    "710": [0, 0.69444, 0.06646, 0, 0.51111],
1968    "711": [0, 0.62847, 0.08295, 0, 0.51111],
1969    "713": [0, 0.56167, 0.10333, 0, 0.51111],
1970    "714": [0, 0.69444, 0.09694, 0, 0.51111],
1971    "715": [0, 0.69444, 0, 0, 0.51111],
1972    "728": [0, 0.69444, 0.10806, 0, 0.51111],
1973    "729": [0, 0.66786, 0.11752, 0, 0.30667],
1974    "730": [0, 0.69444, 0, 0, 0.83129],
1975    "732": [0, 0.66786, 0.11585, 0, 0.51111],
1976    "733": [0, 0.69444, 0.1225, 0, 0.51111],
1977    "915": [0, 0.68333, 0.13305, 0, 0.62722],
1978    "916": [0, 0.68333, 0, 0, 0.81777],
1979    "920": [0, 0.68333, 0.09403, 0, 0.76666],
1980    "923": [0, 0.68333, 0, 0, 0.69222],
1981    "926": [0, 0.68333, 0.15294, 0, 0.66444],
1982    "928": [0, 0.68333, 0.16389, 0, 0.74333],
1983    "931": [0, 0.68333, 0.12028, 0, 0.71555],
1984    "933": [0, 0.68333, 0.11111, 0, 0.76666],
1985    "934": [0, 0.68333, 0.05986, 0, 0.71555],
1986    "936": [0, 0.68333, 0.11111, 0, 0.76666],
1987    "937": [0, 0.68333, 0.10257, 0, 0.71555],
1988    "8211": [0, 0.43056, 0.09208, 0, 0.51111],
1989    "8212": [0, 0.43056, 0.09208, 0, 1.02222],
1990    "8216": [0, 0.69444, 0.12417, 0, 0.30667],
1991    "8217": [0, 0.69444, 0.12417, 0, 0.30667],
1992    "8220": [0, 0.69444, 0.1685, 0, 0.51444],
1993    "8221": [0, 0.69444, 0.06961, 0, 0.51444],
1994    "8463": [0, 0.68889, 0, 0, 0.54028]
1995  },
1996  "Main-Regular": {
1997    "32": [0, 0, 0, 0, 0.25],
1998    "33": [0, 0.69444, 0, 0, 0.27778],
1999    "34": [0, 0.69444, 0, 0, 0.5],
2000    "35": [0.19444, 0.69444, 0, 0, 0.83334],
2001    "36": [0.05556, 0.75, 0, 0, 0.5],
2002    "37": [0.05556, 0.75, 0, 0, 0.83334],
2003    "38": [0, 0.69444, 0, 0, 0.77778],
2004    "39": [0, 0.69444, 0, 0, 0.27778],
2005    "40": [0.25, 0.75, 0, 0, 0.38889],
2006    "41": [0.25, 0.75, 0, 0, 0.38889],
2007    "42": [0, 0.75, 0, 0, 0.5],
2008    "43": [0.08333, 0.58333, 0, 0, 0.77778],
2009    "44": [0.19444, 0.10556, 0, 0, 0.27778],
2010    "45": [0, 0.43056, 0, 0, 0.33333],
2011    "46": [0, 0.10556, 0, 0, 0.27778],
2012    "47": [0.25, 0.75, 0, 0, 0.5],
2013    "48": [0, 0.64444, 0, 0, 0.5],
2014    "49": [0, 0.64444, 0, 0, 0.5],
2015    "50": [0, 0.64444, 0, 0, 0.5],
2016    "51": [0, 0.64444, 0, 0, 0.5],
2017    "52": [0, 0.64444, 0, 0, 0.5],
2018    "53": [0, 0.64444, 0, 0, 0.5],
2019    "54": [0, 0.64444, 0, 0, 0.5],
2020    "55": [0, 0.64444, 0, 0, 0.5],
2021    "56": [0, 0.64444, 0, 0, 0.5],
2022    "57": [0, 0.64444, 0, 0, 0.5],
2023    "58": [0, 0.43056, 0, 0, 0.27778],
2024    "59": [0.19444, 0.43056, 0, 0, 0.27778],
2025    "60": [0.0391, 0.5391, 0, 0, 0.77778],
2026    "61": [-0.13313, 0.36687, 0, 0, 0.77778],
2027    "62": [0.0391, 0.5391, 0, 0, 0.77778],
2028    "63": [0, 0.69444, 0, 0, 0.47222],
2029    "64": [0, 0.69444, 0, 0, 0.77778],
2030    "65": [0, 0.68333, 0, 0, 0.75],
2031    "66": [0, 0.68333, 0, 0, 0.70834],
2032    "67": [0, 0.68333, 0, 0, 0.72222],
2033    "68": [0, 0.68333, 0, 0, 0.76389],
2034    "69": [0, 0.68333, 0, 0, 0.68056],
2035    "70": [0, 0.68333, 0, 0, 0.65278],
2036    "71": [0, 0.68333, 0, 0, 0.78472],
2037    "72": [0, 0.68333, 0, 0, 0.75],
2038    "73": [0, 0.68333, 0, 0, 0.36111],
2039    "74": [0, 0.68333, 0, 0, 0.51389],
2040    "75": [0, 0.68333, 0, 0, 0.77778],
2041    "76": [0, 0.68333, 0, 0, 0.625],
2042    "77": [0, 0.68333, 0, 0, 0.91667],
2043    "78": [0, 0.68333, 0, 0, 0.75],
2044    "79": [0, 0.68333, 0, 0, 0.77778],
2045    "80": [0, 0.68333, 0, 0, 0.68056],
2046    "81": [0.19444, 0.68333, 0, 0, 0.77778],
2047    "82": [0, 0.68333, 0, 0, 0.73611],
2048    "83": [0, 0.68333, 0, 0, 0.55556],
2049    "84": [0, 0.68333, 0, 0, 0.72222],
2050    "85": [0, 0.68333, 0, 0, 0.75],
2051    "86": [0, 0.68333, 0.01389, 0, 0.75],
2052    "87": [0, 0.68333, 0.01389, 0, 1.02778],
2053    "88": [0, 0.68333, 0, 0, 0.75],
2054    "89": [0, 0.68333, 0.025, 0, 0.75],
2055    "90": [0, 0.68333, 0, 0, 0.61111],
2056    "91": [0.25, 0.75, 0, 0, 0.27778],
2057    "92": [0.25, 0.75, 0, 0, 0.5],
2058    "93": [0.25, 0.75, 0, 0, 0.27778],
2059    "94": [0, 0.69444, 0, 0, 0.5],
2060    "95": [0.31, 0.12056, 0.02778, 0, 0.5],
2061    "97": [0, 0.43056, 0, 0, 0.5],
2062    "98": [0, 0.69444, 0, 0, 0.55556],
2063    "99": [0, 0.43056, 0, 0, 0.44445],
2064    "100": [0, 0.69444, 0, 0, 0.55556],
2065    "101": [0, 0.43056, 0, 0, 0.44445],
2066    "102": [0, 0.69444, 0.07778, 0, 0.30556],
2067    "103": [0.19444, 0.43056, 0.01389, 0, 0.5],
2068    "104": [0, 0.69444, 0, 0, 0.55556],
2069    "105": [0, 0.66786, 0, 0, 0.27778],
2070    "106": [0.19444, 0.66786, 0, 0, 0.30556],
2071    "107": [0, 0.69444, 0, 0, 0.52778],
2072    "108": [0, 0.69444, 0, 0, 0.27778],
2073    "109": [0, 0.43056, 0, 0, 0.83334],
2074    "110": [0, 0.43056, 0, 0, 0.55556],
2075    "111": [0, 0.43056, 0, 0, 0.5],
2076    "112": [0.19444, 0.43056, 0, 0, 0.55556],
2077    "113": [0.19444, 0.43056, 0, 0, 0.52778],
2078    "114": [0, 0.43056, 0, 0, 0.39167],
2079    "115": [0, 0.43056, 0, 0, 0.39445],
2080    "116": [0, 0.61508, 0, 0, 0.38889],
2081    "117": [0, 0.43056, 0, 0, 0.55556],
2082    "118": [0, 0.43056, 0.01389, 0, 0.52778],
2083    "119": [0, 0.43056, 0.01389, 0, 0.72222],
2084    "120": [0, 0.43056, 0, 0, 0.52778],
2085    "121": [0.19444, 0.43056, 0.01389, 0, 0.52778],
2086    "122": [0, 0.43056, 0, 0, 0.44445],
2087    "123": [0.25, 0.75, 0, 0, 0.5],
2088    "124": [0.25, 0.75, 0, 0, 0.27778],
2089    "125": [0.25, 0.75, 0, 0, 0.5],
2090    "126": [0.35, 0.31786, 0, 0, 0.5],
2091    "160": [0, 0, 0, 0, 0.25],
2092    "163": [0, 0.69444, 0, 0, 0.76909],
2093    "167": [0.19444, 0.69444, 0, 0, 0.44445],
2094    "168": [0, 0.66786, 0, 0, 0.5],
2095    "172": [0, 0.43056, 0, 0, 0.66667],
2096    "176": [0, 0.69444, 0, 0, 0.75],
2097    "177": [0.08333, 0.58333, 0, 0, 0.77778],
2098    "182": [0.19444, 0.69444, 0, 0, 0.61111],
2099    "184": [0.17014, 0, 0, 0, 0.44445],
2100    "198": [0, 0.68333, 0, 0, 0.90278],
2101    "215": [0.08333, 0.58333, 0, 0, 0.77778],
2102    "216": [0.04861, 0.73194, 0, 0, 0.77778],
2103    "223": [0, 0.69444, 0, 0, 0.5],
2104    "230": [0, 0.43056, 0, 0, 0.72222],
2105    "247": [0.08333, 0.58333, 0, 0, 0.77778],
vendor: 16,221 bytes, lines 2106-2475
2106    "248": [0.09722, 0.52778, 0, 0, 0.5],
2107    "305": [0, 0.43056, 0, 0, 0.27778],
2108    "338": [0, 0.68333, 0, 0, 1.01389],
2109    "339": [0, 0.43056, 0, 0, 0.77778],
2110    "567": [0.19444, 0.43056, 0, 0, 0.30556],
2111    "710": [0, 0.69444, 0, 0, 0.5],
2112    "711": [0, 0.62847, 0, 0, 0.5],
2113    "713": [0, 0.56778, 0, 0, 0.5],
2114    "714": [0, 0.69444, 0, 0, 0.5],
2115    "715": [0, 0.69444, 0, 0, 0.5],
2116    "728": [0, 0.69444, 0, 0, 0.5],
2117    "729": [0, 0.66786, 0, 0, 0.27778],
2118    "730": [0, 0.69444, 0, 0, 0.75],
2119    "732": [0, 0.66786, 0, 0, 0.5],
2120    "733": [0, 0.69444, 0, 0, 0.5],
2121    "915": [0, 0.68333, 0, 0, 0.625],
2122    "916": [0, 0.68333, 0, 0, 0.83334],
2123    "920": [0, 0.68333, 0, 0, 0.77778],
2124    "923": [0, 0.68333, 0, 0, 0.69445],
2125    "926": [0, 0.68333, 0, 0, 0.66667],
2126    "928": [0, 0.68333, 0, 0, 0.75],
2127    "931": [0, 0.68333, 0, 0, 0.72222],
2128    "933": [0, 0.68333, 0, 0, 0.77778],
2129    "934": [0, 0.68333, 0, 0, 0.72222],
2130    "936": [0, 0.68333, 0, 0, 0.77778],
2131    "937": [0, 0.68333, 0, 0, 0.72222],
2132    "8211": [0, 0.43056, 0.02778, 0, 0.5],
2133    "8212": [0, 0.43056, 0.02778, 0, 1.0],
2134    "8216": [0, 0.69444, 0, 0, 0.27778],
2135    "8217": [0, 0.69444, 0, 0, 0.27778],
2136    "8220": [0, 0.69444, 0, 0, 0.5],
2137    "8221": [0, 0.69444, 0, 0, 0.5],
2138    "8224": [0.19444, 0.69444, 0, 0, 0.44445],
2139    "8225": [0.19444, 0.69444, 0, 0, 0.44445],
2140    "8230": [0, 0.123, 0, 0, 1.172],
2141    "8242": [0, 0.55556, 0, 0, 0.275],
2142    "8407": [0, 0.71444, 0.15382, 0, 0.5],
2143    "8463": [0, 0.68889, 0, 0, 0.54028],
2144    "8465": [0, 0.69444, 0, 0, 0.72222],
2145    "8467": [0, 0.69444, 0, 0.11111, 0.41667],
2146    "8472": [0.19444, 0.43056, 0, 0.11111, 0.63646],
2147    "8476": [0, 0.69444, 0, 0, 0.72222],
2148    "8501": [0, 0.69444, 0, 0, 0.61111],
2149    "8592": [-0.13313, 0.36687, 0, 0, 1.0],
2150    "8593": [0.19444, 0.69444, 0, 0, 0.5],
2151    "8594": [-0.13313, 0.36687, 0, 0, 1.0],
2152    "8595": [0.19444, 0.69444, 0, 0, 0.5],
2153    "8596": [-0.13313, 0.36687, 0, 0, 1.0],
2154    "8597": [0.25, 0.75, 0, 0, 0.5],
2155    "8598": [0.19444, 0.69444, 0, 0, 1.0],
2156    "8599": [0.19444, 0.69444, 0, 0, 1.0],
2157    "8600": [0.19444, 0.69444, 0, 0, 1.0],
2158    "8601": [0.19444, 0.69444, 0, 0, 1.0],
2159    "8614": [0.011, 0.511, 0, 0, 1.0],
2160    "8617": [0.011, 0.511, 0, 0, 1.126],
2161    "8618": [0.011, 0.511, 0, 0, 1.126],
2162    "8636": [-0.13313, 0.36687, 0, 0, 1.0],
2163    "8637": [-0.13313, 0.36687, 0, 0, 1.0],
2164    "8640": [-0.13313, 0.36687, 0, 0, 1.0],
2165    "8641": [-0.13313, 0.36687, 0, 0, 1.0],
2166    "8652": [0.011, 0.671, 0, 0, 1.0],
2167    "8656": [-0.13313, 0.36687, 0, 0, 1.0],
2168    "8657": [0.19444, 0.69444, 0, 0, 0.61111],
2169    "8658": [-0.13313, 0.36687, 0, 0, 1.0],
2170    "8659": [0.19444, 0.69444, 0, 0, 0.61111],
2171    "8660": [-0.13313, 0.36687, 0, 0, 1.0],
2172    "8661": [0.25, 0.75, 0, 0, 0.61111],
2173    "8704": [0, 0.69444, 0, 0, 0.55556],
2174    "8706": [0, 0.69444, 0.05556, 0.08334, 0.5309],
2175    "8707": [0, 0.69444, 0, 0, 0.55556],
2176    "8709": [0.05556, 0.75, 0, 0, 0.5],
2177    "8711": [0, 0.68333, 0, 0, 0.83334],
2178    "8712": [0.0391, 0.5391, 0, 0, 0.66667],
2179    "8715": [0.0391, 0.5391, 0, 0, 0.66667],
2180    "8722": [0.08333, 0.58333, 0, 0, 0.77778],
2181    "8723": [0.08333, 0.58333, 0, 0, 0.77778],
2182    "8725": [0.25, 0.75, 0, 0, 0.5],
2183    "8726": [0.25, 0.75, 0, 0, 0.5],
2184    "8727": [-0.03472, 0.46528, 0, 0, 0.5],
2185    "8728": [-0.05555, 0.44445, 0, 0, 0.5],
2186    "8729": [-0.05555, 0.44445, 0, 0, 0.5],
2187    "8730": [0.2, 0.8, 0, 0, 0.83334],
2188    "8733": [0, 0.43056, 0, 0, 0.77778],
2189    "8734": [0, 0.43056, 0, 0, 1.0],
2190    "8736": [0, 0.69224, 0, 0, 0.72222],
2191    "8739": [0.25, 0.75, 0, 0, 0.27778],
2192    "8741": [0.25, 0.75, 0, 0, 0.5],
2193    "8743": [0, 0.55556, 0, 0, 0.66667],
2194    "8744": [0, 0.55556, 0, 0, 0.66667],
2195    "8745": [0, 0.55556, 0, 0, 0.66667],
2196    "8746": [0, 0.55556, 0, 0, 0.66667],
2197    "8747": [0.19444, 0.69444, 0.11111, 0, 0.41667],
2198    "8764": [-0.13313, 0.36687, 0, 0, 0.77778],
2199    "8768": [0.19444, 0.69444, 0, 0, 0.27778],
2200    "8771": [-0.03625, 0.46375, 0, 0, 0.77778],
2201    "8773": [-0.022, 0.589, 0, 0, 0.778],
2202    "8776": [-0.01688, 0.48312, 0, 0, 0.77778],
2203    "8781": [-0.03625, 0.46375, 0, 0, 0.77778],
2204    "8784": [-0.133, 0.673, 0, 0, 0.778],
2205    "8801": [-0.03625, 0.46375, 0, 0, 0.77778],
2206    "8804": [0.13597, 0.63597, 0, 0, 0.77778],
2207    "8805": [0.13597, 0.63597, 0, 0, 0.77778],
2208    "8810": [0.0391, 0.5391, 0, 0, 1.0],
2209    "8811": [0.0391, 0.5391, 0, 0, 1.0],
2210    "8826": [0.0391, 0.5391, 0, 0, 0.77778],
2211    "8827": [0.0391, 0.5391, 0, 0, 0.77778],
2212    "8834": [0.0391, 0.5391, 0, 0, 0.77778],
2213    "8835": [0.0391, 0.5391, 0, 0, 0.77778],
2214    "8838": [0.13597, 0.63597, 0, 0, 0.77778],
2215    "8839": [0.13597, 0.63597, 0, 0, 0.77778],
2216    "8846": [0, 0.55556, 0, 0, 0.66667],
2217    "8849": [0.13597, 0.63597, 0, 0, 0.77778],
2218    "8850": [0.13597, 0.63597, 0, 0, 0.77778],
2219    "8851": [0, 0.55556, 0, 0, 0.66667],
2220    "8852": [0, 0.55556, 0, 0, 0.66667],
2221    "8853": [0.08333, 0.58333, 0, 0, 0.77778],
2222    "8854": [0.08333, 0.58333, 0, 0, 0.77778],
2223    "8855": [0.08333, 0.58333, 0, 0, 0.77778],
2224    "8856": [0.08333, 0.58333, 0, 0, 0.77778],
2225    "8857": [0.08333, 0.58333, 0, 0, 0.77778],
2226    "8866": [0, 0.69444, 0, 0, 0.61111],
2227    "8867": [0, 0.69444, 0, 0, 0.61111],
2228    "8868": [0, 0.69444, 0, 0, 0.77778],
2229    "8869": [0, 0.69444, 0, 0, 0.77778],
2230    "8872": [0.249, 0.75, 0, 0, 0.867],
2231    "8900": [-0.05555, 0.44445, 0, 0, 0.5],
2232    "8901": [-0.05555, 0.44445, 0, 0, 0.27778],
2233    "8902": [-0.03472, 0.46528, 0, 0, 0.5],
2234    "8904": [0.005, 0.505, 0, 0, 0.9],
2235    "8942": [0.03, 0.903, 0, 0, 0.278],
2236    "8943": [-0.19, 0.313, 0, 0, 1.172],
2237    "8945": [-0.1, 0.823, 0, 0, 1.282],
2238    "8968": [0.25, 0.75, 0, 0, 0.44445],
2239    "8969": [0.25, 0.75, 0, 0, 0.44445],
2240    "8970": [0.25, 0.75, 0, 0, 0.44445],
2241    "8971": [0.25, 0.75, 0, 0, 0.44445],
2242    "8994": [-0.14236, 0.35764, 0, 0, 1.0],
2243    "8995": [-0.14236, 0.35764, 0, 0, 1.0],
2244    "9136": [0.244, 0.744, 0, 0, 0.412],
2245    "9137": [0.244, 0.745, 0, 0, 0.412],
2246    "9651": [0.19444, 0.69444, 0, 0, 0.88889],
2247    "9657": [-0.03472, 0.46528, 0, 0, 0.5],
2248    "9661": [0.19444, 0.69444, 0, 0, 0.88889],
2249    "9667": [-0.03472, 0.46528, 0, 0, 0.5],
2250    "9711": [0.19444, 0.69444, 0, 0, 1.0],
2251    "9824": [0.12963, 0.69444, 0, 0, 0.77778],
2252    "9825": [0.12963, 0.69444, 0, 0, 0.77778],
2253    "9826": [0.12963, 0.69444, 0, 0, 0.77778],
2254    "9827": [0.12963, 0.69444, 0, 0, 0.77778],
2255    "9837": [0, 0.75, 0, 0, 0.38889],
2256    "9838": [0.19444, 0.69444, 0, 0, 0.38889],
2257    "9839": [0.19444, 0.69444, 0, 0, 0.38889],
2258    "10216": [0.25, 0.75, 0, 0, 0.38889],
2259    "10217": [0.25, 0.75, 0, 0, 0.38889],
2260    "10222": [0.244, 0.744, 0, 0, 0.412],
2261    "10223": [0.244, 0.745, 0, 0, 0.412],
2262    "10229": [0.011, 0.511, 0, 0, 1.609],
2263    "10230": [0.011, 0.511, 0, 0, 1.638],
2264    "10231": [0.011, 0.511, 0, 0, 1.859],
2265    "10232": [0.024, 0.525, 0, 0, 1.609],
2266    "10233": [0.024, 0.525, 0, 0, 1.638],
2267    "10234": [0.024, 0.525, 0, 0, 1.858],
2268    "10236": [0.011, 0.511, 0, 0, 1.638],
2269    "10815": [0, 0.68333, 0, 0, 0.75],
2270    "10927": [0.13597, 0.63597, 0, 0, 0.77778],
2271    "10928": [0.13597, 0.63597, 0, 0, 0.77778],
2272    "57376": [0.19444, 0.69444, 0, 0, 0]
2273  },
2274  "Math-BoldItalic": {
2275    "32": [0, 0, 0, 0, 0.25],
2276    "48": [0, 0.44444, 0, 0, 0.575],
2277    "49": [0, 0.44444, 0, 0, 0.575],
2278    "50": [0, 0.44444, 0, 0, 0.575],
2279    "51": [0.19444, 0.44444, 0, 0, 0.575],
2280    "52": [0.19444, 0.44444, 0, 0, 0.575],
2281    "53": [0.19444, 0.44444, 0, 0, 0.575],
2282    "54": [0, 0.64444, 0, 0, 0.575],
2283    "55": [0.19444, 0.44444, 0, 0, 0.575],
2284    "56": [0, 0.64444, 0, 0, 0.575],
2285    "57": [0.19444, 0.44444, 0, 0, 0.575],
2286    "65": [0, 0.68611, 0, 0, 0.86944],
2287    "66": [0, 0.68611, 0.04835, 0, 0.8664],
2288    "67": [0, 0.68611, 0.06979, 0, 0.81694],
2289    "68": [0, 0.68611, 0.03194, 0, 0.93812],
2290    "69": [0, 0.68611, 0.05451, 0, 0.81007],
2291    "70": [0, 0.68611, 0.15972, 0, 0.68889],
2292    "71": [0, 0.68611, 0, 0, 0.88673],
2293    "72": [0, 0.68611, 0.08229, 0, 0.98229],
2294    "73": [0, 0.68611, 0.07778, 0, 0.51111],
2295    "74": [0, 0.68611, 0.10069, 0, 0.63125],
2296    "75": [0, 0.68611, 0.06979, 0, 0.97118],
2297    "76": [0, 0.68611, 0, 0, 0.75555],
2298    "77": [0, 0.68611, 0.11424, 0, 1.14201],
2299    "78": [0, 0.68611, 0.11424, 0, 0.95034],
2300    "79": [0, 0.68611, 0.03194, 0, 0.83666],
2301    "80": [0, 0.68611, 0.15972, 0, 0.72309],
2302    "81": [0.19444, 0.68611, 0, 0, 0.86861],
2303    "82": [0, 0.68611, 0.00421, 0, 0.87235],
2304    "83": [0, 0.68611, 0.05382, 0, 0.69271],
2305    "84": [0, 0.68611, 0.15972, 0, 0.63663],
2306    "85": [0, 0.68611, 0.11424, 0, 0.80027],
2307    "86": [0, 0.68611, 0.25555, 0, 0.67778],
2308    "87": [0, 0.68611, 0.15972, 0, 1.09305],
2309    "88": [0, 0.68611, 0.07778, 0, 0.94722],
2310    "89": [0, 0.68611, 0.25555, 0, 0.67458],
2311    "90": [0, 0.68611, 0.06979, 0, 0.77257],
2312    "97": [0, 0.44444, 0, 0, 0.63287],
2313    "98": [0, 0.69444, 0, 0, 0.52083],
2314    "99": [0, 0.44444, 0, 0, 0.51342],
2315    "100": [0, 0.69444, 0, 0, 0.60972],
2316    "101": [0, 0.44444, 0, 0, 0.55361],
2317    "102": [0.19444, 0.69444, 0.11042, 0, 0.56806],
2318    "103": [0.19444, 0.44444, 0.03704, 0, 0.5449],
2319    "104": [0, 0.69444, 0, 0, 0.66759],
2320    "105": [0, 0.69326, 0, 0, 0.4048],
2321    "106": [0.19444, 0.69326, 0.0622, 0, 0.47083],
2322    "107": [0, 0.69444, 0.01852, 0, 0.6037],
2323    "108": [0, 0.69444, 0.0088, 0, 0.34815],
2324    "109": [0, 0.44444, 0, 0, 1.0324],
2325    "110": [0, 0.44444, 0, 0, 0.71296],
2326    "111": [0, 0.44444, 0, 0, 0.58472],
2327    "112": [0.19444, 0.44444, 0, 0, 0.60092],
2328    "113": [0.19444, 0.44444, 0.03704, 0, 0.54213],
2329    "114": [0, 0.44444, 0.03194, 0, 0.5287],
2330    "115": [0, 0.44444, 0, 0, 0.53125],
2331    "116": [0, 0.63492, 0, 0, 0.41528],
2332    "117": [0, 0.44444, 0, 0, 0.68102],
2333    "118": [0, 0.44444, 0.03704, 0, 0.56666],
2334    "119": [0, 0.44444, 0.02778, 0, 0.83148],
2335    "120": [0, 0.44444, 0, 0, 0.65903],
2336    "121": [0.19444, 0.44444, 0.03704, 0, 0.59028],
2337    "122": [0, 0.44444, 0.04213, 0, 0.55509],
2338    "160": [0, 0, 0, 0, 0.25],
2339    "915": [0, 0.68611, 0.15972, 0, 0.65694],
2340    "916": [0, 0.68611, 0, 0, 0.95833],
2341    "920": [0, 0.68611, 0.03194, 0, 0.86722],
2342    "923": [0, 0.68611, 0, 0, 0.80555],
2343    "926": [0, 0.68611, 0.07458, 0, 0.84125],
2344    "928": [0, 0.68611, 0.08229, 0, 0.98229],
2345    "931": [0, 0.68611, 0.05451, 0, 0.88507],
2346    "933": [0, 0.68611, 0.15972, 0, 0.67083],
2347    "934": [0, 0.68611, 0, 0, 0.76666],
2348    "936": [0, 0.68611, 0.11653, 0, 0.71402],
2349    "937": [0, 0.68611, 0.04835, 0, 0.8789],
2350    "945": [0, 0.44444, 0, 0, 0.76064],
2351    "946": [0.19444, 0.69444, 0.03403, 0, 0.65972],
2352    "947": [0.19444, 0.44444, 0.06389, 0, 0.59003],
2353    "948": [0, 0.69444, 0.03819, 0, 0.52222],
2354    "949": [0, 0.44444, 0, 0, 0.52882],
2355    "950": [0.19444, 0.69444, 0.06215, 0, 0.50833],
2356    "951": [0.19444, 0.44444, 0.03704, 0, 0.6],
2357    "952": [0, 0.69444, 0.03194, 0, 0.5618],
2358    "953": [0, 0.44444, 0, 0, 0.41204],
2359    "954": [0, 0.44444, 0, 0, 0.66759],
2360    "955": [0, 0.69444, 0, 0, 0.67083],
2361    "956": [0.19444, 0.44444, 0, 0, 0.70787],
2362    "957": [0, 0.44444, 0.06898, 0, 0.57685],
2363    "958": [0.19444, 0.69444, 0.03021, 0, 0.50833],
2364    "959": [0, 0.44444, 0, 0, 0.58472],
2365    "960": [0, 0.44444, 0.03704, 0, 0.68241],
2366    "961": [0.19444, 0.44444, 0, 0, 0.6118],
2367    "962": [0.09722, 0.44444, 0.07917, 0, 0.42361],
2368    "963": [0, 0.44444, 0.03704, 0, 0.68588],
2369    "964": [0, 0.44444, 0.13472, 0, 0.52083],
2370    "965": [0, 0.44444, 0.03704, 0, 0.63055],
2371    "966": [0.19444, 0.44444, 0, 0, 0.74722],
2372    "967": [0.19444, 0.44444, 0, 0, 0.71805],
2373    "968": [0.19444, 0.69444, 0.03704, 0, 0.75833],
2374    "969": [0, 0.44444, 0.03704, 0, 0.71782],
2375    "977": [0, 0.69444, 0, 0, 0.69155],
2376    "981": [0.19444, 0.69444, 0, 0, 0.7125],
2377    "982": [0, 0.44444, 0.03194, 0, 0.975],
2378    "1009": [0.19444, 0.44444, 0, 0, 0.6118],
2379    "1013": [0, 0.44444, 0, 0, 0.48333],
2380    "57649": [0, 0.44444, 0, 0, 0.39352],
2381    "57911": [0.19444, 0.44444, 0, 0, 0.43889]
2382  },
2383  "Math-Italic": {
2384    "32": [0, 0, 0, 0, 0.25],
2385    "48": [0, 0.43056, 0, 0, 0.5],
2386    "49": [0, 0.43056, 0, 0, 0.5],
2387    "50": [0, 0.43056, 0, 0, 0.5],
2388    "51": [0.19444, 0.43056, 0, 0, 0.5],
2389    "52": [0.19444, 0.43056, 0, 0, 0.5],
2390    "53": [0.19444, 0.43056, 0, 0, 0.5],
2391    "54": [0, 0.64444, 0, 0, 0.5],
2392    "55": [0.19444, 0.43056, 0, 0, 0.5],
2393    "56": [0, 0.64444, 0, 0, 0.5],
2394    "57": [0.19444, 0.43056, 0, 0, 0.5],
2395    "65": [0, 0.68333, 0, 0.13889, 0.75],
2396    "66": [0, 0.68333, 0.05017, 0.08334, 0.75851],
2397    "67": [0, 0.68333, 0.07153, 0.08334, 0.71472],
2398    "68": [0, 0.68333, 0.02778, 0.05556, 0.82792],
2399    "69": [0, 0.68333, 0.05764, 0.08334, 0.7382],
2400    "70": [0, 0.68333, 0.13889, 0.08334, 0.64306],
2401    "71": [0, 0.68333, 0, 0.08334, 0.78625],
2402    "72": [0, 0.68333, 0.08125, 0.05556, 0.83125],
2403    "73": [0, 0.68333, 0.07847, 0.11111, 0.43958],
2404    "74": [0, 0.68333, 0.09618, 0.16667, 0.55451],
2405    "75": [0, 0.68333, 0.07153, 0.05556, 0.84931],
2406    "76": [0, 0.68333, 0, 0.02778, 0.68056],
2407    "77": [0, 0.68333, 0.10903, 0.08334, 0.97014],
2408    "78": [0, 0.68333, 0.10903, 0.08334, 0.80347],
2409    "79": [0, 0.68333, 0.02778, 0.08334, 0.76278],
2410    "80": [0, 0.68333, 0.13889, 0.08334, 0.64201],
2411    "81": [0.19444, 0.68333, 0, 0.08334, 0.79056],
2412    "82": [0, 0.68333, 0.00773, 0.08334, 0.75929],
2413    "83": [0, 0.68333, 0.05764, 0.08334, 0.6132],
2414    "84": [0, 0.68333, 0.13889, 0.08334, 0.58438],
2415    "85": [0, 0.68333, 0.10903, 0.02778, 0.68278],
2416    "86": [0, 0.68333, 0.22222, 0, 0.58333],
2417    "87": [0, 0.68333, 0.13889, 0, 0.94445],
2418    "88": [0, 0.68333, 0.07847, 0.08334, 0.82847],
2419    "89": [0, 0.68333, 0.22222, 0, 0.58056],
2420    "90": [0, 0.68333, 0.07153, 0.08334, 0.68264],
2421    "97": [0, 0.43056, 0, 0, 0.52859],
2422    "98": [0, 0.69444, 0, 0, 0.42917],
2423    "99": [0, 0.43056, 0, 0.05556, 0.43276],
2424    "100": [0, 0.69444, 0, 0.16667, 0.52049],
2425    "101": [0, 0.43056, 0, 0.05556, 0.46563],
2426    "102": [0.19444, 0.69444, 0.10764, 0.16667, 0.48959],
2427    "103": [0.19444, 0.43056, 0.03588, 0.02778, 0.47697],
2428    "104": [0, 0.69444, 0, 0, 0.57616],
2429    "105": [0, 0.65952, 0, 0, 0.34451],
2430    "106": [0.19444, 0.65952, 0.05724, 0, 0.41181],
2431    "107": [0, 0.69444, 0.03148, 0, 0.5206],
2432    "108": [0, 0.69444, 0.01968, 0.08334, 0.29838],
2433    "109": [0, 0.43056, 0, 0, 0.87801],
2434    "110": [0, 0.43056, 0, 0, 0.60023],
2435    "111": [0, 0.43056, 0, 0.05556, 0.48472],
2436    "112": [0.19444, 0.43056, 0, 0.08334, 0.50313],
2437    "113": [0.19444, 0.43056, 0.03588, 0.08334, 0.44641],
2438    "114": [0, 0.43056, 0.02778, 0.05556, 0.45116],
2439    "115": [0, 0.43056, 0, 0.05556, 0.46875],
2440    "116": [0, 0.61508, 0, 0.08334, 0.36111],
2441    "117": [0, 0.43056, 0, 0.02778, 0.57246],
2442    "118": [0, 0.43056, 0.03588, 0.02778, 0.48472],
2443    "119": [0, 0.43056, 0.02691, 0.08334, 0.71592],
2444    "120": [0, 0.43056, 0, 0.02778, 0.57153],
2445    "121": [0.19444, 0.43056, 0.03588, 0.05556, 0.49028],
2446    "122": [0, 0.43056, 0.04398, 0.05556, 0.46505],
2447    "160": [0, 0, 0, 0, 0.25],
2448    "915": [0, 0.68333, 0.13889, 0.08334, 0.61528],
2449    "916": [0, 0.68333, 0, 0.16667, 0.83334],
2450    "920": [0, 0.68333, 0.02778, 0.08334, 0.76278],
2451    "923": [0, 0.68333, 0, 0.16667, 0.69445],
2452    "926": [0, 0.68333, 0.07569, 0.08334, 0.74236],
2453    "928": [0, 0.68333, 0.08125, 0.05556, 0.83125],
2454    "931": [0, 0.68333, 0.05764, 0.08334, 0.77986],
2455    "933": [0, 0.68333, 0.13889, 0.05556, 0.58333],
2456    "934": [0, 0.68333, 0, 0.08334, 0.66667],
2457    "936": [0, 0.68333, 0.11, 0.05556, 0.61222],
2458    "937": [0, 0.68333, 0.05017, 0.08334, 0.7724],
2459    "945": [0, 0.43056, 0.0037, 0.02778, 0.6397],
2460    "946": [0.19444, 0.69444, 0.05278, 0.08334, 0.56563],
2461    "947": [0.19444, 0.43056, 0.05556, 0, 0.51773],
2462    "948": [0, 0.69444, 0.03785, 0.05556, 0.44444],
2463    "949": [0, 0.43056, 0, 0.08334, 0.46632],
2464    "950": [0.19444, 0.69444, 0.07378, 0.08334, 0.4375],
2465    "951": [0.19444, 0.43056, 0.03588, 0.05556, 0.49653],
2466    "952": [0, 0.69444, 0.02778, 0.08334, 0.46944],
2467    "953": [0, 0.43056, 0, 0.05556, 0.35394],
2468    "954": [0, 0.43056, 0, 0, 0.57616],
2469    "955": [0, 0.69444, 0, 0, 0.58334],
2470    "956": [0.19444, 0.43056, 0, 0.02778, 0.60255],
2471    "957": [0, 0.43056, 0.06366, 0.02778, 0.49398],
2472    "958": [0.19444, 0.69444, 0.04601, 0.11111, 0.4375],
2473    "959": [0, 0.43056, 0, 0.05556, 0.48472],
2474    "960": [0, 0.43056, 0.03588, 0, 0.57003],
2475    "961": [0.19444, 0.43056, 0, 0.08334, 0.51702],
vendor: 5,671 bytes, lines 2476-2616
2476    "962": [0.09722, 0.43056, 0.07986, 0.08334, 0.36285],
2477    "963": [0, 0.43056, 0.03588, 0, 0.57141],
2478    "964": [0, 0.43056, 0.1132, 0.02778, 0.43715],
2479    "965": [0, 0.43056, 0.03588, 0.02778, 0.54028],
2480    "966": [0.19444, 0.43056, 0, 0.08334, 0.65417],
2481    "967": [0.19444, 0.43056, 0, 0.05556, 0.62569],
2482    "968": [0.19444, 0.69444, 0.03588, 0.11111, 0.65139],
2483    "969": [0, 0.43056, 0.03588, 0, 0.62245],
2484    "977": [0, 0.69444, 0, 0.08334, 0.59144],
2485    "981": [0.19444, 0.69444, 0, 0.08334, 0.59583],
2486    "982": [0, 0.43056, 0.02778, 0, 0.82813],
2487    "1009": [0.19444, 0.43056, 0, 0.08334, 0.51702],
2488    "1013": [0, 0.43056, 0, 0.05556, 0.4059],
2489    "57649": [0, 0.43056, 0, 0.02778, 0.32246],
2490    "57911": [0.19444, 0.43056, 0, 0.08334, 0.38403]
2491  },
2492  "SansSerif-Bold": {
2493    "32": [0, 0, 0, 0, 0.25],
2494    "33": [0, 0.69444, 0, 0, 0.36667],
2495    "34": [0, 0.69444, 0, 0, 0.55834],
2496    "35": [0.19444, 0.69444, 0, 0, 0.91667],
2497    "36": [0.05556, 0.75, 0, 0, 0.55],
2498    "37": [0.05556, 0.75, 0, 0, 1.02912],
2499    "38": [0, 0.69444, 0, 0, 0.83056],
2500    "39": [0, 0.69444, 0, 0, 0.30556],
2501    "40": [0.25, 0.75, 0, 0, 0.42778],
2502    "41": [0.25, 0.75, 0, 0, 0.42778],
2503    "42": [0, 0.75, 0, 0, 0.55],
2504    "43": [0.11667, 0.61667, 0, 0, 0.85556],
2505    "44": [0.10556, 0.13056, 0, 0, 0.30556],
2506    "45": [0, 0.45833, 0, 0, 0.36667],
2507    "46": [0, 0.13056, 0, 0, 0.30556],
2508    "47": [0.25, 0.75, 0, 0, 0.55],
2509    "48": [0, 0.69444, 0, 0, 0.55],
2510    "49": [0, 0.69444, 0, 0, 0.55],
2511    "50": [0, 0.69444, 0, 0, 0.55],
2512    "51": [0, 0.69444, 0, 0, 0.55],
2513    "52": [0, 0.69444, 0, 0, 0.55],
2514    "53": [0, 0.69444, 0, 0, 0.55],
2515    "54": [0, 0.69444, 0, 0, 0.55],
2516    "55": [0, 0.69444, 0, 0, 0.55],
2517    "56": [0, 0.69444, 0, 0, 0.55],
2518    "57": [0, 0.69444, 0, 0, 0.55],
2519    "58": [0, 0.45833, 0, 0, 0.30556],
2520    "59": [0.10556, 0.45833, 0, 0, 0.30556],
2521    "61": [-0.09375, 0.40625, 0, 0, 0.85556],
2522    "63": [0, 0.69444, 0, 0, 0.51945],
2523    "64": [0, 0.69444, 0, 0, 0.73334],
2524    "65": [0, 0.69444, 0, 0, 0.73334],
2525    "66": [0, 0.69444, 0, 0, 0.73334],
2526    "67": [0, 0.69444, 0, 0, 0.70278],
2527    "68": [0, 0.69444, 0, 0, 0.79445],
2528    "69": [0, 0.69444, 0, 0, 0.64167],
2529    "70": [0, 0.69444, 0, 0, 0.61111],
2530    "71": [0, 0.69444, 0, 0, 0.73334],
2531    "72": [0, 0.69444, 0, 0, 0.79445],
2532    "73": [0, 0.69444, 0, 0, 0.33056],
2533    "74": [0, 0.69444, 0, 0, 0.51945],
2534    "75": [0, 0.69444, 0, 0, 0.76389],
2535    "76": [0, 0.69444, 0, 0, 0.58056],
2536    "77": [0, 0.69444, 0, 0, 0.97778],
2537    "78": [0, 0.69444, 0, 0, 0.79445],
2538    "79": [0, 0.69444, 0, 0, 0.79445],
2539    "80": [0, 0.69444, 0, 0, 0.70278],
2540    "81": [0.10556, 0.69444, 0, 0, 0.79445],
2541    "82": [0, 0.69444, 0, 0, 0.70278],
2542    "83": [0, 0.69444, 0, 0, 0.61111],
2543    "84": [0, 0.69444, 0, 0, 0.73334],
2544    "85": [0, 0.69444, 0, 0, 0.76389],
2545    "86": [0, 0.69444, 0.01528, 0, 0.73334],
2546    "87": [0, 0.69444, 0.01528, 0, 1.03889],
2547    "88": [0, 0.69444, 0, 0, 0.73334],
2548    "89": [0, 0.69444, 0.0275, 0, 0.73334],
2549    "90": [0, 0.69444, 0, 0, 0.67223],
2550    "91": [0.25, 0.75, 0, 0, 0.34306],
2551    "93": [0.25, 0.75, 0, 0, 0.34306],
2552    "94": [0, 0.69444, 0, 0, 0.55],
2553    "95": [0.35, 0.10833, 0.03056, 0, 0.55],
2554    "97": [0, 0.45833, 0, 0, 0.525],
2555    "98": [0, 0.69444, 0, 0, 0.56111],
2556    "99": [0, 0.45833, 0, 0, 0.48889],
2557    "100": [0, 0.69444, 0, 0, 0.56111],
2558    "101": [0, 0.45833, 0, 0, 0.51111],
2559    "102": [0, 0.69444, 0.07639, 0, 0.33611],
2560    "103": [0.19444, 0.45833, 0.01528, 0, 0.55],
2561    "104": [0, 0.69444, 0, 0, 0.56111],
2562    "105": [0, 0.69444, 0, 0, 0.25556],
2563    "106": [0.19444, 0.69444, 0, 0, 0.28611],
2564    "107": [0, 0.69444, 0, 0, 0.53056],
2565    "108": [0, 0.69444, 0, 0, 0.25556],
2566    "109": [0, 0.45833, 0, 0, 0.86667],
2567    "110": [0, 0.45833, 0, 0, 0.56111],
2568    "111": [0, 0.45833, 0, 0, 0.55],
2569    "112": [0.19444, 0.45833, 0, 0, 0.56111],
2570    "113": [0.19444, 0.45833, 0, 0, 0.56111],
2571    "114": [0, 0.45833, 0.01528, 0, 0.37222],
2572    "115": [0, 0.45833, 0, 0, 0.42167],
2573    "116": [0, 0.58929, 0, 0, 0.40417],
2574    "117": [0, 0.45833, 0, 0, 0.56111],
2575    "118": [0, 0.45833, 0.01528, 0, 0.5],
2576    "119": [0, 0.45833, 0.01528, 0, 0.74445],
2577    "120": [0, 0.45833, 0, 0, 0.5],
2578    "121": [0.19444, 0.45833, 0.01528, 0, 0.5],
2579    "122": [0, 0.45833, 0, 0, 0.47639],
2580    "126": [0.35, 0.34444, 0, 0, 0.55],
2581    "160": [0, 0, 0, 0, 0.25],
2582    "168": [0, 0.69444, 0, 0, 0.55],
2583    "176": [0, 0.69444, 0, 0, 0.73334],
2584    "180": [0, 0.69444, 0, 0, 0.55],
2585    "184": [0.17014, 0, 0, 0, 0.48889],
2586    "305": [0, 0.45833, 0, 0, 0.25556],
2587    "567": [0.19444, 0.45833, 0, 0, 0.28611],
2588    "710": [0, 0.69444, 0, 0, 0.55],
2589    "711": [0, 0.63542, 0, 0, 0.55],
2590    "713": [0, 0.63778, 0, 0, 0.55],
2591    "728": [0, 0.69444, 0, 0, 0.55],
2592    "729": [0, 0.69444, 0, 0, 0.30556],
2593    "730": [0, 0.69444, 0, 0, 0.73334],
2594    "732": [0, 0.69444, 0, 0, 0.55],
2595    "733": [0, 0.69444, 0, 0, 0.55],
2596    "915": [0, 0.69444, 0, 0, 0.58056],
2597    "916": [0, 0.69444, 0, 0, 0.91667],
2598    "920": [0, 0.69444, 0, 0, 0.85556],
2599    "923": [0, 0.69444, 0, 0, 0.67223],
2600    "926": [0, 0.69444, 0, 0, 0.73334],
2601    "928": [0, 0.69444, 0, 0, 0.79445],
2602    "931": [0, 0.69444, 0, 0, 0.79445],
2603    "933": [0, 0.69444, 0, 0, 0.85556],
2604    "934": [0, 0.69444, 0, 0, 0.79445],
2605    "936": [0, 0.69444, 0, 0, 0.85556],
2606    "937": [0, 0.69444, 0, 0, 0.79445],
2607    "8211": [0, 0.45833, 0.03056, 0, 0.55],
2608    "8212": [0, 0.45833, 0.03056, 0, 1.10001],
2609    "8216": [0, 0.69444, 0, 0, 0.30556],
2610    "8217": [0, 0.69444, 0, 0, 0.30556],
2611    "8220": [0, 0.69444, 0, 0, 0.55834],
2612    "8221": [0, 0.69444, 0, 0, 0.55834]
2613  },
2614  "SansSerif-Italic": {
2615    "32": [0, 0, 0, 0, 0.25],
2616    "33": [0, 0.69444, 0.05733, 0, 0.31945],
vendor: 17,727 bytes, lines 2617-3050
2617    "34": [0, 0.69444, 0.00316, 0, 0.5],
2618    "35": [0.19444, 0.69444, 0.05087, 0, 0.83334],
2619    "36": [0.05556, 0.75, 0.11156, 0, 0.5],
2620    "37": [0.05556, 0.75, 0.03126, 0, 0.83334],
2621    "38": [0, 0.69444, 0.03058, 0, 0.75834],
2622    "39": [0, 0.69444, 0.07816, 0, 0.27778],
2623    "40": [0.25, 0.75, 0.13164, 0, 0.38889],
2624    "41": [0.25, 0.75, 0.02536, 0, 0.38889],
2625    "42": [0, 0.75, 0.11775, 0, 0.5],
2626    "43": [0.08333, 0.58333, 0.02536, 0, 0.77778],
2627    "44": [0.125, 0.08333, 0, 0, 0.27778],
2628    "45": [0, 0.44444, 0.01946, 0, 0.33333],
2629    "46": [0, 0.08333, 0, 0, 0.27778],
2630    "47": [0.25, 0.75, 0.13164, 0, 0.5],
2631    "48": [0, 0.65556, 0.11156, 0, 0.5],
2632    "49": [0, 0.65556, 0.11156, 0, 0.5],
2633    "50": [0, 0.65556, 0.11156, 0, 0.5],
2634    "51": [0, 0.65556, 0.11156, 0, 0.5],
2635    "52": [0, 0.65556, 0.11156, 0, 0.5],
2636    "53": [0, 0.65556, 0.11156, 0, 0.5],
2637    "54": [0, 0.65556, 0.11156, 0, 0.5],
2638    "55": [0, 0.65556, 0.11156, 0, 0.5],
2639    "56": [0, 0.65556, 0.11156, 0, 0.5],
2640    "57": [0, 0.65556, 0.11156, 0, 0.5],
2641    "58": [0, 0.44444, 0.02502, 0, 0.27778],
2642    "59": [0.125, 0.44444, 0.02502, 0, 0.27778],
2643    "61": [-0.13, 0.37, 0.05087, 0, 0.77778],
2644    "63": [0, 0.69444, 0.11809, 0, 0.47222],
2645    "64": [0, 0.69444, 0.07555, 0, 0.66667],
2646    "65": [0, 0.69444, 0, 0, 0.66667],
2647    "66": [0, 0.69444, 0.08293, 0, 0.66667],
2648    "67": [0, 0.69444, 0.11983, 0, 0.63889],
2649    "68": [0, 0.69444, 0.07555, 0, 0.72223],
2650    "69": [0, 0.69444, 0.11983, 0, 0.59722],
2651    "70": [0, 0.69444, 0.13372, 0, 0.56945],
2652    "71": [0, 0.69444, 0.11983, 0, 0.66667],
2653    "72": [0, 0.69444, 0.08094, 0, 0.70834],
2654    "73": [0, 0.69444, 0.13372, 0, 0.27778],
2655    "74": [0, 0.69444, 0.08094, 0, 0.47222],
2656    "75": [0, 0.69444, 0.11983, 0, 0.69445],
2657    "76": [0, 0.69444, 0, 0, 0.54167],
2658    "77": [0, 0.69444, 0.08094, 0, 0.875],
2659    "78": [0, 0.69444, 0.08094, 0, 0.70834],
2660    "79": [0, 0.69444, 0.07555, 0, 0.73611],
2661    "80": [0, 0.69444, 0.08293, 0, 0.63889],
2662    "81": [0.125, 0.69444, 0.07555, 0, 0.73611],
2663    "82": [0, 0.69444, 0.08293, 0, 0.64584],
2664    "83": [0, 0.69444, 0.09205, 0, 0.55556],
2665    "84": [0, 0.69444, 0.13372, 0, 0.68056],
2666    "85": [0, 0.69444, 0.08094, 0, 0.6875],
2667    "86": [0, 0.69444, 0.1615, 0, 0.66667],
2668    "87": [0, 0.69444, 0.1615, 0, 0.94445],
2669    "88": [0, 0.69444, 0.13372, 0, 0.66667],
2670    "89": [0, 0.69444, 0.17261, 0, 0.66667],
2671    "90": [0, 0.69444, 0.11983, 0, 0.61111],
2672    "91": [0.25, 0.75, 0.15942, 0, 0.28889],
2673    "93": [0.25, 0.75, 0.08719, 0, 0.28889],
2674    "94": [0, 0.69444, 0.0799, 0, 0.5],
2675    "95": [0.35, 0.09444, 0.08616, 0, 0.5],
2676    "97": [0, 0.44444, 0.00981, 0, 0.48056],
2677    "98": [0, 0.69444, 0.03057, 0, 0.51667],
2678    "99": [0, 0.44444, 0.08336, 0, 0.44445],
2679    "100": [0, 0.69444, 0.09483, 0, 0.51667],
2680    "101": [0, 0.44444, 0.06778, 0, 0.44445],
2681    "102": [0, 0.69444, 0.21705, 0, 0.30556],
2682    "103": [0.19444, 0.44444, 0.10836, 0, 0.5],
2683    "104": [0, 0.69444, 0.01778, 0, 0.51667],
2684    "105": [0, 0.67937, 0.09718, 0, 0.23889],
2685    "106": [0.19444, 0.67937, 0.09162, 0, 0.26667],
2686    "107": [0, 0.69444, 0.08336, 0, 0.48889],
2687    "108": [0, 0.69444, 0.09483, 0, 0.23889],
2688    "109": [0, 0.44444, 0.01778, 0, 0.79445],
2689    "110": [0, 0.44444, 0.01778, 0, 0.51667],
2690    "111": [0, 0.44444, 0.06613, 0, 0.5],
2691    "112": [0.19444, 0.44444, 0.0389, 0, 0.51667],
2692    "113": [0.19444, 0.44444, 0.04169, 0, 0.51667],
2693    "114": [0, 0.44444, 0.10836, 0, 0.34167],
2694    "115": [0, 0.44444, 0.0778, 0, 0.38333],
2695    "116": [0, 0.57143, 0.07225, 0, 0.36111],
2696    "117": [0, 0.44444, 0.04169, 0, 0.51667],
2697    "118": [0, 0.44444, 0.10836, 0, 0.46111],
2698    "119": [0, 0.44444, 0.10836, 0, 0.68334],
2699    "120": [0, 0.44444, 0.09169, 0, 0.46111],
2700    "121": [0.19444, 0.44444, 0.10836, 0, 0.46111],
2701    "122": [0, 0.44444, 0.08752, 0, 0.43472],
2702    "126": [0.35, 0.32659, 0.08826, 0, 0.5],
2703    "160": [0, 0, 0, 0, 0.25],
2704    "168": [0, 0.67937, 0.06385, 0, 0.5],
2705    "176": [0, 0.69444, 0, 0, 0.73752],
2706    "184": [0.17014, 0, 0, 0, 0.44445],
2707    "305": [0, 0.44444, 0.04169, 0, 0.23889],
2708    "567": [0.19444, 0.44444, 0.04169, 0, 0.26667],
2709    "710": [0, 0.69444, 0.0799, 0, 0.5],
2710    "711": [0, 0.63194, 0.08432, 0, 0.5],
2711    "713": [0, 0.60889, 0.08776, 0, 0.5],
2712    "714": [0, 0.69444, 0.09205, 0, 0.5],
2713    "715": [0, 0.69444, 0, 0, 0.5],
2714    "728": [0, 0.69444, 0.09483, 0, 0.5],
2715    "729": [0, 0.67937, 0.07774, 0, 0.27778],
2716    "730": [0, 0.69444, 0, 0, 0.73752],
2717    "732": [0, 0.67659, 0.08826, 0, 0.5],
2718    "733": [0, 0.69444, 0.09205, 0, 0.5],
2719    "915": [0, 0.69444, 0.13372, 0, 0.54167],
2720    "916": [0, 0.69444, 0, 0, 0.83334],
2721    "920": [0, 0.69444, 0.07555, 0, 0.77778],
2722    "923": [0, 0.69444, 0, 0, 0.61111],
2723    "926": [0, 0.69444, 0.12816, 0, 0.66667],
2724    "928": [0, 0.69444, 0.08094, 0, 0.70834],
2725    "931": [0, 0.69444, 0.11983, 0, 0.72222],
2726    "933": [0, 0.69444, 0.09031, 0, 0.77778],
2727    "934": [0, 0.69444, 0.04603, 0, 0.72222],
2728    "936": [0, 0.69444, 0.09031, 0, 0.77778],
2729    "937": [0, 0.69444, 0.08293, 0, 0.72222],
2730    "8211": [0, 0.44444, 0.08616, 0, 0.5],
2731    "8212": [0, 0.44444, 0.08616, 0, 1.0],
2732    "8216": [0, 0.69444, 0.07816, 0, 0.27778],
2733    "8217": [0, 0.69444, 0.07816, 0, 0.27778],
2734    "8220": [0, 0.69444, 0.14205, 0, 0.5],
2735    "8221": [0, 0.69444, 0.00316, 0, 0.5]
2736  },
2737  "SansSerif-Regular": {
2738    "32": [0, 0, 0, 0, 0.25],
2739    "33": [0, 0.69444, 0, 0, 0.31945],
2740    "34": [0, 0.69444, 0, 0, 0.5],
2741    "35": [0.19444, 0.69444, 0, 0, 0.83334],
2742    "36": [0.05556, 0.75, 0, 0, 0.5],
2743    "37": [0.05556, 0.75, 0, 0, 0.83334],
2744    "38": [0, 0.69444, 0, 0, 0.75834],
2745    "39": [0, 0.69444, 0, 0, 0.27778],
2746    "40": [0.25, 0.75, 0, 0, 0.38889],
2747    "41": [0.25, 0.75, 0, 0, 0.38889],
2748    "42": [0, 0.75, 0, 0, 0.5],
2749    "43": [0.08333, 0.58333, 0, 0, 0.77778],
2750    "44": [0.125, 0.08333, 0, 0, 0.27778],
2751    "45": [0, 0.44444, 0, 0, 0.33333],
2752    "46": [0, 0.08333, 0, 0, 0.27778],
2753    "47": [0.25, 0.75, 0, 0, 0.5],
2754    "48": [0, 0.65556, 0, 0, 0.5],
2755    "49": [0, 0.65556, 0, 0, 0.5],
2756    "50": [0, 0.65556, 0, 0, 0.5],
2757    "51": [0, 0.65556, 0, 0, 0.5],
2758    "52": [0, 0.65556, 0, 0, 0.5],
2759    "53": [0, 0.65556, 0, 0, 0.5],
2760    "54": [0, 0.65556, 0, 0, 0.5],
2761    "55": [0, 0.65556, 0, 0, 0.5],
2762    "56": [0, 0.65556, 0, 0, 0.5],
2763    "57": [0, 0.65556, 0, 0, 0.5],
2764    "58": [0, 0.44444, 0, 0, 0.27778],
2765    "59": [0.125, 0.44444, 0, 0, 0.27778],
2766    "61": [-0.13, 0.37, 0, 0, 0.77778],
2767    "63": [0, 0.69444, 0, 0, 0.47222],
2768    "64": [0, 0.69444, 0, 0, 0.66667],
2769    "65": [0, 0.69444, 0, 0, 0.66667],
2770    "66": [0, 0.69444, 0, 0, 0.66667],
2771    "67": [0, 0.69444, 0, 0, 0.63889],
2772    "68": [0, 0.69444, 0, 0, 0.72223],
2773    "69": [0, 0.69444, 0, 0, 0.59722],
2774    "70": [0, 0.69444, 0, 0, 0.56945],
2775    "71": [0, 0.69444, 0, 0, 0.66667],
2776    "72": [0, 0.69444, 0, 0, 0.70834],
2777    "73": [0, 0.69444, 0, 0, 0.27778],
2778    "74": [0, 0.69444, 0, 0, 0.47222],
2779    "75": [0, 0.69444, 0, 0, 0.69445],
2780    "76": [0, 0.69444, 0, 0, 0.54167],
2781    "77": [0, 0.69444, 0, 0, 0.875],
2782    "78": [0, 0.69444, 0, 0, 0.70834],
2783    "79": [0, 0.69444, 0, 0, 0.73611],
2784    "80": [0, 0.69444, 0, 0, 0.63889],
2785    "81": [0.125, 0.69444, 0, 0, 0.73611],
2786    "82": [0, 0.69444, 0, 0, 0.64584],
2787    "83": [0, 0.69444, 0, 0, 0.55556],
2788    "84": [0, 0.69444, 0, 0, 0.68056],
2789    "85": [0, 0.69444, 0, 0, 0.6875],
2790    "86": [0, 0.69444, 0.01389, 0, 0.66667],
2791    "87": [0, 0.69444, 0.01389, 0, 0.94445],
2792    "88": [0, 0.69444, 0, 0, 0.66667],
2793    "89": [0, 0.69444, 0.025, 0, 0.66667],
2794    "90": [0, 0.69444, 0, 0, 0.61111],
2795    "91": [0.25, 0.75, 0, 0, 0.28889],
2796    "93": [0.25, 0.75, 0, 0, 0.28889],
2797    "94": [0, 0.69444, 0, 0, 0.5],
2798    "95": [0.35, 0.09444, 0.02778, 0, 0.5],
2799    "97": [0, 0.44444, 0, 0, 0.48056],
2800    "98": [0, 0.69444, 0, 0, 0.51667],
2801    "99": [0, 0.44444, 0, 0, 0.44445],
2802    "100": [0, 0.69444, 0, 0, 0.51667],
2803    "101": [0, 0.44444, 0, 0, 0.44445],
2804    "102": [0, 0.69444, 0.06944, 0, 0.30556],
2805    "103": [0.19444, 0.44444, 0.01389, 0, 0.5],
2806    "104": [0, 0.69444, 0, 0, 0.51667],
2807    "105": [0, 0.67937, 0, 0, 0.23889],
2808    "106": [0.19444, 0.67937, 0, 0, 0.26667],
2809    "107": [0, 0.69444, 0, 0, 0.48889],
2810    "108": [0, 0.69444, 0, 0, 0.23889],
2811    "109": [0, 0.44444, 0, 0, 0.79445],
2812    "110": [0, 0.44444, 0, 0, 0.51667],
2813    "111": [0, 0.44444, 0, 0, 0.5],
2814    "112": [0.19444, 0.44444, 0, 0, 0.51667],
2815    "113": [0.19444, 0.44444, 0, 0, 0.51667],
2816    "114": [0, 0.44444, 0.01389, 0, 0.34167],
2817    "115": [0, 0.44444, 0, 0, 0.38333],
2818    "116": [0, 0.57143, 0, 0, 0.36111],
2819    "117": [0, 0.44444, 0, 0, 0.51667],
2820    "118": [0, 0.44444, 0.01389, 0, 0.46111],
2821    "119": [0, 0.44444, 0.01389, 0, 0.68334],
2822    "120": [0, 0.44444, 0, 0, 0.46111],
2823    "121": [0.19444, 0.44444, 0.01389, 0, 0.46111],
2824    "122": [0, 0.44444, 0, 0, 0.43472],
2825    "126": [0.35, 0.32659, 0, 0, 0.5],
2826    "160": [0, 0, 0, 0, 0.25],
2827    "168": [0, 0.67937, 0, 0, 0.5],
2828    "176": [0, 0.69444, 0, 0, 0.66667],
2829    "184": [0.17014, 0, 0, 0, 0.44445],
2830    "305": [0, 0.44444, 0, 0, 0.23889],
2831    "567": [0.19444, 0.44444, 0, 0, 0.26667],
2832    "710": [0, 0.69444, 0, 0, 0.5],
2833    "711": [0, 0.63194, 0, 0, 0.5],
2834    "713": [0, 0.60889, 0, 0, 0.5],
2835    "714": [0, 0.69444, 0, 0, 0.5],
2836    "715": [0, 0.69444, 0, 0, 0.5],
2837    "728": [0, 0.69444, 0, 0, 0.5],
2838    "729": [0, 0.67937, 0, 0, 0.27778],
2839    "730": [0, 0.69444, 0, 0, 0.66667],
2840    "732": [0, 0.67659, 0, 0, 0.5],
2841    "733": [0, 0.69444, 0, 0, 0.5],
2842    "915": [0, 0.69444, 0, 0, 0.54167],
2843    "916": [0, 0.69444, 0, 0, 0.83334],
2844    "920": [0, 0.69444, 0, 0, 0.77778],
2845    "923": [0, 0.69444, 0, 0, 0.61111],
2846    "926": [0, 0.69444, 0, 0, 0.66667],
2847    "928": [0, 0.69444, 0, 0, 0.70834],
2848    "931": [0, 0.69444, 0, 0, 0.72222],
2849    "933": [0, 0.69444, 0, 0, 0.77778],
2850    "934": [0, 0.69444, 0, 0, 0.72222],
2851    "936": [0, 0.69444, 0, 0, 0.77778],
2852    "937": [0, 0.69444, 0, 0, 0.72222],
2853    "8211": [0, 0.44444, 0.02778, 0, 0.5],
2854    "8212": [0, 0.44444, 0.02778, 0, 1.0],
2855    "8216": [0, 0.69444, 0, 0, 0.27778],
2856    "8217": [0, 0.69444, 0, 0, 0.27778],
2857    "8220": [0, 0.69444, 0, 0, 0.5],
2858    "8221": [0, 0.69444, 0, 0, 0.5]
2859  },
2860  "Script-Regular": {
2861    "32": [0, 0, 0, 0, 0.25],
2862    "65": [0, 0.7, 0.22925, 0, 0.80253],
2863    "66": [0, 0.7, 0.04087, 0, 0.90757],
2864    "67": [0, 0.7, 0.1689, 0, 0.66619],
2865    "68": [0, 0.7, 0.09371, 0, 0.77443],
2866    "69": [0, 0.7, 0.18583, 0, 0.56162],
2867    "70": [0, 0.7, 0.13634, 0, 0.89544],
2868    "71": [0, 0.7, 0.17322, 0, 0.60961],
2869    "72": [0, 0.7, 0.29694, 0, 0.96919],
2870    "73": [0, 0.7, 0.19189, 0, 0.80907],
2871    "74": [0.27778, 0.7, 0.19189, 0, 1.05159],
2872    "75": [0, 0.7, 0.31259, 0, 0.91364],
2873    "76": [0, 0.7, 0.19189, 0, 0.87373],
2874    "77": [0, 0.7, 0.15981, 0, 1.08031],
2875    "78": [0, 0.7, 0.3525, 0, 0.9015],
2876    "79": [0, 0.7, 0.08078, 0, 0.73787],
2877    "80": [0, 0.7, 0.08078, 0, 1.01262],
2878    "81": [0, 0.7, 0.03305, 0, 0.88282],
2879    "82": [0, 0.7, 0.06259, 0, 0.85],
2880    "83": [0, 0.7, 0.19189, 0, 0.86767],
2881    "84": [0, 0.7, 0.29087, 0, 0.74697],
2882    "85": [0, 0.7, 0.25815, 0, 0.79996],
2883    "86": [0, 0.7, 0.27523, 0, 0.62204],
2884    "87": [0, 0.7, 0.27523, 0, 0.80532],
2885    "88": [0, 0.7, 0.26006, 0, 0.94445],
2886    "89": [0, 0.7, 0.2939, 0, 0.70961],
2887    "90": [0, 0.7, 0.24037, 0, 0.8212],
2888    "160": [0, 0, 0, 0, 0.25]
2889  },
2890  "Size1-Regular": {
2891    "32": [0, 0, 0, 0, 0.25],
2892    "40": [0.35001, 0.85, 0, 0, 0.45834],
2893    "41": [0.35001, 0.85, 0, 0, 0.45834],
2894    "47": [0.35001, 0.85, 0, 0, 0.57778],
2895    "91": [0.35001, 0.85, 0, 0, 0.41667],
2896    "92": [0.35001, 0.85, 0, 0, 0.57778],
2897    "93": [0.35001, 0.85, 0, 0, 0.41667],
2898    "123": [0.35001, 0.85, 0, 0, 0.58334],
2899    "125": [0.35001, 0.85, 0, 0, 0.58334],
2900    "160": [0, 0, 0, 0, 0.25],
2901    "710": [0, 0.72222, 0, 0, 0.55556],
2902    "732": [0, 0.72222, 0, 0, 0.55556],
2903    "770": [0, 0.72222, 0, 0, 0.55556],
2904    "771": [0, 0.72222, 0, 0, 0.55556],
2905    "8214": [-0.00099, 0.601, 0, 0, 0.77778],
2906    "8593": [1e-05, 0.6, 0, 0, 0.66667],
2907    "8595": [1e-05, 0.6, 0, 0, 0.66667],
2908    "8657": [1e-05, 0.6, 0, 0, 0.77778],
2909    "8659": [1e-05, 0.6, 0, 0, 0.77778],
2910    "8719": [0.25001, 0.75, 0, 0, 0.94445],
2911    "8720": [0.25001, 0.75, 0, 0, 0.94445],
2912    "8721": [0.25001, 0.75, 0, 0, 1.05556],
2913    "8730": [0.35001, 0.85, 0, 0, 1.0],
2914    "8739": [-0.00599, 0.606, 0, 0, 0.33333],
2915    "8741": [-0.00599, 0.606, 0, 0, 0.55556],
2916    "8747": [0.30612, 0.805, 0.19445, 0, 0.47222],
2917    "8748": [0.306, 0.805, 0.19445, 0, 0.47222],
2918    "8749": [0.306, 0.805, 0.19445, 0, 0.47222],
2919    "8750": [0.30612, 0.805, 0.19445, 0, 0.47222],
2920    "8896": [0.25001, 0.75, 0, 0, 0.83334],
2921    "8897": [0.25001, 0.75, 0, 0, 0.83334],
2922    "8898": [0.25001, 0.75, 0, 0, 0.83334],
2923    "8899": [0.25001, 0.75, 0, 0, 0.83334],
2924    "8968": [0.35001, 0.85, 0, 0, 0.47222],
2925    "8969": [0.35001, 0.85, 0, 0, 0.47222],
2926    "8970": [0.35001, 0.85, 0, 0, 0.47222],
2927    "8971": [0.35001, 0.85, 0, 0, 0.47222],
2928    "9168": [-0.00099, 0.601, 0, 0, 0.66667],
2929    "10216": [0.35001, 0.85, 0, 0, 0.47222],
2930    "10217": [0.35001, 0.85, 0, 0, 0.47222],
2931    "10752": [0.25001, 0.75, 0, 0, 1.11111],
2932    "10753": [0.25001, 0.75, 0, 0, 1.11111],
2933    "10754": [0.25001, 0.75, 0, 0, 1.11111],
2934    "10756": [0.25001, 0.75, 0, 0, 0.83334],
2935    "10758": [0.25001, 0.75, 0, 0, 0.83334]
2936  },
2937  "Size2-Regular": {
2938    "32": [0, 0, 0, 0, 0.25],
2939    "40": [0.65002, 1.15, 0, 0, 0.59722],
2940    "41": [0.65002, 1.15, 0, 0, 0.59722],
2941    "47": [0.65002, 1.15, 0, 0, 0.81111],
2942    "91": [0.65002, 1.15, 0, 0, 0.47222],
2943    "92": [0.65002, 1.15, 0, 0, 0.81111],
2944    "93": [0.65002, 1.15, 0, 0, 0.47222],
2945    "123": [0.65002, 1.15, 0, 0, 0.66667],
2946    "125": [0.65002, 1.15, 0, 0, 0.66667],
2947    "160": [0, 0, 0, 0, 0.25],
2948    "710": [0, 0.75, 0, 0, 1.0],
2949    "732": [0, 0.75, 0, 0, 1.0],
2950    "770": [0, 0.75, 0, 0, 1.0],
2951    "771": [0, 0.75, 0, 0, 1.0],
2952    "8719": [0.55001, 1.05, 0, 0, 1.27778],
2953    "8720": [0.55001, 1.05, 0, 0, 1.27778],
2954    "8721": [0.55001, 1.05, 0, 0, 1.44445],
2955    "8730": [0.65002, 1.15, 0, 0, 1.0],
2956    "8747": [0.86225, 1.36, 0.44445, 0, 0.55556],
2957    "8748": [0.862, 1.36, 0.44445, 0, 0.55556],
2958    "8749": [0.862, 1.36, 0.44445, 0, 0.55556],
2959    "8750": [0.86225, 1.36, 0.44445, 0, 0.55556],
2960    "8896": [0.55001, 1.05, 0, 0, 1.11111],
2961    "8897": [0.55001, 1.05, 0, 0, 1.11111],
2962    "8898": [0.55001, 1.05, 0, 0, 1.11111],
2963    "8899": [0.55001, 1.05, 0, 0, 1.11111],
2964    "8968": [0.65002, 1.15, 0, 0, 0.52778],
2965    "8969": [0.65002, 1.15, 0, 0, 0.52778],
2966    "8970": [0.65002, 1.15, 0, 0, 0.52778],
2967    "8971": [0.65002, 1.15, 0, 0, 0.52778],
2968    "10216": [0.65002, 1.15, 0, 0, 0.61111],
2969    "10217": [0.65002, 1.15, 0, 0, 0.61111],
2970    "10752": [0.55001, 1.05, 0, 0, 1.51112],
2971    "10753": [0.55001, 1.05, 0, 0, 1.51112],
2972    "10754": [0.55001, 1.05, 0, 0, 1.51112],
2973    "10756": [0.55001, 1.05, 0, 0, 1.11111],
2974    "10758": [0.55001, 1.05, 0, 0, 1.11111]
2975  },
2976  "Size3-Regular": {
2977    "32": [0, 0, 0, 0, 0.25],
2978    "40": [0.95003, 1.45, 0, 0, 0.73611],
2979    "41": [0.95003, 1.45, 0, 0, 0.73611],
2980    "47": [0.95003, 1.45, 0, 0, 1.04445],
2981    "91": [0.95003, 1.45, 0, 0, 0.52778],
2982    "92": [0.95003, 1.45, 0, 0, 1.04445],
2983    "93": [0.95003, 1.45, 0, 0, 0.52778],
2984    "123": [0.95003, 1.45, 0, 0, 0.75],
2985    "125": [0.95003, 1.45, 0, 0, 0.75],
2986    "160": [0, 0, 0, 0, 0.25],
2987    "710": [0, 0.75, 0, 0, 1.44445],
2988    "732": [0, 0.75, 0, 0, 1.44445],
2989    "770": [0, 0.75, 0, 0, 1.44445],
2990    "771": [0, 0.75, 0, 0, 1.44445],
2991    "8730": [0.95003, 1.45, 0, 0, 1.0],
2992    "8968": [0.95003, 1.45, 0, 0, 0.58334],
2993    "8969": [0.95003, 1.45, 0, 0, 0.58334],
2994    "8970": [0.95003, 1.45, 0, 0, 0.58334],
2995    "8971": [0.95003, 1.45, 0, 0, 0.58334],
2996    "10216": [0.95003, 1.45, 0, 0, 0.75],
2997    "10217": [0.95003, 1.45, 0, 0, 0.75]
2998  },
2999  "Size4-Regular": {
3000    "32": [0, 0, 0, 0, 0.25],
3001    "40": [1.25003, 1.75, 0, 0, 0.79167],
3002    "41": [1.25003, 1.75, 0, 0, 0.79167],
3003    "47": [1.25003, 1.75, 0, 0, 1.27778],
3004    "91": [1.25003, 1.75, 0, 0, 0.58334],
3005    "92": [1.25003, 1.75, 0, 0, 1.27778],
3006    "93": [1.25003, 1.75, 0, 0, 0.58334],
3007    "123": [1.25003, 1.75, 0, 0, 0.80556],
3008    "125": [1.25003, 1.75, 0, 0, 0.80556],
3009    "160": [0, 0, 0, 0, 0.25],
3010    "710": [0, 0.825, 0, 0, 1.8889],
3011    "732": [0, 0.825, 0, 0, 1.8889],
3012    "770": [0, 0.825, 0, 0, 1.8889],
3013    "771": [0, 0.825, 0, 0, 1.8889],
3014    "8730": [1.25003, 1.75, 0, 0, 1.0],
3015    "8968": [1.25003, 1.75, 0, 0, 0.63889],
3016    "8969": [1.25003, 1.75, 0, 0, 0.63889],
3017    "8970": [1.25003, 1.75, 0, 0, 0.63889],
3018    "8971": [1.25003, 1.75, 0, 0, 0.63889],
3019    "9115": [0.64502, 1.155, 0, 0, 0.875],
3020    "9116": [1e-05, 0.6, 0, 0, 0.875],
3021    "9117": [0.64502, 1.155, 0, 0, 0.875],
3022    "9118": [0.64502, 1.155, 0, 0, 0.875],
3023    "9119": [1e-05, 0.6, 0, 0, 0.875],
3024    "9120": [0.64502, 1.155, 0, 0, 0.875],
3025    "9121": [0.64502, 1.155, 0, 0, 0.66667],
3026    "9122": [-0.00099, 0.601, 0, 0, 0.66667],
3027    "9123": [0.64502, 1.155, 0, 0, 0.66667],
3028    "9124": [0.64502, 1.155, 0, 0, 0.66667],
3029    "9125": [-0.00099, 0.601, 0, 0, 0.66667],
3030    "9126": [0.64502, 1.155, 0, 0, 0.66667],
3031    "9127": [1e-05, 0.9, 0, 0, 0.88889],
3032    "9128": [0.65002, 1.15, 0, 0, 0.88889],
3033    "9129": [0.90001, 0, 0, 0, 0.88889],
3034    "9130": [0, 0.3, 0, 0, 0.88889],
3035    "9131": [1e-05, 0.9, 0, 0, 0.88889],
3036    "9132": [0.65002, 1.15, 0, 0, 0.88889],
3037    "9133": [0.90001, 0, 0, 0, 0.88889],
3038    "9143": [0.88502, 0.915, 0, 0, 1.05556],
3039    "10216": [1.25003, 1.75, 0, 0, 0.80556],
3040    "10217": [1.25003, 1.75, 0, 0, 0.80556],
3041    "57344": [-0.00499, 0.605, 0, 0, 1.05556],
3042    "57345": [-0.00499, 0.605, 0, 0, 1.05556],
3043    "57680": [0, 0.12, 0, 0, 0.45],
3044    "57681": [0, 0.12, 0, 0, 0.45],
3045    "57682": [0, 0.12, 0, 0, 0.45],
3046    "57683": [0, 0.12, 0, 0, 0.45]
3047  },
3048  "Typewriter-Regular": {
3049    "32": [0, 0, 0, 0, 0.525],
3050    "33": [0, 0.61111, 0, 0, 0.525],
vendor: 4,769 bytes, lines 3051-3175
3051    "34": [0, 0.61111, 0, 0, 0.525],
3052    "35": [0, 0.61111, 0, 0, 0.525],
3053    "36": [0.08333, 0.69444, 0, 0, 0.525],
3054    "37": [0.08333, 0.69444, 0, 0, 0.525],
3055    "38": [0, 0.61111, 0, 0, 0.525],
3056    "39": [0, 0.61111, 0, 0, 0.525],
3057    "40": [0.08333, 0.69444, 0, 0, 0.525],
3058    "41": [0.08333, 0.69444, 0, 0, 0.525],
3059    "42": [0, 0.52083, 0, 0, 0.525],
3060    "43": [-0.08056, 0.53055, 0, 0, 0.525],
3061    "44": [0.13889, 0.125, 0, 0, 0.525],
3062    "45": [-0.08056, 0.53055, 0, 0, 0.525],
3063    "46": [0, 0.125, 0, 0, 0.525],
3064    "47": [0.08333, 0.69444, 0, 0, 0.525],
3065    "48": [0, 0.61111, 0, 0, 0.525],
3066    "49": [0, 0.61111, 0, 0, 0.525],
3067    "50": [0, 0.61111, 0, 0, 0.525],
3068    "51": [0, 0.61111, 0, 0, 0.525],
3069    "52": [0, 0.61111, 0, 0, 0.525],
3070    "53": [0, 0.61111, 0, 0, 0.525],
3071    "54": [0, 0.61111, 0, 0, 0.525],
3072    "55": [0, 0.61111, 0, 0, 0.525],
3073    "56": [0, 0.61111, 0, 0, 0.525],
3074    "57": [0, 0.61111, 0, 0, 0.525],
3075    "58": [0, 0.43056, 0, 0, 0.525],
3076    "59": [0.13889, 0.43056, 0, 0, 0.525],
3077    "60": [-0.05556, 0.55556, 0, 0, 0.525],
3078    "61": [-0.19549, 0.41562, 0, 0, 0.525],
3079    "62": [-0.05556, 0.55556, 0, 0, 0.525],
3080    "63": [0, 0.61111, 0, 0, 0.525],
3081    "64": [0, 0.61111, 0, 0, 0.525],
3082    "65": [0, 0.61111, 0, 0, 0.525],
3083    "66": [0, 0.61111, 0, 0, 0.525],
3084    "67": [0, 0.61111, 0, 0, 0.525],
3085    "68": [0, 0.61111, 0, 0, 0.525],
3086    "69": [0, 0.61111, 0, 0, 0.525],
3087    "70": [0, 0.61111, 0, 0, 0.525],
3088    "71": [0, 0.61111, 0, 0, 0.525],
3089    "72": [0, 0.61111, 0, 0, 0.525],
3090    "73": [0, 0.61111, 0, 0, 0.525],
3091    "74": [0, 0.61111, 0, 0, 0.525],
3092    "75": [0, 0.61111, 0, 0, 0.525],
3093    "76": [0, 0.61111, 0, 0, 0.525],
3094    "77": [0, 0.61111, 0, 0, 0.525],
3095    "78": [0, 0.61111, 0, 0, 0.525],
3096    "79": [0, 0.61111, 0, 0, 0.525],
3097    "80": [0, 0.61111, 0, 0, 0.525],
3098    "81": [0.13889, 0.61111, 0, 0, 0.525],
3099    "82": [0, 0.61111, 0, 0, 0.525],
3100    "83": [0, 0.61111, 0, 0, 0.525],
3101    "84": [0, 0.61111, 0, 0, 0.525],
3102    "85": [0, 0.61111, 0, 0, 0.525],
3103    "86": [0, 0.61111, 0, 0, 0.525],
3104    "87": [0, 0.61111, 0, 0, 0.525],
3105    "88": [0, 0.61111, 0, 0, 0.525],
3106    "89": [0, 0.61111, 0, 0, 0.525],
3107    "90": [0, 0.61111, 0, 0, 0.525],
3108    "91": [0.08333, 0.69444, 0, 0, 0.525],
3109    "92": [0.08333, 0.69444, 0, 0, 0.525],
3110    "93": [0.08333, 0.69444, 0, 0, 0.525],
3111    "94": [0, 0.61111, 0, 0, 0.525],
3112    "95": [0.09514, 0, 0, 0, 0.525],
3113    "96": [0, 0.61111, 0, 0, 0.525],
3114    "97": [0, 0.43056, 0, 0, 0.525],
3115    "98": [0, 0.61111, 0, 0, 0.525],
3116    "99": [0, 0.43056, 0, 0, 0.525],
3117    "100": [0, 0.61111, 0, 0, 0.525],
3118    "101": [0, 0.43056, 0, 0, 0.525],
3119    "102": [0, 0.61111, 0, 0, 0.525],
3120    "103": [0.22222, 0.43056, 0, 0, 0.525],
3121    "104": [0, 0.61111, 0, 0, 0.525],
3122    "105": [0, 0.61111, 0, 0, 0.525],
3123    "106": [0.22222, 0.61111, 0, 0, 0.525],
3124    "107": [0, 0.61111, 0, 0, 0.525],
3125    "108": [0, 0.61111, 0, 0, 0.525],
3126    "109": [0, 0.43056, 0, 0, 0.525],
3127    "110": [0, 0.43056, 0, 0, 0.525],
3128    "111": [0, 0.43056, 0, 0, 0.525],
3129    "112": [0.22222, 0.43056, 0, 0, 0.525],
3130    "113": [0.22222, 0.43056, 0, 0, 0.525],
3131    "114": [0, 0.43056, 0, 0, 0.525],
3132    "115": [0, 0.43056, 0, 0, 0.525],
3133    "116": [0, 0.55358, 0, 0, 0.525],
3134    "117": [0, 0.43056, 0, 0, 0.525],
3135    "118": [0, 0.43056, 0, 0, 0.525],
3136    "119": [0, 0.43056, 0, 0, 0.525],
3137    "120": [0, 0.43056, 0, 0, 0.525],
3138    "121": [0.22222, 0.43056, 0, 0, 0.525],
3139    "122": [0, 0.43056, 0, 0, 0.525],
3140    "123": [0.08333, 0.69444, 0, 0, 0.525],
3141    "124": [0.08333, 0.69444, 0, 0, 0.525],
3142    "125": [0.08333, 0.69444, 0, 0, 0.525],
3143    "126": [0, 0.61111, 0, 0, 0.525],
3144    "127": [0, 0.61111, 0, 0, 0.525],
3145    "160": [0, 0, 0, 0, 0.525],
3146    "176": [0, 0.61111, 0, 0, 0.525],
3147    "184": [0.19445, 0, 0, 0, 0.525],
3148    "305": [0, 0.43056, 0, 0, 0.525],
3149    "567": [0.22222, 0.43056, 0, 0, 0.525],
3150    "711": [0, 0.56597, 0, 0, 0.525],
3151    "713": [0, 0.56555, 0, 0, 0.525],
3152    "714": [0, 0.61111, 0, 0, 0.525],
3153    "715": [0, 0.61111, 0, 0, 0.525],
3154    "728": [0, 0.61111, 0, 0, 0.525],
3155    "730": [0, 0.61111, 0, 0, 0.525],
3156    "770": [0, 0.61111, 0, 0, 0.525],
3157    "771": [0, 0.61111, 0, 0, 0.525],
3158    "776": [0, 0.61111, 0, 0, 0.525],
3159    "915": [0, 0.61111, 0, 0, 0.525],
3160    "916": [0, 0.61111, 0, 0, 0.525],
3161    "920": [0, 0.61111, 0, 0, 0.525],
3162    "923": [0, 0.61111, 0, 0, 0.525],
3163    "926": [0, 0.61111, 0, 0, 0.525],
3164    "928": [0, 0.61111, 0, 0, 0.525],
3165    "931": [0, 0.61111, 0, 0, 0.525],
3166    "933": [0, 0.61111, 0, 0, 0.525],
3167    "934": [0, 0.61111, 0, 0, 0.525],
3168    "936": [0, 0.61111, 0, 0, 0.525],
3169    "937": [0, 0.61111, 0, 0, 0.525],
3170    "8216": [0, 0.61111, 0, 0, 0.525],
3171    "8217": [0, 0.61111, 0, 0, 0.525],
3172    "8242": [0, 0.61111, 0, 0, 0.525],
3173    "9251": [0.11111, 0.21944, 0, 0, 0.525]
3174  }
3175};
3176
3177/**
3178 * This file contains metrics regarding fonts and individual symbols. The sigma
3179 * and xi variables, as well as the metricMap map contain data extracted from
3180 * TeX, TeX font metrics, and the TTF files. These data are then exposed via the
3181 * `metrics` variable and the getCharacterMetrics function.
3182 */
3183// In TeX, there are actually three sets of dimensions, one for each of
3184// textstyle (size index 5 and higher: >=9pt), scriptstyle (size index 3 and 4:
3185// 7-8pt), and scriptscriptstyle (size index 1 and 2: 5-6pt).  These are
3186// provided in the arrays below, in that order.
3187//
3188// The font metrics are stored in fonts cmsy10, cmsy7, and cmsy5 respectively.
3189// This was determined by running the following script:
3190//
3191//     latex -interaction=nonstopmode \
3192//     '\documentclass{article}\usepackage{amsmath}\begin{document}' \
3193//     '$a$ \expandafter\show\the\textfont2' \
3194//     '\expandafter\show\the\scriptfont2' \
3195//     '\expandafter\show\the\scriptscriptfont2' \
3196//     '\stop'
3197//
3198// The metrics themselves were retrieved using the following commands:
3199//
3200//     tftopl cmsy10
3201//     tftopl cmsy7
3202//     tftopl cmsy5
3203//
3204// The output of each of these commands is quite lengthy.  The only part we
3205// care about is the FONTDIMEN section. Each value is measured in EMs.
3206var sigmasAndXis = {
3207  slant: [0.250, 0.250, 0.250],
3208  // sigma1
3209  space: [0.000, 0.000, 0.000],
3210  // sigma2
3211  stretch: [0.000, 0.000, 0.000],
3212  // sigma3
3213  shrink: [0.000, 0.000, 0.000],
3214  // sigma4
3215  xHeight: [0.431, 0.431, 0.431],
3216  // sigma5
3217  quad: [1.000, 1.171, 1.472],
3218  // sigma6
3219  extraSpace: [0.000, 0.000, 0.000],
3220  // sigma7
3221  num1: [0.677, 0.732, 0.925],
3222  // sigma8
3223  num2: [0.394, 0.384, 0.387],
3224  // sigma9
3225  num3: [0.444, 0.471, 0.504],
3226  // sigma10
3227  denom1: [0.686, 0.752, 1.025],
3228  // sigma11
3229  denom2: [0.345, 0.344, 0.532],
3230  // sigma12
3231  sup1: [0.413, 0.503, 0.504],
3232  // sigma13
3233  sup2: [0.363, 0.431, 0.404],
3234  // sigma14
3235  sup3: [0.289, 0.286, 0.294],
3236  // sigma15
3237  sub1: [0.150, 0.143, 0.200],
3238  // sigma16
3239  sub2: [0.247, 0.286, 0.400],
3240  // sigma17
3241  supDrop: [0.386, 0.353, 0.494],
3242  // sigma18
3243  subDrop: [0.050, 0.071, 0.100],
3244  // sigma19
3245  delim1: [2.390, 1.700, 1.980],
3246  // sigma20
3247  delim2: [1.010, 1.157, 1.420],
3248  // sigma21
3249  axisHeight: [0.250, 0.250, 0.250],
3250  // sigma22
3251  // These font metrics are extracted from TeX by using tftopl on cmex10.tfm;
3252  // they correspond to the font parameters of the extension fonts (family 3).
3253  // See the TeXbook, page 441. In AMSTeX, the extension fonts scale; to
3254  // match cmex7, we'd use cmex7.tfm values for script and scriptscript
3255  // values.
3256  defaultRuleThickness: [0.04, 0.049, 0.049],
3257  // xi8; cmex7: 0.049
3258  bigOpSpacing1: [0.111, 0.111, 0.111],
3259  // xi9
3260  bigOpSpacing2: [0.166, 0.166, 0.166],
3261  // xi10
3262  bigOpSpacing3: [0.2, 0.2, 0.2],
3263  // xi11
3264  bigOpSpacing4: [0.6, 0.611, 0.611],
3265  // xi12; cmex7: 0.611
3266  bigOpSpacing5: [0.1, 0.143, 0.143],
3267  // xi13; cmex7: 0.143
3268  // The \sqrt rule width is taken from the height of the surd character.
3269  // Since we use the same font at all sizes, this thickness doesn't scale.
3270  sqrtRuleThickness: [0.04, 0.04, 0.04],
3271  // This value determines how large a pt is, for metrics which are defined
3272  // in terms of pts.
3273  // This value is also used in katex.scss; if you change it make sure the
3274  // values match.
3275  ptPerEm: [10.0, 10.0, 10.0],
3276  // The space between adjacent `|` columns in an array definition. From
3277  // `\showthe\doublerulesep` in LaTeX. Equals 2.0 / ptPerEm.
3278  doubleRuleSep: [0.2, 0.2, 0.2],
3279  // The width of separator lines in {array} environments. From
3280  // `\showthe\arrayrulewidth` in LaTeX. Equals 0.4 / ptPerEm.
3281  arrayRuleWidth: [0.04, 0.04, 0.04],
3282  // Two values from LaTeX source2e:
3283  fboxsep: [0.3, 0.3, 0.3],
3284  //        3 pt / ptPerEm
3285  fboxrule: [0.04, 0.04, 0.04] // 0.4 pt / ptPerEm
3286
3287}; // This map contains a mapping from font name and character code to character
vendor: 4,607 bytes, lines 3288-3472
3288// should have Latin-1 and Cyrillic characters, but may not depending on the
3289// operating system.  The metrics do not account for extra height from the
3290// accents.  In the case of Cyrillic characters which have both ascenders and
3291// descenders we prefer approximations with ascenders, primarily to prevent
3292// the fraction bar or root line from intersecting the glyph.
3293// TODO(kevinb) allow union of multiple glyph metrics for better accuracy.
3294
3295var extraCharacterMap = {
3296  // Latin-1
3297  'Å': 'A',
3298  'Ð': 'D',
3299  'Þ': 'o',
3300  'Ã¥': 'a',
3301  'ð': 'd',
3302  'þ': 'o',
3303  // Cyrillic
3304  'А': 'A',
3305  'Б': 'B',
3306  'В': 'B',
3307  'Г': 'F',
3308  'Д': 'A',
3309  'Е': 'E',
3310  'Ж': 'K',
3311  'З': '3',
3312  'И': 'N',
3313  'Й': 'N',
3314  'К': 'K',
3315  'Л': 'N',
3316  'М': 'M',
3317  'Н': 'H',
3318  'О': 'O',
3319  'П': 'N',
3320  'Р': 'P',
3321  'С': 'C',
3322  'Т': 'T',
3323  'У': 'y',
3324  'Ф': 'O',
3325  'Ð¥': 'X',
3326  'Ц': 'U',
3327  'Ч': 'h',
3328  'Ш': 'W',
3329  'Щ': 'W',
3330  'Ъ': 'B',
3331  'Ы': 'X',
3332  'Ь': 'B',
3333  'Э': '3',
3334  'Ю': 'X',
3335  'Я': 'R',
3336  'а': 'a',
3337  'б': 'b',
3338  'в': 'a',
3339  'г': 'r',
3340  'д': 'y',
3341  'е': 'e',
3342  'ж': 'm',
3343  'з': 'e',
3344  'и': 'n',
3345  'й': 'n',
3346  'к': 'n',
3347  'л': 'n',
3348  'м': 'm',
3349  'н': 'n',
3350  'о': 'o',
3351  'п': 'n',
3352  'р': 'p',
3353  'с': 'c',
3354  'т': 'o',
3355  'у': 'y',
3356  'ф': 'b',
3357  'х': 'x',
3358  'ц': 'n',
3359  'ч': 'n',
3360  'ш': 'w',
3361  'щ': 'w',
3362  'ъ': 'a',
3363  'ы': 'm',
3364  'ь': 'a',
3365  'э': 'e',
3366  'ю': 'm',
3367  'я': 'r'
3368};
3369
3370/**
3371 * This function adds new font metrics to default metricMap
3372 * It can also override existing metrics
3373 */
3374function setFontMetrics(fontName, metrics) {
3375  fontMetricsData[fontName] = metrics;
3376}
3377/**
3378 * This function is a convenience function for looking up information in the
3379 * metricMap table. It takes a character as a string, and a font.
3380 *
3381 * Note: the `width` property may be undefined if fontMetricsData.js wasn't
3382 * built using `Make extended_metrics`.
3383 */
3384
3385function getCharacterMetrics(character, font, mode) {
3386  if (!fontMetricsData[font]) {
3387    throw new Error("Font metrics not found for font: " + font + ".");
3388  }
3389
3390  var ch = character.charCodeAt(0);
3391  var metrics = fontMetricsData[font][ch];
3392
3393  if (!metrics && character[0] in extraCharacterMap) {
3394    ch = extraCharacterMap[character[0]].charCodeAt(0);
3395    metrics = fontMetricsData[font][ch];
3396  }
3397
3398  if (!metrics && mode === 'text') {
3399    // We don't typically have font metrics for Asian scripts.
3400    // But since we support them in text mode, we need to return
3401    // some sort of metrics.
3402    // So if the character is in a script we support but we
3403    // don't have metrics for it, just use the metrics for
3404    // the Latin capital letter M. This is close enough because
3405    // we (currently) only care about the height of the glyph
3406    // not its width.
3407    if (supportedCodepoint(ch)) {
3408      metrics = fontMetricsData[font][77]; // 77 is the charcode for 'M'
3409    }
3410  }
3411
3412  if (metrics) {
3413    return {
3414      depth: metrics[0],
3415      height: metrics[1],
3416      italic: metrics[2],
3417      skew: metrics[3],
3418      width: metrics[4]
3419    };
3420  }
3421}
3422var fontMetricsBySizeIndex = {};
3423/**
3424 * Get the font metrics for a given size.
3425 */
3426
3427function getGlobalMetrics(size) {
3428  var sizeIndex;
3429
3430  if (size >= 5) {
3431    sizeIndex = 0;
3432  } else if (size >= 3) {
3433    sizeIndex = 1;
3434  } else {
3435    sizeIndex = 2;
3436  }
3437
3438  if (!fontMetricsBySizeIndex[sizeIndex]) {
3439    var metrics = fontMetricsBySizeIndex[sizeIndex] = {
3440      cssEmPerMu: sigmasAndXis.quad[sizeIndex] / 18
3441    };
3442
3443    for (var key in sigmasAndXis) {
3444      if (sigmasAndXis.hasOwnProperty(key)) {
3445        metrics[key] = sigmasAndXis[key][sizeIndex];
3446      }
3447    }
3448  }
3449
3450  return fontMetricsBySizeIndex[sizeIndex];
3451}
3452
3453/**
3454 * This file contains information about the options that the Parser carries
3455 * around with it while parsing. Data is held in an `Options` object, and when
3456 * recursing, a new `Options` object can be created with the `.with*` and
3457 * `.reset` functions.
3458 */
3459var sizeStyleMap = [// Each element contains [textsize, scriptsize, scriptscriptsize].
3460// The size mappings are taken from TeX with \normalsize=10pt.
3461[1, 1, 1], // size1: [5, 5, 5]              \tiny
3462[2, 1, 1], // size2: [6, 5, 5]
3463[3, 1, 1], // size3: [7, 5, 5]              \scriptsize
3464[4, 2, 1], // size4: [8, 6, 5]              \footnotesize
3465[5, 2, 1], // size5: [9, 6, 5]              \small
3466[6, 3, 1], // size6: [10, 7, 5]             \normalsize
3467[7, 4, 2], // size7: [12, 8, 6]             \large
3468[8, 6, 3], // size8: [14.4, 10, 7]          \Large
3469[9, 7, 6], // size9: [17.28, 12, 10]        \LARGE
3470[10, 8, 7], // size10: [20.74, 14.4, 12]     \huge
3471[11, 10, 9] // size11: [24.88, 20.74, 17.28] \HUGE
3472];
vendor: 10,849 bytes, lines 3473-3898
3473var sizeMultipliers = [// fontMetrics.js:getGlobalMetrics also uses size indexes, so if
3474// you change size indexes, change that function.
34750.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.44, 1.728, 2.074, 2.488];
3476
3477var sizeAtStyle = function sizeAtStyle(size, style) {
3478  return style.size < 2 ? size : sizeStyleMap[size - 1][style.size - 1];
3479}; // In these types, "" (empty string) means "no change".
3480
3481
3482/**
3483 * This is the main options class. It contains the current style, size, color,
3484 * and font.
3485 *
3486 * Options objects should not be modified. To create a new Options with
3487 * different properties, call a `.having*` method.
3488 */
3489class Options {
3490  // A font family applies to a group of fonts (i.e. SansSerif), while a font
3491  // represents a specific font (i.e. SansSerif Bold).
3492  // See: https://tex.stackexchange.com/questions/22350/difference-between-textrm-and-mathrm
3493
3494  /**
3495   * The base size index.
3496   */
3497  constructor(data) {
3498    this.style = void 0;
3499    this.color = void 0;
3500    this.size = void 0;
3501    this.textSize = void 0;
3502    this.phantom = void 0;
3503    this.font = void 0;
3504    this.fontFamily = void 0;
3505    this.fontWeight = void 0;
3506    this.fontShape = void 0;
3507    this.sizeMultiplier = void 0;
3508    this.maxSize = void 0;
3509    this.minRuleThickness = void 0;
3510    this._fontMetrics = void 0;
3511    this.style = data.style;
3512    this.color = data.color;
3513    this.size = data.size || Options.BASESIZE;
3514    this.textSize = data.textSize || this.size;
3515    this.phantom = !!data.phantom;
3516    this.font = data.font || "";
3517    this.fontFamily = data.fontFamily || "";
3518    this.fontWeight = data.fontWeight || '';
3519    this.fontShape = data.fontShape || '';
3520    this.sizeMultiplier = sizeMultipliers[this.size - 1];
3521    this.maxSize = data.maxSize;
3522    this.minRuleThickness = data.minRuleThickness;
3523    this._fontMetrics = undefined;
3524  }
3525  /**
3526   * Returns a new options object with the same properties as "this".  Properties
3527   * from "extension" will be copied to the new options object.
3528   */
3529
3530
3531  extend(extension) {
3532    var data = {
3533      style: this.style,
3534      size: this.size,
3535      textSize: this.textSize,
3536      color: this.color,
3537      phantom: this.phantom,
3538      font: this.font,
3539      fontFamily: this.fontFamily,
3540      fontWeight: this.fontWeight,
3541      fontShape: this.fontShape,
3542      maxSize: this.maxSize,
3543      minRuleThickness: this.minRuleThickness
3544    };
3545
3546    for (var key in extension) {
3547      if (extension.hasOwnProperty(key)) {
3548        data[key] = extension[key];
3549      }
3550    }
3551
3552    return new Options(data);
3553  }
3554  /**
3555   * Return an options object with the given style. If `this.style === style`,
3556   * returns `this`.
3557   */
3558
3559
3560  havingStyle(style) {
3561    if (this.style === style) {
3562      return this;
3563    } else {
3564      return this.extend({
3565        style: style,
3566        size: sizeAtStyle(this.textSize, style)
3567      });
3568    }
3569  }
3570  /**
3571   * Return an options object with a cramped version of the current style. If
3572   * the current style is cramped, returns `this`.
3573   */
3574
3575
3576  havingCrampedStyle() {
3577    return this.havingStyle(this.style.cramp());
3578  }
3579  /**
3580   * Return an options object with the given size and in at least `\textstyle`.
3581   * Returns `this` if appropriate.
3582   */
3583
3584
3585  havingSize(size) {
3586    if (this.size === size && this.textSize === size) {
3587      return this;
3588    } else {
3589      return this.extend({
3590        style: this.style.text(),
3591        size: size,
3592        textSize: size,
3593        sizeMultiplier: sizeMultipliers[size - 1]
3594      });
3595    }
3596  }
3597  /**
3598   * Like `this.havingSize(BASESIZE).havingStyle(style)`. If `style` is omitted,
3599   * changes to at least `\textstyle`.
3600   */
3601
3602
3603  havingBaseStyle(style) {
3604    style = style || this.style.text();
3605    var wantSize = sizeAtStyle(Options.BASESIZE, style);
3606
3607    if (this.size === wantSize && this.textSize === Options.BASESIZE && this.style === style) {
3608      return this;
3609    } else {
3610      return this.extend({
3611        style: style,
3612        size: wantSize
3613      });
3614    }
3615  }
3616  /**
3617   * Remove the effect of sizing changes such as \Huge.
3618   * Keep the effect of the current style, such as \scriptstyle.
3619   */
3620
3621
3622  havingBaseSizing() {
3623    var size;
3624
3625    switch (this.style.id) {
3626      case 4:
3627      case 5:
3628        size = 3; // normalsize in scriptstyle
3629
3630        break;
3631
3632      case 6:
3633      case 7:
3634        size = 1; // normalsize in scriptscriptstyle
3635
3636        break;
3637
3638      default:
3639        size = 6;
3640      // normalsize in textstyle or displaystyle
3641    }
3642
3643    return this.extend({
3644      style: this.style.text(),
3645      size: size
3646    });
3647  }
3648  /**
3649   * Create a new options object with the given color.
3650   */
3651
3652
3653  withColor(color) {
3654    return this.extend({
3655      color: color
3656    });
3657  }
3658  /**
3659   * Create a new options object with "phantom" set to true.
3660   */
3661
3662
3663  withPhantom() {
3664    return this.extend({
3665      phantom: true
3666    });
3667  }
3668  /**
3669   * Creates a new options object with the given math font or old text font.
3670   * @type {[type]}
3671   */
3672
3673
3674  withFont(font) {
3675    return this.extend({
3676      font
3677    });
3678  }
3679  /**
3680   * Create a new options objects with the given fontFamily.
3681   */
3682
3683
3684  withTextFontFamily(fontFamily) {
3685    return this.extend({
3686      fontFamily,
3687      font: ""
3688    });
3689  }
3690  /**
3691   * Creates a new options object with the given font weight
3692   */
3693
3694
3695  withTextFontWeight(fontWeight) {
3696    return this.extend({
3697      fontWeight,
3698      font: ""
3699    });
3700  }
3701  /**
3702   * Creates a new options object with the given font weight
3703   */
3704
3705
3706  withTextFontShape(fontShape) {
3707    return this.extend({
3708      fontShape,
3709      font: ""
3710    });
3711  }
3712  /**
3713   * Return the CSS sizing classes required to switch from enclosing options
3714   * `oldOptions` to `this`. Returns an array of classes.
3715   */
3716
3717
3718  sizingClasses(oldOptions) {
3719    if (oldOptions.size !== this.size) {
3720      return ["sizing", "reset-size" + oldOptions.size, "size" + this.size];
3721    } else {
3722      return [];
3723    }
3724  }
3725  /**
3726   * Return the CSS sizing classes required to switch to the base size. Like
3727   * `this.havingSize(BASESIZE).sizingClasses(this)`.
3728   */
3729
3730
3731  baseSizingClasses() {
3732    if (this.size !== Options.BASESIZE) {
3733      return ["sizing", "reset-size" + this.size, "size" + Options.BASESIZE];
3734    } else {
3735      return [];
3736    }
3737  }
3738  /**
3739   * Return the font metrics for this size.
3740   */
3741
3742
3743  fontMetrics() {
3744    if (!this._fontMetrics) {
3745      this._fontMetrics = getGlobalMetrics(this.size);
3746    }
3747
3748    return this._fontMetrics;
3749  }
3750  /**
3751   * Gets the CSS color of the current options object
3752   */
3753
3754
3755  getColor() {
3756    if (this.phantom) {
3757      return "transparent";
3758    } else {
3759      return this.color;
3760    }
3761  }
3762
3763}
3764
3765Options.BASESIZE = 6;
3766
3767/**
3768 * This file does conversion between units.  In particular, it provides
3769 * calculateSize to convert other units into ems.
3770 */
3771// Thus, multiplying a length by this number converts the length from units
3772// into pts.  Dividing the result by ptPerEm gives the number of ems
3773// *assuming* a font size of ptPerEm (normal size, normal style).
3774
3775var ptPerUnit = {
3776  // https://en.wikibooks.org/wiki/LaTeX/Lengths and
3777  // https://tex.stackexchange.com/a/8263
3778  "pt": 1,
3779  // TeX point
3780  "mm": 7227 / 2540,
3781  // millimeter
3782  "cm": 7227 / 254,
3783  // centimeter
3784  "in": 72.27,
3785  // inch
3786  "bp": 803 / 800,
3787  // big (PostScript) points
3788  "pc": 12,
3789  // pica
3790  "dd": 1238 / 1157,
3791  // didot
3792  "cc": 14856 / 1157,
3793  // cicero (12 didot)
3794  "nd": 685 / 642,
3795  // new didot
3796  "nc": 1370 / 107,
3797  // new cicero (12 new didot)
3798  "sp": 1 / 65536,
3799  // scaled point (TeX's internal smallest unit)
3800  // https://tex.stackexchange.com/a/41371
3801  "px": 803 / 800 // \pdfpxdimen defaults to 1 bp in pdfTeX and LuaTeX
3802
3803}; // Dictionary of relative units, for fast validity testing.
3804
3805var relativeUnit = {
3806  "ex": true,
3807  "em": true,
3808  "mu": true
3809};
3810
3811/**
3812 * Determine whether the specified unit (either a string defining the unit
3813 * or a "size" parse node containing a unit field) is valid.
3814 */
3815var validUnit = function validUnit(unit) {
3816  if (typeof unit !== "string") {
3817    unit = unit.unit;
3818  }
3819
3820  return unit in ptPerUnit || unit in relativeUnit || unit === "ex";
3821};
3822/*
3823 * Convert a "size" parse node (with numeric "number" and string "unit" fields,
3824 * as parsed by functions.js argType "size") into a CSS em value for the
3825 * current style/scale.  `options` gives the current options.
3826 */
3827
3828var calculateSize = function calculateSize(sizeValue, options) {
3829  var scale;
3830
3831  if (sizeValue.unit in ptPerUnit) {
3832    // Absolute units
3833    scale = ptPerUnit[sizeValue.unit] // Convert unit to pt
3834    / options.fontMetrics().ptPerEm // Convert pt to CSS em
3835    / options.sizeMultiplier; // Unscale to make absolute units
3836  } else if (sizeValue.unit === "mu") {
3837    // `mu` units scale with scriptstyle/scriptscriptstyle.
3838    scale = options.fontMetrics().cssEmPerMu;
3839  } else {
3840    // Other relative units always refer to the *textstyle* font
3841    // in the current size.
3842    var unitOptions;
3843
3844    if (options.style.isTight()) {
3845      // isTight() means current style is script/scriptscript.
3846      unitOptions = options.havingStyle(options.style.text());
3847    } else {
3848      unitOptions = options;
3849    } // TODO: In TeX these units are relative to the quad of the current
3850    // *text* font, e.g. cmr10. KaTeX instead uses values from the
3851    // comparably-sized *Computer Modern symbol* font. At 10pt, these
3852    // match. At 7pt and 5pt, they differ: cmr7=1.138894, cmsy7=1.170641;
3853    // cmr5=1.361133, cmsy5=1.472241. Consider $\scriptsize a\kern1emb$.
3854    // TeX \showlists shows a kern of 1.13889 * fontsize;
3855    // KaTeX shows a kern of 1.171 * fontsize.
3856
3857
3858    if (sizeValue.unit === "ex") {
3859      scale = unitOptions.fontMetrics().xHeight;
3860    } else if (sizeValue.unit === "em") {
3861      scale = unitOptions.fontMetrics().quad;
3862    } else {
3863      throw new ParseError("Invalid unit: '" + sizeValue.unit + "'");
3864    }
3865
3866    if (unitOptions !== options) {
3867      scale *= unitOptions.sizeMultiplier / options.sizeMultiplier;
3868    }
3869  }
3870
3871  return Math.min(sizeValue.number * scale, options.maxSize);
3872};
3873/**
3874 * Round `n` to 4 decimal places, or to the nearest 1/10,000th em. See
3875 * https://github.com/KaTeX/KaTeX/pull/2460.
3876 */
3877
3878var makeEm = function makeEm(n) {
3879  return +n.toFixed(4) + "em";
3880};
3881
3882/**
3883 * These objects store the data about the DOM nodes we create, as well as some
3884 * extra data. They can then be transformed into real DOM nodes with the
3885 * `toNode` function or HTML markup using `toMarkup`. They are useful for both
3886 * storing extra properties on the nodes, as well as providing a way to easily
3887 * work with the DOM.
3888 *
3889 * Similar functions for working with MathML nodes exist in mathMLTree.js.
3890 *
3891 * TODO: refactor `span` and `anchor` into common superclass when
3892 * target environments support class inheritance
3893 */
3894
3895/**
3896 * Create an HTML className based on a list of classes. In addition to joining
3897 * with spaces, we also remove empty classes.
3898 */
vendor: 9,232 bytes, lines 3899-4255
3899var createClass = function createClass(classes) {
3900  return classes.filter(cls => cls).join(" ");
3901};
3902
3903var initNode = function initNode(classes, options, style) {
3904  this.classes = classes || [];
3905  this.attributes = {};
3906  this.height = 0;
3907  this.depth = 0;
3908  this.maxFontSize = 0;
3909  this.style = style || {};
3910
3911  if (options) {
3912    if (options.style.isTight()) {
3913      this.classes.push("mtight");
3914    }
3915
3916    var color = options.getColor();
3917
3918    if (color) {
3919      this.style.color = color;
3920    }
3921  }
3922};
3923/**
3924 * Convert into an HTML node
3925 */
3926
3927
3928var toNode = function toNode(tagName) {
3929  var node = document.createElement(tagName); // Apply the class
3930
3931  node.className = createClass(this.classes); // Apply inline styles
3932
3933  for (var style in this.style) {
3934    if (this.style.hasOwnProperty(style)) {
3935      // $FlowFixMe Flow doesn't seem to understand span.style's type.
3936      node.style[style] = this.style[style];
3937    }
3938  } // Apply attributes
3939
3940
3941  for (var attr in this.attributes) {
3942    if (this.attributes.hasOwnProperty(attr)) {
3943      node.setAttribute(attr, this.attributes[attr]);
3944    }
3945  } // Append the children, also as HTML nodes
3946
3947
3948  for (var i = 0; i < this.children.length; i++) {
3949    node.appendChild(this.children[i].toNode());
3950  }
3951
3952  return node;
3953};
3954/**
3955 * https://w3c.github.io/html-reference/syntax.html#syntax-attributes
3956 *
3957 * > Attribute Names must consist of one or more characters
3958 * other than the space characters, U+0000 NULL,
3959 * '"', "'", ">", "/", "=", the control characters,
3960 * and any characters that are not defined by Unicode.
3961 */
3962
3963
3964var invalidAttributeNameRegex = /[\s"'>/=\x00-\x1f]/;
3965/**
3966 * Convert into an HTML markup string
3967 */
3968
3969var toMarkup = function toMarkup(tagName) {
3970  var markup = "<" + tagName; // Add the class
3971
3972  if (this.classes.length) {
3973    markup += " class=\"" + utils.escape(createClass(this.classes)) + "\"";
3974  }
3975
3976  var styles = ""; // Add the styles, after hyphenation
3977
3978  for (var style in this.style) {
3979    if (this.style.hasOwnProperty(style)) {
3980      styles += utils.hyphenate(style) + ":" + this.style[style] + ";";
3981    }
3982  }
3983
3984  if (styles) {
3985    markup += " style=\"" + utils.escape(styles) + "\"";
3986  } // Add the attributes
3987
3988
3989  for (var attr in this.attributes) {
3990    if (this.attributes.hasOwnProperty(attr)) {
3991      if (invalidAttributeNameRegex.test(attr)) {
3992        throw new ParseError("Invalid attribute name '" + attr + "'");
3993      }
3994
3995      markup += " " + attr + "=\"" + utils.escape(this.attributes[attr]) + "\"";
3996    }
3997  }
3998
3999  markup += ">"; // Add the markup of the children, also as markup
4000
4001  for (var i = 0; i < this.children.length; i++) {
4002    markup += this.children[i].toMarkup();
4003  }
4004
4005  markup += "</" + tagName + ">";
4006  return markup;
4007}; // Making the type below exact with all optional fields doesn't work due to
4008// - https://github.com/facebook/flow/issues/4582
4009// - https://github.com/facebook/flow/issues/5688
4010// However, since *all* fields are optional, $Shape<> works as suggested in 5688
4011// above.
4012// This type does not include all CSS properties. Additional properties should
4013// be added as needed.
4014
4015
4016/**
4017 * This node represents a span node, with a className, a list of children, and
4018 * an inline style. It also contains information about its height, depth, and
4019 * maxFontSize.
4020 *
4021 * Represents two types with different uses: SvgSpan to wrap an SVG and DomSpan
4022 * otherwise. This typesafety is important when HTML builders access a span's
4023 * children.
4024 */
4025class Span {
4026  constructor(classes, children, options, style) {
4027    this.children = void 0;
4028    this.attributes = void 0;
4029    this.classes = void 0;
4030    this.height = void 0;
4031    this.depth = void 0;
4032    this.width = void 0;
4033    this.maxFontSize = void 0;
4034    this.style = void 0;
4035    initNode.call(this, classes, options, style);
4036    this.children = children || [];
4037  }
4038  /**
4039   * Sets an arbitrary attribute on the span. Warning: use this wisely. Not
4040   * all browsers support attributes the same, and having too many custom
4041   * attributes is probably bad.
4042   */
4043
4044
4045  setAttribute(attribute, value) {
4046    this.attributes[attribute] = value;
4047  }
4048
4049  hasClass(className) {
4050    return utils.contains(this.classes, className);
4051  }
4052
4053  toNode() {
4054    return toNode.call(this, "span");
4055  }
4056
4057  toMarkup() {
4058    return toMarkup.call(this, "span");
4059  }
4060
4061}
4062/**
4063 * This node represents an anchor (<a>) element with a hyperlink.  See `span`
4064 * for further details.
4065 */
4066
4067class Anchor {
4068  constructor(href, classes, children, options) {
4069    this.children = void 0;
4070    this.attributes = void 0;
4071    this.classes = void 0;
4072    this.height = void 0;
4073    this.depth = void 0;
4074    this.maxFontSize = void 0;
4075    this.style = void 0;
4076    initNode.call(this, classes, options);
4077    this.children = children || [];
4078    this.setAttribute('href', href);
4079  }
4080
4081  setAttribute(attribute, value) {
4082    this.attributes[attribute] = value;
4083  }
4084
4085  hasClass(className) {
4086    return utils.contains(this.classes, className);
4087  }
4088
4089  toNode() {
4090    return toNode.call(this, "a");
4091  }
4092
4093  toMarkup() {
4094    return toMarkup.call(this, "a");
4095  }
4096
4097}
4098/**
4099 * This node represents an image embed (<img>) element.
4100 */
4101
4102class Img {
4103  constructor(src, alt, style) {
4104    this.src = void 0;
4105    this.alt = void 0;
4106    this.classes = void 0;
4107    this.height = void 0;
4108    this.depth = void 0;
4109    this.maxFontSize = void 0;
4110    this.style = void 0;
4111    this.alt = alt;
4112    this.src = src;
4113    this.classes = ["mord"];
4114    this.style = style;
4115  }
4116
4117  hasClass(className) {
4118    return utils.contains(this.classes, className);
4119  }
4120
4121  toNode() {
4122    var node = document.createElement("img");
4123    node.src = this.src;
4124    node.alt = this.alt;
4125    node.className = "mord"; // Apply inline styles
4126
4127    for (var style in this.style) {
4128      if (this.style.hasOwnProperty(style)) {
4129        // $FlowFixMe
4130        node.style[style] = this.style[style];
4131      }
4132    }
4133
4134    return node;
4135  }
4136
4137  toMarkup() {
4138    var markup = "<img src=\"" + utils.escape(this.src) + "\"" + (" alt=\"" + utils.escape(this.alt) + "\""); // Add the styles, after hyphenation
4139
4140    var styles = "";
4141
4142    for (var style in this.style) {
4143      if (this.style.hasOwnProperty(style)) {
4144        styles += utils.hyphenate(style) + ":" + this.style[style] + ";";
4145      }
4146    }
4147
4148    if (styles) {
4149      markup += " style=\"" + utils.escape(styles) + "\"";
4150    }
4151
4152    markup += "'/>";
4153    return markup;
4154  }
4155
4156}
4157var iCombinations = {
4158  'î': '\u0131\u0302',
4159  'ï': '\u0131\u0308',
4160  'í': '\u0131\u0301',
4161  // 'Ä«': '\u0131\u0304', // enable when we add Extended Latin
4162  'ì': '\u0131\u0300'
4163};
4164/**
4165 * A symbol node contains information about a single symbol. It either renders
4166 * to a single text node, or a span with a single text node in it, depending on
4167 * whether it has CSS classes, styles, or needs italic correction.
4168 */
4169
4170class SymbolNode {
4171  constructor(text, height, depth, italic, skew, width, classes, style) {
4172    this.text = void 0;
4173    this.height = void 0;
4174    this.depth = void 0;
4175    this.italic = void 0;
4176    this.skew = void 0;
4177    this.width = void 0;
4178    this.maxFontSize = void 0;
4179    this.classes = void 0;
4180    this.style = void 0;
4181    this.text = text;
4182    this.height = height || 0;
4183    this.depth = depth || 0;
4184    this.italic = italic || 0;
4185    this.skew = skew || 0;
4186    this.width = width || 0;
4187    this.classes = classes || [];
4188    this.style = style || {};
4189    this.maxFontSize = 0; // Mark text from non-Latin scripts with specific classes so that we
4190    // can specify which fonts to use.  This allows us to render these
4191    // characters with a serif font in situations where the browser would
4192    // either default to a sans serif or render a placeholder character.
4193    // We use CSS class names like cjk_fallback, hangul_fallback and
4194    // brahmic_fallback. See ./unicodeScripts.js for the set of possible
4195    // script names
4196
4197    var script = scriptFromCodepoint(this.text.charCodeAt(0));
4198
4199    if (script) {
4200      this.classes.push(script + "_fallback");
4201    }
4202
4203    if (/[îïíì]/.test(this.text)) {
4204      // add Ä« when we add Extended Latin
4205      this.text = iCombinations[this.text];
4206    }
4207  }
4208
4209  hasClass(className) {
4210    return utils.contains(this.classes, className);
4211  }
4212  /**
4213   * Creates a text node or span from a symbol node. Note that a span is only
4214   * created if it is needed.
4215   */
4216
4217
4218  toNode() {
4219    var node = document.createTextNode(this.text);
4220    var span = null;
4221
4222    if (this.italic > 0) {
4223      span = document.createElement("span");
4224      span.style.marginRight = makeEm(this.italic);
4225    }
4226
4227    if (this.classes.length > 0) {
4228      span = span || document.createElement("span");
4229      span.className = createClass(this.classes);
4230    }
4231
4232    for (var style in this.style) {
4233      if (this.style.hasOwnProperty(style)) {
4234        span = span || document.createElement("span"); // $FlowFixMe Flow doesn't seem to understand span.style's type.
4235
4236        span.style[style] = this.style[style];
4237      }
4238    }
4239
4240    if (span) {
4241      span.appendChild(node);
4242      return span;
4243    } else {
4244      return node;
4245    }
4246  }
4247  /**
4248   * Creates markup for a symbol node.
4249   */
4250
4251
4252  toMarkup() {
4253    // TODO(alpert): More duplication than I'd like from
4254    // span.prototype.toMarkup and symbolNode.prototype.toNode...
4255    var needsSpan = false;
vendor: 4,084 bytes, lines 4256-4427
4256    var markup = "<span";
4257
4258    if (this.classes.length) {
4259      needsSpan = true;
4260      markup += " class=\"";
4261      markup += utils.escape(createClass(this.classes));
4262      markup += "\"";
4263    }
4264
4265    var styles = "";
4266
4267    if (this.italic > 0) {
4268      styles += "margin-right:" + this.italic + "em;";
4269    }
4270
4271    for (var style in this.style) {
4272      if (this.style.hasOwnProperty(style)) {
4273        styles += utils.hyphenate(style) + ":" + this.style[style] + ";";
4274      }
4275    }
4276
4277    if (styles) {
4278      needsSpan = true;
4279      markup += " style=\"" + utils.escape(styles) + "\"";
4280    }
4281
4282    var escaped = utils.escape(this.text);
4283
4284    if (needsSpan) {
4285      markup += ">";
4286      markup += escaped;
4287      markup += "</span>";
4288      return markup;
4289    } else {
4290      return escaped;
4291    }
4292  }
4293
4294}
4295/**
4296 * SVG nodes are used to render stretchy wide elements.
4297 */
4298
4299class SvgNode {
4300  constructor(children, attributes) {
4301    this.children = void 0;
4302    this.attributes = void 0;
4303    this.children = children || [];
4304    this.attributes = attributes || {};
4305  }
4306
4307  toNode() {
4308    var svgNS = "http://www.w3.org/2000/svg";
4309    var node = document.createElementNS(svgNS, "svg"); // Apply attributes
4310
4311    for (var attr in this.attributes) {
4312      if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
4313        node.setAttribute(attr, this.attributes[attr]);
4314      }
4315    }
4316
4317    for (var i = 0; i < this.children.length; i++) {
4318      node.appendChild(this.children[i].toNode());
4319    }
4320
4321    return node;
4322  }
4323
4324  toMarkup() {
4325    var markup = "<svg xmlns=\"http://www.w3.org/2000/svg\""; // Apply attributes
4326
4327    for (var attr in this.attributes) {
4328      if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
4329        markup += " " + attr + "=\"" + utils.escape(this.attributes[attr]) + "\"";
4330      }
4331    }
4332
4333    markup += ">";
4334
4335    for (var i = 0; i < this.children.length; i++) {
4336      markup += this.children[i].toMarkup();
4337    }
4338
4339    markup += "</svg>";
4340    return markup;
4341  }
4342
4343}
4344class PathNode {
4345  constructor(pathName, alternate) {
4346    this.pathName = void 0;
4347    this.alternate = void 0;
4348    this.pathName = pathName;
4349    this.alternate = alternate; // Used only for \sqrt, \phase, & tall delims
4350  }
4351
4352  toNode() {
4353    var svgNS = "http://www.w3.org/2000/svg";
4354    var node = document.createElementNS(svgNS, "path");
4355
4356    if (this.alternate) {
4357      node.setAttribute("d", this.alternate);
4358    } else {
4359      node.setAttribute("d", path[this.pathName]);
4360    }
4361
4362    return node;
4363  }
4364
4365  toMarkup() {
4366    if (this.alternate) {
4367      return "<path d=\"" + utils.escape(this.alternate) + "\"/>";
4368    } else {
4369      return "<path d=\"" + utils.escape(path[this.pathName]) + "\"/>";
4370    }
4371  }
4372
4373}
4374class LineNode {
4375  constructor(attributes) {
4376    this.attributes = void 0;
4377    this.attributes = attributes || {};
4378  }
4379
4380  toNode() {
4381    var svgNS = "http://www.w3.org/2000/svg";
4382    var node = document.createElementNS(svgNS, "line"); // Apply attributes
4383
4384    for (var attr in this.attributes) {
4385      if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
4386        node.setAttribute(attr, this.attributes[attr]);
4387      }
4388    }
4389
4390    return node;
4391  }
4392
4393  toMarkup() {
4394    var markup = "<line";
4395
4396    for (var attr in this.attributes) {
4397      if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
4398        markup += " " + attr + "=\"" + utils.escape(this.attributes[attr]) + "\"";
4399      }
4400    }
4401
4402    markup += "/>";
4403    return markup;
4404  }
4405
4406}
4407function assertSymbolDomNode(group) {
4408  if (group instanceof SymbolNode) {
4409    return group;
4410  } else {
4411    throw new Error("Expected symbolNode but got " + String(group) + ".");
4412  }
4413}
4414function assertSpan(group) {
4415  if (group instanceof Span) {
4416    return group;
4417  } else {
4418    throw new Error("Expected span<HtmlDomNode> but got " + String(group) + ".");
4419  }
4420}
4421
4422/**
4423 * This file holds a list of all no-argument functions and single-character
4424 * symbols (like 'a' or ';').
4425 *
4426 * For each of the symbols, there are three properties they can have:
4427 * - font (required): the font to be used for this symbol. Either "main" (the
4428     normal font), or "ams" (the ams fonts).
4429 * - group (required): the ParseNode group type the symbol should have (i.e.
4430     "textord", "mathord", etc).
4431     See https://github.com/KaTeX/KaTeX/wiki/Examining-TeX#group-types
4432 * - replace: the character that this symbol or function should be
4433 *   replaced with (i.e. "\phi" has a replace value of "\u03d5", the phi
4434 *   character in the main font).
4435 *
4436 * The outermost map in the table indicates what mode the symbols should be
4437 * accepted in (e.g. "math" or "text").
4438 */
4439// Some of these have a "-token" suffix since these are also used as `ParseNode`
4440// types for raw text tokens, and we want to avoid conflicts with higher-level
4441// `ParseNode` types. These `ParseNode`s are constructed within `Parser` by
4442// looking up the `symbols` map.
4443var ATOMS = {
4444  "bin": 1,
4445  "close": 1,
4446  "inner": 1,
4447  "open": 1,
4448  "punct": 1,
4449  "rel": 1
4450};
4451var NON_ATOMS = {
4452  "accent-token": 1,
4453  "mathord": 1,
4454  "op-token": 1,
4455  "spacing": 1,
4456  "textord": 1
4457};
4458var symbols = {
4459  "math": {},
4460  "text": {}
4461};
4462/** `acceptUnicodeChar = true` is only applicable if `replace` is set. */
4463
4464function defineSymbol(mode, font, group, replace, name, acceptUnicodeChar) {
4465  symbols[mode][name] = {
4466    font,
4467    group,
4468    replace
4469  };
4470
4471  if (acceptUnicodeChar && replace) {
4472    symbols[mode][replace] = symbols[mode][name];
4473  }
4474} // Some abbreviations for commonly used strings.
4475// This helps minify the code, and also spotting typos using jshint.
4476// modes:
4477
4478var math = "math";
4479var text = "text"; // fonts:
4480
4481var main = "main";
4482var ams = "ams"; // groups:
4483
4484var accent = "accent-token";
4485var bin = "bin";
4486var close = "close";
4487var inner = "inner";
4488var mathord = "mathord";
4489var op = "op-token";
4490var open = "open";
4491var punct = "punct";
4492var rel = "rel";
4493var spacing = "spacing";
4494var textord = "textord"; // Now comes the symbol table
4495// Relation Symbols
4496
4497defineSymbol(math, main, rel, "\u2261", "\\equiv", true);
4498defineSymbol(math, main, rel, "\u227a", "\\prec", true);
4499defineSymbol(math, main, rel, "\u227b", "\\succ", true);
4500defineSymbol(math, main, rel, "\u223c", "\\sim", true);
4501defineSymbol(math, main, rel, "\u22a5", "\\perp");
4502defineSymbol(math, main, rel, "\u2aaf", "\\preceq", true);
4503defineSymbol(math, main, rel, "\u2ab0", "\\succeq", true);
4504defineSymbol(math, main, rel, "\u2243", "\\simeq", true);
4505defineSymbol(math, main, rel, "\u2223", "\\mid", true);
4506defineSymbol(math, main, rel, "\u226a", "\\ll", true);
4507defineSymbol(math, main, rel, "\u226b", "\\gg", true);
4508defineSymbol(math, main, rel, "\u224d", "\\asymp", true);
4509defineSymbol(math, main, rel, "\u2225", "\\parallel");
4510defineSymbol(math, main, rel, "\u22c8", "\\bowtie", true);
4511defineSymbol(math, main, rel, "\u2323", "\\smile", true);
4512defineSymbol(math, main, rel, "\u2291", "\\sqsubseteq", true);
4513defineSymbol(math, main, rel, "\u2292", "\\sqsupseteq", true);
4514defineSymbol(math, main, rel, "\u2250", "\\doteq", true);
4515defineSymbol(math, main, rel, "\u2322", "\\frown", true);
4516defineSymbol(math, main, rel, "\u220b", "\\ni", true);
4517defineSymbol(math, main, rel, "\u221d", "\\propto", true);
4518defineSymbol(math, main, rel, "\u22a2", "\\vdash", true);
4519defineSymbol(math, main, rel, "\u22a3", "\\dashv", true);
4520defineSymbol(math, main, rel, "\u220b", "\\owns"); // Punctuation
4521
4522defineSymbol(math, main, punct, "\u002e", "\\ldotp");
4523defineSymbol(math, main, punct, "\u22c5", "\\cdotp"); // Misc Symbols
4524
4525defineSymbol(math, main, textord, "\u0023", "\\#");
4526defineSymbol(text, main, textord, "\u0023", "\\#");
4527defineSymbol(math, main, textord, "\u0026", "\\&");
4528defineSymbol(text, main, textord, "\u0026", "\\&");
4529defineSymbol(math, main, textord, "\u2135", "\\aleph", true);
4530defineSymbol(math, main, textord, "\u2200", "\\forall", true);
4531defineSymbol(math, main, textord, "\u210f", "\\hbar", true);
4532defineSymbol(math, main, textord, "\u2203", "\\exists", true);
4533defineSymbol(math, main, textord, "\u2207", "\\nabla", true);
4534defineSymbol(math, main, textord, "\u266d", "\\flat", true);
4535defineSymbol(math, main, textord, "\u2113", "\\ell", true);
4536defineSymbol(math, main, textord, "\u266e", "\\natural", true);
4537defineSymbol(math, main, textord, "\u2663", "\\clubsuit", true);
4538defineSymbol(math, main, textord, "\u2118", "\\wp", true);
4539defineSymbol(math, main, textord, "\u266f", "\\sharp", true);
4540defineSymbol(math, main, textord, "\u2662", "\\diamondsuit", true);
4541defineSymbol(math, main, textord, "\u211c", "\\Re", true);
4542defineSymbol(math, main, textord, "\u2661", "\\heartsuit", true);
4543defineSymbol(math, main, textord, "\u2111", "\\Im", true);
4544defineSymbol(math, main, textord, "\u2660", "\\spadesuit", true);
4545defineSymbol(math, main, textord, "\u00a7", "\\S", true);
4546defineSymbol(text, main, textord, "\u00a7", "\\S");
4547defineSymbol(math, main, textord, "\u00b6", "\\P", true);
4548defineSymbol(text, main, textord, "\u00b6", "\\P"); // Math and Text
4549
4550defineSymbol(math, main, textord, "\u2020", "\\dag");
4551defineSymbol(text, main, textord, "\u2020", "\\dag");
4552defineSymbol(text, main, textord, "\u2020", "\\textdagger");
4553defineSymbol(math, main, textord, "\u2021", "\\ddag");
4554defineSymbol(text, main, textord, "\u2021", "\\ddag");
4555defineSymbol(text, main, textord, "\u2021", "\\textdaggerdbl"); // Large Delimiters
4556
4557defineSymbol(math, main, close, "\u23b1", "\\rmoustache", true);
4558defineSymbol(math, main, open, "\u23b0", "\\lmoustache", true);
4559defineSymbol(math, main, close, "\u27ef", "\\rgroup", true);
4560defineSymbol(math, main, open, "\u27ee", "\\lgroup", true); // Binary Operators
4561
4562defineSymbol(math, main, bin, "\u2213", "\\mp", true);
4563defineSymbol(math, main, bin, "\u2296", "\\ominus", true);
4564defineSymbol(math, main, bin, "\u228e", "\\uplus", true);
4565defineSymbol(math, main, bin, "\u2293", "\\sqcap", true);
4566defineSymbol(math, main, bin, "\u2217", "\\ast");
4567defineSymbol(math, main, bin, "\u2294", "\\sqcup", true);
4568defineSymbol(math, main, bin, "\u25ef", "\\bigcirc", true);
4569defineSymbol(math, main, bin, "\u2219", "\\bullet", true);
4570defineSymbol(math, main, bin, "\u2021", "\\ddagger");
4571defineSymbol(math, main, bin, "\u2240", "\\wr", true);
4572defineSymbol(math, main, bin, "\u2a3f", "\\amalg");
4573defineSymbol(math, main, bin, "\u0026", "\\And"); // from amsmath
4574// Arrow Symbols
4575
4576defineSymbol(math, main, rel, "\u27f5", "\\longleftarrow", true);
4577defineSymbol(math, main, rel, "\u21d0", "\\Leftarrow", true);
4578defineSymbol(math, main, rel, "\u27f8", "\\Longleftarrow", true);
4579defineSymbol(math, main, rel, "\u27f6", "\\longrightarrow", true);
4580defineSymbol(math, main, rel, "\u21d2", "\\Rightarrow", true);
4581defineSymbol(math, main, rel, "\u27f9", "\\Longrightarrow", true);
4582defineSymbol(math, main, rel, "\u2194", "\\leftrightarrow", true);
4583defineSymbol(math, main, rel, "\u27f7", "\\longleftrightarrow", true);
4584defineSymbol(math, main, rel, "\u21d4", "\\Leftrightarrow", true);
4585defineSymbol(math, main, rel, "\u27fa", "\\Longleftrightarrow", true);
4586defineSymbol(math, main, rel, "\u21a6", "\\mapsto", true);
4587defineSymbol(math, main, rel, "\u27fc", "\\longmapsto", true);
4588defineSymbol(math, main, rel, "\u2197", "\\nearrow", true);
4589defineSymbol(math, main, rel, "\u21a9", "\\hookleftarrow", true);
4590defineSymbol(math, main, rel, "\u21aa", "\\hookrightarrow", true);
4591defineSymbol(math, main, rel, "\u2198", "\\searrow", true);
4592defineSymbol(math, main, rel, "\u21bc", "\\leftharpoonup", true);
4593defineSymbol(math, main, rel, "\u21c0", "\\rightharpoonup", true);
4594defineSymbol(math, main, rel, "\u2199", "\\swarrow", true);
4595defineSymbol(math, main, rel, "\u21bd", "\\leftharpoondown", true);
4596defineSymbol(math, main, rel, "\u21c1", "\\rightharpoondown", true);
4597defineSymbol(math, main, rel, "\u2196", "\\nwarrow", true);
4598defineSymbol(math, main, rel, "\u21cc", "\\rightleftharpoons", true); // AMS Negated Binary Relations
4599
4600defineSymbol(math, ams, rel, "\u226e", "\\nless", true); // Symbol names preceded by "@" each have a corresponding macro.
4601
4602defineSymbol(math, ams, rel, "\ue010", "\\@nleqslant");
4603defineSymbol(math, ams, rel, "\ue011", "\\@nleqq");
4604defineSymbol(math, ams, rel, "\u2a87", "\\lneq", true);
4605defineSymbol(math, ams, rel, "\u2268", "\\lneqq", true);
4606defineSymbol(math, ams, rel, "\ue00c", "\\@lvertneqq");
4607defineSymbol(math, ams, rel, "\u22e6", "\\lnsim", true);
4608defineSymbol(math, ams, rel, "\u2a89", "\\lnapprox", true);
4609defineSymbol(math, ams, rel, "\u2280", "\\nprec", true); // unicode-math maps \u22e0 to \npreccurlyeq. We'll use the AMS synonym.
4610
4611defineSymbol(math, ams, rel, "\u22e0", "\\npreceq", true);
4612defineSymbol(math, ams, rel, "\u22e8", "\\precnsim", true);
4613defineSymbol(math, ams, rel, "\u2ab9", "\\precnapprox", true);
4614defineSymbol(math, ams, rel, "\u2241", "\\nsim", true);
4615defineSymbol(math, ams, rel, "\ue006", "\\@nshortmid");
4616defineSymbol(math, ams, rel, "\u2224", "\\nmid", true);
4617defineSymbol(math, ams, rel, "\u22ac", "\\nvdash", true);
4618defineSymbol(math, ams, rel, "\u22ad", "\\nvDash", true);
4619defineSymbol(math, ams, rel, "\u22ea", "\\ntriangleleft");
4620defineSymbol(math, ams, rel, "\u22ec", "\\ntrianglelefteq", true);
4621defineSymbol(math, ams, rel, "\u228a", "\\subsetneq", true);
4622defineSymbol(math, ams, rel, "\ue01a", "\\@varsubsetneq");
4623defineSymbol(math, ams, rel, "\u2acb", "\\subsetneqq", true);
4624defineSymbol(math, ams, rel, "\ue017", "\\@varsubsetneqq");
4625defineSymbol(math, ams, rel, "\u226f", "\\ngtr", true);
4626defineSymbol(math, ams, rel, "\ue00f", "\\@ngeqslant");
4627defineSymbol(math, ams, rel, "\ue00e", "\\@ngeqq");
4628defineSymbol(math, ams, rel, "\u2a88", "\\gneq", true);
4629defineSymbol(math, ams, rel, "\u2269", "\\gneqq", true);
4630defineSymbol(math, ams, rel, "\ue00d", "\\@gvertneqq");
4631defineSymbol(math, ams, rel, "\u22e7", "\\gnsim", true);
4632defineSymbol(math, ams, rel, "\u2a8a", "\\gnapprox", true);
4633defineSymbol(math, ams, rel, "\u2281", "\\nsucc", true);
4633 // unicode-math maps \u22e1 to \nsucccurlyeq. We'll use the AMS synonym.
4634
4635defineSymbol(math, ams, rel, "\u22e1", "\\nsucceq", true);
4636defineSymbol(math, ams, rel, "\u22e9", "\\succnsim", true);
4637defineSymbol(math, ams, rel, "\u2aba", "\\succnapprox", true); // unicode-math maps \u2246 to \simneqq. We'll use the AMS synonym.
4638
4639defineSymbol(math, ams, rel, "\u2246", "\\ncong", true);
4640defineSymbol(math, ams, rel, "\ue007", "\\@nshortparallel");
4641defineSymbol(math, ams, rel, "\u2226", "\\nparallel", true);
4642defineSymbol(math, ams, rel, "\u22af", "\\nVDash", true);
4643defineSymbol(math, ams, rel, "\u22eb", "\\ntriangleright");
4644defineSymbol(math, ams, rel, "\u22ed", "\\ntrianglerighteq", true);
4645defineSymbol(math, ams, rel, "\ue018", "\\@nsupseteqq");
4646defineSymbol(math, ams, rel, "\u228b", "\\supsetneq", true);
4647defineSymbol(math, ams, rel, "\ue01b", "\\@varsupsetneq");
4648defineSymbol(math, ams, rel, "\u2acc", "\\supsetneqq", true);
4649defineSymbol(math, ams, rel, "\ue019", "\\@varsupsetneqq");
4650defineSymbol(math, ams, rel, "\u22ae", "\\nVdash", true);
4651defineSymbol(math, ams, rel, "\u2ab5", "\\precneqq", true);
4652defineSymbol(math, ams, rel, "\u2ab6", "\\succneqq", true);
4653defineSymbol(math, ams, rel, "\ue016", "\\@nsubseteqq");
4654defineSymbol(math, ams, bin, "\u22b4", "\\unlhd");
4655defineSymbol(math, ams, bin, "\u22b5", "\\unrhd"); // AMS Negated Arrows
4656
4657defineSymbol(math, ams, rel, "\u219a", "\\nleftarrow", true);
4658defineSymbol(math, ams, rel, "\u219b", "\\nrightarrow", true);
4659defineSymbol(math, ams, rel, "\u21cd", "\\nLeftarrow", true);
4660defineSymbol(math, ams, rel, "\u21cf", "\\nRightarrow", true);
4661defineSymbol(math, ams, rel, "\u21ae", "\\nleftrightarrow", true);
4662defineSymbol(math, ams, rel, "\u21ce", "\\nLeftrightarrow", true); // AMS Misc
4663
4664defineSymbol(math, ams, rel, "\u25b3", "\\vartriangle");
4665defineSymbol(math, ams, textord, "\u210f", "\\hslash");
4666defineSymbol(math, ams, textord, "\u25bd", "\\triangledown");
4667defineSymbol(math, ams, textord, "\u25ca", "\\lozenge");
4668defineSymbol(math, ams, textord, "\u24c8", "\\circledS");
4669defineSymbol(math, ams, textord, "\u00ae", "\\circledR");
4670defineSymbol(text, ams, textord, "\u00ae", "\\circledR");
4671defineSymbol(math, ams, textord, "\u2221", "\\measuredangle", true);
4672defineSymbol(math, ams, textord, "\u2204", "\\nexists");
4673defineSymbol(math, ams, textord, "\u2127", "\\mho");
4674defineSymbol(math, ams, textord, "\u2132", "\\Finv", true);
4675defineSymbol(math, ams, textord, "\u2141", "\\Game", true);
4676defineSymbol(math, ams, textord, "\u2035", "\\backprime");
4677defineSymbol(math, ams, textord, "\u25b2", "\\blacktriangle");
4678defineSymbol(math, ams, textord, "\u25bc", "\\blacktriangledown");
4679defineSymbol(math, ams, textord, "\u25a0", "\\blacksquare");
4680defineSymbol(math, ams, textord, "\u29eb", "\\blacklozenge");
4681defineSymbol(math, ams, textord, "\u2605", "\\bigstar");
4682defineSymbol(math, ams, textord, "\u2222", "\\sphericalangle", true);
4683defineSymbol(math, ams, textord, "\u2201", "\\complement", true); // unicode-math maps U+F0 to \matheth. We map to AMS function \eth
4684
4685defineSymbol(math, ams, textord, "\u00f0", "\\eth", true);
4686defineSymbol(text, main, textord, "\u00f0", "\u00f0");
4687defineSymbol(math, ams, textord, "\u2571", "\\diagup");
4688defineSymbol(math, ams, textord, "\u2572", "\\diagdown");
4689defineSymbol(math, ams, textord, "\u25a1", "\\square");
4690defineSymbol(math, ams, textord, "\u25a1", "\\Box");
4691defineSymbol(math, ams, textord, "\u25ca", "\\Diamond"); // unicode-math maps U+A5 to \mathyen. We map to AMS function \yen
4692
4693defineSymbol(math, ams, textord, "\u00a5", "\\yen", true);
4694defineSymbol(text, ams, textord, "\u00a5", "\\yen", true);
4695defineSymbol(math, ams, textord, "\u2713", "\\checkmark", true);
4696defineSymbol(text, ams, textord, "\u2713", "\\checkmark"); // AMS Hebrew
4697
4698defineSymbol(math, ams, textord, "\u2136", "\\beth", true);
4699defineSymbol(math, ams, textord, "\u2138", "\\daleth", true);
4700defineSymbol(math, ams, textord, "\u2137", "\\gimel", true); // AMS Greek
4701
4702defineSymbol(math, ams, textord, "\u03dd", "\\digamma", true);
4703defineSymbol(math, ams, textord, "\u03f0", "\\varkappa"); // AMS Delimiters
4704
4705defineSymbol(math, ams, open, "\u250c", "\\@ulcorner", true);
4706defineSymbol(math, ams, close, "\u2510", "\\@urcorner", true);
4707defineSymbol(math, ams, open, "\u2514", "\\@llcorner", true);
4708defineSymbol(math, ams, close, "\u2518", "\\@lrcorner", true); // AMS Binary Relations
4709
4710defineSymbol(math, ams, rel, "\u2266", "\\leqq", true);
4711defineSymbol(math, ams, rel, "\u2a7d", "\\leqslant", true);
4712defineSymbol(math, ams, rel, "\u2a95", "\\eqslantless", true);
4713defineSymbol(math, ams, rel, "\u2272", "\\lesssim", true);
4714defineSymbol(math, ams, rel, "\u2a85", "\\lessapprox", true);
4715defineSymbol(math, ams, rel, "\u224a", "\\approxeq", true);
4716defineSymbol(math, ams, bin, "\u22d6", "\\lessdot");
4717defineSymbol(math, ams, rel, "\u22d8", "\\lll", true);
4718defineSymbol(math, ams, rel, "\u2276", "\\lessgtr", true);
4719defineSymbol(math, ams, rel, "\u22da", "\\lesseqgtr", true);
4720defineSymbol(math, ams, rel, "\u2a8b", "\\lesseqqgtr", true);
4721defineSymbol(math, ams, rel, "\u2251", "\\doteqdot");
4722defineSymbol(math, ams, rel, "\u2253", "\\risingdotseq", true);
4723defineSymbol(math, ams, rel, "\u2252", "\\fallingdotseq", true);
4724defineSymbol(math, ams, rel, "\u223d", "\\backsim", true);
4725defineSymbol(math, ams, rel, "\u22cd", "\\backsimeq", true);
4726defineSymbol(math, ams, rel, "\u2ac5", "\\subseteqq", true);
4727defineSymbol(math, ams, rel, "\u22d0", "\\Subset", true);
4728defineSymbol(math, ams, rel, "\u228f", "\\sqsubset", true);
4729defineSymbol(math, ams, rel, "\u227c", "\\preccurlyeq", true);
4730defineSymbol(math, ams, rel, "\u22de", "\\curlyeqprec", true);
4731defineSymbol(math, ams, rel, "\u227e", "\\precsim", true);
4732defineSymbol(math, ams, rel, "\u2ab7", "\\precapprox", true);
4733defineSymbol(math, ams, rel, "\u22b2", "\\vartriangleleft");
4734defineSymbol(math, ams, rel, "\u22b4", "\\trianglelefteq");
4735defineSymbol(math, ams, rel, "\u22a8", "\\vDash", true);
4736defineSymbol(math, ams, rel, "\u22aa", "\\Vvdash", true);
4737defineSymbol(math, ams, rel, "\u2323", "\\smallsmile");
4738defineSymbol(math, ams, rel, "\u2322", "\\smallfrown");
4739defineSymbol(math, ams, rel, "\u224f", "\\bumpeq", true);
4740defineSymbol(math, ams, rel, "\u224e", "\\Bumpeq", true);
4741defineSymbol(math, ams, rel, "\u2267", "\\geqq", true);
4742defineSymbol(math, ams, rel, "\u2a7e", "\\geqslant", true);
4743defineSymbol(math, ams, rel, "\u2a96", "\\eqslantgtr", true);
4744defineSymbol(math, ams, rel, "\u2273", "\\gtrsim", true);
4745defineSymbol(math, ams, rel, "\u2a86", "\\gtrapprox", true);
4746defineSymbol(math, ams, bin, "\u22d7", "\\gtrdot");
4747defineSymbol(math, ams, rel, "\u22d9", "\\ggg", true);
4748defineSymbol(math, ams, rel, "\u2277", "\\gtrless", true);
4749defineSymbol(math, ams, rel, "\u22db", "\\gtreqless", true);
4750defineSymbol(math, ams, rel, "\u2a8c", "\\gtreqqless", true);
4751defineSymbol(math, ams, rel, "\u2256", "\\eqcirc", true);
4752defineSymbol(math, ams, rel, "\u2257", "\\circeq", true);
4753defineSymbol(math, ams, rel, "\u225c", "\\triangleq", true);
4754defineSymbol(math, ams, rel, "\u223c", "\\thicksim");
4755defineSymbol(math, ams, rel, "\u2248", "\\thickapprox");
4756defineSymbol(math, ams, rel, "\u2ac6", "\\supseteqq", true);
4757defineSymbol(math, ams, rel, "\u22d1", "\\Supset", true);
4758defineSymbol(math, ams, rel, "\u2290", "\\sqsupset", true);
4759defineSymbol(math, ams, rel, "\u227d", "\\succcurlyeq", true);
4760defineSymbol(math, ams, rel, "\u22df", "\\curlyeqsucc", true);
4761defineSymbol(math, ams, rel, "\u227f", "\\succsim", true);
4762defineSymbol(math, ams, rel, "\u2ab8", "\\succapprox", true);
4763defineSymbol(math, ams, rel, "\u22b3", "\\vartriangleright");
4764defineSymbol(math, ams, rel, "\u22b5", "\\trianglerighteq");
4765defineSymbol(math, ams, rel, "\u22a9", "\\Vdash", true);
4766defineSymbol(math, ams, rel, "\u2223", "\\shortmid");
4767defineSymbol(math, ams, rel, "\u2225", "\\shortparallel");
4768defineSymbol(math, ams, rel, "\u226c", "\\between", true);
4769defineSymbol(math, ams, rel, "\u22d4", "\\pitchfork", true);
4770defineSymbol(math, ams, rel, "\u221d", "\\varpropto");
4771defineSymbol(math, ams, rel, "\u25c0", "\\blacktriangleleft");
4771 // unicode-math says that \therefore is a mathord atom.
4772// We kept the amssymb atom type, which is rel.
4773
4774defineSymbol(math, ams, rel, "\u2234", "\\therefore", true);
4775defineSymbol(math, ams, rel, "\u220d", "\\backepsilon");
4776defineSymbol(math, ams, rel, "\u25b6", "\\blacktriangleright"); // unicode-math says that \because is a mathord atom.
4777// We kept the amssymb atom type, which is rel.
4778
4779defineSymbol(math, ams, rel, "\u2235", "\\because", true);
4780defineSymbol(math, ams, rel, "\u22d8", "\\llless");
4781defineSymbol(math, ams, rel, "\u22d9", "\\gggtr");
4782defineSymbol(math, ams, bin, "\u22b2", "\\lhd");
4783defineSymbol(math, ams, bin, "\u22b3", "\\rhd");
4784defineSymbol(math, ams, rel, "\u2242", "\\eqsim", true);
4785defineSymbol(math, main, rel, "\u22c8", "\\Join");
4786defineSymbol(math, ams, rel, "\u2251", "\\Doteq", true); // AMS Binary Operators
4787
4788defineSymbol(math, ams, bin, "\u2214", "\\dotplus", true);
4789defineSymbol(math, ams, bin, "\u2216", "\\smallsetminus");
4790defineSymbol(math, ams, bin, "\u22d2", "\\Cap", true);
4791defineSymbol(math, ams, bin, "\u22d3", "\\Cup", true);
4792defineSymbol(math, ams, bin, "\u2a5e", "\\doublebarwedge", true);
4793defineSymbol(math, ams, bin, "\u229f", "\\boxminus", true);
4794defineSymbol(math, ams, bin, "\u229e", "\\boxplus", true);
4795defineSymbol(math, ams, bin, "\u22c7", "\\divideontimes", true);
4796defineSymbol(math, ams, bin, "\u22c9", "\\ltimes", true);
4797defineSymbol(math, ams, bin, "\u22ca", "\\rtimes", true);
4798defineSymbol(math, ams, bin, "\u22cb", "\\leftthreetimes", true);
4799defineSymbol(math, ams, bin, "\u22cc", "\\rightthreetimes", true);
4800defineSymbol(math, ams, bin, "\u22cf", "\\curlywedge", true);
4801defineSymbol(math, ams, bin, "\u22ce", "\\curlyvee", true);
4802defineSymbol(math, ams, bin, "\u229d", "\\circleddash", true);
4803defineSymbol(math, ams, bin, "\u229b", "\\circledast", true);
4804defineSymbol(math, ams, bin, "\u22c5", "\\centerdot");
4805defineSymbol(math, ams, bin, "\u22ba", "\\intercal", true);
4806defineSymbol(math, ams, bin, "\u22d2", "\\doublecap");
4807defineSymbol(math, ams, bin, "\u22d3", "\\doublecup");
4808defineSymbol(math, ams, bin, "\u22a0", "\\boxtimes", true); // AMS Arrows
4809// Note: unicode-math maps \u21e2 to their own function \rightdasharrow.
4810// We'll map it to AMS function \dashrightarrow. It produces the same atom.
4811
4812defineSymbol(math, ams, rel, "\u21e2", "\\dashrightarrow", true); // unicode-math maps \u21e0 to \leftdasharrow. We'll use the AMS synonym.
4813
4814defineSymbol(math, ams, rel, "\u21e0", "\\dashleftarrow", true);
4815defineSymbol(math, ams, rel, "\u21c7", "\\leftleftarrows", true);
4816defineSymbol(math, ams, rel, "\u21c6", "\\leftrightarrows", true);
4817defineSymbol(math, ams, rel, "\u21da", "\\Lleftarrow", true);
4818defineSymbol(math, ams, rel, "\u219e", "\\twoheadleftarrow", true);
4819defineSymbol(math, ams, rel, "\u21a2", "\\leftarrowtail", true);
4820defineSymbol(math, ams, rel, "\u21ab", "\\looparrowleft", true);
4821defineSymbol(math, ams, rel, "\u21cb", "\\leftrightharpoons", true);
4822defineSymbol(math, ams, rel, "\u21b6", "\\curvearrowleft", true); // unicode-math maps \u21ba to \acwopencirclearrow. We'll use the AMS synonym.
4823
4824defineSymbol(math, ams, rel, "\u21ba", "\\circlearrowleft", true);
4825defineSymbol(math, ams, rel, "\u21b0", "\\Lsh", true);
4826defineSymbol(math, ams, rel, "\u21c8", "\\upuparrows", true);
4827defineSymbol(math, ams, rel, "\u21bf", "\\upharpoonleft", true);
4828defineSymbol(math, ams, rel, "\u21c3", "\\downharpoonleft", true);
4829defineSymbol(math, main, rel, "\u22b6", "\\origof", true); // not in font
4830
4831defineSymbol(math, main, rel, "\u22b7", "\\imageof", true); // not in font
4832
4833defineSymbol(math, ams, rel, "\u22b8", "\\multimap", true);
4834defineSymbol(math, ams, rel, "\u21ad", "\\leftrightsquigarrow", true);
4835defineSymbol(math, ams, rel, "\u21c9", "\\rightrightarrows", true);
4836defineSymbol(math, ams, rel, "\u21c4", "\\rightleftarrows", true);
4837defineSymbol(math, ams, rel, "\u21a0", "\\twoheadrightarrow", true);
4838defineSymbol(math, ams, rel, "\u21a3", "\\rightarrowtail", true);
4839defineSymbol(math, ams, rel, "\u21ac", "\\looparrowright", true);
4840defineSymbol(math, ams, rel, "\u21b7", "\\curvearrowright", true); // unicode-math maps \u21bb to \cwopencirclearrow. We'll use the AMS synonym.
4841
4842defineSymbol(math, ams, rel, "\u21bb", "\\circlearrowright", true);
4843defineSymbol(math, ams, rel, "\u21b1", "\\Rsh", true);
4844defineSymbol(math, ams, rel, "\u21ca", "\\downdownarrows", true);
4845defineSymbol(math, ams, rel, "\u21be", "\\upharpoonright", true);
4846defineSymbol(math, ams, rel, "\u21c2", "\\downharpoonright", true);
4847defineSymbol(math, ams, rel, "\u21dd", "\\rightsquigarrow", true);
4848defineSymbol(math, ams, rel, "\u21dd", "\\leadsto");
4849defineSymbol(math, ams, rel, "\u21db", "\\Rrightarrow", true);
4850defineSymbol(math, ams, rel, "\u21be", "\\restriction");
4851defineSymbol(math, main, textord, "\u2018", "`");
4852defineSymbol(math, main, textord, "$", "\\$");
4853defineSymbol(text, main, textord, "$", "\\$");
4854defineSymbol(text, main, textord, "$", "\\textdollar");
4855defineSymbol(math, main, textord, "%", "\\%");
4856defineSymbol(text, main, textord, "%", "\\%");
4857defineSymbol(math, main, textord, "_", "\\_");
4858defineSymbol(text, main, textord, "_", "\\_");
4859defineSymbol(text, main, textord, "_", "\\textunderscore");
4860defineSymbol(math, main, textord, "\u2220", "\\angle", true);
4861defineSymbol(math, main, textord, "\u221e", "\\infty", true);
4862defineSymbol(math, main, textord, "\u2032", "\\prime");
4863defineSymbol(math, main, textord, "\u25b3", "\\triangle");
4864defineSymbol(math, main, textord, "\u0393", "\\Gamma", true);
4865defineSymbol(math, main, textord, "\u0394", "\\Delta", true);
4866defineSymbol(math, main, textord, "\u0398", "\\Theta", true);
4867defineSymbol(math, main, textord, "\u039b", "\\Lambda", true);
4868defineSymbol(math, main, textord, "\u039e", "\\Xi", true);
4869defineSymbol(math, main, textord, "\u03a0", "\\Pi", true);
4870defineSymbol(math, main, textord, "\u03a3", "\\Sigma", true);
4871defineSymbol(math, main, textord, "\u03a5", "\\Upsilon", true);
4872defineSymbol(math, main, textord, "\u03a6", "\\Phi", true);
4873defineSymbol(math, main, textord, "\u03a8", "\\Psi", true);
4874defineSymbol(math, main, textord, "\u03a9", "\\Omega", true);
4875defineSymbol(math, main, textord, "A", "\u0391");
4876defineSymbol(math, main, textord, "B", "\u0392");
4877defineSymbol(math, main, textord, "E", "\u0395");
4878defineSymbol(math, main, textord, "Z", "\u0396");
4879defineSymbol(math, main, textord, "H", "\u0397");
4880defineSymbol(math, main, textord, "I", "\u0399");
4881defineSymbol(math, main, textord, "K", "\u039A");
4882defineSymbol(math, main, textord, "M", "\u039C");
4883defineSymbol(math, main, textord, "N", "\u039D");
4884defineSymbol(math, main, textord, "O", "\u039F");
4885defineSymbol(math, main, textord, "P", "\u03A1");
4886defineSymbol(math, main, textord, "T", "\u03A4");
4887defineSymbol(math, main, textord, "X", "\u03A7");
4888defineSymbol(math, main, textord, "\u00ac", "\\neg", true);
4889defineSymbol(math, main, textord, "\u00ac", "\\lnot");
4890defineSymbol(math, main, textord, "\u22a4", "\\top");
4891defineSymbol(math, main, textord, "\u22a5", "\\bot");
4892defineSymbol(math, main, textord, "\u2205", "\\emptyset");
4893defineSymbol(math, ams, textord, "\u2205", "\\varnothing");
4894defineSymbol(math, main, mathord, "\u03b1", "\\alpha", true);
4895defineSymbol(math, main, mathord, "\u03b2", "\\beta", true);
4896defineSymbol(math, main, mathord, "\u03b3", "\\gamma", true);
4897defineSymbol(math, main, mathord, "\u03b4", "\\delta", true);
4898defineSymbol(math, main, mathord, "\u03f5", "\\epsilon", true);
4899defineSymbol(math, main, mathord, "\u03b6", "\\zeta", true);
4900defineSymbol(math, main, mathord, "\u03b7", "\\eta", true);
4901defineSymbol(math, main, mathord, "\u03b8", "\\theta", true);
4902defineSymbol(math, main, mathord, "\u03b9", "\\iota", true);
4903defineSymbol(math, main, mathord, "\u03ba", "\\kappa", true);
4904defineSymbol(math, main, mathord, "\u03bb", "\\lambda", true);
4905defineSymbol(math, main, mathord, "\u03bc", "\\mu", true);
4906defineSymbol(math, main, mathord, "\u03bd", "\\nu", true);
4907defineSymbol(math, main, mathord, "\u03be", "\\xi", true);
4908defineSymbol(math, main, mathord, "\u03bf", "\\omicron", true);
4909defineSymbol(math, main, mathord, "\u03c0", "\\pi", true);
4910defineSymbol(math, main, mathord, "\u03c1", "\\rho", true);
4911defineSymbol(math, main, mathord, "\u03c3", "\\sigma", true);
4912defineSymbol(math, main, mathord, "\u03c4", "\\tau", true);
4913defineSymbol(math, main, mathord, "\u03c5", "\\upsilon", true);
4914defineSymbol(math, main, mathord, "\u03d5", "\\phi", true);
4915defineSymbol(math, main, mathord, "\u03c7", "\\chi", true);
4916defineSymbol(math, main, mathord, "\u03c8", "\\psi", true);
4917defineSymbol(math, main, mathord, "\u03c9", "\\omega", true);
4918defineSymbol(math, main, mathord, "\u03b5", "\\varepsilon", true);
4919defineSymbol(math, main, mathord, "\u03d1", "\\vartheta", true);
4920defineSymbol(math, main, mathord, "\u03d6", "\\varpi", true);
4921defineSymbol(math, main, mathord, "\u03f1", "\\varrho", true);
4922defineSymbol(math, main, mathord, "\u03c2", "\\varsigma", true);
4923defineSymbol(math, main, mathord, "\u03c6", "\\varphi", true);
4924defineSymbol(math, main, bin, "\u2217", "*", true);
4925defineSymbol(math, main, bin, "+", "+");
4926defineSymbol(math, main, bin, "\u2212", "-", true);
4927defineSymbol(math, main, bin, "\u22c5", "\\cdot", true);
4928defineSymbol(math, main, bin, "\u2218", "\\circ", true);
4929defineSymbol(math, main, bin, "\u00f7", "\\div", true);
4930defineSymbol(math, main, bin, "\u00b1", "\\pm", true);
4931defineSymbol(math, main, bin, "\u00d7", "\\times", true);
4932defineSymbol(math, main, bin, "\u2229", "\\cap", true);
4933defineSymbol(math, main, bin, "\u222a", "\\cup", true);
4934defineSymbol(math, main, bin, "\u2216", "\\setminus", true);
4935defineSymbol(math, main, bin, "\u2227", "\\land");
4936defineSymbol(math, main, bin, "\u2228", "\\lor");
4937defineSymbol(math, main, bin, "\u2227", "\\wedge", true);
4938defineSymbol(math, main, bin, "\u2228", "\\vee", true);
4939defineSymbol(math, main, textord, "\u221a", "\\surd");
4940defineSymbol(math, main, open, "\u27e8", "\\langle", true);
4941defineSymbol(math, main, open, "\u2223", "\\lvert");
4942defineSymbol(math, main, open, "\u2225", "\\lVert");
4943defineSymbol(math, main, close, "?", "?");
4944defineSymbol(math, main, close, "!", "!");
4945defineSymbol(math, main, close, "\u27e9", "\\rangle", true);
4946defineSymbol(math, main, close, "\u2223", "\\rvert");
4947defineSymbol(math, main, close, "\u2225", "\\rVert");
4948defineSymbol(math, main, rel, "=", "=");
4949defineSymbol(math, main, rel, ":", ":");
4950defineSymbol(math, main, rel, "\u2248", "\\approx", true);
4951defineSymbol(math, main, rel, "\u2245", "\\cong", true);
4952defineSymbol(math, main, rel, "\u2265", "\\ge");
4953defineSymbol(math, main, rel, "\u2265", "\\geq", true);
4954defineSymbol(math, main, rel, "\u2190", "\\gets");
4955defineSymbol(math, main, rel, ">", "\\gt", true);
4956defineSymbol(math, main, rel, "\u2208", "\\in", true);
4957defineSymbol(math, main, rel, "\ue020", "\\@not");
4958defineSymbol(math, main, rel, "\u2282", "\\subset", true);
4959defineSymbol(math, main, rel, "\u2283", "\\supset", true);
4960defineSymbol(math, main, rel, "\u2286", "\\subseteq", true);
4961defineSymbol(math, main, rel, "\u2287", "\\supseteq", true);
4962defineSymbol(math, ams, rel, "\u2288", "\\nsubseteq", true);
4963defineSymbol(math, ams, rel, "\u2289", "\\nsupseteq", true);
4964defineSymbol(math, main, rel, "\u22a8", "\\models");
4965defineSymbol(math, main, rel, "\u2190", "\\leftarrow", true);
4966defineSymbol(math, main, rel, "\u2264", "\\le");
4967defineSymbol(math, main, rel, "\u2264", "\\leq", true);
4968defineSymbol(math, main, rel, "<", "\\lt", true);
4969defineSymbol(math, main, rel, "\u2192", "\\rightarrow", true);
4970defineSymbol(math, main, rel, "\u2192", "\\to");
4971defineSymbol(math, ams, rel, "\u2271", "\\ngeq", true);
4972defineSymbol(math, ams, rel, "\u2270", "\\nleq", true);
4973defineSymbol(math, main, spacing, "\u00a0", "\\ ");
4974defineSymbol(math, main, spacing, "\u00a0", "\\space"); // Ref: LaTeX Source 2e: \DeclareRobustCommand{\nobreakspace}{%
4975
4976defineSymbol(math, main, spacing, "\u00a0", "\\nobreakspace");
4977defineSymbol(text, main, spacing, "\u00a0", "\\ ");
4978defineSymbol(text, main, spacing, "\u00a0", " ");
4979defineSymbol(text, main, spacing, "\u00a0", "\\space");
4980defineSymbol(text, main, spacing, "\u00a0", "\\nobreakspace");
4981defineSymbol(math, main, spacing, null, "\\nobreak");
4982defineSymbol(math, main, spacing, null, "\\allowbreak");
4983defineSymbol(math, main, punct, ",", ",");
4984defineSymbol(math, main, punct, ";", ";");
4985defineSymbol(math, ams, bin, "\u22bc", "\\barwedge", true);
4986defineSymbol(math, ams, bin, "\u22bb", "\\veebar", true);
4987defineSymbol(math, main, bin, "\u2299", "\\odot", true);
4988defineSymbol(math, main, bin, "\u2295", "\\oplus", true);
4989defineSymbol(math, main, bin, "\u2297", "\\otimes", true);
4990defineSymbol(math, main, textord, "\u2202", "\\partial", true);
4991defineSymbol(math, main, bin, "\u2298", "\\oslash", true);
4992defineSymbol(math, ams, bin, "\u229a", "\\circledcirc", true);
4993defineSymbol(math, ams, bin, "\u22a1", "\\boxdot", true);
4994defineSymbol(math, main, bin, "\u25b3", "\\bigtriangleup");
4995defineSymbol(math, main, bin, "\u25bd", "\\bigtriangledown");
4996defineSymbol(math, main, bin, "\u2020", "\\dagger");
4997defineSymbol(math, main, bin, "\u22c4", "\\diamond");
4998defineSymbol(math, main, bin, "\u22c6", "\\star");
4999defineSymbol(math, main, bin, "\u25c3", "\\triangleleft");
5000defineSymbol(math, main, bin, "\u25b9", "\\triangleright");
5001defineSymbol(math, main, open, "{", "\\{");
5002defineSymbol(text, main, textord, "{", "\\{");
5003defineSymbol(text, main, textord, "{", "\\textbraceleft");
5004defineSymbol(math, main, close, "}", "\\}");
5005defineSymbol(text, main, textord, "}", "\\}");
5006defineSymbol(text, main, textord, "}", "\\textbraceright");
5007defineSymbol(math, main, open, "{", "\\lbrace");
5008defineSymbol(math, main, close, "}", "\\rbrace");
5009defineSymbol(math, main, open, "[", "\\lbrack", true);
5010defineSymbol(text, main, textord, "[", "\\lbrack", true);
5011defineSymbol(math, main, close, "]", "\\rbrack", true);
5012defineSymbol(text, main, textord, "]", "\\rbrack", true);
5013defineSymbol(math, main, open, "(", "\\lparen", true);
5014defineSymbol(math, main, close, ")", "\\rparen", true);
5015defineSymbol(text, main, textord, "<", "\\textless", true); // in T1 fontenc
5016
5017defineSymbol(text, main, textord, ">", "\\textgreater", true); // in T1 fontenc
5018
5019defineSymbol(math, main, open, "\u230a", "\\lfloor", true);
5020defineSymbol(math, main, close, "\u230b", "\\rfloor", true);
5021defineSymbol(math, main, open, "\u2308", "\\lceil", true);
5022defineSymbol(math, main, close, "\u2309", "\\rceil", true);
5023defineSymbol(math, main, textord, "\\", "\\backslash");
5024defineSymbol(math, main, textord, "\u2223", "|");
5025defineSymbol(math, main, textord, "\u2223", "\\vert");
5026defineSymbol(text, main, textord, "|", "\\textbar", true); // in T1 fontenc
5027
5028defineSymbol(math, main, textord, "\u2225", "\\|");
5029defineSymbol(math, main, textord, "\u2225", "\\Vert");
5030defineSymbol(text, main, textord, "\u2225", "\\textbardbl");
5031defineSymbol(text, main, textord, "~", "\\textasciitilde");
5032defineSymbol(text, main, textord, "\\", "\\textbackslash");
5033defineSymbol(text, main, textord, "^", "\\textasciicircum");
5034defineSymbol(math, main, rel, "\u2191", "\\uparrow", true);
5035defineSymbol(math, main, rel, "\u21d1", "\\Uparrow", true);
5036defineSymbol(math, main, rel, "\u2193", "\\downarrow", true);
5037defineSymbol(math, main, rel, "\u21d3", "\\Downarrow", true);
5038defineSymbol(math, main, rel, "\u2195", "\\updownarrow", true);
5039defineSymbol(math, main, rel, "\u21d5", "\\Updownarrow", true);
5040defineSymbol(math, main, op, "\u2210", "\\coprod");
5041defineSymbol(math, main, op, "\u22c1", "\\bigvee");
5042defineSymbol(math, main, op, "\u22c0", "\\bigwedge");
5043defineSymbol(math, main, op, "\u2a04", "\\biguplus");
5044defineSymbol(math, main, op, "\u22c2", "\\bigcap");
5045defineSymbol(math, main, op, "\u22c3", "\\bigcup");
5046defineSymbol(math, main, op, "\u222b", "\\int");
5047defineSymbol(math, main, op, "\u222b", "\\intop");
5048defineSymbol(math, main, op, "\u222c", "\\iint");
5049defineSymbol(math, main, op, "\u222d", "\\iiint");
5050defineSymbol(math, main, op, "\u220f", "\\prod");
5051defineSymbol(math, main, op, "\u2211", "\\sum");
5052defineSymbol(math, main, op, "\u2a02", "\\bigotimes");
5053defineSymbol(math, main, op, "\u2a01", "\\bigoplus");
5054defineSymbol(math, main, op, "\u2a00", "\\bigodot");
5055defineSymbol(math, main, op, "\u222e", "\\oint");
5056defineSymbol(math, main, op, "\u222f", "\\oiint");
5057defineSymbol(math, main, op, "\u2230", "\\oiiint");
5058defineSymbol(math, main, op, "\u2a06", "\\bigsqcup");
5059defineSymbol(math, main, op, "\u222b", "\\smallint");
5060defineSymbol(text, main, inner, "\u2026", "\\textellipsis");
5061defineSymbol(math, main, inner, "\u2026", "\\mathellipsis");
5062defineSymbol(text, main, inner, "\u2026", "\\ldots", true);
5063defineSymbol(math, main, inner, "\u2026", "\\ldots", true);
5064defineSymbol(math, main, inner, "\u22ef", "\\@cdots", true);
5065defineSymbol(math, main, inner, "\u22f1", "\\ddots", true); // \vdots is a macro that uses one of these two symbols (with made-up names):
5066
5067defineSymbol(math, main, textord, "\u22ee", "\\varvdots");
5068defineSymbol(text, main, textord, "\u22ee", "\\varvdots");
5069defineSymbol(math, main, accent, "\u02ca", "\\acute");
5070defineSymbol(math, main, accent, "\u02cb", "\\grave");
5071defineSymbol(math, main, accent, "\u00a8", "\\ddot");
5072defineSymbol(math, main, accent, "\u007e", "\\tilde");
5073defineSymbol(math, main, accent, "\u02c9", "\\bar");
5074defineSymbol(math, main, accent, "\u02d8", "\\breve");
5075defineSymbol(math, main, accent, "\u02c7", "\\check");
5076defineSymbol(math, main, accent, "\u005e", "\\hat");
5077defineSymbol(math, main, accent, "\u20d7", "\\vec");
5078defineSymbol(math, main, accent, "\u02d9", "\\dot");
5079defineSymbol(math, main, accent, "\u02da", "\\mathring"); // \imath and \jmath should be invariant to \mathrm, \mathbf, etc., so use PUA
5080
5081defineSymbol(math, main, mathord, "\ue131", "\\@imath");
5082defineSymbol(math, main, mathord, "\ue237", "\\@jmath");
5083defineSymbol(math, main, textord, "\u0131", "\u0131");
5084defineSymbol(math, main, textord, "\u0237", "\u0237");
5085defineSymbol(text, main, textord, "\u0131", "\\i", true);
5086defineSymbol(text, main, textord, "\u0237", "\\j", true);
5087defineSymbol(text, main, textord, "\u00df", "\\ss", true);
5088defineSymbol(text, main, textord, "\u00e6", "\\ae", true);
5089defineSymbol(text, main, textord, "\u0153", "\\oe", true);
5090defineSymbol(text, main, textord, "\u00f8", "\\o", true);
5091defineSymbol(text, main, textord, "\u00c6", "\\AE", true);
5092defineSymbol(text, main, textord, "\u0152", "\\OE", true);
5093defineSymbol(text, main, textord, "\u00d8", "\\O", true);
5094defineSymbol(text, main, accent, "\u02ca", "\\'"); // acute
5095
5096defineSymbol(text, main, accent, "\u02cb", "\\`"); // grave
5097
5098defineSymbol(text, main, accent, "\u02c6", "\\^"); // circumflex
5099
5100defineSymbol(text, main, accent, "\u02dc", "\\~"); // tilde
5101
5102defineSymbol(text, main, accent, "\u02c9", "\\="); // macron
5103
5104defineSymbol(text, main, accent, "\u02d8", "\\u"); // breve
5105
5106defineSymbol(text, main, accent, "\u02d9", "\\."); // dot above
5107
5108defineSymbol(text, main, accent, "\u00b8", "\\c"); // cedilla
5109
5110defineSymbol(text, main, accent, "\u02da", "\\r"); // ring above
5111
5112defineSymbol(text, main, accent, "\u02c7", "\\v"); // caron
5113
5114defineSymbol(text, main, accent, "\u00a8", '\\"'); // diaresis
5115
5116defineSymbol(text, main, accent, "\u02dd", "\\H"); // double acute
5117
5118defineSymbol(text, main, accent, "\u25ef", "\\textcircled"); // \bigcirc glyph
5119// These ligatures are detected and created in Parser.js's `formLigatures`.
5120
5121var ligatures = {
5122  "--": true,
5123  "---": true,
5124  "``": true,
5125  "''": true
5126};
vendor: 14,159 bytes, lines 5127-5468
5127defineSymbol(text, main, textord, "\u2013", "--", true);
5128defineSymbol(text, main, textord, "\u2013", "\\textendash");
5129defineSymbol(text, main, textord, "\u2014", "---", true);
5130defineSymbol(text, main, textord, "\u2014", "\\textemdash");
5131defineSymbol(text, main, textord, "\u2018", "`", true);
5132defineSymbol(text, main, textord, "\u2018", "\\textquoteleft");
5133defineSymbol(text, main, textord, "\u2019", "'", true);
5134defineSymbol(text, main, textord, "\u2019", "\\textquoteright");
5135defineSymbol(text, main, textord, "\u201c", "``", true);
5136defineSymbol(text, main, textord, "\u201c", "\\textquotedblleft");
5137defineSymbol(text, main, textord, "\u201d", "''", true);
5138defineSymbol(text, main, textord, "\u201d", "\\textquotedblright"); //  \degree from gensymb package
5139
5140defineSymbol(math, main, textord, "\u00b0", "\\degree", true);
5141defineSymbol(text, main, textord, "\u00b0", "\\degree"); // \textdegree from inputenc package
5142
5143defineSymbol(text, main, textord, "\u00b0", "\\textdegree", true); // TODO: In LaTeX, \pounds can generate a different character in text and math
5144// mode, but among our fonts, only Main-Regular defines this character "163".
5145
5146defineSymbol(math, main, textord, "\u00a3", "\\pounds");
5147defineSymbol(math, main, textord, "\u00a3", "\\mathsterling", true);
5148defineSymbol(text, main, textord, "\u00a3", "\\pounds");
5149defineSymbol(text, main, textord, "\u00a3", "\\textsterling", true);
5150defineSymbol(math, ams, textord, "\u2720", "\\maltese");
5151defineSymbol(text, ams, textord, "\u2720", "\\maltese"); // There are lots of symbols which are the same, so we add them in afterwards.
5152// All of these are textords in math mode
5153
5154var mathTextSymbols = "0123456789/@.\"";
5155
5156for (var i = 0; i < mathTextSymbols.length; i++) {
5157  var ch = mathTextSymbols.charAt(i);
5158  defineSymbol(math, main, textord, ch, ch);
5159} // All of these are textords in text mode
5160
5161
5162var textSymbols = "0123456789!@*()-=+\";:?/.,";
5163
5164for (var _i = 0; _i < textSymbols.length; _i++) {
5165  var _ch = textSymbols.charAt(_i);
5166
5167  defineSymbol(text, main, textord, _ch, _ch);
5168} // All of these are textords in text mode, and mathords in math mode
5169
5170
5171var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
5172
5173for (var _i2 = 0; _i2 < letters.length; _i2++) {
5174  var _ch2 = letters.charAt(_i2);
5175
5176  defineSymbol(math, main, mathord, _ch2, _ch2);
5177  defineSymbol(text, main, textord, _ch2, _ch2);
5178} // Blackboard bold and script letters in Unicode range
5179
5180
5181defineSymbol(math, ams, textord, "C", "\u2102"); // blackboard bold
5182
5183defineSymbol(text, ams, textord, "C", "\u2102");
5184defineSymbol(math, ams, textord, "H", "\u210D");
5185defineSymbol(text, ams, textord, "H", "\u210D");
5186defineSymbol(math, ams, textord, "N", "\u2115");
5187defineSymbol(text, ams, textord, "N", "\u2115");
5188defineSymbol(math, ams, textord, "P", "\u2119");
5189defineSymbol(text, ams, textord, "P", "\u2119");
5190defineSymbol(math, ams, textord, "Q", "\u211A");
5191defineSymbol(text, ams, textord, "Q", "\u211A");
5192defineSymbol(math, ams, textord, "R", "\u211D");
5193defineSymbol(text, ams, textord, "R", "\u211D");
5194defineSymbol(math, ams, textord, "Z", "\u2124");
5195defineSymbol(text, ams, textord, "Z", "\u2124");
5196defineSymbol(math, main, mathord, "h", "\u210E"); // italic h, Planck constant
5197
5198defineSymbol(text, main, mathord, "h", "\u210E"); // The next loop loads wide (surrogate pair) characters.
5199// We support some letters in the Unicode range U+1D400 to U+1D7FF,
5200// Mathematical Alphanumeric Symbols.
5201// Some editors do not deal well with wide characters. So don't write the
5202// string into this file. Instead, create the string from the surrogate pair.
5203
5204var wideChar = "";
5205
5206for (var _i3 = 0; _i3 < letters.length; _i3++) {
5207  var _ch3 = letters.charAt(_i3); // The hex numbers in the next line are a surrogate pair.
5208  // 0xD835 is the high surrogate for all letters in the range we support.
5209  // 0xDC00 is the low surrogate for bold A.
5210
5211
5212  wideChar = String.fromCharCode(0xD835, 0xDC00 + _i3); // A-Z a-z bold
5213
5214  defineSymbol(math, main, mathord, _ch3, wideChar);
5215  defineSymbol(text, main, textord, _ch3, wideChar);
5216  wideChar = String.fromCharCode(0xD835, 0xDC34 + _i3); // A-Z a-z italic
5217
5218  defineSymbol(math, main, mathord, _ch3, wideChar);
5219  defineSymbol(text, main, textord, _ch3, wideChar);
5220  wideChar = String.fromCharCode(0xD835, 0xDC68 + _i3); // A-Z a-z bold italic
5221
5222  defineSymbol(math, main, mathord, _ch3, wideChar);
5223  defineSymbol(text, main, textord, _ch3, wideChar);
5224  wideChar = String.fromCharCode(0xD835, 0xDD04 + _i3); // A-Z a-z Fraktur
5225
5226  defineSymbol(math, main, mathord, _ch3, wideChar);
5227  defineSymbol(text, main, textord, _ch3, wideChar);
5228  wideChar = String.fromCharCode(0xD835, 0xDD6C + _i3); // A-Z a-z bold Fraktur
5229
5230  defineSymbol(math, main, mathord, _ch3, wideChar);
5231  defineSymbol(text, main, textord, _ch3, wideChar);
5232  wideChar = String.fromCharCode(0xD835, 0xDDA0 + _i3); // A-Z a-z sans-serif
5233
5234  defineSymbol(math, main, mathord, _ch3, wideChar);
5235  defineSymbol(text, main, textord, _ch3, wideChar);
5236  wideChar = String.fromCharCode(0xD835, 0xDDD4 + _i3); // A-Z a-z sans bold
5237
5238  defineSymbol(math, main, mathord, _ch3, wideChar);
5239  defineSymbol(text, main, textord, _ch3, wideChar);
5240  wideChar = String.fromCharCode(0xD835, 0xDE08 + _i3); // A-Z a-z sans italic
5241
5242  defineSymbol(math, main, mathord, _ch3, wideChar);
5243  defineSymbol(text, main, textord, _ch3, wideChar);
5244  wideChar = String.fromCharCode(0xD835, 0xDE70 + _i3); // A-Z a-z monospace
5245
5246  defineSymbol(math, main, mathord, _ch3, wideChar);
5247  defineSymbol(text, main, textord, _ch3, wideChar);
5248
5249  if (_i3 < 26) {
5250    // KaTeX fonts have only capital letters for blackboard bold and script.
5251    // See exception for k below.
5252    wideChar = String.fromCharCode(0xD835, 0xDD38 + _i3); // A-Z double struck
5253
5254    defineSymbol(math, main, mathord, _ch3, wideChar);
5255    defineSymbol(text, main, textord, _ch3, wideChar);
5256    wideChar = String.fromCharCode(0xD835, 0xDC9C + _i3); // A-Z script
5257
5258    defineSymbol(math, main, mathord, _ch3, wideChar);
5259    defineSymbol(text, main, textord, _ch3, wideChar);
5260  } // TODO: Add bold script when it is supported by a KaTeX font.
5261
5262} // "k" is the only double struck lower case letter in the KaTeX fonts.
5263
5264
5265wideChar = String.fromCharCode(0xD835, 0xDD5C); // k double struck
5266
5267defineSymbol(math, main, mathord, "k", wideChar);
5268defineSymbol(text, main, textord, "k", wideChar); // Next, some wide character numerals
5269
5270for (var _i4 = 0; _i4 < 10; _i4++) {
5271  var _ch4 = _i4.toString();
5272
5273  wideChar = String.fromCharCode(0xD835, 0xDFCE + _i4); // 0-9 bold
5274
5275  defineSymbol(math, main, mathord, _ch4, wideChar);
5276  defineSymbol(text, main, textord, _ch4, wideChar);
5277  wideChar = String.fromCharCode(0xD835, 0xDFE2 + _i4); // 0-9 sans serif
5278
5279  defineSymbol(math, main, mathord, _ch4, wideChar);
5280  defineSymbol(text, main, textord, _ch4, wideChar);
5281  wideChar = String.fromCharCode(0xD835, 0xDFEC + _i4); // 0-9 bold sans
5282
5283  defineSymbol(math, main, mathord, _ch4, wideChar);
5284  defineSymbol(text, main, textord, _ch4, wideChar);
5285  wideChar = String.fromCharCode(0xD835, 0xDFF6 + _i4); // 0-9 monospace
5286
5287  defineSymbol(math, main, mathord, _ch4, wideChar);
5288  defineSymbol(text, main, textord, _ch4, wideChar);
5289} // We add these Latin-1 letters as symbols for backwards-compatibility,
5290// but they are not actually in the font, nor are they supported by the
5291// Unicode accent mechanism, so they fall back to Times font and look ugly.
5292// TODO(edemaine): Fix this.
5293
5294
5295var extraLatin = "\u00d0\u00de\u00fe";
5296
5297for (var _i5 = 0; _i5 < extraLatin.length; _i5++) {
5298  var _ch5 = extraLatin.charAt(_i5);
5299
5300  defineSymbol(math, main, mathord, _ch5, _ch5);
5301  defineSymbol(text, main, textord, _ch5, _ch5);
5302}
5303
5304/**
5305 * This file provides support for Unicode range U+1D400 to U+1D7FF,
5306 * Mathematical Alphanumeric Symbols.
5307 *
5308 * Function wideCharacterFont takes a wide character as input and returns
5309 * the font information necessary to render it properly.
5310 */
5311/**
5312 * Data below is from https://www.unicode.org/charts/PDF/U1D400.pdf
5313 * That document sorts characters into groups by font type, say bold or italic.
5314 *
5315 * In the arrays below, each subarray consists three elements:
5316 *      * The CSS class of that group when in math mode.
5317 *      * The CSS class of that group when in text mode.
5318 *      * The font name, so that KaTeX can get font metrics.
5319 */
5320
5321var wideLatinLetterData = [["mathbf", "textbf", "Main-Bold"], // A-Z bold upright
5322["mathbf", "textbf", "Main-Bold"], // a-z bold upright
5323["mathnormal", "textit", "Math-Italic"], // A-Z italic
5324["mathnormal", "textit", "Math-Italic"], // a-z italic
5325["boldsymbol", "boldsymbol", "Main-BoldItalic"], // A-Z bold italic
5326["boldsymbol", "boldsymbol", "Main-BoldItalic"], // a-z bold italic
5327// Map fancy A-Z letters to script, not calligraphic.
5328// This aligns with unicode-math and math fonts (except Cambria Math).
5329["mathscr", "textscr", "Script-Regular"], // A-Z script
5330["", "", ""], // a-z script.  No font
5331["", "", ""], // A-Z bold script. No font
5332["", "", ""], // a-z bold script. No font
5333["mathfrak", "textfrak", "Fraktur-Regular"], // A-Z Fraktur
5334["mathfrak", "textfrak", "Fraktur-Regular"], // a-z Fraktur
5335["mathbb", "textbb", "AMS-Regular"], // A-Z double-struck
5336["mathbb", "textbb", "AMS-Regular"], // k double-struck
5337// Note that we are using a bold font, but font metrics for regular Fraktur.
5338["mathboldfrak", "textboldfrak", "Fraktur-Regular"], // A-Z bold Fraktur
5339["mathboldfrak", "textboldfrak", "Fraktur-Regular"], // a-z bold Fraktur
5340["mathsf", "textsf", "SansSerif-Regular"], // A-Z sans-serif
5341["mathsf", "textsf", "SansSerif-Regular"], // a-z sans-serif
5342["mathboldsf", "textboldsf", "SansSerif-Bold"], // A-Z bold sans-serif
5343["mathboldsf", "textboldsf", "SansSerif-Bold"], // a-z bold sans-serif
5344["mathitsf", "textitsf", "SansSerif-Italic"], // A-Z italic sans-serif
5345["mathitsf", "textitsf", "SansSerif-Italic"], // a-z italic sans-serif
5346["", "", ""], // A-Z bold italic sans. No font
5347["", "", ""], // a-z bold italic sans. No font
5348["mathtt", "texttt", "Typewriter-Regular"], // A-Z monospace
5349["mathtt", "texttt", "Typewriter-Regular"] // a-z monospace
5350];
5351var wideNumeralData = [["mathbf", "textbf", "Main-Bold"], // 0-9 bold
5352["", "", ""], // 0-9 double-struck. No KaTeX font.
5353["mathsf", "textsf", "SansSerif-Regular"], // 0-9 sans-serif
5354["mathboldsf", "textboldsf", "SansSerif-Bold"], // 0-9 bold sans-serif
5355["mathtt", "texttt", "Typewriter-Regular"] // 0-9 monospace
5356];
5357var wideCharacterFont = function wideCharacterFont(wideChar, mode) {
5358  // IE doesn't support codePointAt(). So work with the surrogate pair.
5359  var H = wideChar.charCodeAt(0); // high surrogate
5360
5361  var L = wideChar.charCodeAt(1); // low surrogate
5362
5363  var codePoint = (H - 0xD800) * 0x400 + (L - 0xDC00) + 0x10000;
5364  var j = mode === "math" ? 0 : 1; // column index for CSS class.
5365
5366  if (0x1D400 <= codePoint && codePoint < 0x1D6A4) {
5367    // wideLatinLetterData contains exactly 26 chars on each row.
5368    // So we can calculate the relevant row. No traverse necessary.
5369    var i = Math.floor((codePoint - 0x1D400) / 26);
5370    return [wideLatinLetterData[i][2], wideLatinLetterData[i][j]];
5371  } else if (0x1D7CE <= codePoint && codePoint <= 0x1D7FF) {
5372    // Numerals, ten per row.
5373    var _i = Math.floor((codePoint - 0x1D7CE) / 10);
5374
5375    return [wideNumeralData[_i][2], wideNumeralData[_i][j]];
5376  } else if (codePoint === 0x1D6A5 || codePoint === 0x1D6A6) {
5377    // dotless i or j
5378    return [wideLatinLetterData[0][2], wideLatinLetterData[0][j]];
5379  } else if (0x1D6A6 < codePoint && codePoint < 0x1D7CE) {
5380    // Greek letters. Not supported, yet.
5381    return ["", ""];
5382  } else {
5383    // We don't support any wide characters outside 1D400–1D7FF.
5384    throw new ParseError("Unsupported character: " + wideChar);
5385  }
5386};
5387
5388/* eslint no-console:0 */
5389
5390/**
5391 * Looks up the given symbol in fontMetrics, after applying any symbol
5392 * replacements defined in symbol.js
5393 */
5394var lookupSymbol = function lookupSymbol(value, // TODO(#963): Use a union type for this.
5395fontName, mode) {
5396  // Replace the value with its replaced value from symbol.js
5397  if (symbols[mode][value] && symbols[mode][value].replace) {
5398    value = symbols[mode][value].replace;
5399  }
5400
5401  return {
5402    value: value,
5403    metrics: getCharacterMetrics(value, fontName, mode)
5404  };
5405};
5406/**
5407 * Makes a symbolNode after translation via the list of symbols in symbols.js.
5408 * Correctly pulls out metrics for the character, and optionally takes a list of
5409 * classes to be attached to the node.
5410 *
5411 * TODO: make argument order closer to makeSpan
5412 * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which
5413 * should if present come first in `classes`.
5414 * TODO(#953): Make `options` mandatory and always pass it in.
5415 */
5416
5417
5418var makeSymbol = function makeSymbol(value, fontName, mode, options, classes) {
5419  var lookup = lookupSymbol(value, fontName, mode);
5420  var metrics = lookup.metrics;
5421  value = lookup.value;
5422  var symbolNode;
5423
5424  if (metrics) {
5425    var italic = metrics.italic;
5426
5427    if (mode === "text" || options && options.font === "mathit") {
5428      italic = 0;
5429    }
5430
5431    symbolNode = new SymbolNode(value, metrics.height, metrics.depth, italic, metrics.skew, metrics.width, classes);
5432  } else {
5433    // TODO(emily): Figure out a good way to only print this in development
5434    typeof console !== "undefined" && console.warn("No character metrics " + ("for '" + value + "' in style '" + fontName + "' and mode '" + mode + "'"));
5435    symbolNode = new SymbolNode(value, 0, 0, 0, 0, 0, classes);
5436  }
5437
5438  if (options) {
5439    symbolNode.maxFontSize = options.sizeMultiplier;
5440
5441    if (options.style.isTight()) {
5442      symbolNode.classes.push("mtight");
5443    }
5444
5445    var color = options.getColor();
5446
5447    if (color) {
5448      symbolNode.style.color = color;
5449    }
5450  }
5451
5452  return symbolNode;
5453};
5454/**
5455 * Makes a symbol in Main-Regular or AMS-Regular.
5456 * Used for rel, bin, open, close, inner, and punct.
5457 */
5458
5459
5460var mathsym = function mathsym(value, mode, options, classes) {
5461  if (classes === void 0) {
5462    classes = [];
5463  }
5464
5465  // Decide what font to render the symbol in by its entry in the symbols
5466  // table.
5467  // Have a special case for when the value = \ because the \ is used as a
5468  // textord in unsupported command errors but cannot be parsed as a regular
vendor: 18,539 bytes, lines 5469-6085
5469  // text ordinal and is therefore not present as a symbol in the symbols
5470  // table for text, as well as a special case for boldsymbol because it
5471  // can be used for bold + and -
5472  if (options.font === "boldsymbol" && lookupSymbol(value, "Main-Bold", mode).metrics) {
5473    return makeSymbol(value, "Main-Bold", mode, options, classes.concat(["mathbf"]));
5474  } else if (value === "\\" || symbols[mode][value].font === "main") {
5475    return makeSymbol(value, "Main-Regular", mode, options, classes);
5476  } else {
5477    return makeSymbol(value, "AMS-Regular", mode, options, classes.concat(["amsrm"]));
5478  }
5479};
5480/**
5481 * Determines which of the two font names (Main-Bold and Math-BoldItalic) and
5482 * corresponding style tags (mathbf or boldsymbol) to use for font "boldsymbol",
5483 * depending on the symbol.  Use this function instead of fontMap for font
5484 * "boldsymbol".
5485 */
5486
5487
5488var boldsymbol = function boldsymbol(value, mode, options, classes, type) {
5489  if (type !== "textord" && lookupSymbol(value, "Math-BoldItalic", mode).metrics) {
5490    return {
5491      fontName: "Math-BoldItalic",
5492      fontClass: "boldsymbol"
5493    };
5494  } else {
5495    // Some glyphs do not exist in Math-BoldItalic so we need to use
5496    // Main-Bold instead.
5497    return {
5498      fontName: "Main-Bold",
5499      fontClass: "mathbf"
5500    };
5501  }
5502};
5503/**
5504 * Makes either a mathord or textord in the correct font and color.
5505 */
5506
5507
5508var makeOrd = function makeOrd(group, options, type) {
5509  var mode = group.mode;
5510  var text = group.text;
5511  var classes = ["mord"]; // Math mode or Old font (i.e. \rm)
5512
5513  var isFont = mode === "math" || mode === "text" && options.font;
5514  var fontOrFamily = isFont ? options.font : options.fontFamily;
5515  var wideFontName = "";
5516  var wideFontClass = "";
5517
5518  if (text.charCodeAt(0) === 0xD835) {
5519    [wideFontName, wideFontClass] = wideCharacterFont(text, mode);
5520  }
5521
5522  if (wideFontName.length > 0) {
5523    // surrogate pairs get special treatment
5524    return makeSymbol(text, wideFontName, mode, options, classes.concat(wideFontClass));
5525  } else if (fontOrFamily) {
5526    var fontName;
5527    var fontClasses;
5528
5529    if (fontOrFamily === "boldsymbol") {
5530      var fontData = boldsymbol(text, mode, options, classes, type);
5531      fontName = fontData.fontName;
5532      fontClasses = [fontData.fontClass];
5533    } else if (isFont) {
5534      fontName = fontMap[fontOrFamily].fontName;
5535      fontClasses = [fontOrFamily];
5536    } else {
5537      fontName = retrieveTextFontName(fontOrFamily, options.fontWeight, options.fontShape);
5538      fontClasses = [fontOrFamily, options.fontWeight, options.fontShape];
5539    }
5540
5541    if (lookupSymbol(text, fontName, mode).metrics) {
5542      return makeSymbol(text, fontName, mode, options, classes.concat(fontClasses));
5543    } else if (ligatures.hasOwnProperty(text) && fontName.slice(0, 10) === "Typewriter") {
5544      // Deconstruct ligatures in monospace fonts (\texttt, \tt).
5545      var parts = [];
5546
5547      for (var i = 0; i < text.length; i++) {
5548        parts.push(makeSymbol(text[i], fontName, mode, options, classes.concat(fontClasses)));
5549      }
5550
5551      return makeFragment(parts);
5552    }
5553  } // Makes a symbol in the default font for mathords and textords.
5554
5555
5556  if (type === "mathord") {
5557    return makeSymbol(text, "Math-Italic", mode, options, classes.concat(["mathnormal"]));
5558  } else if (type === "textord") {
5559    var font = symbols[mode][text] && symbols[mode][text].font;
5560
5561    if (font === "ams") {
5562      var _fontName = retrieveTextFontName("amsrm", options.fontWeight, options.fontShape);
5563
5564      return makeSymbol(text, _fontName, mode, options, classes.concat("amsrm", options.fontWeight, options.fontShape));
5565    } else if (font === "main" || !font) {
5566      var _fontName2 = retrieveTextFontName("textrm", options.fontWeight, options.fontShape);
5567
5568      return makeSymbol(text, _fontName2, mode, options, classes.concat(options.fontWeight, options.fontShape));
5569    } else {
5570      // fonts added by plugins
5571      var _fontName3 = retrieveTextFontName(font, options.fontWeight, options.fontShape); // We add font name as a css class
5572
5573
5574      return makeSymbol(text, _fontName3, mode, options, classes.concat(_fontName3, options.fontWeight, options.fontShape));
5575    }
5576  } else {
5577    throw new Error("unexpected type: " + type + " in makeOrd");
5578  }
5579};
5580/**
5581 * Returns true if subsequent symbolNodes have the same classes, skew, maxFont,
5582 * and styles.
5583 */
5584
5585
5586var canCombine = (prev, next) => {
5587  if (createClass(prev.classes) !== createClass(next.classes) || prev.skew !== next.skew || prev.maxFontSize !== next.maxFontSize) {
5588    return false;
5589  } // If prev and next both are just "mbin"s or "mord"s we don't combine them
5590  // so that the proper spacing can be preserved.
5591
5592
5593  if (prev.classes.length === 1) {
5594    var cls = prev.classes[0];
5595
5596    if (cls === "mbin" || cls === "mord") {
5597      return false;
5598    }
5599  }
5600
5601  for (var style in prev.style) {
5602    if (prev.style.hasOwnProperty(style) && prev.style[style] !== next.style[style]) {
5603      return false;
5604    }
5605  }
5606
5607  for (var _style in next.style) {
5608    if (next.style.hasOwnProperty(_style) && prev.style[_style] !== next.style[_style]) {
5609      return false;
5610    }
5611  }
5612
5613  return true;
5614};
5615/**
5616 * Combine consecutive domTree.symbolNodes into a single symbolNode.
5617 * Note: this function mutates the argument.
5618 */
5619
5620
5621var tryCombineChars = chars => {
5622  for (var i = 0; i < chars.length - 1; i++) {
5623    var prev = chars[i];
5624    var next = chars[i + 1];
5625
5626    if (prev instanceof SymbolNode && next instanceof SymbolNode && canCombine(prev, next)) {
5627      prev.text += next.text;
5628      prev.height = Math.max(prev.height, next.height);
5629      prev.depth = Math.max(prev.depth, next.depth); // Use the last character's italic correction since we use
5630      // it to add padding to the right of the span created from
5631      // the combined characters.
5632
5633      prev.italic = next.italic;
5634      chars.splice(i + 1, 1);
5635      i--;
5636    }
5637  }
5638
5639  return chars;
5640};
5641/**
5642 * Calculate the height, depth, and maxFontSize of an element based on its
5643 * children.
5644 */
5645
5646
5647var sizeElementFromChildren = function sizeElementFromChildren(elem) {
5648  var height = 0;
5649  var depth = 0;
5650  var maxFontSize = 0;
5651
5652  for (var i = 0; i < elem.children.length; i++) {
5653    var child = elem.children[i];
5654
5655    if (child.height > height) {
5656      height = child.height;
5657    }
5658
5659    if (child.depth > depth) {
5660      depth = child.depth;
5661    }
5662
5663    if (child.maxFontSize > maxFontSize) {
5664      maxFontSize = child.maxFontSize;
5665    }
5666  }
5667
5668  elem.height = height;
5669  elem.depth = depth;
5670  elem.maxFontSize = maxFontSize;
5671};
5672/**
5673 * Makes a span with the given list of classes, list of children, and options.
5674 *
5675 * TODO(#953): Ensure that `options` is always provided (currently some call
5676 * sites don't pass it) and make the type below mandatory.
5677 * TODO: add a separate argument for math class (e.g. `mop`, `mbin`), which
5678 * should if present come first in `classes`.
5679 */
5680
5681
5682var makeSpan$2 = function makeSpan(classes, children, options, style) {
5683  var span = new Span(classes, children, options, style);
5684  sizeElementFromChildren(span);
5685  return span;
5686}; // SVG one is simpler -- doesn't require height, depth, max-font setting.
5687// This is also a separate method for typesafety.
5688
5689
5690var makeSvgSpan = (classes, children, options, style) => new Span(classes, children, options, style);
5691
5692var makeLineSpan = function makeLineSpan(className, options, thickness) {
5693  var line = makeSpan$2([className], [], options);
5694  line.height = Math.max(thickness || options.fontMetrics().defaultRuleThickness, options.minRuleThickness);
5695  line.style.borderBottomWidth = makeEm(line.height);
5696  line.maxFontSize = 1.0;
5697  return line;
5698};
5699/**
5700 * Makes an anchor with the given href, list of classes, list of children,
5701 * and options.
5702 */
5703
5704
5705var makeAnchor = function makeAnchor(href, classes, children, options) {
5706  var anchor = new Anchor(href, classes, children, options);
5707  sizeElementFromChildren(anchor);
5708  return anchor;
5709};
5710/**
5711 * Makes a document fragment with the given list of children.
5712 */
5713
5714
5715var makeFragment = function makeFragment(children) {
5716  var fragment = new DocumentFragment(children);
5717  sizeElementFromChildren(fragment);
5718  return fragment;
5719};
5720/**
5721 * Wraps group in a span if it's a document fragment, allowing to apply classes
5722 * and styles
5723 */
5724
5725
5726var wrapFragment = function wrapFragment(group, options) {
5727  if (group instanceof DocumentFragment) {
5728    return makeSpan$2([], [group], options);
5729  }
5730
5731  return group;
5732}; // These are exact object types to catch typos in the names of the optional fields.
5733
5734
5735// Computes the updated `children` list and the overall depth.
5736//
5737// This helper function for makeVList makes it easier to enforce type safety by
5738// allowing early exits (returns) in the logic.
5739var getVListChildrenAndDepth = function getVListChildrenAndDepth(params) {
5740  if (params.positionType === "individualShift") {
5741    var oldChildren = params.children;
5742    var children = [oldChildren[0]]; // Add in kerns to the list of params.children to get each element to be
5743    // shifted to the correct specified shift
5744
5745    var _depth = -oldChildren[0].shift - oldChildren[0].elem.depth;
5746
5747    var currPos = _depth;
5748
5749    for (var i = 1; i < oldChildren.length; i++) {
5750      var diff = -oldChildren[i].shift - currPos - oldChildren[i].elem.depth;
5751      var size = diff - (oldChildren[i - 1].elem.height + oldChildren[i - 1].elem.depth);
5752      currPos = currPos + diff;
5753      children.push({
5754        type: "kern",
5755        size
5756      });
5757      children.push(oldChildren[i]);
5758    }
5759
5760    return {
5761      children,
5762      depth: _depth
5763    };
5764  }
5765
5766  var depth;
5767
5768  if (params.positionType === "top") {
5769    // We always start at the bottom, so calculate the bottom by adding up
5770    // all the sizes
5771    var bottom = params.positionData;
5772
5773    for (var _i = 0; _i < params.children.length; _i++) {
5774      var child = params.children[_i];
5775      bottom -= child.type === "kern" ? child.size : child.elem.height + child.elem.depth;
5776    }
5777
5778    depth = bottom;
5779  } else if (params.positionType === "bottom") {
5780    depth = -params.positionData;
5781  } else {
5782    var firstChild = params.children[0];
5783
5784    if (firstChild.type !== "elem") {
5785      throw new Error('First child must have type "elem".');
5786    }
5787
5788    if (params.positionType === "shift") {
5789      depth = -firstChild.elem.depth - params.positionData;
5790    } else if (params.positionType === "firstBaseline") {
5791      depth = -firstChild.elem.depth;
5792    } else {
5793      throw new Error("Invalid positionType " + params.positionType + ".");
5794    }
5795  }
5796
5797  return {
5798    children: params.children,
5799    depth
5800  };
5801};
5802/**
5803 * Makes a vertical list by stacking elements and kerns on top of each other.
5804 * Allows for many different ways of specifying the positioning method.
5805 *
5806 * See VListParam documentation above.
5807 */
5808
5809
5810var makeVList = function makeVList(params, options) {
5811  var {
5812    children,
5813    depth
5814  } = getVListChildrenAndDepth(params); // Create a strut that is taller than any list item. The strut is added to
5815  // each item, where it will determine the item's baseline. Since it has
5816  // `overflow:hidden`, the strut's top edge will sit on the item's line box's
5817  // top edge and the strut's bottom edge will sit on the item's baseline,
5818  // with no additional line-height spacing. This allows the item baseline to
5819  // be positioned precisely without worrying about font ascent and
5820  // line-height.
5821
5822  var pstrutSize = 0;
5823
5824  for (var i = 0; i < children.length; i++) {
5825    var child = children[i];
5826
5827    if (child.type === "elem") {
5828      var elem = child.elem;
5829      pstrutSize = Math.max(pstrutSize, elem.maxFontSize, elem.height);
5830    }
5831  }
5832
5833  pstrutSize += 2;
5834  var pstrut = makeSpan$2(["pstrut"], []);
5835  pstrut.style.height = makeEm(pstrutSize); // Create a new list of actual children at the correct offsets
5836
5837  var realChildren = [];
5838  var minPos = depth;
5839  var maxPos = depth;
5840  var currPos = depth;
5841
5842  for (var _i2 = 0; _i2 < children.length; _i2++) {
5843    var _child = children[_i2];
5844
5845    if (_child.type === "kern") {
5846      currPos += _child.size;
5847    } else {
5848      var _elem = _child.elem;
5849      var classes = _child.wrapperClasses || [];
5850      var style = _child.wrapperStyle || {};
5851      var childWrap = makeSpan$2(classes, [pstrut, _elem], undefined, style);
5852      childWrap.style.top = makeEm(-pstrutSize - currPos - _elem.depth);
5853
5854      if (_child.marginLeft) {
5855        childWrap.style.marginLeft = _child.marginLeft;
5856      }
5857
5858      if (_child.marginRight) {
5859        childWrap.style.marginRight = _child.marginRight;
5860      }
5861
5862      realChildren.push(childWrap);
5863      currPos += _elem.height + _elem.depth;
5864    }
5865
5866    minPos = Math.min(minPos, currPos);
5867    maxPos = Math.max(maxPos, currPos);
5868  } // The vlist contents go in a table-cell with `vertical-align:bottom`.
5869  // This cell's bottom edge will determine the containing table's baseline
5870  // without overly expanding the containing line-box.
5871
5872
5873  var vlist = makeSpan$2(["vlist"], realChildren);
5874  vlist.style.height = makeEm(maxPos); // A second row is used if necessary to represent the vlist's depth.
5875
5876  var rows;
5877
5878  if (minPos < 0) {
5879    // We will define depth in an empty span with display: table-cell.
5880    // It should render with the height that we define. But Chrome, in
5881    // contenteditable mode only, treats that span as if it contains some
5882    // text content. And that min-height over-rides our desired height.
5883    // So we put another empty span inside the depth strut span.
5884    var emptySpan = makeSpan$2([], []);
5885    var depthStrut = makeSpan$2(["vlist"], [emptySpan]);
5886    depthStrut.style.height = makeEm(-minPos); // Safari wants the first row to have inline content; otherwise it
5887    // puts the bottom of the *second* row on the baseline.
5888
5889    var topStrut = makeSpan$2(["vlist-s"], [new SymbolNode("\u200b")]);
5890    rows = [makeSpan$2(["vlist-r"], [vlist, topStrut]), makeSpan$2(["vlist-r"], [depthStrut])];
5891  } else {
5892    rows = [makeSpan$2(["vlist-r"], [vlist])];
5893  }
5894
5895  var vtable = makeSpan$2(["vlist-t"], rows);
5896
5897  if (rows.length === 2) {
5898    vtable.classes.push("vlist-t2");
5899  }
5900
5901  vtable.height = maxPos;
5902  vtable.depth = -minPos;
5903  return vtable;
5904}; // Glue is a concept from TeX which is a flexible space between elements in
5905// either a vertical or horizontal list. In KaTeX, at least for now, it's
5906// static space between elements in a horizontal layout.
5907
5908
5909var makeGlue = (measurement, options) => {
5910  // Make an empty span for the space
5911  var rule = makeSpan$2(["mspace"], [], options);
5912  var size = calculateSize(measurement, options);
5913  rule.style.marginRight = makeEm(size);
5914  return rule;
5915}; // Takes font options, and returns the appropriate fontLookup name
5916
5917
5918var retrieveTextFontName = function retrieveTextFontName(fontFamily, fontWeight, fontShape) {
5919  var baseFontName = "";
5920
5921  switch (fontFamily) {
5922    case "amsrm":
5923      baseFontName = "AMS";
5924      break;
5925
5926    case "textrm":
5927      baseFontName = "Main";
5928      break;
5929
5930    case "textsf":
5931      baseFontName = "SansSerif";
5932      break;
5933
5934    case "texttt":
5935      baseFontName = "Typewriter";
5936      break;
5937
5938    default:
5939      baseFontName = fontFamily;
5940    // use fonts added by a plugin
5941  }
5942
5943  var fontStylesName;
5944
5945  if (fontWeight === "textbf" && fontShape === "textit") {
5946    fontStylesName = "BoldItalic";
5947  } else if (fontWeight === "textbf") {
5948    fontStylesName = "Bold";
5949  } else if (fontWeight === "textit") {
5950    fontStylesName = "Italic";
5951  } else {
5952    fontStylesName = "Regular";
5953  }
5954
5955  return baseFontName + "-" + fontStylesName;
5956};
5957/**
5958 * Maps TeX font commands to objects containing:
5959 * - variant: string used for "mathvariant" attribute in buildMathML.js
5960 * - fontName: the "style" parameter to fontMetrics.getCharacterMetrics
5961 */
5962// A map between tex font commands an MathML mathvariant attribute values
5963
5964
5965var fontMap = {
5966  // styles
5967  "mathbf": {
5968    variant: "bold",
5969    fontName: "Main-Bold"
5970  },
5971  "mathrm": {
5972    variant: "normal",
5973    fontName: "Main-Regular"
5974  },
5975  "textit": {
5976    variant: "italic",
5977    fontName: "Main-Italic"
5978  },
5979  "mathit": {
5980    variant: "italic",
5981    fontName: "Main-Italic"
5982  },
5983  "mathnormal": {
5984    variant: "italic",
5985    fontName: "Math-Italic"
5986  },
5987  "mathsfit": {
5988    variant: "sans-serif-italic",
5989    fontName: "SansSerif-Italic"
5990  },
5991  // "boldsymbol" is missing because they require the use of multiple fonts:
5992  // Math-BoldItalic and Main-Bold.  This is handled by a special case in
5993  // makeOrd which ends up calling boldsymbol.
5994  // families
5995  "mathbb": {
5996    variant: "double-struck",
5997    fontName: "AMS-Regular"
5998  },
5999  "mathcal": {
6000    variant: "script",
6001    fontName: "Caligraphic-Regular"
6002  },
6003  "mathfrak": {
6004    variant: "fraktur",
6005    fontName: "Fraktur-Regular"
6006  },
6007  "mathscr": {
6008    variant: "script",
6009    fontName: "Script-Regular"
6010  },
6011  "mathsf": {
6012    variant: "sans-serif",
6013    fontName: "SansSerif-Regular"
6014  },
6015  "mathtt": {
6016    variant: "monospace",
6017    fontName: "Typewriter-Regular"
6018  }
6019};
6020var svgData = {
6021  //   path, width, height
6022  vec: ["vec", 0.471, 0.714],
6023  // values from the font glyph
6024  oiintSize1: ["oiintSize1", 0.957, 0.499],
6025  // oval to overlay the integrand
6026  oiintSize2: ["oiintSize2", 1.472, 0.659],
6027  oiiintSize1: ["oiiintSize1", 1.304, 0.499],
6028  oiiintSize2: ["oiiintSize2", 1.98, 0.659]
6029};
6030
6031var staticSvg = function staticSvg(value, options) {
6032  // Create a span with inline SVG for the element.
6033  var [pathName, width, height] = svgData[value];
6034  var path = new PathNode(pathName);
6035  var svgNode = new SvgNode([path], {
6036    "width": makeEm(width),
6037    "height": makeEm(height),
6038    // Override CSS rule `.katex svg { width: 100% }`
6039    "style": "width:" + makeEm(width),
6040    "viewBox": "0 0 " + 1000 * width + " " + 1000 * height,
6041    "preserveAspectRatio": "xMinYMin"
6042  });
6043  var span = makeSvgSpan(["overlay"], [svgNode], options);
6044  span.height = height;
6045  span.style.height = makeEm(height);
6046  span.style.width = makeEm(width);
6047  return span;
6048};
6049
6050var buildCommon = {
6051  fontMap,
6052  makeSymbol,
6053  mathsym,
6054  makeSpan: makeSpan$2,
6055  makeSvgSpan,
6056  makeLineSpan,
6057  makeAnchor,
6058  makeFragment,
6059  wrapFragment,
6060  makeVList,
6061  makeOrd,
6062  makeGlue,
6063  staticSvg,
6064  svgData,
6065  tryCombineChars
6066};
6067
6068/**
6069 * Describes spaces between different classes of atoms.
6070 */
6071var thinspace = {
6072  number: 3,
6073  unit: "mu"
6074};
6075var mediumspace = {
6076  number: 4,
6077  unit: "mu"
6078};
6079var thickspace = {
6080  number: 5,
6081  unit: "mu"
6082}; // Making the type below exact with all optional fields doesn't work due to
6083// - https://github.com/facebook/flow/issues/4582
6084// - https://github.com/facebook/flow/issues/5688
6085// However, since *all* fields are optional, $Shape<> works as suggested in 5688
6086// above.
6087
6088// Spacing relationships for display and text styles
6089var spacings = {
6090  mord: {
6091    mop: thinspace,
6092    mbin: mediumspace,
6093    mrel: thickspace,
6094    minner: thinspace
6095  },
6096  mop: {
6097    mord: thinspace,
6098    mop: thinspace,
6099    mrel: thickspace,
6100    minner: thinspace
6101  },
6102  mbin: {
6103    mord: mediumspace,
6104    mop: mediumspace,
6105    mopen: mediumspace,
6106    minner: mediumspace
6107  },
6108  mrel: {
6109    mord: thickspace,
6110    mop: thickspace,
6111    mopen: thickspace,
6112    minner: thickspace
6113  },
6114  mopen: {},
6115  mclose: {
6116    mop: thinspace,
6117    mbin: mediumspace,
6118    mrel: thickspace,
6119    minner: thinspace
6120  },
6121  mpunct: {
6122    mord: thinspace,
6123    mop: thinspace,
6124    mrel: thickspace,
6125    mopen: thinspace,
6126    mclose: thinspace,
6127    mpunct: thinspace,
6128    minner: thinspace
6129  },
6130  minner: {
6131    mord: thinspace,
6132    mop: thinspace,
6133    mbin: mediumspace,
6134    mrel: thickspace,
6135    mopen: thinspace,
6136    mpunct: thinspace,
6137    minner: thinspace
6138  }
6139}; // Spacing relationships for script and scriptscript styles
6140
6141var tightSpacings = {
6142  mord: {
6143    mop: thinspace
6144  },
6145  mop: {
6146    mord: thinspace,
6147    mop: thinspace
6148  },
6149  mbin: {},
6150  mrel: {},
6151  mopen: {},
6152  mclose: {
6153    mop: thinspace
6154  },
6155  mpunct: {},
6156  minner: {
6157    mop: thinspace
6158  }
6159};
6160
6161/** Context provided to function handlers for error messages. */
6162// Note: reverse the order of the return type union will cause a flow error.
6163// See https://github.com/facebook/flow/issues/3663.
6164// More general version of `HtmlBuilder` for nodes (e.g. \sum, accent types)
6165// whose presence impacts super/subscripting. In this case, ParseNode<"supsub">
6166// delegates its HTML building to the HtmlBuilder corresponding to these nodes.
6167
6168/**
6169 * Final function spec for use at parse time.
6170 * This is almost identical to `FunctionPropSpec`, except it
6171 * 1. includes the function handler, and
6172 * 2. requires all arguments except argTypes.
6173 * It is generated by `defineFunction()` below.
6174 */
6175
6176/**
6177 * All registered functions.
6178 * `functions.js` just exports this same dictionary again and makes it public.
6179 * `Parser.js` requires this dictionary.
6180 */
6181var _functions = {};
6182/**
6183 * All HTML builders. Should be only used in the `define*` and the `build*ML`
6184 * functions.
6185 */
6186
6187var _htmlGroupBuilders = {};
6188/**
6189 * All MathML builders. Should be only used in the `define*` and the `build*ML`
6190 * functions.
6191 */
6192
6193var _mathmlGroupBuilders = {};
6194function defineFunction(_ref) {
6195  var {
6196    type,
6197    names,
6198    props,
6199    handler,
6200    htmlBuilder,
6201    mathmlBuilder
6202  }
6202 = _ref;
6203  // Set default values of functions
6204  var data = {
6205    type,
6206    numArgs: props.numArgs,
6207    argTypes: props.argTypes,
6208    allowedInArgument: !!props.allowedInArgument,
6209    allowedInText: !!props.allowedInText,
6210    allowedInMath: props.allowedInMath === undefined ? true : props.allowedInMath,
6211    numOptionalArgs: props.numOptionalArgs || 0,
6212    infix: !!props.infix,
6213    primitive: !!props.primitive,
6214    handler: handler
6215  };
6216
6217  for (var i = 0; i < names.length; ++i) {
6218    _functions[names[i]] = data;
6219  }
6220
6221  if (type) {
6222    if (htmlBuilder) {
6223      _htmlGroupBuilders[type] = htmlBuilder;
6224    }
6225
6226    if (mathmlBuilder) {
6227      _mathmlGroupBuilders[type] = mathmlBuilder;
6228    }
6229  }
6230}
6231/**
6232 * Use this to register only the HTML and MathML builders for a function (e.g.
6233 * if the function's ParseNode is generated in Parser.js rather than via a
6234 * stand-alone handler provided to `defineFunction`).
6235 */
6236
6237function defineFunctionBuilders(_ref2) {
6238  var {
6239    type,
6240    htmlBuilder,
6241    mathmlBuilder
6242  } = _ref2;
6243  defineFunction({
6244    type,
6245    names: [],
6246    props: {
6247      numArgs: 0
6248    },
6249
6250    handler() {
6251      throw new Error('Should never be called.');
6252    },
6253
6254    htmlBuilder,
6255    mathmlBuilder
6256  });
6257}
6258var normalizeArgument = function normalizeArgument(arg) {
6259  return arg.type === "ordgroup" && arg.body.length === 1 ? arg.body[0] : arg;
6260}; // Since the corresponding buildHTML/buildMathML function expects a
6261// list of elements, we normalize for different kinds of arguments
6262
6263var ordargument = function ordargument(arg) {
6264  return arg.type === "ordgroup" ? arg.body : [arg];
6265};
6266
6267/**
6268 * This file does the main work of building a domTree structure from a parse
6269 * tree. The entry point is the `buildHTML` function, which takes a parse tree.
6270 * Then, the buildExpression, buildGroup, and various groupBuilders functions
6271 * are called, to produce a final HTML tree.
6272 */
6273var makeSpan$1 = buildCommon.makeSpan; // Binary atoms (first class `mbin`) change into ordinary atoms (`mord`)
6274// depending on their surroundings. See TeXbook pg. 442-446, Rules 5 and 6,
6275// and the text before Rule 19.
6276
6277var binLeftCanceller = ["leftmost", "mbin", "mopen", "mrel", "mop", "mpunct"];
6278var binRightCanceller = ["rightmost", "mrel", "mclose", "mpunct"];
6279var styleMap$1 = {
6280  "display": Style$1.DISPLAY,
6281  "text": Style$1.TEXT,
6282  "script": Style$1.SCRIPT,
6283  "scriptscript": Style$1.SCRIPTSCRIPT
6284};
6285var DomEnum = {
6286  mord: "mord",
6287  mop: "mop",
6288  mbin: "mbin",
6289  mrel: "mrel",
6290  mopen: "mopen",
6291  mclose: "mclose",
6292  mpunct: "mpunct",
6293  minner: "minner"
6294};
6295
6296/**
6297 * Take a list of nodes, build them in order, and return a list of the built
6298 * nodes. documentFragments are flattened into their contents, so the
6299 * returned list contains no fragments. `isRealGroup` is true if `expression`
6300 * is a real group (no atoms will be added on either side), as opposed to
6301 * a partial group (e.g. one created by \color). `surrounding` is an array
6302 * consisting type of nodes that will be added to the left and right.
6303 */
6304var buildExpression$1 = function buildExpression(expression, options, isRealGroup, surrounding) {
6305  if (surrounding === void 0) {
6306    surrounding = [null, null];
6307  }
6308
6309  // Parse expressions into `groups`.
6310  var groups = [];
6311
6312  for (var i = 0; i < expression.length; i++) {
6313    var output = buildGroup$1(expression[i], options);
6314
6315    if (output instanceof DocumentFragment) {
6316      var children = output.children;
6317      groups.push(...children);
6318    } else {
6319      groups.push(output);
6320    }
6321  } // Combine consecutive domTree.symbolNodes into a single symbolNode.
6322
6323
6324  buildCommon.tryCombineChars(groups); // If `expression` is a partial group, let the parent handle spacings
6325  // to avoid processing groups multiple times.
6326
6327  if (!isRealGroup) {
6328    return groups;
6329  }
6330
6331  var glueOptions = options;
6332
6333  if (expression.length === 1) {
6334    var node = expression[0];
6335
6336    if (node.type === "sizing") {
6337      glueOptions = options.havingSize(node.size);
6338    } else if (node.type === "styling") {
6339      glueOptions = options.havingStyle(styleMap$1[node.style]);
6340    }
6341  } // Dummy spans for determining spacings between surrounding atoms.
6342  // If `expression` has no atoms on the left or right, class "leftmost"
6343  // or "rightmost", respectively, is used to indicate it.
6344
6345
6346  var dummyPrev = makeSpan$1([surrounding[0] || "leftmost"], [], options);
6347  var dummyNext = makeSpan$1([surrounding[1] || "rightmost"], [], options); // TODO: These code assumes that a node's math class is the first element
6348  // of its `classes` array. A later cleanup should ensure this, for
6349  // instance by changing the signature of `makeSpan`.
6350  // Before determining what spaces to insert, perform bin cancellation.
6351  // Binary operators change to ordinary symbols in some contexts.
6352
vendor: 18,533 bytes, lines 6353-6987
6353  var isRoot = isRealGroup === "root";
6354  traverseNonSpaceNodes(groups, (node, prev) => {
6355    var prevType = prev.classes[0];
6356    var type = node.classes[0];
6357
6358    if (prevType === "mbin" && utils.contains(binRightCanceller, type)) {
6359      prev.classes[0] = "mord";
6360    } else if (type === "mbin" && utils.contains(binLeftCanceller, prevType)) {
6361      node.classes[0] = "mord";
6362    }
6363  }, {
6364    node: dummyPrev
6365  }, dummyNext, isRoot);
6366  traverseNonSpaceNodes(groups, (node, prev) => {
6367    var prevType = getTypeOfDomTree(prev);
6368    var type = getTypeOfDomTree(node); // 'mtight' indicates that the node is script or scriptscript style.
6369
6370    var space = prevType && type ? node.hasClass("mtight") ? tightSpacings[prevType][type] : spacings[prevType][type] : null;
6371
6372    if (space) {
6373      // Insert glue (spacing) after the `prev`.
6374      return buildCommon.makeGlue(space, glueOptions);
6375    }
6376  }, {
6377    node: dummyPrev
6378  }, dummyNext, isRoot);
6379  return groups;
6380}; // Depth-first traverse non-space `nodes`, calling `callback` with the current and
6381// previous node as arguments, optionally returning a node to insert after the
6382// previous node. `prev` is an object with the previous node and `insertAfter`
6383// function to insert after it. `next` is a node that will be added to the right.
6384// Used for bin cancellation and inserting spacings.
6385
6386var traverseNonSpaceNodes = function traverseNonSpaceNodes(nodes, callback, prev, next, isRoot) {
6387  if (next) {
6388    // temporarily append the right node, if exists
6389    nodes.push(next);
6390  }
6391
6392  var i = 0;
6393
6394  for (; i < nodes.length; i++) {
6395    var node = nodes[i];
6396    var partialGroup = checkPartialGroup(node);
6397
6398    if (partialGroup) {
6399      // Recursive DFS
6400      // $FlowFixMe: make nodes a $ReadOnlyArray by returning a new array
6401      traverseNonSpaceNodes(partialGroup.children, callback, prev, null, isRoot);
6402      continue;
6403    } // Ignore explicit spaces (e.g., \;, \,) when determining what implicit
6404    // spacing should go between atoms of different classes
6405
6406
6407    var nonspace = !node.hasClass("mspace");
6408
6409    if (nonspace) {
6410      var result = callback(node, prev.node);
6411
6412      if (result) {
6413        if (prev.insertAfter) {
6414          prev.insertAfter(result);
6415        } else {
6416          // insert at front
6417          nodes.unshift(result);
6418          i++;
6419        }
6420      }
6421    }
6422
6423    if (nonspace) {
6424      prev.node = node;
6425    } else if (isRoot && node.hasClass("newline")) {
6426      prev.node = makeSpan$1(["leftmost"]); // treat like beginning of line
6427    }
6428
6429    prev.insertAfter = (index => n => {
6430      nodes.splice(index + 1, 0, n);
6431      i++;
6432    })(i);
6433  }
6434
6435  if (next) {
6436    nodes.pop();
6437  }
6438}; // Check if given node is a partial group, i.e., does not affect spacing around.
6439
6440
6441var checkPartialGroup = function checkPartialGroup(node) {
6442  if (node instanceof DocumentFragment || node instanceof Anchor || node instanceof Span && node.hasClass("enclosing")) {
6443    return node;
6444  }
6445
6446  return null;
6447}; // Return the outermost node of a domTree.
6448
6449
6450var getOutermostNode = function getOutermostNode(node, side) {
6451  var partialGroup = checkPartialGroup(node);
6452
6453  if (partialGroup) {
6454    var children = partialGroup.children;
6455
6456    if (children.length) {
6457      if (side === "right") {
6458        return getOutermostNode(children[children.length - 1], "right");
6459      } else if (side === "left") {
6460        return getOutermostNode(children[0], "left");
6461      }
6462    }
6463  }
6464
6465  return node;
6466}; // Return math atom class (mclass) of a domTree.
6467// If `side` is given, it will get the type of the outermost node at given side.
6468
6469
6470var getTypeOfDomTree = function getTypeOfDomTree(node, side) {
6471  if (!node) {
6472    return null;
6473  }
6474
6475  if (side) {
6476    node = getOutermostNode(node, side);
6477  } // This makes a lot of assumptions as to where the type of atom
6478  // appears.  We should do a better job of enforcing this.
6479
6480
6481  return DomEnum[node.classes[0]] || null;
6482};
6483var makeNullDelimiter = function makeNullDelimiter(options, classes) {
6484  var moreClasses = ["nulldelimiter"].concat(options.baseSizingClasses());
6485  return makeSpan$1(classes.concat(moreClasses));
6486};
6487/**
6488 * buildGroup is the function that takes a group and calls the correct groupType
6489 * function for it. It also handles the interaction of size and style changes
6490 * between parents and children.
6491 */
6492
6493var buildGroup$1 = function buildGroup(group, options, baseOptions) {
6494  if (!group) {
6495    return makeSpan$1();
6496  }
6497
6498  if (_htmlGroupBuilders[group.type]) {
6499    // Call the groupBuilders function
6500    // $FlowFixMe
6501    var groupNode = _htmlGroupBuilders[group.type](group, options); // If the size changed between the parent and the current group, account
6502    // for that size difference.
6503
6504    if (baseOptions && options.size !== baseOptions.size) {
6505      groupNode = makeSpan$1(options.sizingClasses(baseOptions), [groupNode], options);
6506      var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier;
6507      groupNode.height *= multiplier;
6508      groupNode.depth *= multiplier;
6509    }
6510
6511    return groupNode;
6512  } else {
6513    throw new ParseError("Got group of unknown type: '" + group.type + "'");
6514  }
6515};
6516/**
6517 * Combine an array of HTML DOM nodes (e.g., the output of `buildExpression`)
6518 * into an unbreakable HTML node of class .base, with proper struts to
6519 * guarantee correct vertical extent.  `buildHTML` calls this repeatedly to
6520 * make up the entire expression as a sequence of unbreakable units.
6521 */
6522
6523function buildHTMLUnbreakable(children, options) {
6524  // Compute height and depth of this chunk.
6525  var body = makeSpan$1(["base"], children, options); // Add strut, which ensures that the top of the HTML element falls at
6526  // the height of the expression, and the bottom of the HTML element
6527  // falls at the depth of the expression.
6528
6529  var strut = makeSpan$1(["strut"]);
6530  strut.style.height = makeEm(body.height + body.depth);
6531
6532  if (body.depth) {
6533    strut.style.verticalAlign = makeEm(-body.depth);
6534  }
6535
6536  body.children.unshift(strut);
6537  return body;
6538}
6539/**
6540 * Take an entire parse tree, and build it into an appropriate set of HTML
6541 * nodes.
6542 */
6543
6544
6545function buildHTML(tree, options) {
6546  // Strip off outer tag wrapper for processing below.
6547  var tag = null;
6548
6549  if (tree.length === 1 && tree[0].type === "tag") {
6550    tag = tree[0].tag;
6551    tree = tree[0].body;
6552  } // Build the expression contained in the tree
6553
6554
6555  var expression = buildExpression$1(tree, options, "root");
6556  var eqnNum;
6557
6558  if (expression.length === 2 && expression[1].hasClass("tag")) {
6559    // An environment with automatic equation numbers, e.g. {gather}.
6560    eqnNum = expression.pop();
6561  }
6562
6563  var children = []; // Create one base node for each chunk between potential line breaks.
6564  // The TeXBook [p.173] says "A formula will be broken only after a
6565  // relation symbol like $=$ or $<$ or $\rightarrow$, or after a binary
6566  // operation symbol like $+$ or $-$ or $\times$, where the relation or
6567  // binary operation is on the ``outer level'' of the formula (i.e., not
6568  // enclosed in {...} and not part of an \over construction)."
6569
6570  var parts = [];
6571
6572  for (var i = 0; i < expression.length; i++) {
6573    parts.push(expression[i]);
6574
6575    if (expression[i].hasClass("mbin") || expression[i].hasClass("mrel") || expression[i].hasClass("allowbreak")) {
6576      // Put any post-operator glue on same line as operator.
6577      // Watch for \nobreak along the way, and stop at \newline.
6578      var nobreak = false;
6579
6580      while (i < expression.length - 1 && expression[i + 1].hasClass("mspace") && !expression[i + 1].hasClass("newline")) {
6581        i++;
6582        parts.push(expression[i]);
6583
6584        if (expression[i].hasClass("nobreak")) {
6585          nobreak = true;
6586        }
6587      } // Don't allow break if \nobreak among the post-operator glue.
6588
6589
6590      if (!nobreak) {
6591        children.push(buildHTMLUnbreakable(parts, options));
6592        parts = [];
6593      }
6594    } else if (expression[i].hasClass("newline")) {
6595      // Write the line except the newline
6596      parts.pop();
6597
6598      if (parts.length > 0) {
6599        children.push(buildHTMLUnbreakable(parts, options));
6600        parts = [];
6601      } // Put the newline at the top level
6602
6603
6604      children.push(expression[i]);
6605    }
6606  }
6607
6608  if (parts.length > 0) {
6609    children.push(buildHTMLUnbreakable(parts, options));
6610  } // Now, if there was a tag, build it too and append it as a final child.
6611
6612
6613  var tagChild;
6614
6615  if (tag) {
6616    tagChild = buildHTMLUnbreakable(buildExpression$1(tag, options, true));
6617    tagChild.classes = ["tag"];
6618    children.push(tagChild);
6619  } else if (eqnNum) {
6620    children.push(eqnNum);
6621  }
6622
6623  var htmlNode = makeSpan$1(["katex-html"], children);
6624  htmlNode.setAttribute("aria-hidden", "true"); // Adjust the strut of the tag to be the maximum height of all children
6625  // (the height of the enclosing htmlNode) for proper vertical alignment.
6626
6627  if (tagChild) {
6628    var strut = tagChild.children[0];
6629    strut.style.height = makeEm(htmlNode.height + htmlNode.depth);
6630
6631    if (htmlNode.depth) {
6632      strut.style.verticalAlign = makeEm(-htmlNode.depth);
6633    }
6634  }
6635
6636  return htmlNode;
6637}
6638
6639/**
6640 * These objects store data about MathML nodes. This is the MathML equivalent
6641 * of the types in domTree.js. Since MathML handles its own rendering, and
6642 * since we're mainly using MathML to improve accessibility, we don't manage
6643 * any of the styling state that the plain DOM nodes do.
6644 *
6645 * The `toNode` and `toMarkup` functions work similarly to how they do in
6646 * domTree.js, creating namespaced DOM nodes and HTML text markup respectively.
6647 */
6648function newDocumentFragment(children) {
6649  return new DocumentFragment(children);
6650}
6651/**
6652 * This node represents a general purpose MathML node of any type. The
6653 * constructor requires the type of node to create (for example, `"mo"` or
6654 * `"mspace"`, corresponding to `<mo>` and `<mspace>` tags).
6655 */
6656
6657class MathNode {
6658  constructor(type, children, classes) {
6659    this.type = void 0;
6660    this.attributes = void 0;
6661    this.children = void 0;
6662    this.classes = void 0;
6663    this.type = type;
6664    this.attributes = {};
6665    this.children = children || [];
6666    this.classes = classes || [];
6667  }
6668  /**
6669   * Sets an attribute on a MathML node. MathML depends on attributes to convey a
6670   * semantic content, so this is used heavily.
6671   */
6672
6673
6674  setAttribute(name, value) {
6675    this.attributes[name] = value;
6676  }
6677  /**
6678   * Gets an attribute on a MathML node.
6679   */
6680
6681
6682  getAttribute(name) {
6683    return this.attributes[name];
6684  }
6685  /**
6686   * Converts the math node into a MathML-namespaced DOM element.
6687   */
6688
6689
6690  toNode() {
6691    var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", this.type);
6692
6693    for (var attr in this.attributes) {
6694      if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
6695        node.setAttribute(attr, this.attributes[attr]);
6696      }
6697    }
6698
6699    if (this.classes.length > 0) {
6700      node.className = createClass(this.classes);
6701    }
6702
6703    for (var i = 0; i < this.children.length; i++) {
6704      // Combine multiple TextNodes into one TextNode, to prevent
6705      // screen readers from reading each as a separate word [#3995]
6706      if (this.children[i] instanceof TextNode && this.children[i + 1] instanceof TextNode) {
6707        var text = this.children[i].toText() + this.children[++i].toText();
6708
6709        while (this.children[i + 1] instanceof TextNode) {
6710          text += this.children[++i].toText();
6711        }
6712
6713        node.appendChild(new TextNode(text).toNode());
6714      } else {
6715        node.appendChild(this.children[i].toNode());
6716      }
6717    }
6718
6719    return node;
6720  }
6721  /**
6722   * Converts the math node into an HTML markup string.
6723   */
6724
6725
6726  toMarkup() {
6727    var markup = "<" + this.type; // Add the attributes
6728
6729    for (var attr in this.attributes) {
6730      if (Object.prototype.hasOwnProperty.call(this.attributes, attr)) {
6731        markup += " " + attr + "=\"";
6732        markup += utils.escape(this.attributes[attr]);
6733        markup += "\"";
6734      }
6735    }
6736
6737    if (this.classes.length > 0) {
6738      markup += " class =\"" + utils.escape(createClass(this.classes)) + "\"";
6739    }
6740
6741    markup += ">";
6742
6743    for (var i = 0; i < this.children.length; i++) {
6744      markup += this.children[i].toMarkup();
6745    }
6746
6747    markup += "</" + this.type + ">";
6748    return markup;
6749  }
6750  /**
6751   * Converts the math node into a string, similar to innerText, but escaped.
6752   */
6753
6754
6755  toText() {
6756    return this.children.map(child => child.toText()).join("");
6757  }
6758
6759}
6760/**
6761 * This node represents a piece of text.
6762 */
6763
6764class TextNode {
6765  constructor(text) {
6766    this.text = void 0;
6767    this.text = text;
6768  }
6769  /**
6770   * Converts the text node into a DOM text node.
6771   */
6772
6773
6774  toNode() {
6775    return document.createTextNode(this.text);
6776  }
6777  /**
6778   * Converts the text node into escaped HTML markup
6779   * (representing the text itself).
6780   */
6781
6782
6783  toMarkup() {
6784    return utils.escape(this.toText());
6785  }
6786  /**
6787   * Converts the text node into a string
6788   * (representing the text itself).
6789   */
6790
6791
6792  toText() {
6793    return this.text;
6794  }
6795
6796}
6797/**
6798 * This node represents a space, but may render as <mspace.../> or as text,
6799 * depending on the width.
6800 */
6801
6802class SpaceNode {
6803  /**
6804   * Create a Space node with width given in CSS ems.
6805   */
6806  constructor(width) {
6807    this.width = void 0;
6808    this.character = void 0;
6809    this.width = width; // See https://www.w3.org/TR/2000/WD-MathML2-20000328/chapter6.html
6810    // for a table of space-like characters.  We use Unicode
6811    // representations instead of &LongNames; as it's not clear how to
6812    // make the latter via document.createTextNode.
6813
6814    if (width >= 0.05555 && width <= 0.05556) {
6815      this.character = "\u200a"; // &VeryThinSpace;
6816    } else if (width >= 0.1666 && width <= 0.1667) {
6817      this.character = "\u2009"; // &ThinSpace;
6818    } else if (width >= 0.2222 && width <= 0.2223) {
6819      this.character = "\u2005"; // &MediumSpace;
6820    } else if (width >= 0.2777 && width <= 0.2778) {
6821      this.character = "\u2005\u200a"; // &ThickSpace;
6822    } else if (width >= -0.05556 && width <= -0.05555) {
6823      this.character = "\u200a\u2063"; // &NegativeVeryThinSpace;
6824    } else if (width >= -0.1667 && width <= -0.1666) {
6825      this.character = "\u2009\u2063"; // &NegativeThinSpace;
6826    } else if (width >= -0.2223 && width <= -0.2222) {
6827      this.character = "\u205f\u2063"; // &NegativeMediumSpace;
6828    } else if (width >= -0.2778 && width <= -0.2777) {
6829      this.character = "\u2005\u2063"; // &NegativeThickSpace;
6830    } else {
6831      this.character = null;
6832    }
6833  }
6834  /**
6835   * Converts the math node into a MathML-namespaced DOM element.
6836   */
6837
6838
6839  toNode() {
6840    if (this.character) {
6841      return document.createTextNode(this.character);
6842    } else {
6843      var node = document.createElementNS("http://www.w3.org/1998/Math/MathML", "mspace");
6844      node.setAttribute("width", makeEm(this.width));
6845      return node;
6846    }
6847  }
6848  /**
6849   * Converts the math node into an HTML markup string.
6850   */
6851
6852
6853  toMarkup() {
6854    if (this.character) {
6855      return "<mtext>" + this.character + "</mtext>";
6856    } else {
6857      return "<mspace width=\"" + makeEm(this.width) + "\"/>";
6858    }
6859  }
6860  /**
6861   * Converts the math node into a string, similar to innerText.
6862   */
6863
6864
6865  toText() {
6866    if (this.character) {
6867      return this.character;
6868    } else {
6869      return " ";
6870    }
6871  }
6872
6873}
6874
6875var mathMLTree = {
6876  MathNode,
6877  TextNode,
6878  SpaceNode,
6879  newDocumentFragment
6880};
6881
6882/**
6883 * This file converts a parse tree into a corresponding MathML tree. The main
6884 * entry point is the `buildMathML` function, which takes a parse tree from the
6885 * parser.
6886 */
6887
6888/**
6889 * Takes a symbol and converts it into a MathML text node after performing
6890 * optional replacement from symbols.js.
6891 */
6892var makeText = function makeText(text, mode, options) {
6893  if (symbols[mode][text] && symbols[mode][text].replace && text.charCodeAt(0) !== 0xD835 && !(ligatures.hasOwnProperty(text) && options && (options.fontFamily && options.fontFamily.slice(4, 6) === "tt" || options.font && options.font.slice(4, 6) === "tt"))) {
6894    text = symbols[mode][text].replace;
6895  }
6896
6897  return new mathMLTree.TextNode(text);
6898};
6899/**
6900 * Wrap the given array of nodes in an <mrow> node if needed, i.e.,
6901 * unless the array has length 1.  Always returns a single node.
6902 */
6903
6904var makeRow = function makeRow(body) {
6905  if (body.length === 1) {
6906    return body[0];
6907  } else {
6908    return new mathMLTree.MathNode("mrow", body);
6909  }
6910};
6911/**
6912 * Returns the math variant as a string or null if none is required.
6913 */
6914
6915var getVariant = function getVariant(group, options) {
6916  // Handle \text... font specifiers as best we can.
6917  // MathML has a limited list of allowable mathvariant specifiers; see
6918  // https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt
6919  if (options.fontFamily === "texttt") {
6920    return "monospace";
6921  } else if (options.fontFamily === "textsf") {
6922    if (options.fontShape === "textit" && options.fontWeight === "textbf") {
6923      return "sans-serif-bold-italic";
6924    } else if (options.fontShape === "textit") {
6925      return "sans-serif-italic";
6926    } else if (options.fontWeight === "textbf") {
6927      return "bold-sans-serif";
6928    } else {
6929      return "sans-serif";
6930    }
6931  } else if (options.fontShape === "textit" && options.fontWeight === "textbf") {
6932    return "bold-italic";
6933  } else if (options.fontShape === "textit") {
6934    return "italic";
6935  } else if (options.fontWeight === "textbf") {
6936    return "bold";
6937  }
6938
6939  var font = options.font;
6940
6941  if (!font || font === "mathnormal") {
6942    return null;
6943  }
6944
6945  var mode = group.mode;
6946
6947  if (font === "mathit") {
6948    return "italic";
6949  } else if (font === "boldsymbol") {
6950    return group.type === "textord" ? "bold" : "bold-italic";
6951  } else if (font === "mathbf") {
6952    return "bold";
6953  } else if (font === "mathbb") {
6954    return "double-struck";
6955  } else if (font === "mathsfit") {
6956    return "sans-serif-italic";
6957  } else if (font === "mathfrak") {
6958    return "fraktur";
6959  } else if (font === "mathscr" || font === "mathcal") {
6960    // MathML makes no distinction between script and calligraphic
6961    return "script";
6962  } else if (font === "mathsf") {
6963    return "sans-serif";
6964  } else if (font === "mathtt") {
6965    return "monospace";
6966  }
6967
6968  var text = group.text;
6969
6970  if (utils.contains(["\\imath", "\\jmath"], text)) {
6971    return null;
6972  }
6973
6974  if (symbols[mode][text] && symbols[mode][text].replace) {
6975    text = symbols[mode][text].replace;
6976  }
6977
6978  var fontName = buildCommon.fontMap[font].fontName;
6979
6980  if (getCharacterMetrics(text, fontName, mode)) {
6981    return buildCommon.fontMap[font].variant;
6982  }
6983
6984  return null;
6985};
6986/**
6987 * Check for <mi>.</mi> which is how a dot renders in MathML,
vendor: 4,662 bytes, lines 6988-7110
6988 * or <mo separator="true" lspace="0em" rspace="0em">,</mo>
6989 * which is how a braced comma {,} renders in MathML
6990 */
6991
6992function isNumberPunctuation(group) {
6993  if (!group) {
6994    return false;
6995  }
6996
6997  if (group.type === 'mi' && group.children.length === 1) {
6998    var child = group.children[0];
6999    return child instanceof TextNode && child.text === '.';
7000  } else if (group.type === 'mo' && group.children.length === 1 && group.getAttribute('separator') === 'true' && group.getAttribute('lspace') === '0em' && group.getAttribute('rspace') === '0em') {
7001    var _child = group.children[0];
7002    return _child instanceof TextNode && _child.text === ',';
7003  } else {
7004    return false;
7005  }
7006}
7007/**
7008 * Takes a list of nodes, builds them, and returns a list of the generated
7009 * MathML nodes.  Also combine consecutive <mtext> outputs into a single
7010 * <mtext> tag.
7011 */
7012
7013
7014var buildExpression = function buildExpression(expression, options, isOrdgroup) {
7015  if (expression.length === 1) {
7016    var group = buildGroup(expression[0], options);
7017
7018    if (isOrdgroup && group instanceof MathNode && group.type === "mo") {
7019      // When TeX writers want to suppress spacing on an operator,
7020      // they often put the operator by itself inside braces.
7021      group.setAttribute("lspace", "0em");
7022      group.setAttribute("rspace", "0em");
7023    }
7024
7025    return [group];
7026  }
7027
7028  var groups = [];
7029  var lastGroup;
7030
7031  for (var i = 0; i < expression.length; i++) {
7032    var _group = buildGroup(expression[i], options);
7033
7034    if (_group instanceof MathNode && lastGroup instanceof MathNode) {
7035      // Concatenate adjacent <mtext>s
7036      if (_group.type === 'mtext' && lastGroup.type === 'mtext' && _group.getAttribute('mathvariant') === lastGroup.getAttribute('mathvariant')) {
7037        lastGroup.children.push(..._group.children);
7038        continue; // Concatenate adjacent <mn>s
7039      } else if (_group.type === 'mn' && lastGroup.type === 'mn') {
7040        lastGroup.children.push(..._group.children);
7041        continue; // Concatenate <mn>...</mn> followed by <mi>.</mi>
7042      } else if (isNumberPunctuation(_group) && lastGroup.type === 'mn') {
7043        lastGroup.children.push(..._group.children);
7044        continue; // Concatenate <mi>.</mi> followed by <mn>...</mn>
7045      } else if (_group.type === 'mn' && isNumberPunctuation(lastGroup)) {
7046        _group.children = [...lastGroup.children, ..._group.children];
7047        groups.pop(); // Put preceding <mn>...</mn> or <mi>.</mi> inside base of
7048        // <msup><mn>...base...</mn>...exponent...</msup> (or <msub>)
7049      } else if ((_group.type === 'msup' || _group.type === 'msub') && _group.children.length >= 1 && (lastGroup.type === 'mn' || isNumberPunctuation(lastGroup))) {
7050        var base = _group.children[0];
7051
7052        if (base instanceof MathNode && base.type === 'mn') {
7053          base.children = [...lastGroup.children, ...base.children];
7054          groups.pop();
7055        } // \not
7056
7057      } else if (lastGroup.type === 'mi' && lastGroup.children.length === 1) {
7058        var lastChild = lastGroup.children[0];
7059
7060        if (lastChild instanceof TextNode && lastChild.text === '\u0338' && (_group.type === 'mo' || _group.type === 'mi' || _group.type === 'mn')) {
7061          var child = _group.children[0];
7062
7063          if (child instanceof TextNode && child.text.length > 0) {
7064            // Overlay with combining character long solidus
7065            child.text = child.text.slice(0, 1) + "\u0338" + child.text.slice(1);
7066            groups.pop();
7067          }
7068        }
7069      }
7070    }
7071
7072    groups.push(_group);
7073    lastGroup = _group;
7074  }
7075
7076  return groups;
7077};
7078/**
7079 * Equivalent to buildExpression, but wraps the elements in an <mrow>
7080 * if there's more than one.  Returns a single node instead of an array.
7081 */
7082
7083var buildExpressionRow = function buildExpressionRow(expression, options, isOrdgroup) {
7084  return makeRow(buildExpression(expression, options, isOrdgroup));
7085};
7086/**
7087 * Takes a group from the parser and calls the appropriate groupBuilders function
7088 * on it to produce a MathML node.
7089 */
7090
7091var buildGroup = function buildGroup(group, options) {
7092  if (!group) {
7093    return new mathMLTree.MathNode("mrow");
7094  }
7095
7096  if (_mathmlGroupBuilders[group.type]) {
7097    // Call the groupBuilders function
7098    // $FlowFixMe
7099    var result = _mathmlGroupBuilders[group.type](group, options); // $FlowFixMe
7100
7101    return result;
7102  } else {
7103    throw new ParseError("Got group of unknown type: '" + group.type + "'");
7104  }
7105};
7106/**
7107 * Takes a full parse tree and settings and builds a MathML representation of
7108 * it. In particular, we put the elements from building the parse tree into a
7109 * <semantics> tag so we can also include that TeX source as an annotation.
7110 *
vendor: 55,190 bytes, lines 7111-8857
7111 * Note that we actually return a domTree element with a `<math>` inside it so
7112 * we can do appropriate styling.
7113 */
7114
7115function buildMathML(tree, texExpression, options, isDisplayMode, forMathmlOnly) {
7116  var expression = buildExpression(tree, options); // TODO: Make a pass thru the MathML similar to buildHTML.traverseNonSpaceNodes
7117  // and add spacing nodes. This is necessary only adjacent to math operators
7118  // like \sin or \lim or to subsup elements that contain math operators.
7119  // MathML takes care of the other spacing issues.
7120  // Wrap up the expression in an mrow so it is presented in the semantics
7121  // tag correctly, unless it's a single <mrow> or <mtable>.
7122
7123  var wrapper;
7124
7125  if (expression.length === 1 && expression[0] instanceof MathNode && utils.contains(["mrow", "mtable"], expression[0].type)) {
7126    wrapper = expression[0];
7127  } else {
7128    wrapper = new mathMLTree.MathNode("mrow", expression);
7129  } // Build a TeX annotation of the source
7130
7131
7132  var annotation = new mathMLTree.MathNode("annotation", [new mathMLTree.TextNode(texExpression)]);
7133  annotation.setAttribute("encoding", "application/x-tex");
7134  var semantics = new mathMLTree.MathNode("semantics", [wrapper, annotation]);
7135  var math = new mathMLTree.MathNode("math", [semantics]);
7136  math.setAttribute("xmlns", "http://www.w3.org/1998/Math/MathML");
7137
7138  if (isDisplayMode) {
7139    math.setAttribute("display", "block");
7140  } // You can't style <math> nodes, so we wrap the node in a span.
7141  // NOTE: The span class is not typed to have <math> nodes as children, and
7142  // we don't want to make the children type more generic since the children
7143  // of span are expected to have more fields in `buildHtml` contexts.
7144
7145
7146  var wrapperClass = forMathmlOnly ? "katex" : "katex-mathml"; // $FlowFixMe
7147
7148  return buildCommon.makeSpan([wrapperClass], [math]);
7149}
7150
7151var optionsFromSettings = function optionsFromSettings(settings) {
7152  return new Options({
7153    style: settings.displayMode ? Style$1.DISPLAY : Style$1.TEXT,
7154    maxSize: settings.maxSize,
7155    minRuleThickness: settings.minRuleThickness
7156  });
7157};
7158
7159var displayWrap = function displayWrap(node, settings) {
7160  if (settings.displayMode) {
7161    var classes = ["katex-display"];
7162
7163    if (settings.leqno) {
7164      classes.push("leqno");
7165    }
7166
7167    if (settings.fleqn) {
7168      classes.push("fleqn");
7169    }
7170
7171    node = buildCommon.makeSpan(classes, [node]);
7172  }
7173
7174  return node;
7175};
7176
7177var buildTree = function buildTree(tree, expression, settings) {
7178  var options = optionsFromSettings(settings);
7179  var katexNode;
7180
7181  if (settings.output === "mathml") {
7182    return buildMathML(tree, expression, options, settings.displayMode, true);
7183  } else if (settings.output === "html") {
7184    var htmlNode = buildHTML(tree, options);
7185    katexNode = buildCommon.makeSpan(["katex"], [htmlNode]);
7186  } else {
7187    var mathMLNode = buildMathML(tree, expression, options, settings.displayMode, false);
7188
7189    var _htmlNode = buildHTML(tree, options);
7190
7191    katexNode = buildCommon.makeSpan(["katex"], [mathMLNode, _htmlNode]);
7192  }
7193
7194  return displayWrap(katexNode, settings);
7195};
7196var buildHTMLTree = function buildHTMLTree(tree, expression, settings) {
7197  var options = optionsFromSettings(settings);
7198  var htmlNode = buildHTML(tree, options);
7199  var katexNode = buildCommon.makeSpan(["katex"], [htmlNode]);
7200  return displayWrap(katexNode, settings);
7201};
7202
7203/**
7204 * This file provides support to buildMathML.js and buildHTML.js
7205 * for stretchy wide elements rendered from SVG files
7206 * and other CSS trickery.
7207 */
7208var stretchyCodePoint = {
7209  widehat: "^",
7210  widecheck: "ˇ",
7211  widetilde: "~",
7212  utilde: "~",
7213  overleftarrow: "\u2190",
7214  underleftarrow: "\u2190",
7215  xleftarrow: "\u2190",
7216  overrightarrow: "\u2192",
7217  underrightarrow: "\u2192",
7218  xrightarrow: "\u2192",
7219  underbrace: "\u23df",
7220  overbrace: "\u23de",
7221  overgroup: "\u23e0",
7222  undergroup: "\u23e1",
7223  overleftrightarrow: "\u2194",
7224  underleftrightarrow: "\u2194",
7225  xleftrightarrow: "\u2194",
7226  Overrightarrow: "\u21d2",
7227  xRightarrow: "\u21d2",
7228  overleftharpoon: "\u21bc",
7229  xleftharpoonup: "\u21bc",
7230  overrightharpoon: "\u21c0",
7231  xrightharpoonup: "\u21c0",
7232  xLeftarrow: "\u21d0",
7233  xLeftrightarrow: "\u21d4",
7234  xhookleftarrow: "\u21a9",
7235  xhookrightarrow: "\u21aa",
7236  xmapsto: "\u21a6",
7237  xrightharpoondown: "\u21c1",
7238  xleftharpoondown: "\u21bd",
7239  xrightleftharpoons: "\u21cc",
7240  xleftrightharpoons: "\u21cb",
7241  xtwoheadleftarrow: "\u219e",
7242  xtwoheadrightarrow: "\u21a0",
7243  xlongequal: "=",
7244  xtofrom: "\u21c4",
7245  xrightleftarrows: "\u21c4",
7246  xrightequilibrium: "\u21cc",
7247  // Not a perfect match.
7248  xleftequilibrium: "\u21cb",
7249  // None better available.
7250  "\\cdrightarrow": "\u2192",
7251  "\\cdleftarrow": "\u2190",
7252  "\\cdlongequal": "="
7253};
7254
7255var mathMLnode = function mathMLnode(label) {
7256  var node = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(stretchyCodePoint[label.replace(/^\\/, '')])]);
7257  node.setAttribute("stretchy", "true");
7258  return node;
7259}; // Many of the KaTeX SVG images have been adapted from glyphs in KaTeX fonts.
7260// Copyright (c) 2009-2010, Design Science, Inc. (<www.mathjax.org>)
7261// Copyright (c) 2014-2017 Khan Academy (<www.khanacademy.org>)
7262// Licensed under the SIL Open Font License, Version 1.1.
7263// See \nhttp://scripts.sil.org/OFL
7264// Very Long SVGs
7265//    Many of the KaTeX stretchy wide elements use a long SVG image and an
7266//    overflow: hidden tactic to achieve a stretchy image while avoiding
7267//    distortion of arrowheads or brace corners.
7268//    The SVG typically contains a very long (400 em) arrow.
7269//    The SVG is in a container span that has overflow: hidden, so the span
7270//    acts like a window that exposes only part of the  SVG.
7271//    The SVG always has a longer, thinner aspect ratio than the container span.
7272//    After the SVG fills 100% of the height of the container span,
7273//    there is a long arrow shaft left over. That left-over shaft is not shown.
7274//    Instead, it is sliced off because the span's CSS has overflow: hidden.
7275//    Thus, the reader sees an arrow that matches the subject matter width
7276//    without distortion.
7277//    Some functions, such as \cancel, need to vary their aspect ratio. These
7278//    functions do not get the overflow SVG treatment.
7279// Second Brush Stroke
7280//    Low resolution monitors struggle to display images in fine detail.
7281//    So browsers apply anti-aliasing. A long straight arrow shaft therefore
7282//    will sometimes appear as if it has a blurred edge.
7283//    To mitigate this, these SVG files contain a second "brush-stroke" on the
7284//    arrow shafts. That is, a second long thin rectangular SVG path has been
7285//    written directly on top of each arrow shaft. This reinforcement causes
7286//    some of the screen pixels to display as black instead of the anti-aliased
7287//    gray pixel that a  single path would generate. So we get arrow shafts
7288//    whose edges appear to be sharper.
7289// In the katexImagesData object just below, the dimensions all
7290// correspond to path geometry inside the relevant SVG.
7291// For example, \overrightarrow uses the same arrowhead as glyph U+2192
7292// from the KaTeX Main font. The scaling factor is 1000.
7293// That is, inside the font, that arrowhead is 522 units tall, which
7294// corresponds to 0.522 em inside the document.
7295
7296
7297var katexImagesData = {
7298  //   path(s), minWidth, height, align
7299  overrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"],
7300  overleftarrow: [["leftarrow"], 0.888, 522, "xMinYMin"],
7301  underrightarrow: [["rightarrow"], 0.888, 522, "xMaxYMin"],
7302  underleftarrow: [["leftarrow"], 0.888, 522, "xMinYMin"],
7303  xrightarrow: [["rightarrow"], 1.469, 522, "xMaxYMin"],
7304  "\\cdrightarrow": [["rightarrow"], 3.0, 522, "xMaxYMin"],
7305  // CD minwwidth2.5pc
7306  xleftarrow: [["leftarrow"], 1.469, 522, "xMinYMin"],
7307  "\\cdleftarrow": [["leftarrow"], 3.0, 522, "xMinYMin"],
7308  Overrightarrow: [["doublerightarrow"], 0.888, 560, "xMaxYMin"],
7309  xRightarrow: [["doublerightarrow"], 1.526, 560, "xMaxYMin"],
7310  xLeftarrow: [["doubleleftarrow"], 1.526, 560, "xMinYMin"],
7311  overleftharpoon: [["leftharpoon"], 0.888, 522, "xMinYMin"],
7312  xleftharpoonup: [["leftharpoon"], 0.888, 522, "xMinYMin"],
7313  xleftharpoondown: [["leftharpoondown"], 0.888, 522, "xMinYMin"],
7314  overrightharpoon: [["rightharpoon"], 0.888, 522, "xMaxYMin"],
7315  xrightharpoonup: [["rightharpoon"], 0.888, 522, "xMaxYMin"],
7316  xrightharpoondown: [["rightharpoondown"], 0.888, 522, "xMaxYMin"],
7317  xlongequal: [["longequal"], 0.888, 334, "xMinYMin"],
7318  "\\cdlongequal": [["longequal"], 3.0, 334, "xMinYMin"],
7319  xtwoheadleftarrow: [["twoheadleftarrow"], 0.888, 334, "xMinYMin"],
7320  xtwoheadrightarrow: [["twoheadrightarrow"], 0.888, 334, "xMaxYMin"],
7321  overleftrightarrow: [["leftarrow", "rightarrow"], 0.888, 522],
7322  overbrace: [["leftbrace", "midbrace", "rightbrace"], 1.6, 548],
7323  underbrace: [["leftbraceunder", "midbraceunder", "rightbraceunder"], 1.6, 548],
7324  underleftrightarrow: [["leftarrow", "rightarrow"], 0.888, 522],
7325  xleftrightarrow: [["leftarrow", "rightarrow"], 1.75, 522],
7326  xLeftrightarrow: [["doubleleftarrow", "doublerightarrow"], 1.75, 560],
7327  xrightleftharpoons: [["leftharpoondownplus", "rightharpoonplus"], 1.75, 716],
7328  xleftrightharpoons: [["leftharpoonplus", "rightharpoondownplus"], 1.75, 716],
7329  xhookleftarrow: [["leftarrow", "righthook"], 1.08, 522],
7330  xhookrightarrow: [["lefthook", "rightarrow"], 1.08, 522],
7331  overlinesegment: [["leftlinesegment", "rightlinesegment"], 0.888, 522],
7332  underlinesegment: [["leftlinesegment", "rightlinesegment"], 0.888, 522],
7333  overgroup: [["leftgroup", "rightgroup"], 0.888, 342],
7334  undergroup: [["leftgroupunder", "rightgroupunder"], 0.888, 342],
7335  xmapsto: [["leftmapsto", "rightarrow"], 1.5, 522],
7336  xtofrom: [["leftToFrom", "rightToFrom"], 1.75, 528],
7337  // The next three arrows are from the mhchem package.
7338  // In mhchem.sty, min-length is 2.0em. But these arrows might appear in the
7339  // document as \xrightarrow or \xrightleftharpoons. Those have
7340  // min-length = 1.75em, so we set min-length on these next three to match.
7341  xrightleftarrows: [["baraboveleftarrow", "rightarrowabovebar"], 1.75, 901],
7342  xrightequilibrium: [["baraboveshortleftharpoon", "rightharpoonaboveshortbar"], 1.75, 716],
7343  xleftequilibrium: [["shortbaraboveleftharpoon", "shortrightharpoonabovebar"], 1.75, 716]
7344};
7345
7346var groupLength = function groupLength(arg) {
7347  if (arg.type === "ordgroup") {
7348    return arg.body.length;
7349  } else {
7350    return 1;
7351  }
7352};
7353
7354var svgSpan = function svgSpan(group, options) {
7355  // Create a span with inline SVG for the element.
7356  function buildSvgSpan_() {
7357    var viewBoxWidth = 400000; // default
7358
7359    var label = group.label.slice(1);
7360
7361    if (utils.contains(["widehat", "widecheck", "widetilde", "utilde"], label)) {
7362      // Each type in the `if` statement corresponds to one of the ParseNode
7363      // types below. This narrowing is required to access `grp.base`.
7364      // $FlowFixMe
7365      var grp = group; // There are four SVG images available for each function.
7366      // Choose a taller image when there are more characters.
7367
7368      var numChars = groupLength(grp.base);
7369      var viewBoxHeight;
7370      var pathName;
7371
7372      var _height;
7373
7374      if (numChars > 5) {
7375        if (label === "widehat" || label === "widecheck") {
7376          viewBoxHeight = 420;
7377          viewBoxWidth = 2364;
7378          _height = 0.42;
7379          pathName = label + "4";
7380        } else {
7381          viewBoxHeight = 312;
7382          viewBoxWidth = 2340;
7383          _height = 0.34;
7384          pathName = "tilde4";
7385        }
7386      } else {
7387        var imgIndex = [1, 1, 2, 2, 3, 3][numChars];
7388
7389        if (label === "widehat" || label === "widecheck") {
7390          viewBoxWidth = [0, 1062, 2364, 2364, 2364][imgIndex];
7391          viewBoxHeight = [0, 239, 300, 360, 420][imgIndex];
7392          _height = [0, 0.24, 0.3, 0.3, 0.36, 0.42][imgIndex];
7393          pathName = label + imgIndex;
7394        } else {
7395          viewBoxWidth = [0, 600, 1033, 2339, 2340][imgIndex];
7396          viewBoxHeight = [0, 260, 286, 306, 312][imgIndex];
7397          _height = [0, 0.26, 0.286, 0.3, 0.306, 0.34][imgIndex];
7398          pathName = "tilde" + imgIndex;
7399        }
7400      }
7401
7402      var path = new PathNode(pathName);
7403      var svgNode = new SvgNode([path], {
7404        "width": "100%",
7405        "height": makeEm(_height),
7406        "viewBox": "0 0 " + viewBoxWidth + " " + viewBoxHeight,
7407        "preserveAspectRatio": "none"
7408      });
7409      return {
7410        span: buildCommon.makeSvgSpan([], [svgNode], options),
7411        minWidth: 0,
7412        height: _height
7413      };
7414    } else {
7415      var spans = [];
7416      var data = katexImagesData[label];
7417      var [paths, _minWidth, _viewBoxHeight] = data;
7418
7419      var _height2 = _viewBoxHeight / 1000;
7420
7421      var numSvgChildren = paths.length;
7422      var widthClasses;
7423      var aligns;
7424
7425      if (numSvgChildren === 1) {
7426        // $FlowFixMe: All these cases must be of the 4-tuple type.
7427        var align1 = data[3];
7428        widthClasses = ["hide-tail"];
7429        aligns = [align1];
7430      } else if (numSvgChildren === 2) {
7431        widthClasses = ["halfarrow-left", "halfarrow-right"];
7432        aligns = ["xMinYMin", "xMaxYMin"];
7433      } else if (numSvgChildren === 3) {
7434        widthClasses = ["brace-left", "brace-center", "brace-right"];
7435        aligns = ["xMinYMin", "xMidYMin", "xMaxYMin"];
7436      } else {
7437        throw new Error("Correct katexImagesData or update code here to support\n                    " + numSvgChildren + " children.");
7438      }
7439
7440      for (var i = 0; i < numSvgChildren; i++) {
7441        var _path = new PathNode(paths[i]);
7442
7443        var _svgNode = new SvgNode([_path], {
7444          "width": "400em",
7445          "height": makeEm(_height2),
7446          "viewBox": "0 0 " + viewBoxWidth + " " + _viewBoxHeight,
7447          "preserveAspectRatio": aligns[i] + " slice"
7448        });
7449
7450        var _span = buildCommon.makeSvgSpan([widthClasses[i]], [_svgNode], options);
7451
7452        if (numSvgChildren === 1) {
7453          return {
7454            span: _span,
7455            minWidth: _minWidth,
7456            height: _height2
7457          };
7458        } else {
7459          _span.style.height = makeEm(_height2);
7460          spans.push(_span);
7461        }
7462      }
7463
7464      return {
7465        span: buildCommon.makeSpan(["stretchy"], spans, options),
7466        minWidth: _minWidth,
7467        height: _height2
7468      };
7469    }
7470  } // buildSvgSpan_()
7471
7472
7473  var {
7474    span,
7475    minWidth,
7476    height
7477  } = buildSvgSpan_(); // Note that we are returning span.depth = 0.
7478  // Any adjustments relative to the baseline must be done in buildHTML.
7479
7480  span.height = height;
7481  span.style.height = makeEm(height);
7482
7483  if (minWidth > 0) {
7484    span.style.minWidth = makeEm(minWidth);
7485  }
7486
7487  return span;
7488};
7489
7490var encloseSpan = function encloseSpan(inner, label, topPad, bottomPad, options) {
7491  // Return an image span for \cancel, \bcancel, \xcancel, \fbox, or \angl
7492  var img;
7493  var totalHeight = inner.height + inner.depth + topPad + bottomPad;
7494
7495  if (/fbox|color|angl/.test(label)) {
7496    img = buildCommon.makeSpan(["stretchy", label], [], options);
7497
7498    if (label === "fbox") {
7499      var color = options.color && options.getColor();
7500
7501      if (color) {
7502        img.style.borderColor = color;
7503      }
7504    }
7505  } else {
7506    // \cancel, \bcancel, or \xcancel
7507    // Since \cancel's SVG is inline and it omits the viewBox attribute,
7508    // its stroke-width will not vary with span area.
7509    var lines = [];
7510
7511    if (/^[bx]cancel$/.test(label)) {
7512      lines.push(new LineNode({
7513        "x1": "0",
7514        "y1": "0",
7515        "x2": "100%",
7516        "y2": "100%",
7517        "stroke-width": "0.046em"
7518      }));
7519    }
7520
7521    if (/^x?cancel$/.test(label)) {
7522      lines.push(new LineNode({
7523        "x1": "0",
7524        "y1": "100%",
7525        "x2": "100%",
7526        "y2": "0",
7527        "stroke-width": "0.046em"
7528      }));
7529    }
7530
7531    var svgNode = new SvgNode(lines, {
7532      "width": "100%",
7533      "height": makeEm(totalHeight)
7534    });
7535    img = buildCommon.makeSvgSpan([], [svgNode], options);
7536  }
7537
7538  img.height = totalHeight;
7539  img.style.height = makeEm(totalHeight);
7540  return img;
7541};
7542
7543var stretchy = {
7544  encloseSpan,
7545  mathMLnode,
7546  svgSpan
7547};
7548
7549/**
7550 * Asserts that the node is of the given type and returns it with stricter
7551 * typing. Throws if the node's type does not match.
7552 */
7553function assertNodeType(node, type) {
7554  if (!node || node.type !== type) {
7555    throw new Error("Expected node of type " + type + ", but got " + (node ? "node of type " + node.type : String(node)));
7556  } // $FlowFixMe, >=0.125
7557
7558
7559  return node;
7560}
7561/**
7562 * Returns the node more strictly typed iff it is of the given type. Otherwise,
7563 * returns null.
7564 */
7565
7566function assertSymbolNodeType(node) {
7567  var typedNode = checkSymbolNodeType(node);
7568
7569  if (!typedNode) {
7570    throw new Error("Expected node of symbol group type, but got " + (node ? "node of type " + node.type : String(node)));
7571  }
7572
7573  return typedNode;
7574}
7575/**
7576 * Returns the node more strictly typed iff it is of the given type. Otherwise,
7577 * returns null.
7578 */
7579
7580function checkSymbolNodeType(node) {
7581  if (node && (node.type === "atom" || NON_ATOMS.hasOwnProperty(node.type))) {
7582    // $FlowFixMe
7583    return node;
7584  }
7585
7586  return null;
7587}
7588
7589// NOTE: Unlike most `htmlBuilder`s, this one handles not only "accent", but
7590// also "supsub" since an accent can affect super/subscripting.
7591var htmlBuilder$a = (grp, options) => {
7592  // Accents are handled in the TeXbook pg. 443, rule 12.
7593  var base;
7594  var group;
7595  var supSubGroup;
7596
7597  if (grp && grp.type === "supsub") {
7598    // If our base is a character box, and we have superscripts and
7599    // subscripts, the supsub will defer to us. In particular, we want
7600    // to attach the superscripts and subscripts to the inner body (so
7601    // that the position of the superscripts and subscripts won't be
7602    // affected by the height of the accent). We accomplish this by
7603    // sticking the base of the accent into the base of the supsub, and
7604    // rendering that, while keeping track of where the accent is.
7605    // The real accent group is the base of the supsub group
7606    group = assertNodeType(grp.base, "accent"); // The character box is the base of the accent group
7607
7608    base = group.base; // Stick the character box into the base of the supsub group
7609
7610    grp.base = base; // Rerender the supsub group with its new base, and store that
7611    // result.
7612
7613    supSubGroup = assertSpan(buildGroup$1(grp, options)); // reset original base
7614
7615    grp.base = group;
7616  } else {
7617    group = assertNodeType(grp, "accent");
7618    base = group.base;
7619  } // Build the base group
7620
7621
7622  var body = buildGroup$1(base, options.havingCrampedStyle()); // Does the accent need to shift for the skew of a character?
7623
7624  var mustShift = group.isShifty && utils.isCharacterBox(base); // Calculate the skew of the accent. This is based on the line "If the
7625  // nucleus is not a single character, let s = 0; otherwise set s to the
7626  // kern amount for the nucleus followed by the \skewchar of its font."
7627  // Note that our skew metrics are just the kern between each character
7628  // and the skewchar.
7629
7630  var skew = 0;
7631
7632  if (mustShift) {
7633    // If the base is a character box, then we want the skew of the
7634    // innermost character. To do that, we find the innermost character:
7635    var baseChar = utils.getBaseElem(base); // Then, we render its group to get the symbol inside it
7636
7637    var baseGroup = buildGroup$1(baseChar, options.havingCrampedStyle()); // Finally, we pull the skew off of the symbol.
7638
7639    skew = assertSymbolDomNode(baseGroup).skew; // Note that we now throw away baseGroup, because the layers we
7640    // removed with getBaseElem might contain things like \color which
7641    // we can't get rid of.
7642    // TODO(emily): Find a better way to get the skew
7643  }
7644
7645  var accentBelow = group.label === "\\c"; // calculate the amount of space between the body and the accent
7646
7647  var clearance = accentBelow ? body.height + body.depth : Math.min(body.height, options.fontMetrics().xHeight); // Build the accent
7648
7649  var accentBody;
7650
7651  if (!group.isStretchy) {
7652    var accent;
7653    var width;
7654
7655    if (group.label === "\\vec") {
7656      // Before version 0.9, \vec used the combining font glyph U+20D7.
7657      // But browsers, especially Safari, are not consistent in how they
7658      // render combining characters when not preceded by a character.
7659      // So now we use an SVG.
7660      // If Safari reforms, we should consider reverting to the glyph.
7661      accent = buildCommon.staticSvg("vec", options);
7662      width = buildCommon.svgData.vec[1];
7663    } else {
7664      accent = buildCommon.makeOrd({
7665        mode: group.mode,
7666        text: group.label
7667      }, options, "textord");
7668      accent = assertSymbolDomNode(accent); // Remove the italic correction of the accent, because it only serves to
7669      // shift the accent over to a place we don't want.
7670
7671      accent.italic = 0;
7672      width = accent.width;
7673
7674      if (accentBelow) {
7675        clearance += accent.depth;
7676      }
7677    }
7678
7679    accentBody = buildCommon.makeSpan(["accent-body"], [accent]); // "Full" accents expand the width of the resulting symbol to be
7680    // at least the width of the accent, and overlap directly onto the
7681    // character without any vertical offset.
7682
7683    var accentFull = group.label === "\\textcircled";
7684
7685    if (accentFull) {
7686      accentBody.classes.push('accent-full');
7687      clearance = body.height;
7688    } // Shift the accent over by the skew.
7689
7690
7691    var left = skew; // CSS defines `.katex .accent .accent-body:not(.accent-full) { width: 0 }`
7692    // so that the accent doesn't contribute to the bounding box.
7693    // We need to shift the character by its width (effectively half
7694    // its width) to compensate.
7695
7696    if (!accentFull) {
7697      left -= width / 2;
7698    }
7699
7700    accentBody.style.left = makeEm(left); // \textcircled uses the \bigcirc glyph, so it needs some
7701    // vertical adjustment to match LaTeX.
7702
7703    if (group.label === "\\textcircled") {
7704      accentBody.style.top = ".2em";
7705    }
7706
7707    accentBody = buildCommon.makeVList({
7708      positionType: "firstBaseline",
7709      children: [{
7710        type: "elem",
7711        elem: body
7712      }, {
7713        type: "kern",
7714        size: -clearance
7715      }, {
7716        type: "elem",
7717        elem: accentBody
7718      }]
7719    }, options);
7720  } else {
7721    accentBody = stretchy.svgSpan(group, options);
7722    accentBody = buildCommon.makeVList({
7723      positionType: "firstBaseline",
7724      children: [{
7725        type: "elem",
7726        elem: body
7727      }, {
7728        type: "elem",
7729        elem: accentBody,
7730        wrapperClasses: ["svg-align"],
7731        wrapperStyle: skew > 0 ? {
7732          width: "calc(100% - " + makeEm(2 * skew) + ")",
7733          marginLeft: makeEm(2 * skew)
7734        } : undefined
7735      }]
7736    }, options);
7737  }
7738
7739  var accentWrap = buildCommon.makeSpan(["mord", "accent"], [accentBody], options);
7740
7741  if (supSubGroup) {
7742    // Here, we replace the "base" child of the supsub with our newly
7743    // generated accent.
7744    supSubGroup.children[0] = accentWrap; // Since we don't rerun the height calculation after replacing the
7745    // accent, we manually recalculate height.
7746
7747    supSubGroup.height = Math.max(accentWrap.height, supSubGroup.height); // Accents should always be ords, even when their innards are not.
7748
7749    supSubGroup.classes[0] = "mord";
7750    return supSubGroup;
7751  } else {
7752    return accentWrap;
7753  }
7754};
7755
7756var mathmlBuilder$9 = (group, options) => {
7757  var accentNode = group.isStretchy ? stretchy.mathMLnode(group.label) : new mathMLTree.MathNode("mo", [makeText(group.label, group.mode)]);
7758  var node = new mathMLTree.MathNode("mover", [buildGroup(group.base, options), accentNode]);
7759  node.setAttribute("accent", "true");
7760  return node;
7761};
7762
7763var NON_STRETCHY_ACCENT_REGEX = new RegExp(["\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", "\\check", "\\hat", "\\vec", "\\dot", "\\mathring"].map(accent => "\\" + accent).join("|")); // Accents
7764
7765defineFunction({
7766  type: "accent",
7767  names: ["\\acute", "\\grave", "\\ddot", "\\tilde", "\\bar", "\\breve", "\\check", "\\hat", "\\vec", "\\dot", "\\mathring", "\\widecheck", "\\widehat", "\\widetilde", "\\overrightarrow", "\\overleftarrow", "\\Overrightarrow", "\\overleftrightarrow", "\\overgroup", "\\overlinesegment", "\\overleftharpoon", "\\overrightharpoon"],
7768  props: {
7769    numArgs: 1
7770  },
7771  handler: (context, args) => {
7772    var base = normalizeArgument(args[0]);
7773    var isStretchy = !NON_STRETCHY_ACCENT_REGEX.test(context.funcName);
7774    var isShifty = !isStretchy || context.funcName === "\\widehat" || context.funcName === "\\widetilde" || context.funcName === "\\widecheck";
7775    return {
7776      type: "accent",
7777      mode: context.parser.mode,
7778      label: context.funcName,
7779      isStretchy: isStretchy,
7780      isShifty: isShifty,
7781      base: base
7782    };
7783  },
7784  htmlBuilder: htmlBuilder$a,
7785  mathmlBuilder: mathmlBuilder$9
7786}); // Text-mode accents
7787
7788defineFunction({
7789  type: "accent",
7790  names: ["\\'", "\\`", "\\^", "\\~", "\\=", "\\u", "\\.", '\\"', "\\c", "\\r", "\\H", "\\v", "\\textcircled"],
7791  props: {
7792    numArgs: 1,
7793    allowedInText: true,
7794    allowedInMath: true,
7795    // unless in strict mode
7796    argTypes: ["primitive"]
7797  },
7798  handler: (context, args) => {
7799    var base = args[0];
7800    var mode = context.parser.mode;
7801
7802    if (mode === "math") {
7803      context.parser.settings.reportNonstrict("mathVsTextAccents", "LaTeX's accent " + context.funcName + " works only in text mode");
7804      mode = "text";
7805    }
7806
7807    return {
7808      type: "accent",
7809      mode: mode,
7810      label: context.funcName,
7811      isStretchy: false,
7812      isShifty: true,
7813      base: base
7814    };
7815  },
7816  htmlBuilder: htmlBuilder$a,
7817  mathmlBuilder: mathmlBuilder$9
7818});
7819
7820// Horizontal overlap functions
7821defineFunction({
7822  type: "accentUnder",
7823  names: ["\\underleftarrow", "\\underrightarrow", "\\underleftrightarrow", "\\undergroup", "\\underlinesegment", "\\utilde"],
7824  props: {
7825    numArgs: 1
7826  },
7827  handler: (_ref, args) => {
7828    var {
7829      parser,
7830      funcName
7831    } = _ref;
7832    var base = args[0];
7833    return {
7834      type: "accentUnder",
7835      mode: parser.mode,
7836      label: funcName,
7837      base: base
7838    };
7839  },
7840  htmlBuilder: (group, options) => {
7841    // Treat under accents much like underlines.
7842    var innerGroup = buildGroup$1(group.base, options);
7843    var accentBody = stretchy.svgSpan(group, options);
7844    var kern = group.label === "\\utilde" ? 0.12 : 0; // Generate the vlist, with the appropriate kerns
7845
7846    var vlist = buildCommon.makeVList({
7847      positionType: "top",
7848      positionData: innerGroup.height,
7849      children: [{
7850        type: "elem",
7851        elem: accentBody,
7852        wrapperClasses: ["svg-align"]
7853      }, {
7854        type: "kern",
7855        size: kern
7856      }, {
7857        type: "elem",
7858        elem: innerGroup
7859      }]
7860    }, options);
7861    return buildCommon.makeSpan(["mord", "accentunder"], [vlist], options);
7862  },
7863  mathmlBuilder: (group, options) => {
7864    var accentNode = stretchy.mathMLnode(group.label);
7865    var node = new mathMLTree.MathNode("munder", [buildGroup(group.base, options), accentNode]);
7866    node.setAttribute("accentunder", "true");
7867    return node;
7868  }
7869});
7870
7871// Helper function
7872var paddedNode = group => {
7873  var node = new mathMLTree.MathNode("mpadded", group ? [group] : []);
7874  node.setAttribute("width", "+0.6em");
7875  node.setAttribute("lspace", "0.3em");
7876  return node;
7877}; // Stretchy arrows with an optional argument
7878
7879
7880defineFunction({
7881  type: "xArrow",
7882  names: ["\\xleftarrow", "\\xrightarrow", "\\xLeftarrow", "\\xRightarrow", "\\xleftrightarrow", "\\xLeftrightarrow", "\\xhookleftarrow", "\\xhookrightarrow", "\\xmapsto", "\\xrightharpoondown", "\\xrightharpoonup", "\\xleftharpoondown", "\\xleftharpoonup", "\\xrightleftharpoons", "\\xleftrightharpoons", "\\xlongequal", "\\xtwoheadrightarrow", "\\xtwoheadleftarrow", "\\xtofrom", // The next 3 functions are here to support the mhchem extension.
7883  // Direct use of these functions is discouraged and may break someday.
7884  "\\xrightleftarrows", "\\xrightequilibrium", "\\xleftequilibrium", // The next 3 functions are here only to support the {CD} environment.
7885  "\\\\cdrightarrow", "\\\\cdleftarrow", "\\\\cdlongequal"],
7886  props: {
7887    numArgs: 1,
7888    numOptionalArgs: 1
7889  },
7890
7891  handler(_ref, args, optArgs) {
7892    var {
7893      parser,
7894      funcName
7895    } = _ref;
7896    return {
7897      type: "xArrow",
7898      mode: parser.mode,
7899      label: funcName,
7900      body: args[0],
7901      below: optArgs[0]
7902    };
7903  },
7904
7905  // Flow is unable to correctly infer the type of `group`, even though it's
7906  // unambiguously determined from the passed-in `type` above.
7907  htmlBuilder(group, options) {
7908    var style = options.style; // Build the argument groups in the appropriate style.
7909    // Ref: amsmath.dtx:   \hbox{$\scriptstyle\mkern#3mu{#6}\mkern#4mu$}%
7910    // Some groups can return document fragments.  Handle those by wrapping
7911    // them in a span.
7912
7913    var newOptions = options.havingStyle(style.sup());
7914    var upperGroup = buildCommon.wrapFragment(buildGroup$1(group.body, newOptions, options), options);
7915    var arrowPrefix = group.label.slice(0, 2) === "\\x" ? "x" : "cd";
7916    upperGroup.classes.push(arrowPrefix + "-arrow-pad");
7917    var lowerGroup;
7918
7919    if (group.below) {
7920      // Build the lower group
7921      newOptions = options.havingStyle(style.sub());
7922      lowerGroup = buildCommon.wrapFragment(buildGroup$1(group.below, newOptions, options), options);
7923      lowerGroup.classes.push(arrowPrefix + "-arrow-pad");
7924    }
7925
7926    var arrowBody = stretchy.svgSpan(group, options); // Re shift: Note that stretchy.svgSpan returned arrowBody.depth = 0.
7927    // The point we want on the math axis is at 0.5 * arrowBody.height.
7928
7929    var arrowShift = -options.fontMetrics().axisHeight + 0.5 * arrowBody.height; // 2 mu kern. Ref: amsmath.dtx: #7\if0#2\else\mkern#2mu\fi
7930
7931    var upperShift = -options.fontMetrics().axisHeight - 0.5 * arrowBody.height - 0.111; // 0.111 em = 2 mu
7932
7933    if (upperGroup.depth > 0.25 || group.label === "\\xleftequilibrium") {
7934      upperShift -= upperGroup.depth; // shift up if depth encroaches
7935    } // Generate the vlist
7936
7937
7938    var vlist;
7939
7940    if (lowerGroup) {
7941      var lowerShift = -options.fontMetrics().axisHeight + lowerGroup.height + 0.5 * arrowBody.height + 0.111;
7942      vlist = buildCommon.makeVList({
7943        positionType: "individualShift",
7944        children: [{
7945          type: "elem",
7946          elem: upperGroup,
7947          shift: upperShift
7948        }, {
7949          type: "elem",
7950          elem: arrowBody,
7951          shift: arrowShift
7952        }, {
7953          type: "elem",
7954          elem: lowerGroup,
7955          shift: lowerShift
7956        }]
7957      }, options);
7958    } else {
7959      vlist = buildCommon.makeVList({
7960        positionType: "individualShift",
7961        children: [{
7962          type: "elem",
7963          elem: upperGroup,
7964          shift: upperShift
7965        }, {
7966          type: "elem",
7967          elem: arrowBody,
7968          shift: arrowShift
7969        }]
7970      }, options);
7971    } // $FlowFixMe: Replace this with passing "svg-align" into makeVList.
7972
7973
7974    vlist.children[0].children[0].children[1].classes.push("svg-align");
7975    return buildCommon.makeSpan(["mrel", "x-arrow"], [vlist], options);
7976  },
7977
7978  mathmlBuilder(group, options) {
7979    var arrowNode = stretchy.mathMLnode(group.label);
7980    arrowNode.setAttribute("minsize", group.label.charAt(0) === "x" ? "1.75em" : "3.0em");
7981    var node;
7982
7983    if (group.body) {
7984      var upperNode = paddedNode(buildGroup(group.body, options));
7985
7986      if (group.below) {
7987        var lowerNode = paddedNode(buildGroup(group.below, options));
7988        node = new mathMLTree.MathNode("munderover", [arrowNode, lowerNode, upperNode]);
7989      } else {
7990        node = new mathMLTree.MathNode("mover", [arrowNode, upperNode]);
7991      }
7992    } else if (group.below) {
7993      var _lowerNode = paddedNode(buildGroup(group.below, options));
7994
7995      node = new mathMLTree.MathNode("munder", [arrowNode, _lowerNode]);
7996    } else {
7997      // This should never happen.
7998      // Parser.js throws an error if there is no argument.
7999      node = paddedNode();
8000      node = new mathMLTree.MathNode("mover", [arrowNode, node]);
8001    }
8002
8003    return node;
8004  }
8005
8006});
8007
8008var makeSpan = buildCommon.makeSpan;
8009
8010function htmlBuilder$9(group, options) {
8011  var elements = buildExpression$1(group.body, options, true);
8012  return makeSpan([group.mclass], elements, options);
8013}
8014
8015function mathmlBuilder$8(group, options) {
8016  var node;
8017  var inner = buildExpression(group.body, options);
8018
8019  if (group.mclass === "minner") {
8020    node = new mathMLTree.MathNode("mpadded", inner);
8021  } else if (group.mclass === "mord") {
8022    if (group.isCharacterBox) {
8023      node = inner[0];
8024      node.type = "mi";
8025    } else {
8026      node = new mathMLTree.MathNode("mi", inner);
8027    }
8028  } else {
8029    if (group.isCharacterBox) {
8030      node = inner[0];
8031      node.type = "mo";
8032    } else {
8033      node = new mathMLTree.MathNode("mo", inner);
8034    } // Set spacing based on what is the most likely adjacent atom type.
8035    // See TeXbook p170.
8036
8037
8038    if (group.mclass === "mbin") {
8039      node.attributes.lspace = "0.22em"; // medium space
8040
8041      node.attributes.rspace = "0.22em";
8042    } else if (group.mclass === "mpunct") {
8043      node.attributes.lspace = "0em";
8044      node.attributes.rspace = "0.17em"; // thinspace
8045    } else if (group.mclass === "mopen" || group.mclass === "mclose") {
8046      node.attributes.lspace = "0em";
8047      node.attributes.rspace = "0em";
8048    } else if (group.mclass === "minner") {
8049      node.attributes.lspace = "0.0556em"; // 1 mu is the most likely option
8050
8051      node.attributes.width = "+0.1111em";
8052    } // MathML <mo> default space is 5/18 em, so <mrel> needs no action.
8053    // Ref: https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo
8054
8055  }
8056
8057  return node;
8058} // Math class commands except \mathop
8059
8060
8061defineFunction({
8062  type: "mclass",
8063  names: ["\\mathord", "\\mathbin", "\\mathrel", "\\mathopen", "\\mathclose", "\\mathpunct", "\\mathinner"],
8064  props: {
8065    numArgs: 1,
8066    primitive: true
8067  },
8068
8069  handler(_ref, args) {
8070    var {
8071      parser,
8072      funcName
8073    } = _ref;
8074    var body = args[0];
8075    return {
8076      type: "mclass",
8077      mode: parser.mode,
8078      mclass: "m" + funcName.slice(5),
8079      // TODO(kevinb): don't prefix with 'm'
8080      body: ordargument(body),
8081      isCharacterBox: utils.isCharacterBox(body)
8082    };
8083  },
8084
8085  htmlBuilder: htmlBuilder$9,
8086  mathmlBuilder: mathmlBuilder$8
8087});
8088var binrelClass = arg => {
8089  // \binrel@ spacing varies with (bin|rel|ord) of the atom in the argument.
8090  // (by rendering separately and with {}s before and after, and measuring
8091  // the change in spacing).  We'll do roughly the same by detecting the
8092  // atom type directly.
8093  var atom = arg.type === "ordgroup" && arg.body.length ? arg.body[0] : arg;
8094
8095  if (atom.type === "atom" && (atom.family === "bin" || atom.family === "rel")) {
8096    return "m" + atom.family;
8097  } else {
8098    return "mord";
8099  }
8100}; // \@binrel{x}{y} renders like y but as mbin/mrel/mord if x is mbin/mrel/mord.
8101// This is equivalent to \binrel@{x}\binrel@@{y} in AMSTeX.
8102
8103defineFunction({
8104  type: "mclass",
8105  names: ["\\@binrel"],
8106  props: {
8107    numArgs: 2
8108  },
8109
8110  handler(_ref2, args) {
8111    var {
8112      parser
8113    } = _ref2;
8114    return {
8115      type: "mclass",
8116      mode: parser.mode,
8117      mclass: binrelClass(args[0]),
8118      body: ordargument(args[1]),
8119      isCharacterBox: utils.isCharacterBox(args[1])
8120    };
8121  }
8122
8123}); // Build a relation or stacked op by placing one symbol on top of another
8124
8125defineFunction({
8126  type: "mclass",
8127  names: ["\\stackrel", "\\overset", "\\underset"],
8128  props: {
8129    numArgs: 2
8130  },
8131
8132  handler(_ref3, args) {
8133    var {
8134      parser,
8135      funcName
8136    } = _ref3;
8137    var baseArg = args[1];
8138    var shiftedArg = args[0];
8139    var mclass;
8140
8141    if (funcName !== "\\stackrel") {
8142      // LaTeX applies \binrel spacing to \overset and \underset.
8143      mclass = binrelClass(baseArg);
8144    } else {
8145      mclass = "mrel"; // for \stackrel
8146    }
8147
8148    var baseOp = {
8149      type: "op",
8150      mode: baseArg.mode,
8151      limits: true,
8152      alwaysHandleSupSub: true,
8153      parentIsSupSub: false,
8154      symbol: false,
8155      suppressBaseShift: funcName !== "\\stackrel",
8156      body: ordargument(baseArg)
8157    };
8158    var supsub = {
8159      type: "supsub",
8160      mode: shiftedArg.mode,
8161      base: baseOp,
8162      sup: funcName === "\\underset" ? null : shiftedArg,
8163      sub: funcName === "\\underset" ? shiftedArg : null
8164    };
8165    return {
8166      type: "mclass",
8167      mode: parser.mode,
8168      mclass,
8169      body: [supsub],
8170      isCharacterBox: utils.isCharacterBox(supsub)
8171    };
8172  },
8173
8174  htmlBuilder: htmlBuilder$9,
8175  mathmlBuilder: mathmlBuilder$8
8176});
8177
8178// \pmb is a simulation of bold font.
8179// The version of \pmb in ambsy.sty works by typesetting three copies
8180// with small offsets. We use CSS text-shadow.
8181// It's a hack. Not as good as a real bold font. Better than nothing.
8182defineFunction({
8183  type: "pmb",
8184  names: ["\\pmb"],
8185  props: {
8186    numArgs: 1,
8187    allowedInText: true
8188  },
8189
8190  handler(_ref, args) {
8191    var {
8192      parser
8193    } = _ref;
8194    return {
8195      type: "pmb",
8196      mode: parser.mode,
8197      mclass: binrelClass(args[0]),
8198      body: ordargument(args[0])
8199    };
8200  },
8201
8202  htmlBuilder(group, options) {
8203    var elements = buildExpression$1(group.body, options, true);
8204    var node = buildCommon.makeSpan([group.mclass], elements, options);
8205    node.style.textShadow = "0.02em 0.01em 0.04px";
8206    return node;
8207  },
8208
8209  mathmlBuilder(group, style) {
8210    var inner = buildExpression(group.body, style); // Wrap with an <mstyle> element.
8211
8212    var node = new mathMLTree.MathNode("mstyle", inner);
8213    node.setAttribute("style", "text-shadow: 0.02em 0.01em 0.04px");
8214    return node;
8215  }
8216
8217});
8218
8219var cdArrowFunctionName = {
8220  ">": "\\\\cdrightarrow",
8221  "<": "\\\\cdleftarrow",
8222  "=": "\\\\cdlongequal",
8223  "A": "\\uparrow",
8224  "V": "\\downarrow",
8225  "|": "\\Vert",
8226  ".": "no arrow"
8227};
8228
8229var newCell = () => {
8230  // Create an empty cell, to be filled below with parse nodes.
8231  // The parseTree from this module must be constructed like the
8232  // one created by parseArray(), so an empty CD cell must
8233  // be a ParseNode<"styling">. And CD is always displaystyle.
8234  // So these values are fixed and flow can do implicit typing.
8235  return {
8236    type: "styling",
8237    body: [],
8238    mode: "math",
8239    style: "display"
8240  };
8241};
8242
8243var isStartOfArrow = node => {
8244  return node.type === "textord" && node.text === "@";
8245};
8246
8247var isLabelEnd = (node, endChar) => {
8248  return (node.type === "mathord" || node.type === "atom") && node.text === endChar;
8249};
8250
8251function cdArrow(arrowChar, labels, parser) {
8252  // Return a parse tree of an arrow and its labels.
8253  // This acts in a way similar to a macro expansion.
8254  var funcName = cdArrowFunctionName[arrowChar];
8255
8256  switch (funcName) {
8257    case "\\\\cdrightarrow":
8258    case "\\\\cdleftarrow":
8259      return parser.callFunction(funcName, [labels[0]], [labels[1]]);
8260
8261    case "\\uparrow":
8262    case "\\downarrow":
8263      {
8264        var leftLabel = parser.callFunction("\\\\cdleft", [labels[0]], []);
8265        var bareArrow = {
8266          type: "atom",
8267          text: funcName,
8268          mode: "math",
8269          family: "rel"
8270        };
8271        var sizedArrow = parser.callFunction("\\Big", [bareArrow], []);
8272        var rightLabel = parser.callFunction("\\\\cdright", [labels[1]], []);
8273        var arrowGroup = {
8274          type: "ordgroup",
8275          mode: "math",
8276          body: [leftLabel, sizedArrow, rightLabel]
8277        };
8278        return parser.callFunction("\\\\cdparent", [arrowGroup], []);
8279      }
8280
8281    case "\\\\cdlongequal":
8282      return parser.callFunction("\\\\cdlongequal", [], []);
8283
8284    case "\\Vert":
8285      {
8286        var arrow = {
8287          type: "textord",
8288          text: "\\Vert",
8289          mode: "math"
8290        };
8291        return parser.callFunction("\\Big", [arrow], []);
8292      }
8293
8294    default:
8295      return {
8296        type: "textord",
8297        text: " ",
8298        mode: "math"
8299      };
8300  }
8301}
8302
8303function parseCD(parser) {
8304  // Get the array's parse nodes with \\ temporarily mapped to \cr.
8305  var parsedRows = [];
8306  parser.gullet.beginGroup();
8307  parser.gullet.macros.set("\\cr", "\\\\\\relax");
8308  parser.gullet.beginGroup();
8309
8310  while (true) {
8311    // eslint-disable-line no-constant-condition
8312    // Get the parse nodes for the next row.
8313    parsedRows.push(parser.parseExpression(false, "\\\\"));
8314    parser.gullet.endGroup();
8315    parser.gullet.beginGroup();
8316    var next = parser.fetch().text;
8317
8318    if (next === "&" || next === "\\\\") {
8319      parser.consume();
8320    } else if (next === "\\end") {
8321      if (parsedRows[parsedRows.length - 1].length === 0) {
8322        parsedRows.pop(); // final row ended in \\
8323      }
8324
8325      break;
8326    } else {
8327      throw new ParseError("Expected \\\\ or \\cr or \\end", parser.nextToken);
8328    }
8329  }
8330
8331  var row = [];
8332  var body = [row]; // Loop thru the parse nodes. Collect them into cells and arrows.
8333
8334  for (var i = 0; i < parsedRows.length; i++) {
8335    // Start a new row.
8336    var rowNodes = parsedRows[i]; // Create the first cell.
8337
8338    var cell = newCell();
8339
8340    for (var j = 0; j < rowNodes.length; j++) {
8341      if (!isStartOfArrow(rowNodes[j])) {
8342        // If a parseNode is not an arrow, it goes into a cell.
8343        cell.body.push(rowNodes[j]);
8344      } else {
8345        // Parse node j is an "@", the start of an arrow.
8346        // Before starting on the arrow, push the cell into `row`.
8347        row.push(cell); // Now collect parseNodes into an arrow.
8348        // The character after "@" defines the arrow type.
8349
8350        j += 1;
8351        var arrowChar = assertSymbolNodeType(rowNodes[j]).text; // Create two empty label nodes. We may or may not use them.
8352
8353        var labels = new Array(2);
8354        labels[0] = {
8355          type: "ordgroup",
8356          mode: "math",
8357          body: []
8358        };
8359        labels[1] = {
8360          type: "ordgroup",
8361          mode: "math",
8362          body: []
8363        }; // Process the arrow.
8364
8365        if ("=|.".indexOf(arrowChar) > -1) ; else if ("<>AV".indexOf(arrowChar) > -1) {
8366          // Four arrows, `@>>>`, `@<<<`, `@AAA`, and `@VVV`, each take
8367          // two optional labels. E.g. the right-point arrow syntax is
8368          // really:  @>{optional label}>{optional label}>
8369          // Collect parseNodes into labels.
8370          for (var labelNum = 0; labelNum < 2; labelNum++) {
8371            var inLabel = true;
8372
8373            for (var k = j + 1; k < rowNodes.length; k++) {
8374              if (isLabelEnd(rowNodes[k], arrowChar)) {
8375                inLabel = false;
8376                j = k;
8377                break;
8378              }
8379
8380              if (isStartOfArrow(rowNodes[k])) {
8381                throw new ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[k]);
8382              }
8383
8384              labels[labelNum].body.push(rowNodes[k]);
8385            }
8386
8387            if (inLabel) {
8388              // isLabelEnd never returned a true.
8389              throw new ParseError("Missing a " + arrowChar + " character to complete a CD arrow.", rowNodes[j]);
8390            }
8391          }
8392        } else {
8393          throw new ParseError("Expected one of \"<>AV=|.\" after @", rowNodes[j]);
8394        } // Now join the arrow to its labels.
8395
8396
8397        var arrow = cdArrow(arrowChar, labels, parser); // Wrap the arrow in  ParseNode<"styling">.
8398        // This is done to match parseArray() behavior.
8399
8400        var wrappedArrow = {
8401          type: "styling",
8402          body: [arrow],
8403          mode: "math",
8404          style: "display" // CD is always displaystyle.
8405
8406        };
8407        row.push(wrappedArrow); // In CD's syntax, cells are implicit. That is, everything that
8408        // is not an arrow gets collected into a cell. So create an empty
8409        // cell now. It will collect upcoming parseNodes.
8410
8411        cell = newCell();
8412      }
8413    }
8414
8415    if (i % 2 === 0) {
8416      // Even-numbered rows consist of: cell, arrow, cell, arrow, ... cell
8417      // The last cell is not yet pushed into `row`, so:
8418      row.push(cell);
8419    } else {
8420      // Odd-numbered rows consist of: vert arrow, empty cell, ... vert arrow
8421      // Remove the empty cell that was placed at the beginning of `row`.
8422      row.shift();
8423    }
8424
8425    row = [];
8426    body.push(row);
8427  } // End row group
8428
8429
8430  parser.gullet.endGroup(); // End array group defining \\
8431
8432  parser.gullet.endGroup(); // define column separation.
8433
8434  var cols = new Array(body[0].length).fill({
8435    type: "align",
8436    align: "c",
8437    pregap: 0.25,
8438    // CD package sets \enskip between columns.
8439    postgap: 0.25 // So pre and post each get half an \enskip, i.e. 0.25em.
8440
8441  });
8442  return {
8443    type: "array",
8444    mode: "math",
8445    body,
8446    arraystretch: 1,
8447    addJot: true,
8448    rowGaps: [null],
8449    cols,
8450    colSeparationType: "CD",
8451    hLinesBeforeRow: new Array(body.length + 1).fill([])
8452  };
8453} // The functions below are not available for general use.
8454// They are here only for internal use by the {CD} environment in placing labels
8455// next to vertical arrows.
8456// We don't need any such functions for horizontal arrows because we can reuse
8457// the functionality that already exists for extensible arrows.
8458
8459defineFunction({
8460  type: "cdlabel",
8461  names: ["\\\\cdleft", "\\\\cdright"],
8462  props: {
8463    numArgs: 1
8464  },
8465
8466  handler(_ref, args) {
8467    var {
8468      parser,
8469      funcName
8470    } = _ref;
8471    return {
8472      type: "cdlabel",
8473      mode: parser.mode,
8474      side: funcName.slice(4),
8475      label: args[0]
8476    };
8477  },
8478
8479  htmlBuilder(group, options) {
8480    var newOptions = options.havingStyle(options.style.sup());
8481    var label = buildCommon.wrapFragment(buildGroup$1(group.label, newOptions, options), options);
8482    label.classes.push("cd-label-" + group.side);
8483    label.style.bottom = makeEm(0.8 - label.depth); // Zero out label height & depth, so vertical align of arrow is set
8484    // by the arrow height, not by the label.
8485
8486    label.height = 0;
8487    label.depth = 0;
8488    return label;
8489  },
8490
8491  mathmlBuilder(group, options) {
8492    var label = new mathMLTree.MathNode("mrow", [buildGroup(group.label, options)]);
8493    label = new mathMLTree.MathNode("mpadded", [label]);
8494    label.setAttribute("width", "0");
8495
8496    if (group.side === "left") {
8497      label.setAttribute("lspace", "-1width");
8498    } // We have to guess at vertical alignment. We know the arrow is 1.8em tall,
8499    // But we don't know the height or depth of the label.
8500
8501
8502    label.setAttribute("voffset", "0.7em");
8503    label = new mathMLTree.MathNode("mstyle", [label]);
8504    label.setAttribute("displaystyle", "false");
8505    label.setAttribute("scriptlevel", "1");
8506    return label;
8507  }
8508
8509});
8510defineFunction({
8511  type: "cdlabelparent",
8512  names: ["\\\\cdparent"],
8513  props: {
8514    numArgs: 1
8515  },
8516
8517  handler(_ref2, args) {
8518    var {
8519      parser
8520    } = _ref2;
8521    return {
8522      type: "cdlabelparent",
8523      mode: parser.mode,
8524      fragment: args[0]
8525    };
8526  },
8527
8528  htmlBuilder(group, options) {
8529    // Wrap the vertical arrow and its labels.
8530    // The parent gets position: relative. The child gets position: absolute.
8531    // So CSS can locate the label correctly.
8532    var parent = buildCommon.wrapFragment(buildGroup$1(group.fragment, options), options);
8533    parent.classes.push("cd-vert-arrow");
8534    return parent;
8535  },
8536
8537  mathmlBuilder(group, options) {
8538    return new mathMLTree.MathNode("mrow", [buildGroup(group.fragment, options)]);
8539  }
8540
8541});
8542
8543// {123} and converts into symbol with code 123.  It is used by the *macro*
8544// \char defined in macros.js.
8545
8546defineFunction({
8547  type: "textord",
8548  names: ["\\@char"],
8549  props: {
8550    numArgs: 1,
8551    allowedInText: true
8552  },
8553
8554  handler(_ref, args) {
8555    var {
8556      parser
8557    } = _ref;
8558    var arg = assertNodeType(args[0], "ordgroup");
8559    var group = arg.body;
8560    var number = "";
8561
8562    for (var i = 0; i < group.length; i++) {
8563      var node = assertNodeType(group[i], "textord");
8564      number += node.text;
8565    }
8566
8567    var code = parseInt(number);
8568    var text;
8569
8570    if (isNaN(code)) {
8571      throw new ParseError("\\@char has non-numeric argument " + number); // If we drop IE support, the following code could be replaced with
8572      // text = String.fromCodePoint(code)
8573    } else if (code < 0 || code >= 0x10ffff) {
8574      throw new ParseError("\\@char with invalid code point " + number);
8575    } else if (code <= 0xffff) {
8576      text = String.fromCharCode(code);
8577    } else {
8578      // Astral code point; split into surrogate halves
8579      code -= 0x10000;
8580      text = String.fromCharCode((code >> 10) + 0xd800, (code & 0x3ff) + 0xdc00);
8581    }
8582
8583    return {
8584      type: "textord",
8585      mode: parser.mode,
8586      text: text
8587    };
8588  }
8589
8590});
8591
8592var htmlBuilder$8 = (group, options) => {
8593  var elements = buildExpression$1(group.body, options.withColor(group.color), false); // \color isn't supposed to affect the type of the elements it contains.
8594  // To accomplish this, we wrap the results in a fragment, so the inner
8595  // elements will be able to directly interact with their neighbors. For
8596  // example, `\color{red}{2 +} 3` has the same spacing as `2 + 3`
8597
8598  return buildCommon.makeFragment(elements);
8599};
8600
8601var mathmlBuilder$7 = (group, options) => {
8602  var inner = buildExpression(group.body, options.withColor(group.color));
8603  var node = new mathMLTree.MathNode("mstyle", inner);
8604  node.setAttribute("mathcolor", group.color);
8605  return node;
8606};
8607
8608defineFunction({
8609  type: "color",
8610  names: ["\\textcolor"],
8611  props: {
8612    numArgs: 2,
8613    allowedInText: true,
8614    argTypes: ["color", "original"]
8615  },
8616
8617  handler(_ref, args) {
8618    var {
8619      parser
8620    } = _ref;
8621    var color = assertNodeType(args[0], "color-token").color;
8622    var body = args[1];
8623    return {
8624      type: "color",
8625      mode: parser.mode,
8626      color,
8627      body: ordargument(body)
8628    };
8629  },
8630
8631  htmlBuilder: htmlBuilder$8,
8632  mathmlBuilder: mathmlBuilder$7
8633});
8634defineFunction({
8635  type: "color",
8636  names: ["\\color"],
8637  props: {
8638    numArgs: 1,
8639    allowedInText: true,
8640    argTypes: ["color"]
8641  },
8642
8643  handler(_ref2, args) {
8644    var {
8645      parser,
8646      breakOnTokenText
8647    } = _ref2;
8648    var color = assertNodeType(args[0], "color-token").color; // Set macro \current@color in current namespace to store the current
8649    // color, mimicking the behavior of color.sty.
8650    // This is currently used just to correctly color a \right
8651    // that follows a \color command.
8652
8653    parser.gullet.macros.set("\\current@color", color); // Parse out the implicit body that should be colored.
8654
8655    var body = parser.parseExpression(true, breakOnTokenText);
8656    return {
8657      type: "color",
8658      mode: parser.mode,
8659      color,
8660      body
8661    };
8662  },
8663
8664  htmlBuilder: htmlBuilder$8,
8665  mathmlBuilder: mathmlBuilder$7
8666});
8667
8668// Row breaks within tabular environments, and line breaks at top level
8669
8670defineFunction({
8671  type: "cr",
8672  names: ["\\\\"],
8673  props: {
8674    numArgs: 0,
8675    numOptionalArgs: 0,
8676    allowedInText: true
8677  },
8678
8679  handler(_ref, args, optArgs) {
8680    var {
8681      parser
8682    } = _ref;
8683    var size = parser.gullet.future().text === "[" ? parser.parseSizeGroup(true) : null;
8684    var newLine = !parser.settings.displayMode || !parser.settings.useStrictBehavior("newLineInDisplayMode", "In LaTeX, \\\\ or \\newline " + "does nothing in display mode");
8685    return {
8686      type: "cr",
8687      mode: parser.mode,
8688      newLine,
8689      size: size && assertNodeType(size, "size").value
8690    };
8691  },
8692
8693  // The following builders are called only at the top level,
8694  // not within tabular/array environments.
8695  htmlBuilder(group, options) {
8696    var span = buildCommon.makeSpan(["mspace"], [], options);
8697
8698    if (group.newLine) {
8699      span.classes.push("newline");
8700
8701      if (group.size) {
8702        span.style.marginTop = makeEm(calculateSize(group.size, options));
8703      }
8704    }
8705
8706    return span;
8707  },
8708
8709  mathmlBuilder(group, options) {
8710    var node = new mathMLTree.MathNode("mspace");
8711
8712    if (group.newLine) {
8713      node.setAttribute("linebreak", "newline");
8714
8715      if (group.size) {
8716        node.setAttribute("height", makeEm(calculateSize(group.size, options)));
8717      }
8718    }
8719
8720    return node;
8721  }
8722
8723});
8724
8725var globalMap = {
8726  "\\global": "\\global",
8727  "\\long": "\\\\globallong",
8728  "\\\\globallong": "\\\\globallong",
8729  "\\def": "\\gdef",
8730  "\\gdef": "\\gdef",
8731  "\\edef": "\\xdef",
8732  "\\xdef": "\\xdef",
8733  "\\let": "\\\\globallet",
8734  "\\futurelet": "\\\\globalfuture"
8735};
8736
8737var checkControlSequence = tok => {
8738  var name = tok.text;
8739
8740  if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) {
8741    throw new ParseError("Expected a control sequence", tok);
8742  }
8743
8744  return name;
8745};
8746
8747var getRHS = parser => {
8748  var tok = parser.gullet.popToken();
8749
8750  if (tok.text === "=") {
8751    // consume optional equals
8752    tok = parser.gullet.popToken();
8753
8754    if (tok.text === " ") {
8755      // consume one optional space
8756      tok = parser.gullet.popToken();
8757    }
8758  }
8759
8760  return tok;
8761};
8762
8763var letCommand = (parser, name, tok, global) => {
8764  var macro = parser.gullet.macros.get(tok.text);
8765
8766  if (macro == null) {
8767    // don't expand it later even if a macro with the same name is defined
8768    // e.g., \let\foo=\frac \def\frac{\relax} \frac12
8769    tok.noexpand = true;
8770    macro = {
8771      tokens: [tok],
8772      numArgs: 0,
8773      // reproduce the same behavior in expansion
8774      unexpandable: !parser.gullet.isExpandable(tok.text)
8775    };
8776  }
8777
8778  parser.gullet.macros.set(name, macro, global);
8779}; // <assignment> -> <non-macro assignment>|<macro assignment>
8780// <non-macro assignment> -> <simple assignment>|\global<non-macro assignment>
8781// <macro assignment> -> <definition>|<prefix><macro assignment>
8782// <prefix> -> \global|\long|\outer
8783
8784
8785defineFunction({
8786  type: "internal",
8787  names: ["\\global", "\\long", "\\\\globallong" // can’t be entered directly
8788  ],
8789  props: {
8790    numArgs: 0,
8791    allowedInText: true
8792  },
8793
8794  handler(_ref) {
8795    var {
8796      parser,
8797      funcName
8798    } = _ref;
8799    parser.consumeSpaces();
8800    var token = parser.fetch();
8801
8802    if (globalMap[token.text]) {
8803      // KaTeX doesn't have \par, so ignore \long
8804      if (funcName === "\\global" || funcName === "\\\\globallong") {
8805        token.text = globalMap[token.text];
8806      }
8807
8808      return assertNodeType(parser.parseFunction(), "internal");
8809    }
8810
8811    throw new ParseError("Invalid token after macro prefix", token);
8812  }
8813
8814}); // Basic support for macro definitions: \def, \gdef, \edef, \xdef
8815// <definition> -> <def><control sequence><definition text>
8816// <def> -> \def|\gdef|\edef|\xdef
8817// <definition text> -> <parameter text><left brace><balanced text><right brace>
8818
8819defineFunction({
8820  type: "internal",
8821  names: ["\\def", "\\gdef", "\\edef", "\\xdef"],
8822  props: {
8823    numArgs: 0,
8824    allowedInText: true,
8825    primitive: true
8826  },
8827
8828  handler(_ref2) {
8829    var {
8830      parser,
8831      funcName
8832    } = _ref2;
8833    var tok = parser.gullet.popToken();
8834    var name = tok.text;
8835
8836    if (/^(?:[\\{}$&#^_]|EOF)$/.test(name)) {
8837      throw new ParseError("Expected a control sequence", tok);
8838    }
8839
8840    var numArgs = 0;
8841    var insert;
8842    var delimiters = [[]]; // <parameter text> contains no braces
8843
8844    while (parser.gullet.future().text !== "{") {
8845      tok = parser.gullet.popToken();
8846
8847      if (tok.text === "#") {
8848        // If the very last character of the <parameter text> is #, so that
8849        // this # is immediately followed by {, TeX will behave as if the {
8850        // had been inserted at the right end of both the parameter text
8851        // and the replacement text.
8852        if (parser.gullet.future().text === "{") {
8853          insert = parser.gullet.future();
8854          delimiters[numArgs].push("{");
8855          break;
8856        } // A parameter, the first appearance of # must be followed by 1,
8857        // the next by 2, and so on;
vendor: 4,192 bytes, lines 8857-9002
8857 up to nine #’s are allowed
8858
8859
8860        tok = parser.gullet.popToken();
8861
8862        if (!/^[1-9]$/.test(tok.text)) {
8863          throw new ParseError("Invalid argument number \"" + tok.text + "\"");
8864        }
8865
8866        if (parseInt(tok.text) !== numArgs + 1) {
8867          throw new ParseError("Argument number \"" + tok.text + "\" out of order");
8868        }
8869
8870        numArgs++;
8871        delimiters.push([]);
8872      } else if (tok.text === "EOF") {
8873        throw new ParseError("Expected a macro definition");
8874      } else {
8875        delimiters[numArgs].push(tok.text);
8876      }
8877    } // replacement text, enclosed in '{' and '}' and properly nested
8878
8879
8880    var {
8881      tokens
8882    } = parser.gullet.consumeArg();
8883
8884    if (insert) {
8885      tokens.unshift(insert);
8886    }
8887
8888    if (funcName === "\\edef" || funcName === "\\xdef") {
8889      tokens = parser.gullet.expandTokens(tokens);
8890      tokens.reverse(); // to fit in with stack order
8891    } // Final arg is the expansion of the macro
8892
8893
8894    parser.gullet.macros.set(name, {
8895      tokens,
8896      numArgs,
8897      delimiters
8898    }, funcName === globalMap[funcName]);
8899    return {
8900      type: "internal",
8901      mode: parser.mode
8902    };
8903  }
8904
8905}); // <simple assignment> -> <let assignment>
8906// <let assignment> -> \futurelet<control sequence><token><token>
8907//     | \let<control sequence><equals><one optional space><token>
8908// <equals> -> <optional spaces>|<optional spaces>=
8909
8910defineFunction({
8911  type: "internal",
8912  names: ["\\let", "\\\\globallet" // can’t be entered directly
8913  ],
8914  props: {
8915    numArgs: 0,
8916    allowedInText: true,
8917    primitive: true
8918  },
8919
8920  handler(_ref3) {
8921    var {
8922      parser,
8923      funcName
8924    } = _ref3;
8925    var name = checkControlSequence(parser.gullet.popToken());
8926    parser.gullet.consumeSpaces();
8927    var tok = getRHS(parser);
8928    letCommand(parser, name, tok, funcName === "\\\\globallet");
8929    return {
8930      type: "internal",
8931      mode: parser.mode
8932    };
8933  }
8934
8935}); // ref: https://www.tug.org/TUGboat/tb09-3/tb22bechtolsheim.pdf
8936
8937defineFunction({
8938  type: "internal",
8939  names: ["\\futurelet", "\\\\globalfuture" // can’t be entered directly
8940  ],
8941  props: {
8942    numArgs: 0,
8943    allowedInText: true,
8944    primitive: true
8945  },
8946
8947  handler(_ref4) {
8948    var {
8949      parser,
8950      funcName
8951    } = _ref4;
8952    var name = checkControlSequence(parser.gullet.popToken());
8953    var middle = parser.gullet.popToken();
8954    var tok = parser.gullet.popToken();
8955    letCommand(parser, name, tok, funcName === "\\\\globalfuture");
8956    parser.gullet.pushToken(tok);
8957    parser.gullet.pushToken(middle);
8958    return {
8959      type: "internal",
8960      mode: parser.mode
8961    };
8962  }
8963
8964});
8965
8966/**
8967 * This file deals with creating delimiters of various sizes. The TeXbook
8968 * discusses these routines on page 441-442, in the "Another subroutine sets box
8969 * x to a specified variable delimiter" paragraph.
8970 *
8971 * There are three main routines here. `makeSmallDelim` makes a delimiter in the
8972 * normal font, but in either text, script, or scriptscript style.
8973 * `makeLargeDelim` makes a delimiter in textstyle, but in one of the Size1,
8974 * Size2, Size3, or Size4 fonts. `makeStackedDelim` makes a delimiter out of
8975 * smaller pieces that are stacked on top of one another.
8976 *
8977 * The functions take a parameter `center`, which determines if the delimiter
8978 * should be centered around the axis.
8979 *
8980 * Then, there are three exposed functions. `sizedDelim` makes a delimiter in
8981 * one of the given sizes. This is used for things like `\bigl`.
8982 * `customSizedDelim` makes a delimiter with a given total height+depth. It is
8983 * called in places like `\sqrt`. `leftRightDelim` makes an appropriate
8984 * delimiter which surrounds an expression of a given height an depth. It is
8985 * used in `\left` and `\right`.
8986 */
8987
8988/**
8989 * Get the metrics for a given symbol and font, after transformation (i.e.
8990 * after following replacement from symbols.js)
8991 */
8992var getMetrics = function getMetrics(symbol, font, mode) {
8993  var replace = symbols.math[symbol] && symbols.math[symbol].replace;
8994  var metrics = getCharacterMetrics(replace || symbol, font, mode);
8995
8996  if (!metrics) {
8997    throw new Error("Unsupported symbol " + symbol + " and font size " + font + ".");
8998  }
8999
9000  return metrics;
9001};
9002/**
vendor: 173,327 bytes, lines 9003-15080
9003 * Puts a delimiter span in a given style, and adds appropriate height, depth,
9004 * and maxFontSizes.
9005 */
9006
9007
9008var styleWrap = function styleWrap(delim, toStyle, options, classes) {
9009  var newOptions = options.havingBaseStyle(toStyle);
9010  var span = buildCommon.makeSpan(classes.concat(newOptions.sizingClasses(options)), [delim], options);
9011  var delimSizeMultiplier = newOptions.sizeMultiplier / options.sizeMultiplier;
9012  span.height *= delimSizeMultiplier;
9013  span.depth *= delimSizeMultiplier;
9014  span.maxFontSize = newOptions.sizeMultiplier;
9015  return span;
9016};
9017
9018var centerSpan = function centerSpan(span, options, style) {
9019  var newOptions = options.havingBaseStyle(style);
9020  var shift = (1 - options.sizeMultiplier / newOptions.sizeMultiplier) * options.fontMetrics().axisHeight;
9021  span.classes.push("delimcenter");
9022  span.style.top = makeEm(shift);
9023  span.height -= shift;
9024  span.depth += shift;
9025};
9026/**
9027 * Makes a small delimiter. This is a delimiter that comes in the Main-Regular
9028 * font, but is restyled to either be in textstyle, scriptstyle, or
9029 * scriptscriptstyle.
9030 */
9031
9032
9033var makeSmallDelim = function makeSmallDelim(delim, style, center, options, mode, classes) {
9034  var text = buildCommon.makeSymbol(delim, "Main-Regular", mode, options);
9035  var span = styleWrap(text, style, options, classes);
9036
9037  if (center) {
9038    centerSpan(span, options, style);
9039  }
9040
9041  return span;
9042};
9043/**
9044 * Builds a symbol in the given font size (note size is an integer)
9045 */
9046
9047
9048var mathrmSize = function mathrmSize(value, size, mode, options) {
9049  return buildCommon.makeSymbol(value, "Size" + size + "-Regular", mode, options);
9050};
9051/**
9052 * Makes a large delimiter. This is a delimiter that comes in the Size1, Size2,
9053 * Size3, or Size4 fonts. It is always rendered in textstyle.
9054 */
9055
9056
9057var makeLargeDelim = function makeLargeDelim(delim, size, center, options, mode, classes) {
9058  var inner = mathrmSize(delim, size, mode, options);
9059  var span = styleWrap(buildCommon.makeSpan(["delimsizing", "size" + size], [inner], options), Style$1.TEXT, options, classes);
9060
9061  if (center) {
9062    centerSpan(span, options, Style$1.TEXT);
9063  }
9064
9065  return span;
9066};
9067/**
9068 * Make a span from a font glyph with the given offset and in the given font.
9069 * This is used in makeStackedDelim to make the stacking pieces for the delimiter.
9070 */
9071
9072
9073var makeGlyphSpan = function makeGlyphSpan(symbol, font, mode) {
9074  var sizeClass; // Apply the correct CSS class to choose the right font.
9075
9076  if (font === "Size1-Regular") {
9077    sizeClass = "delim-size1";
9078  } else
9079    /* if (font === "Size4-Regular") */
9080    {
9081      sizeClass = "delim-size4";
9082    }
9083
9084  var corner = buildCommon.makeSpan(["delimsizinginner", sizeClass], [buildCommon.makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]); // Since this will be passed into `makeVList` in the end, wrap the element
9085  // in the appropriate tag that VList uses.
9086
9087  return {
9088    type: "elem",
9089    elem: corner
9090  };
9091};
9092
9093var makeInner = function makeInner(ch, height, options) {
9094  // Create a span with inline SVG for the inner part of a tall stacked delimiter.
9095  var width = fontMetricsData['Size4-Regular'][ch.charCodeAt(0)] ? fontMetricsData['Size4-Regular'][ch.charCodeAt(0)][4] : fontMetricsData['Size1-Regular'][ch.charCodeAt(0)][4];
9096  var path = new PathNode("inner", innerPath(ch, Math.round(1000 * height)));
9097  var svgNode = new SvgNode([path], {
9098    "width": makeEm(width),
9099    "height": makeEm(height),
9100    // Override CSS rule `.katex svg { width: 100% }`
9101    "style": "width:" + makeEm(width),
9102    "viewBox": "0 0 " + 1000 * width + " " + Math.round(1000 * height),
9103    "preserveAspectRatio": "xMinYMin"
9104  });
9105  var span = buildCommon.makeSvgSpan([], [svgNode], options);
9106  span.height = height;
9107  span.style.height = makeEm(height);
9108  span.style.width = makeEm(width);
9109  return {
9110    type: "elem",
9111    elem: span
9112  };
9113}; // Helpers for makeStackedDelim
9114
9115
9116var lapInEms = 0.008;
9117var lap = {
9118  type: "kern",
9119  size: -1 * lapInEms
9120};
9121var verts = ["|", "\\lvert", "\\rvert", "\\vert"];
9122var doubleVerts = ["\\|", "\\lVert", "\\rVert", "\\Vert"];
9123/**
9124 * Make a stacked delimiter out of a given delimiter, with the total height at
9125 * least `heightTotal`. This routine is mentioned on page 442 of the TeXbook.
9126 */
9127
9128var makeStackedDelim = function makeStackedDelim(delim, heightTotal, center, options, mode, classes) {
9129  // There are four parts, the top, an optional middle, a repeated part, and a
9130  // bottom.
9131  var top;
9132  var middle;
9133  var repeat;
9134  var bottom;
9135  var svgLabel = "";
9136  var viewBoxWidth = 0;
9137  top = repeat = bottom = delim;
9138  middle = null; // Also keep track of what font the delimiters are in
9139
9140  var font = "Size1-Regular"; // We set the parts and font based on the symbol. Note that we use
9141  // '\u23d0' instead of '|' and '\u2016' instead of '\\|' for the
9142  // repeats of the arrows
9143
9144  if (delim === "\\uparrow") {
9145    repeat = bottom = "\u23d0";
9146  } else if (delim === "\\Uparrow") {
9147    repeat = bottom = "\u2016";
9148  } else if (delim === "\\downarrow") {
9149    top = repeat = "\u23d0";
9150  } else if (delim === "\\Downarrow") {
9151    top = repeat = "\u2016";
9152  } else if (delim === "\\updownarrow") {
9153    top = "\\uparrow";
9154    repeat = "\u23d0";
9155    bottom = "\\downarrow";
9156  } else if (delim === "\\Updownarrow") {
9157    top = "\\Uparrow";
9158    repeat = "\u2016";
9159    bottom = "\\Downarrow";
9160  } else if (utils.contains(verts, delim)) {
9161    repeat = "\u2223";
9162    svgLabel = "vert";
9163    viewBoxWidth = 333;
9164  } else if (utils.contains(doubleVerts, delim)) {
9165    repeat = "\u2225";
9166    svgLabel = "doublevert";
9167    viewBoxWidth = 556;
9168  } else if (delim === "[" || delim === "\\lbrack") {
9169    top = "\u23a1";
9170    repeat = "\u23a2";
9171    bottom = "\u23a3";
9172    font = "Size4-Regular";
9173    svgLabel = "lbrack";
9174    viewBoxWidth = 667;
9175  } else if (delim === "]" || delim === "\\rbrack") {
9176    top = "\u23a4";
9177    repeat = "\u23a5";
9178    bottom = "\u23a6";
9179    font = "Size4-Regular";
9180    svgLabel = "rbrack";
9181    viewBoxWidth = 667;
9182  } else if (delim === "\\lfloor" || delim === "\u230a") {
9183    repeat = top = "\u23a2";
9184    bottom = "\u23a3";
9185    font = "Size4-Regular";
9186    svgLabel = "lfloor";
9187    viewBoxWidth = 667;
9188  } else if (delim === "\\lceil" || delim === "\u2308") {
9189    top = "\u23a1";
9190    repeat = bottom = "\u23a2";
9191    font = "Size4-Regular";
9192    svgLabel = "lceil";
9193    viewBoxWidth = 667;
9194  } else if (delim === "\\rfloor" || delim === "\u230b") {
9195    repeat = top = "\u23a5";
9196    bottom = "\u23a6";
9197    font = "Size4-Regular";
9198    svgLabel = "rfloor";
9199    viewBoxWidth = 667;
9200  } else if (delim === "\\rceil" || delim === "\u2309") {
9201    top = "\u23a4";
9202    repeat = bottom = "\u23a5";
9203    font = "Size4-Regular";
9204    svgLabel = "rceil";
9205    viewBoxWidth = 667;
9206  } else if (delim === "(" || delim === "\\lparen") {
9207    top = "\u239b";
9208    repeat = "\u239c";
9209    bottom = "\u239d";
9210    font = "Size4-Regular";
9211    svgLabel = "lparen";
9212    viewBoxWidth = 875;
9213  } else if (delim === ")" || delim === "\\rparen") {
9214    top = "\u239e";
9215    repeat = "\u239f";
9216    bottom = "\u23a0";
9217    font = "Size4-Regular";
9218    svgLabel = "rparen";
9219    viewBoxWidth = 875;
9220  } else if (delim === "\\{" || delim === "\\lbrace") {
9221    top = "\u23a7";
9222    middle = "\u23a8";
9223    bottom = "\u23a9";
9224    repeat = "\u23aa";
9225    font = "Size4-Regular";
9226  } else if (delim === "\\}" || delim === "\\rbrace") {
9227    top = "\u23ab";
9228    middle = "\u23ac";
9229    bottom = "\u23ad";
9230    repeat = "\u23aa";
9231    font = "Size4-Regular";
9232  } else if (delim === "\\lgroup" || delim === "\u27ee") {
9233    top = "\u23a7";
9234    bottom = "\u23a9";
9235    repeat = "\u23aa";
9236    font = "Size4-Regular";
9237  } else if (delim === "\\rgroup" || delim === "\u27ef") {
9238    top = "\u23ab";
9239    bottom = "\u23ad";
9240    repeat = "\u23aa";
9241    font = "Size4-Regular";
9242  } else if (delim === "\\lmoustache" || delim === "\u23b0") {
9243    top = "\u23a7";
9244    bottom = "\u23ad";
9245    repeat = "\u23aa";
9246    font = "Size4-Regular";
9247  } else if (delim === "\\rmoustache" || delim === "\u23b1") {
9248    top = "\u23ab";
9249    bottom = "\u23a9";
9250    repeat = "\u23aa";
9251    font = "Size4-Regular";
9252  } // Get the metrics of the four sections
9253
9254
9255  var topMetrics = getMetrics(top, font, mode);
9256  var topHeightTotal = topMetrics.height + topMetrics.depth;
9257  var repeatMetrics = getMetrics(repeat, font, mode);
9258  var repeatHeightTotal = repeatMetrics.height + repeatMetrics.depth;
9259  var bottomMetrics = getMetrics(bottom, font, mode);
9260  var bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth;
9261  var middleHeightTotal = 0;
9262  var middleFactor = 1;
9263
9264  if (middle !== null) {
9265    var middleMetrics = getMetrics(middle, font, mode);
9266    middleHeightTotal = middleMetrics.height + middleMetrics.depth;
9267    middleFactor = 2; // repeat symmetrically above and below middle
9268  } // Calculate the minimal height that the delimiter can have.
9269  // It is at least the size of the top, bottom, and optional middle combined.
9270
9271
9272  var minHeight = topHeightTotal + bottomHeightTotal + middleHeightTotal; // Compute the number of copies of the repeat symbol we will need
9273
9274  var repeatCount = Math.max(0, Math.ceil((heightTotal - minHeight) / (middleFactor * repeatHeightTotal))); // Compute the total height of the delimiter including all the symbols
9275
9276  var realHeightTotal = minHeight + repeatCount * middleFactor * repeatHeightTotal; // The center of the delimiter is placed at the center of the axis. Note
9277  // that in this context, "center" means that the delimiter should be
9278  // centered around the axis in the current style, while normally it is
9279  // centered around the axis in textstyle.
9280
9281  var axisHeight = options.fontMetrics().axisHeight;
9282
9283  if (center) {
9284    axisHeight *= options.sizeMultiplier;
9285  } // Calculate the depth
9286
9287
9288  var depth = realHeightTotal / 2 - axisHeight; // Now, we start building the pieces that will go into the vlist
9289  // Keep a list of the pieces of the stacked delimiter
9290
9291  var stack = [];
9292
9293  if (svgLabel.length > 0) {
9294    // Instead of stacking glyphs, create a single SVG.
9295    // This evades browser problems with imprecise positioning of spans.
9296    var midHeight = realHeightTotal - topHeightTotal - bottomHeightTotal;
9297    var viewBoxHeight = Math.round(realHeightTotal * 1000);
9298    var pathStr = tallDelim(svgLabel, Math.round(midHeight * 1000));
9299    var path = new PathNode(svgLabel, pathStr);
9300    var width = (viewBoxWidth / 1000).toFixed(3) + "em";
9301    var height = (viewBoxHeight / 1000).toFixed(3) + "em";
9302    var svg = new SvgNode([path], {
9303      "width": width,
9304      "height": height,
9305      "viewBox": "0 0 " + viewBoxWidth + " " + viewBoxHeight
9306    });
9307    var wrapper = buildCommon.makeSvgSpan([], [svg], options);
9308    wrapper.height = viewBoxHeight / 1000;
9309    wrapper.style.width = width;
9310    wrapper.style.height = height;
9311    stack.push({
9312      type: "elem",
9313      elem: wrapper
9314    });
9315  } else {
9316    // Stack glyphs
9317    // Start by adding the bottom symbol
9318    stack.push(makeGlyphSpan(bottom, font, mode));
9319    stack.push(lap); // overlap
9320
9321    if (middle === null) {
9322      // The middle section will be an SVG. Make it an extra 0.016em tall.
9323      // We'll overlap by 0.008em at top and bottom.
9324      var innerHeight = realHeightTotal - topHeightTotal - bottomHeightTotal + 2 * lapInEms;
9325      stack.push(makeInner(repeat, innerHeight, options));
9326    } else {
9327      // When there is a middle bit, we need the middle part and two repeated
9328      // sections
9329      var _innerHeight = (realHeightTotal - topHeightTotal - bottomHeightTotal - middleHeightTotal) / 2 + 2 * lapInEms;
9330
9331      stack.push(makeInner(repeat, _innerHeight, options)); // Now insert the middle of the brace.
9332
9333      stack.push(lap);
9334      stack.push(makeGlyphSpan(middle, font, mode));
9335      stack.push(lap);
9336      stack.push(makeInner(repeat, _innerHeight, options));
9337    } // Add the top symbol
9338
9339
9340    stack.push(lap);
9341    stack.push(makeGlyphSpan(top, font, mode));
9342  } // Finally, build the vlist
9343
9344
9345  var newOptions = options.havingBaseStyle(Style$1.TEXT);
9346  var inner = buildCommon.makeVList({
9347    positionType: "bottom",
9348    positionData: depth,
9349    children: stack
9350  }, newOptions);
9351  return styleWrap(buildCommon.makeSpan(["delimsizing", "mult"], [inner], newOptions), Style$1.TEXT, options, classes);
9352}; // All surds have 0.08em padding above the vinculum inside the SVG.
9353// That keeps browser span height rounding error from pinching the line.
9354
9355
9356var vbPad = 80; // padding above the surd, measured inside the viewBox.
9357
9358var emPad = 0.08; // padding, in ems, measured in the document.
9359
9360var sqrtSvg = function sqrtSvg(sqrtName, height, viewBoxHeight, extraVinculum, options) {
9361  var path = sqrtPath(sqrtName, extraVinculum, viewBoxHeight);
9362  var pathNode = new PathNode(sqrtName, path);
9363  var svg = new SvgNode([pathNode], {
9364    // Note: 1000:1 ratio of viewBox to document em width.
9365    "width": "400em",
9366    "height": makeEm(height),
9367    "viewBox": "0 0 400000 " + viewBoxHeight,
9368    "preserveAspectRatio": "xMinYMin slice"
9369  });
9370  return buildCommon.makeSvgSpan(["hide-tail"], [svg], options);
9371};
9372/**
9373 * Make a sqrt image of the given height,
9374 */
9375
9376
9377var makeSqrtImage = function makeSqrtImage(height, options) {
9378  // Define a newOptions that removes the effect of size changes such as \Huge.
9379  // We don't pick different a height surd for \Huge. For it, we scale up.
9380  var newOptions = options.havingBaseSizing(); // Pick the desired surd glyph from a sequence of surds.
9381
9382  var delim = traverseSequence("\\surd", height * newOptions.sizeMultiplier, stackLargeDelimiterSequence, newOptions);
9383  var sizeMultiplier = newOptions.sizeMultiplier; // default
9384  // The standard sqrt SVGs each have a 0.04em thick vinculum.
9385  // If Settings.minRuleThickness is larger than that, we add extraVinculum.
9386
9387  var extraVinculum = Math.max(0, options.minRuleThickness - options.fontMetrics().sqrtRuleThickness); // Create a span containing an SVG image of a sqrt symbol.
9388
9389  var span;
9390  var spanHeight = 0;
9391  var texHeight = 0;
9392  var viewBoxHeight = 0;
9393  var advanceWidth; // We create viewBoxes with 80 units of "padding" above each surd.
9394  // Then browser rounding error on the parent span height will not
9395  // encroach on the ink of the vinculum. But that padding is not
9396  // included in the TeX-like `height` used for calculation of
9397  // vertical alignment. So texHeight = span.height < span.style.height.
9398
9399  if (delim.type === "small") {
9400    // Get an SVG that is derived from glyph U+221A in font KaTeX-Main.
9401    // 1000 unit normal glyph height.
9402    viewBoxHeight = 1000 + 1000 * extraVinculum + vbPad;
9403
9404    if (height < 1.0) {
9405      sizeMultiplier = 1.0; // mimic a \textfont radical
9406    } else if (height < 1.4) {
9407      sizeMultiplier = 0.7; // mimic a \scriptfont radical
9408    }
9409
9410    spanHeight = (1.0 + extraVinculum + emPad) / sizeMultiplier;
9411    texHeight = (1.00 + extraVinculum) / sizeMultiplier;
9412    span = sqrtSvg("sqrtMain", spanHeight, viewBoxHeight, extraVinculum, options);
9413    span.style.minWidth = "0.853em";
9414    advanceWidth = 0.833 / sizeMultiplier; // from the font.
9415  } else if (delim.type === "large") {
9416    // These SVGs come from fonts: KaTeX_Size1, _Size2, etc.
9417    viewBoxHeight = (1000 + vbPad) * sizeToMaxHeight[delim.size];
9418    texHeight = (sizeToMaxHeight[delim.size] + extraVinculum) / sizeMultiplier;
9419    spanHeight = (sizeToMaxHeight[delim.size] + extraVinculum + emPad) / sizeMultiplier;
9420    span = sqrtSvg("sqrtSize" + delim.size, spanHeight, viewBoxHeight, extraVinculum, options);
9421    span.style.minWidth = "1.02em";
9422    advanceWidth = 1.0 / sizeMultiplier; // 1.0 from the font.
9423  } else {
9424    // Tall sqrt. In TeX, this would be stacked using multiple glyphs.
9425    // We'll use a single SVG to accomplish the same thing.
9426    spanHeight = height + extraVinculum + emPad;
9427    texHeight = height + extraVinculum;
9428    viewBoxHeight = Math.floor(1000 * height + extraVinculum) + vbPad;
9429    span = sqrtSvg("sqrtTall", spanHeight, viewBoxHeight, extraVinculum, options);
9430    span.style.minWidth = "0.742em";
9431    advanceWidth = 1.056;
9432  }
9433
9434  span.height = texHeight;
9435  span.style.height = makeEm(spanHeight);
9436  return {
9437    span,
9438    advanceWidth,
9439    // Calculate the actual line width.
9440    // This actually should depend on the chosen font -- e.g. \boldmath
9441    // should use the thicker surd symbols from e.g. KaTeX_Main-Bold, and
9442    // have thicker rules.
9443    ruleWidth: (options.fontMetrics().sqrtRuleThickness + extraVinculum) * sizeMultiplier
9444  };
9445}; // There are three kinds of delimiters, delimiters that stack when they become
9446// too large
9447
9448
9449var stackLargeDelimiters = ["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230a", "\u230b", "\\lceil", "\\rceil", "\u2308", "\u2309", "\\surd"]; // delimiters that always stack
9450
9451var stackAlwaysDelimiters = ["\\uparrow", "\\downarrow", "\\updownarrow", "\\Uparrow", "\\Downarrow", "\\Updownarrow", "|", "\\|", "\\vert", "\\Vert", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27ee", "\u27ef", "\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1"]; // and delimiters that never stack
9452
9453var stackNeverDelimiters = ["<", ">", "\\langle", "\\rangle", "/", "\\backslash", "\\lt", "\\gt"]; // Metrics of the different sizes. Found by looking at TeX's output of
9454// $\bigl| // \Bigl| \biggl| \Biggl| \showlists$
9455// Used to create stacked delimiters of appropriate sizes in makeSizedDelim.
9456
9457var sizeToMaxHeight = [0, 1.2, 1.8, 2.4, 3.0];
9458/**
9459 * Used to create a delimiter of a specific size, where `size` is 1, 2, 3, or 4.
9460 */
9461
9462var makeSizedDelim = function makeSizedDelim(delim, size, options, mode, classes) {
9463  // < and > turn into \langle and \rangle in delimiters
9464  if (delim === "<" || delim === "\\lt" || delim === "\u27e8") {
9465    delim = "\\langle";
9466  } else if (delim === ">" || delim === "\\gt" || delim === "\u27e9") {
9467    delim = "\\rangle";
9468  } // Sized delimiters are never centered.
9469
9470
9471  if (utils.contains(stackLargeDelimiters, delim) || utils.contains(stackNeverDelimiters, delim)) {
9472    return makeLargeDelim(delim, size, false, options, mode, classes);
9473  } else if (utils.contains(stackAlwaysDelimiters, delim)) {
9474    return makeStackedDelim(delim, sizeToMaxHeight[size], false, options, mode, classes);
9475  } else {
9476    throw new ParseError("Illegal delimiter: '" + delim + "'");
9477  }
9478};
9479/**
9480 * There are three different sequences of delimiter sizes that the delimiters
9481 * follow depending on the kind of delimiter. This is used when creating custom
9482 * sized delimiters to decide whether to create a small, large, or stacked
9483 * delimiter.
9484 *
9485 * In real TeX, these sequences aren't explicitly defined, but are instead
9486 * defined inside the font metrics. Since there are only three sequences that
9487 * are possible for the delimiters that TeX defines, it is easier to just encode
9488 * them explicitly here.
9489 */
9490
9491
9492// Delimiters that never stack try small delimiters and large delimiters only
9493var stackNeverDelimiterSequence = [{
9494  type: "small",
9495  style: Style$1.SCRIPTSCRIPT
9496}, {
9497  type: "small",
9498  style: Style$1.SCRIPT
9499}, {
9500  type: "small",
9501  style: Style$1.TEXT
9502}, {
9503  type: "large",
9504  size: 1
9505}, {
9506  type: "large",
9507  size: 2
9508}, {
9509  type: "large",
9510  size: 3
9511}, {
9512  type: "large",
9513  size: 4
9514}]; // Delimiters that always stack try the small delimiters first, then stack
9515
9516var stackAlwaysDelimiterSequence = [{
9517  type: "small",
9518  style: Style$1.SCRIPTSCRIPT
9519}, {
9520  type: "small",
9521  style: Style$1.SCRIPT
9522}, {
9523  type: "small",
9524  style: Style$1.TEXT
9525}, {
9526  type: "stack"
9527}]; // Delimiters that stack when large try the small and then large delimiters, and
9528// stack afterwards
9529
9530var stackLargeDelimiterSequence = [{
9531  type: "small",
9532  style: Style$1.SCRIPTSCRIPT
9533}, {
9534  type: "small",
9535  style: Style$1.SCRIPT
9536}, {
9537  type: "small",
9538  style: Style$1.TEXT
9539}, {
9540  type: "large",
9541  size: 1
9542}, {
9543  type: "large",
9544  size: 2
9545}, {
9546  type: "large",
9547  size: 3
9548}, {
9549  type: "large",
9550  size: 4
9551}, {
9552  type: "stack"
9553}];
9554/**
9555 * Get the font used in a delimiter based on what kind of delimiter it is.
9556 * TODO(#963) Use more specific font family return type once that is introduced.
9557 */
9558
9559var delimTypeToFont = function delimTypeToFont(type) {
9560  if (type.type === "small") {
9561    return "Main-Regular";
9562  } else if (type.type === "large") {
9563    return "Size" + type.size + "-Regular";
9564  } else if (type.type === "stack") {
9565    return "Size4-Regular";
9566  } else {
9567    throw new Error("Add support for delim type '" + type.type + "' here.");
9568  }
9569};
9570/**
9571 * Traverse a sequence of types of delimiters to decide what kind of delimiter
9572 * should be used to create a delimiter of the given height+depth.
9573 */
9574
9575
9576var traverseSequence = function traverseSequence(delim, height, sequence, options) {
9577  // Here, we choose the index we should start at in the sequences. In smaller
9578  // sizes (which correspond to larger numbers in style.size) we start earlier
9579  // in the sequence. Thus, scriptscript starts at index 3-3=0, script starts
9580  // at index 3-2=1, text starts at 3-1=2, and display starts at min(2,3-0)=2
9581  var start = Math.min(2, 3 - options.style.size);
9582
9583  for (var i = start; i < sequence.length; i++) {
9584    if (sequence[i].type === "stack") {
9585      // This is always the last delimiter, so we just break the loop now.
9586      break;
9587    }
9588
9589    var metrics = getMetrics(delim, delimTypeToFont(sequence[i]), "math");
9590    var heightDepth = metrics.height + metrics.depth; // Small delimiters are scaled down versions of the same font, so we
9591    // account for the style change size.
9592
9593    if (sequence[i].type === "small") {
9594      var newOptions = options.havingBaseStyle(sequence[i].style);
9595      heightDepth *= newOptions.sizeMultiplier;
9596    } // Check if the delimiter at this size works for the given height.
9597
9598
9599    if (heightDepth > height) {
9600      return sequence[i];
9601    }
9602  } // If we reached the end of the sequence, return the last sequence element.
9603
9604
9605  return sequence[sequence.length - 1];
9606};
9607/**
9608 * Make a delimiter of a given height+depth, with optional centering. Here, we
9609 * traverse the sequences, and create a delimiter that the sequence tells us to.
9610 */
9611
9612
9613var makeCustomSizedDelim = function makeCustomSizedDelim(delim, height, center, options, mode, classes) {
9614  if (delim === "<" || delim === "\\lt" || delim === "\u27e8") {
9615    delim = "\\langle";
9616  } else if (delim === ">" || delim === "\\gt" || delim === "\u27e9") {
9617    delim = "\\rangle";
9618  } // Decide what sequence to use
9619
9620
9621  var sequence;
9622
9623  if (utils.contains(stackNeverDelimiters, delim)) {
9624    sequence = stackNeverDelimiterSequence;
9625  } else if (utils.contains(stackLargeDelimiters, delim)) {
9626    sequence = stackLargeDelimiterSequence;
9627  } else {
9628    sequence = stackAlwaysDelimiterSequence;
9629  } // Look through the sequence
9630
9631
9632  var delimType = traverseSequence(delim, height, sequence, options); // Get the delimiter from font glyphs.
9633  // Depending on the sequence element we decided on, call the
9634  // appropriate function.
9635
9636  if (delimType.type === "small") {
9637    return makeSmallDelim(delim, delimType.style, center, options, mode, classes);
9638  } else if (delimType.type === "large") {
9639    return makeLargeDelim(delim, delimType.size, center, options, mode, classes);
9640  } else
9641    /* if (delimType.type === "stack") */
9642    {
9643      return makeStackedDelim(delim, height, center, options, mode, classes);
9644    }
9645};
9646/**
9647 * Make a delimiter for use with `\left` and `\right`, given a height and depth
9648 * of an expression that the delimiters surround.
9649 */
9650
9651
9652var makeLeftRightDelim = function makeLeftRightDelim(delim, height, depth, options, mode, classes) {
9653  // We always center \left/\right delimiters, so the axis is always shifted
9654  var axisHeight = options.fontMetrics().axisHeight * options.sizeMultiplier; // Taken from TeX source, tex.web, function make_left_right
9655
9656  var delimiterFactor = 901;
9657  var delimiterExtend = 5.0 / options.fontMetrics().ptPerEm;
9658  var maxDistFromAxis = Math.max(height - axisHeight, depth + axisHeight);
9659  var totalHeight = Math.max( // In real TeX, calculations are done using integral values which are
9660  // 65536 per pt, or 655360 per em. So, the division here truncates in
9661  // TeX but doesn't here, producing different results. If we wanted to
9662  // exactly match TeX's calculation, we could do
9663  //   Math.floor(655360 * maxDistFromAxis / 500) *
9664  //    delimiterFactor / 655360
9665  // (To see the difference, compare
9666  //    x^{x^{\left(\rule{0.1em}{0.68em}\right)}}
9667  // in TeX and KaTeX)
9668  maxDistFromAxis / 500 * delimiterFactor, 2 * maxDistFromAxis - delimiterExtend); // Finally, we defer to `makeCustomSizedDelim` with our calculated total
9669  // height
9670
9671  return makeCustomSizedDelim(delim, totalHeight, true, options, mode, classes);
9672};
9673
9674var delimiter = {
9675  sqrtImage: makeSqrtImage,
9676  sizedDelim: makeSizedDelim,
9677  sizeToMaxHeight: sizeToMaxHeight,
9678  customSizedDelim: makeCustomSizedDelim,
9679  leftRightDelim: makeLeftRightDelim
9680};
9681
9682// Extra data needed for the delimiter handler down below
9683var delimiterSizes = {
9684  "\\bigl": {
9685    mclass: "mopen",
9686    size: 1
9687  },
9688  "\\Bigl": {
9689    mclass: "mopen",
9690    size: 2
9691  },
9692  "\\biggl": {
9693    mclass: "mopen",
9694    size: 3
9695  },
9696  "\\Biggl": {
9697    mclass: "mopen",
9698    size: 4
9699  },
9700  "\\bigr": {
9701    mclass: "mclose",
9702    size: 1
9703  },
9704  "\\Bigr": {
9705    mclass: "mclose",
9706    size: 2
9707  },
9708  "\\biggr": {
9709    mclass: "mclose",
9710    size: 3
9711  },
9712  "\\Biggr": {
9713    mclass: "mclose",
9714    size: 4
9715  },
9716  "\\bigm": {
9717    mclass: "mrel",
9718    size: 1
9719  },
9720  "\\Bigm": {
9721    mclass: "mrel",
9722    size: 2
9723  },
9724  "\\biggm": {
9725    mclass: "mrel",
9726    size: 3
9727  },
9728  "\\Biggm": {
9729    mclass: "mrel",
9730    size: 4
9731  },
9732  "\\big": {
9733    mclass: "mord",
9734    size: 1
9735  },
9736  "\\Big": {
9737    mclass: "mord",
9738    size: 2
9739  },
9740  "\\bigg": {
9741    mclass: "mord",
9742    size: 3
9743  },
9744  "\\Bigg": {
9745    mclass: "mord",
9746    size: 4
9747  }
9748};
9749var delimiters = ["(", "\\lparen", ")", "\\rparen", "[", "\\lbrack", "]", "\\rbrack", "\\{", "\\lbrace", "\\}", "\\rbrace", "\\lfloor", "\\rfloor", "\u230a", "\u230b", "\\lceil", "\\rceil", "\u2308", "\u2309", "<", ">", "\\langle", "\u27e8", "\\rangle", "\u27e9", "\\lt", "\\gt", "\\lvert", "\\rvert", "\\lVert", "\\rVert", "\\lgroup", "\\rgroup", "\u27ee", "\u27ef", "\\lmoustache", "\\rmoustache", "\u23b0", "\u23b1", "/", "\\backslash", "|", "\\vert", "\\|", "\\Vert", "\\uparrow", "\\Uparrow", "\\downarrow", "\\Downarrow", "\\updownarrow", "\\Updownarrow", "."];
9750
9751// Delimiter functions
9752function checkDelimiter(delim, context) {
9753  var symDelim = checkSymbolNodeType(delim);
9754
9755  if (symDelim && utils.contains(delimiters, symDelim.text)) {
9756    return symDelim;
9757  } else if (symDelim) {
9758    throw new ParseError("Invalid delimiter '" + symDelim.text + "' after '" + context.funcName + "'", delim);
9759  } else {
9760    throw new ParseError("Invalid delimiter type '" + delim.type + "'", delim);
9761  }
9762}
9763
9764defineFunction({
9765  type: "delimsizing",
9766  names: ["\\bigl", "\\Bigl", "\\biggl", "\\Biggl", "\\bigr", "\\Bigr", "\\biggr", "\\Biggr", "\\bigm", "\\Bigm", "\\biggm", "\\Biggm", "\\big", "\\Big", "\\bigg", "\\Bigg"],
9767  props: {
9768    numArgs: 1,
9769    argTypes: ["primitive"]
9770  },
9771  handler: (context, args) => {
9772    var delim = checkDelimiter(args[0], context);
9773    return {
9774      type: "delimsizing",
9775      mode: context.parser.mode,
9776      size: delimiterSizes[context.funcName].size,
9777      mclass: delimiterSizes[context.funcName].mclass,
9778      delim: delim.text
9779    };
9780  },
9781  htmlBuilder: (group, options) => {
9782    if (group.delim === ".") {
9783      // Empty delimiters still count as elements, even though they don't
9784      // show anything.
9785      return buildCommon.makeSpan([group.mclass]);
9786    } // Use delimiter.sizedDelim to generate the delimiter.
9787
9788
9789    return delimiter.sizedDelim(group.delim, group.size, options, group.mode, [group.mclass]);
9790  },
9791  mathmlBuilder: group => {
9792    var children = [];
9793
9794    if (group.delim !== ".") {
9795      children.push(makeText(group.delim, group.mode));
9796    }
9797
9798    var node = new mathMLTree.MathNode("mo", children);
9799
9800    if (group.mclass === "mopen" || group.mclass === "mclose") {
9801      // Only some of the delimsizing functions act as fences, and they
9802      // return "mopen" or "mclose" mclass.
9803      node.setAttribute("fence", "true");
9804    } else {
9805      // Explicitly disable fencing if it's not a fence, to override the
9806      // defaults.
9807      node.setAttribute("fence", "false");
9808    }
9809
9810    node.setAttribute("stretchy", "true");
9811    var size = makeEm(delimiter.sizeToMaxHeight[group.size]);
9812    node.setAttribute("minsize", size);
9813    node.setAttribute("maxsize", size);
9814    return node;
9815  }
9816});
9817
9818function assertParsed(group) {
9819  if (!group.body) {
9820    throw new Error("Bug: The leftright ParseNode wasn't fully parsed.");
9821  }
9822}
9823
9824defineFunction({
9825  type: "leftright-right",
9826  names: ["\\right"],
9827  props: {
9828    numArgs: 1,
9829    primitive: true
9830  },
9831  handler: (context, args) => {
9832    // \left case below triggers parsing of \right in
9833    //   `const right = parser.parseFunction();`
9834    // uses this return value.
9835    var color = context.parser.gullet.macros.get("\\current@color");
9836
9837    if (color && typeof color !== "string") {
9838      throw new ParseError("\\current@color set to non-string in \\right");
9839    }
9840
9841    return {
9842      type: "leftright-right",
9843      mode: context.parser.mode,
9844      delim: checkDelimiter(args[0], context).text,
9845      color // undefined if not set via \color
9846
9847    };
9848  }
9849});
9850defineFunction({
9851  type: "leftright",
9852  names: ["\\left"],
9853  props: {
9854    numArgs: 1,
9855    primitive: true
9856  },
9857  handler: (context, args) => {
9858    var delim = checkDelimiter(args[0], context);
9859    var parser = context.parser; // Parse out the implicit body
9860
9861    ++parser.leftrightDepth; // parseExpression stops before '\\right'
9862
9863    var body = parser.parseExpression(false);
9864    --parser.leftrightDepth; // Check the next token
9865
9866    parser.expect("\\right", false);
9867    var right = assertNodeType(parser.parseFunction(), "leftright-right");
9868    return {
9869      type: "leftright",
9870      mode: parser.mode,
9871      body,
9872      left: delim.text,
9873      right: right.delim,
9874      rightColor: right.color
9875    };
9876  },
9877  htmlBuilder: (group, options) => {
9878    assertParsed(group); // Build the inner expression
9879
9880    var inner = buildExpression$1(group.body, options, true, ["mopen", "mclose"]);
9881    var innerHeight = 0;
9882    var innerDepth = 0;
9883    var hadMiddle = false; // Calculate its height and depth
9884
9885    for (var i = 0; i < inner.length; i++) {
9886      // Property `isMiddle` not defined on `span`. See comment in
9887      // "middle"'s htmlBuilder.
9888      // $FlowFixMe
9889      if (inner[i].isMiddle) {
9890        hadMiddle = true;
9891      } else {
9892        innerHeight = Math.max(inner[i].height, innerHeight);
9893        innerDepth = Math.max(inner[i].depth, innerDepth);
9894      }
9895    } // The size of delimiters is the same, regardless of what style we are
9896    // in. Thus, to correctly calculate the size of delimiter we need around
9897    // a group, we scale down the inner size based on the size.
9898
9899
9900    innerHeight *= options.sizeMultiplier;
9901    innerDepth *= options.sizeMultiplier;
9902    var leftDelim;
9903
9904    if (group.left === ".") {
9905      // Empty delimiters in \left and \right make null delimiter spaces.
9906      leftDelim = makeNullDelimiter(options, ["mopen"]);
9907    } else {
9908      // Otherwise, use leftRightDelim to generate the correct sized
9909      // delimiter.
9910      leftDelim = delimiter.leftRightDelim(group.left, innerHeight, innerDepth, options, group.mode, ["mopen"]);
9911    } // Add it to the beginning of the expression
9912
9913
9914    inner.unshift(leftDelim); // Handle middle delimiters
9915
9916    if (hadMiddle) {
9917      for (var _i = 1; _i < inner.length; _i++) {
9918        var middleDelim = inner[_i]; // Property `isMiddle` not defined on `span`. See comment in
9919        // "middle"'s htmlBuilder.
9920        // $FlowFixMe
9921
9922        var isMiddle = middleDelim.isMiddle;
9923
9924        if (isMiddle) {
9925          // Apply the options that were active when \middle was called
9926          inner[_i] = delimiter.leftRightDelim(isMiddle.delim, innerHeight, innerDepth, isMiddle.options, group.mode, []);
9927        }
9928      }
9929    }
9930
9931    var rightDelim; // Same for the right delimiter, but using color specified by \color
9932
9933    if (group.right === ".") {
9934      rightDelim = makeNullDelimiter(options, ["mclose"]);
9935    } else {
9936      var colorOptions = group.rightColor ? options.withColor(group.rightColor) : options;
9937      rightDelim = delimiter.leftRightDelim(group.right, innerHeight, innerDepth, colorOptions, group.mode, ["mclose"]);
9938    } // Add it to the end of the expression.
9939
9940
9941    inner.push(rightDelim);
9942    return buildCommon.makeSpan(["minner"], inner, options);
9943  },
9944  mathmlBuilder: (group, options) => {
9945    assertParsed(group);
9946    var inner = buildExpression(group.body, options);
9947
9948    if (group.left !== ".") {
9949      var leftNode = new mathMLTree.MathNode("mo", [makeText(group.left, group.mode)]);
9950      leftNode.setAttribute("fence", "true");
9951      inner.unshift(leftNode);
9952    }
9953
9954    if (group.right !== ".") {
9955      var rightNode = new mathMLTree.MathNode("mo", [makeText(group.right, group.mode)]);
9956      rightNode.setAttribute("fence", "true");
9957
9958      if (group.rightColor) {
9959        rightNode.setAttribute("mathcolor", group.rightColor);
9960      }
9961
9962      inner.push(rightNode);
9963    }
9964
9965    return makeRow(inner);
9966  }
9967});
9968defineFunction({
9969  type: "middle",
9970  names: ["\\middle"],
9971  props: {
9972    numArgs: 1,
9973    primitive: true
9974  },
9975  handler: (context, args) => {
9976    var delim = checkDelimiter(args[0], context);
9977
9978    if (!context.parser.leftrightDepth) {
9979      throw new ParseError("\\middle without preceding \\left", delim);
9980    }
9981
9982    return {
9983      type: "middle",
9984      mode: context.parser.mode,
9985      delim: delim.text
9986    };
9987  },
9988  htmlBuilder: (group, options) => {
9989    var middleDelim;
9990
9991    if (group.delim === ".") {
9992      middleDelim = makeNullDelimiter(options, []);
9993    } else {
9994      middleDelim = delimiter.sizedDelim(group.delim, 1, options, group.mode, []);
9995      var isMiddle = {
9996        delim: group.delim,
9997        options
9998      }; // Property `isMiddle` not defined on `span`. It is only used in
9999      // this file above.
10000      // TODO: Fix this violation of the `span` type and possibly rename
10001      // things since `isMiddle` sounds like a boolean, but is a struct.
10002      // $FlowFixMe
10003
10004      middleDelim.isMiddle = isMiddle;
10005    }
10006
10007    return middleDelim;
10008  },
10009  mathmlBuilder: (group, options) => {
10010    // A Firefox \middle will stretch a character vertically only if it
10011    // is in the fence part of the operator dictionary at:
10012    // https://www.w3.org/TR/MathML3/appendixc.html.
10013    // So we need to avoid U+2223 and use plain "|" instead.
10014    var textNode = group.delim === "\\vert" || group.delim === "|" ? makeText("|", "text") : makeText(group.delim, group.mode);
10015    var middleNode = new mathMLTree.MathNode("mo", [textNode]);
10016    middleNode.setAttribute("fence", "true"); // MathML gives 5/18em spacing to each <mo> element.
10017    // \middle should get delimiter spacing instead.
10018
10019    middleNode.setAttribute("lspace", "0.05em");
10020    middleNode.setAttribute("rspace", "0.05em");
10021    return middleNode;
10022  }
10023});
10024
10025var htmlBuilder$7 = (group, options) => {
10026  // \cancel, \bcancel, \xcancel, \sout, \fbox, \colorbox, \fcolorbox, \phase
10027  // Some groups can return document fragments.  Handle those by wrapping
10028  // them in a span.
10029  var inner = buildCommon.wrapFragment(buildGroup$1(group.body, options), options);
10030  var label = group.label.slice(1);
10031  var scale = options.sizeMultiplier;
10032  var img;
10033  var imgShift = 0; // In the LaTeX cancel package, line geometry is slightly different
10034  // depending on whether the subject is wider than it is tall, or vice versa.
10035  // We don't know the width of a group, so as a proxy, we test if
10036  // the subject is a single character. This captures most of the
10037  // subjects that should get the "tall" treatment.
10038
10039  var isSingleChar = utils.isCharacterBox(group.body);
10040
10041  if (label === "sout") {
10042    img = buildCommon.makeSpan(["stretchy", "sout"]);
10043    img.height = options.fontMetrics().defaultRuleThickness / scale;
10044    imgShift = -0.5 * options.fontMetrics().xHeight;
10045  } else if (label === "phase") {
10046    // Set a couple of dimensions from the steinmetz package.
10047    var lineWeight = calculateSize({
10048      number: 0.6,
10049      unit: "pt"
10050    }, options);
10051    var clearance = calculateSize({
10052      number: 0.35,
10053      unit: "ex"
10054    }, options); // Prevent size changes like \Huge from affecting line thickness
10055
10056    var newOptions = options.havingBaseSizing();
10057    scale = scale / newOptions.sizeMultiplier;
10058    var angleHeight = inner.height + inner.depth + lineWeight + clearance; // Reserve a left pad for the angle.
10059
10060    inner.style.paddingLeft = makeEm(angleHeight / 2 + lineWeight); // Create an SVG
10061
10062    var viewBoxHeight = Math.floor(1000 * angleHeight * scale);
10063    var path = phasePath(viewBoxHeight);
10064    var svgNode = new SvgNode([new PathNode("phase", path)], {
10065      "width": "400em",
10066      "height": makeEm(viewBoxHeight / 1000),
10067      "viewBox": "0 0 400000 " + viewBoxHeight,
10068      "preserveAspectRatio": "xMinYMin slice"
10069    }); // Wrap it in a span with overflow: hidden.
10070
10071    img = buildCommon.makeSvgSpan(["hide-tail"], [svgNode], options);
10072    img.style.height = makeEm(angleHeight);
10073    imgShift = inner.depth + lineWeight + clearance;
10074  } else {
10075    // Add horizontal padding
10076    if (/cancel/.test(label)) {
10077      if (!isSingleChar) {
10078        inner.classes.push("cancel-pad");
10079      }
10080    } else if (label === "angl") {
10081      inner.classes.push("anglpad");
10082    } else {
10083      inner.classes.push("boxpad");
10084    } // Add vertical padding
10085
10086
10087    var topPad = 0;
10088    var bottomPad = 0;
10089    var ruleThickness = 0; // ref: cancel package: \advance\totalheight2\p@ % "+2"
10090
10091    if (/box/.test(label)) {
10092      ruleThickness = Math.max(options.fontMetrics().fboxrule, // default
10093      options.minRuleThickness // User override.
10094      );
10095      topPad = options.fontMetrics().fboxsep + (label === "colorbox" ? 0 : ruleThickness);
10096      bottomPad = topPad;
10097    } else if (label === "angl") {
10098      ruleThickness = Math.max(options.fontMetrics().defaultRuleThickness, options.minRuleThickness);
10099      topPad = 4 * ruleThickness; // gap = 3 × line, plus the line itself.
10100
10101      bottomPad = Math.max(0, 0.25 - inner.depth);
10102    } else {
10103      topPad = isSingleChar ? 0.2 : 0;
10104      bottomPad = topPad;
10105    }
10106
10107    img = stretchy.encloseSpan(inner, label, topPad, bottomPad, options);
10108
10109    if (/fbox|boxed|fcolorbox/.test(label)) {
10110      img.style.borderStyle = "solid";
10111      img.style.borderWidth = makeEm(ruleThickness);
10112    } else if (label === "angl" && ruleThickness !== 0.049) {
10113      img.style.borderTopWidth = makeEm(ruleThickness);
10114      img.style.borderRightWidth = makeEm(ruleThickness);
10115    }
10116
10117    imgShift = inner.depth + bottomPad;
10118
10119    if (group.backgroundColor) {
10120      img.style.backgroundColor = group.backgroundColor;
10121
10122      if (group.borderColor) {
10123        img.style.borderColor = group.borderColor;
10124      }
10125    }
10126  }
10127
10128  var vlist;
10129
10130  if (group.backgroundColor) {
10131    vlist = buildCommon.makeVList({
10132      positionType: "individualShift",
10133      children: [// Put the color background behind inner;
10134      {
10135        type: "elem",
10136        elem: img,
10137        shift: imgShift
10138      }, {
10139        type: "elem",
10140        elem: inner,
10141        shift: 0
10142      }]
10143    }, options);
10144  } else {
10145    var classes = /cancel|phase/.test(label) ? ["svg-align"] : [];
10146    vlist = buildCommon.makeVList({
10147      positionType: "individualShift",
10148      children: [// Write the \cancel stroke on top of inner.
10149      {
10150        type: "elem",
10151        elem: inner,
10152        shift: 0
10153      }, {
10154        type: "elem",
10155        elem: img,
10156        shift: imgShift,
10157        wrapperClasses: classes
10158      }]
10159    }, options);
10160  }
10161
10162  if (/cancel/.test(label)) {
10163    // The cancel package documentation says that cancel lines add their height
10164    // to the expression, but tests show that isn't how it actually works.
10165    vlist.height = inner.height;
10166    vlist.depth = inner.depth;
10167  }
10168
10169  if (/cancel/.test(label) && !isSingleChar) {
10170    // cancel does not create horiz space for its line extension.
10171    return buildCommon.makeSpan(["mord", "cancel-lap"], [vlist], options);
10172  } else {
10173    return buildCommon.makeSpan(["mord"], [vlist], options);
10174  }
10175};
10176
10177var mathmlBuilder$6 = (group, options) => {
10178  var fboxsep = 0;
10179  var node = new mathMLTree.MathNode(group.label.indexOf("colorbox") > -1 ? "mpadded" : "menclose", [buildGroup(group.body, options)]);
10180
10181  switch (group.label) {
10182    case "\\cancel":
10183      node.setAttribute("notation", "updiagonalstrike");
10184      break;
10185
10186    case "\\bcancel":
10187      node.setAttribute("notation", "downdiagonalstrike");
10188      break;
10189
10190    case "\\phase":
10191      node.setAttribute("notation", "phasorangle");
10192      break;
10193
10194    case "\\sout":
10195      node.setAttribute("notation", "horizontalstrike");
10196      break;
10197
10198    case "\\fbox":
10199      node.setAttribute("notation", "box");
10200      break;
10201
10202    case "\\angl":
10203      node.setAttribute("notation", "actuarial");
10204      break;
10205
10206    case "\\fcolorbox":
10207    case "\\colorbox":
10208      // <menclose> doesn't have a good notation option. So use <mpadded>
10209      // instead. Set some attributes that come included with <menclose>.
10210      fboxsep = options.fontMetrics().fboxsep * options.fontMetrics().ptPerEm;
10211      node.setAttribute("width", "+" + 2 * fboxsep + "pt");
10212      node.setAttribute("height", "+" + 2 * fboxsep + "pt");
10213      node.setAttribute("lspace", fboxsep + "pt"); //
10214
10215      node.setAttribute("voffset", fboxsep + "pt");
10216
10217      if (group.label === "\\fcolorbox") {
10218        var thk = Math.max(options.fontMetrics().fboxrule, // default
10219        options.minRuleThickness // user override
10220        );
10221        node.setAttribute("style", "border: " + thk + "em solid " + String(group.borderColor));
10222      }
10223
10224      break;
10225
10226    case "\\xcancel":
10227      node.setAttribute("notation", "updiagonalstrike downdiagonalstrike");
10228      break;
10229  }
10230
10231  if (group.backgroundColor) {
10232    node.setAttribute("mathbackground", group.backgroundColor);
10233  }
10234
10235  return node;
10236};
10237
10238defineFunction({
10239  type: "enclose",
10240  names: ["\\colorbox"],
10241  props: {
10242    numArgs: 2,
10243    allowedInText: true,
10244    argTypes: ["color", "text"]
10245  },
10246
10247  handler(_ref, args, optArgs) {
10248    var {
10249      parser,
10250      funcName
10251    } = _ref;
10252    var color = assertNodeType(args[0], "color-token").color;
10253    var body = args[1];
10254    return {
10255      type: "enclose",
10256      mode: parser.mode,
10257      label: funcName,
10258      backgroundColor: color,
10259      body
10260    };
10261  },
10262
10263  htmlBuilder: htmlBuilder$7,
10264  mathmlBuilder: mathmlBuilder$6
10265});
10266defineFunction({
10267  type: "enclose",
10268  names: ["\\fcolorbox"],
10269  props: {
10270    numArgs: 3,
10271    allowedInText: true,
10272    argTypes: ["color", "color", "text"]
10273  },
10274
10275  handler(_ref2, args, optArgs) {
10276    var {
10277      parser,
10278      funcName
10279    } = _ref2;
10280    var borderColor = assertNodeType(args[0], "color-token").color;
10281    var backgroundColor = assertNodeType(args[1], "color-token").color;
10282    var body = args[2];
10283    return {
10284      type: "enclose",
10285      mode: parser.mode,
10286      label: funcName,
10287      backgroundColor,
10288      borderColor,
10289      body
10290    };
10291  },
10292
10293  htmlBuilder: htmlBuilder$7,
10294  mathmlBuilder: mathmlBuilder$6
10295});
10296defineFunction({
10297  type: "enclose",
10298  names: ["\\fbox"],
10299  props: {
10300    numArgs: 1,
10301    argTypes: ["hbox"],
10302    allowedInText: true
10303  },
10304
10305  handler(_ref3, args) {
10306    var {
10307      parser
10308    } = _ref3;
10309    return {
10310      type: "enclose",
10311      mode: parser.mode,
10312      label: "\\fbox",
10313      body: args[0]
10314    };
10315  }
10316
10317});
10318defineFunction({
10319  type: "enclose",
10320  names: ["\\cancel", "\\bcancel", "\\xcancel", "\\sout", "\\phase"],
10321  props: {
10322    numArgs: 1
10323  },
10324
10325  handler(_ref4, args) {
10326    var {
10327      parser,
10328      funcName
10329    } = _ref4;
10330    var body = args[0];
10331    return {
10332      type: "enclose",
10333      mode: parser.mode,
10334      label: funcName,
10335      body
10336    };
10337  },
10338
10339  htmlBuilder: htmlBuilder$7,
10340  mathmlBuilder: mathmlBuilder$6
10341});
10342defineFunction({
10343  type: "enclose",
10344  names: ["\\angl"],
10345  props: {
10346    numArgs: 1,
10347    argTypes: ["hbox"],
10348    allowedInText: false
10349  },
10350
10351  handler(_ref5, args) {
10352    var {
10353      parser
10354    } = _ref5;
10355    return {
10356      type: "enclose",
10357      mode: parser.mode,
10358      label: "\\angl",
10359      body: args[0]
10360    };
10361  }
10362
10363});
10364
10365/**
10366 * All registered environments.
10367 * `environments.js` exports this same dictionary again and makes it public.
10368 * `Parser.js` requires this dictionary via `environments.js`.
10369 */
10370var _environments = {};
10371function defineEnvironment(_ref) {
10372  var {
10373    type,
10374    names,
10375    props,
10376    handler,
10377    htmlBuilder,
10378    mathmlBuilder
10379  } = _ref;
10380  // Set default values of environments.
10381  var data = {
10382    type,
10383    numArgs: props.numArgs || 0,
10384    allowedInText: false,
10385    numOptionalArgs: 0,
10386    handler
10387  };
10388
10389  for (var i = 0; i < names.length; ++i) {
10390    // TODO: The value type of _environments should be a type union of all
10391    // possible `EnvSpec<>` possibilities instead of `EnvSpec<*>`, which is
10392    // an existential type.
10393    _environments[names[i]] = data;
10394  }
10395
10396  if (htmlBuilder) {
10397    _htmlGroupBuilders[type] = htmlBuilder;
10398  }
10399
10400  if (mathmlBuilder) {
10401    _mathmlGroupBuilders[type] = mathmlBuilder;
10402  }
10403}
10404
10405/**
10406 * All registered global/built-in macros.
10407 * `macros.js` exports this same dictionary again and makes it public.
10408 * `Parser.js` requires this dictionary via `macros.js`.
10409 */
10410var _macros = {}; // This function might one day accept an additional argument and do more things.
10411
10412function defineMacro(name, body) {
10413  _macros[name] = body;
10414}
10415
10416// Helper functions
10417function getHLines(parser) {
10418  // Return an array. The array length = number of hlines.
10419  // Each element in the array tells if the line is dashed.
10420  var hlineInfo = [];
10421  parser.consumeSpaces();
10422  var nxt = parser.fetch().text;
10423
10424  if (nxt === "\\relax") {
10425    // \relax is an artifact of the \cr macro below
10426    parser.consume();
10427    parser.consumeSpaces();
10428    nxt = parser.fetch().text;
10429  }
10430
10431  while (nxt === "\\hline" || nxt === "\\hdashline") {
10432    parser.consume();
10433    hlineInfo.push(nxt === "\\hdashline");
10434    parser.consumeSpaces();
10435    nxt = parser.fetch().text;
10436  }
10437
10438  return hlineInfo;
10439}
10440
10441var validateAmsEnvironmentContext = context => {
10442  var settings = context.parser.settings;
10443
10444  if (!settings.displayMode) {
10445    throw new ParseError("{" + context.envName + "} can be used only in" + " display mode.");
10446  }
10447}; // autoTag (an argument to parseArray) can be one of three values:
10448// * undefined: Regular (not-top-level) array; no tags on each row
10449// * true: Automatic equation numbering, overridable by \tag
10450// * false: Tags allowed on each row, but no automatic numbering
10451// This function *doesn't* work with the "split" environment name.
10452
10453
10454function getAutoTag(name) {
10455  if (name.indexOf("ed") === -1) {
10456    return name.indexOf("*") === -1;
10457  } // return undefined;
10458
10459}
10460/**
10461 * Parse the body of the environment, with rows delimited by \\ and
10462 * columns delimited by &, and create a nested list in row-major order
10463 * with one group per cell.  If given an optional argument style
10464 * ("text", "display", etc.), then each cell is cast into that style.
10465 */
10466
10467
10468function parseArray(parser, _ref, style) {
10469  var {
10470    hskipBeforeAndAfter,
10471    addJot,
10472    cols,
10473    arraystretch,
10474    colSeparationType,
10475    autoTag,
10476    singleRow,
10477    emptySingleRow,
10478    maxNumCols,
10479    leqno
10480  } = _ref;
10481  parser.gullet.beginGroup();
10482
10483  if (!singleRow) {
10484    // \cr is equivalent to \\ without the optional size argument (see below)
10485    // TODO: provide helpful error when \cr is used outside array environment
10486    parser.gullet.macros.set("\\cr", "\\\\\\relax");
10487  } // Get current arraystretch if it's not set by the environment
10488
10489
10490  if (!arraystretch) {
10491    var stretch = parser.gullet.expandMacroAsText("\\arraystretch");
10492
10493    if (stretch == null) {
10494      // Default \arraystretch from lttab.dtx
10495      arraystretch = 1;
10496    } else {
10497      arraystretch = parseFloat(stretch);
10498
10499      if (!arraystretch || arraystretch < 0) {
10500        throw new ParseError("Invalid \\arraystretch: " + stretch);
10501      }
10502    }
10503  } // Start group for first cell
10504
10505
10506  parser.gullet.beginGroup();
10507  var row = [];
10508  var body = [row];
10509  var rowGaps = [];
10510  var hLinesBeforeRow = [];
10511  var tags = autoTag != null ? [] : undefined; // amsmath uses \global\@eqnswtrue and \global\@eqnswfalse to represent
10512  // whether this row should have an equation number.  Simulate this with
10513  // a \@eqnsw macro set to 1 or 0.
10514
10515  function beginRow() {
10516    if (autoTag) {
10517      parser.gullet.macros.set("\\@eqnsw", "1", true);
10518    }
10519  }
10520
10521  function endRow() {
10522    if (tags) {
10523      if (parser.gullet.macros.get("\\df@tag")) {
10524        tags.push(parser.subparse([new Token("\\df@tag")]));
10525        parser.gullet.macros.set("\\df@tag", undefined, true);
10526      } else {
10527        tags.push(Boolean(autoTag) && parser.gullet.macros.get("\\@eqnsw") === "1");
10528      }
10529    }
10530  }
10531
10532  beginRow(); // Test for \hline at the top of the array.
10533
10534  hLinesBeforeRow.push(getHLines(parser));
10535
10536  while (true) {
10537    // eslint-disable-line no-constant-condition
10538    // Parse each cell in its own group (namespace)
10539    var cell = parser.parseExpression(false, singleRow ? "\\end" : "\\\\");
10540    parser.gullet.endGroup();
10541    parser.gullet.beginGroup();
10542    cell = {
10543      type: "ordgroup",
10544      mode: parser.mode,
10545      body: cell
10546    };
10547
10548    if (style) {
10549      cell = {
10550        type: "styling",
10551        mode: parser.mode,
10552        style,
10553        body: [cell]
10554      };
10555    }
10556
10557    row.push(cell);
10558    var next = parser.fetch().text;
10559
10560    if (next === "&") {
10561      if (maxNumCols && row.length === maxNumCols) {
10562        if (singleRow || colSeparationType) {
10563          // {equation} or {split}
10564          throw new ParseError("Too many tab characters: &", parser.nextToken);
10565        } else {
10566          // {array} environment
10567          parser.settings.reportNonstrict("textEnv", "Too few columns " + "specified in the {array} column argument.");
10568        }
10569      }
10570
10571      parser.consume();
10572    } else if (next === "\\end") {
10573      endRow(); // Arrays terminate newlines with `\crcr` which consumes a `\cr` if
10574      // the last line is empty.  However, AMS environments keep the
10575      // empty row if it's the only one.
10576      // NOTE: Currently, `cell` is the last item added into `row`.
10577
10578      if (row.length === 1 && cell.type === "styling" && cell.body[0].body.length === 0 && (body.length > 1 || !emptySingleRow)) {
10579        body.pop();
10580      }
10581
10582      if (hLinesBeforeRow.length < body.length + 1) {
10583        hLinesBeforeRow.push([]);
10584      }
10585
10586      break;
10587    } else if (next === "\\\\") {
10588      parser.consume();
10589      var size = void 0; // \def\Let@{\let\\\math@cr}
10590      // \def\math@cr{...\math@cr@}
10591      // \def\math@cr@{\new@ifnextchar[\math@cr@@{\math@cr@@[\z@]}}
10592      // \def\math@cr@@[#1]{...\math@cr@@@...}
10593      // \def\math@cr@@@{\cr}
10594
10595      if (parser.gullet.future().text !== " ") {
10596        size = parser.parseSizeGroup(true);
10597      }
10598
10599      rowGaps.push(size ? size.value : null);
10600      endRow(); // check for \hline(s) following the row separator
10601
10602      hLinesBeforeRow.push(getHLines(parser));
10603      row = [];
10604      body.push(row);
10605      beginRow();
10606    } else {
10607      throw new ParseError("Expected & or \\\\ or \\cr or \\end", parser.nextToken);
10608    }
10609  } // End cell group
10610
10611
10612  parser.gullet.endGroup(); // End array group defining \cr
10613
10614  parser.gullet.endGroup();
10615  return {
10616    type: "array",
10617    mode: parser.mode,
10618    addJot,
10619    arraystretch,
10620    body,
10621    cols,
10622    rowGaps,
10623    hskipBeforeAndAfter,
10624    hLinesBeforeRow,
10625    colSeparationType,
10626    tags,
10627    leqno
10628  };
10629} // Decides on a style for cells in an array according to whether the given
10630// environment name starts with the letter 'd'.
10631
10632
10633function dCellStyle(envName) {
10634  if (envName.slice(0, 1) === "d") {
10635    return "display";
10636  } else {
10637    return "text";
10638  }
10639}
10640
10641var htmlBuilder$6 = function htmlBuilder(group, options) {
10642  var r;
10643  var c;
10644  var nr = group.body.length;
10645  var hLinesBeforeRow = group.hLinesBeforeRow;
10646  var nc = 0;
10647  var body = new Array(nr);
10648  var hlines = [];
10649  var ruleThickness = Math.max( // From LaTeX \showthe\arrayrulewidth. Equals 0.04 em.
10650  options.fontMetrics().arrayRuleWidth, options.minRuleThickness // User override.
10651  ); // Horizontal spacing
10652
10653  var pt = 1 / options.fontMetrics().ptPerEm;
10654  var arraycolsep = 5 * pt; // default value, i.e. \arraycolsep in article.cls
10655
10656  if (group.colSeparationType && group.colSeparationType === "small") {
10657    // We're in a {smallmatrix}. Default column space is \thickspace,
10658    // i.e. 5/18em = 0.2778em, per amsmath.dtx for {smallmatrix}.
10659    // But that needs adjustment because LaTeX applies \scriptstyle to the
10660    // entire array, including the colspace, but this function applies
10661    // \scriptstyle only inside each element.
10662    var localMultiplier = options.havingStyle(Style$1.SCRIPT).sizeMultiplier;
10663    arraycolsep = 0.2778 * (localMultiplier / options.sizeMultiplier);
10664  } // Vertical spacing
10665
10666
10667  var baselineskip = group.colSeparationType === "CD" ? calculateSize({
10668    number: 3,
10669    unit: "ex"
10670  }, options) : 12 * pt; // see size10.clo
10671  // Default \jot from ltmath.dtx
10672  // TODO(edemaine): allow overriding \jot via \setlength (#687)
10673
10674  var jot = 3 * pt;
10675  var arrayskip = group.arraystretch * baselineskip;
10676  var arstrutHeight = 0.7 * arrayskip; // \strutbox in ltfsstrc.dtx and
10677
10678  var arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx
10679
10680  var totalHeight = 0; // Set a position for \hline(s) at the top of the array, if any.
10681
10682  function setHLinePos(hlinesInGap) {
10683    for (var i = 0; i < hlinesInGap.length; ++i) {
10684      if (i > 0) {
10685        totalHeight += 0.25;
10686      }
10687
10688      hlines.push({
10689        pos: totalHeight,
10690        isDashed: hlinesInGap[i]
10691      });
10692    }
10693  }
10694
10695  setHLinePos(hLinesBeforeRow[0]);
10696
10697  for (r = 0; r < group.body.length; ++r) {
10698    var inrow = group.body[r];
10699    var height = arstrutHeight; // \@array adds an \@arstrut
10700
10701    var depth = arstrutDepth; // to each tow (via the template)
10702
10703    if (nc < inrow.length) {
10704      nc = inrow.length;
10705    }
10706
10707    var outrow = new Array(inrow.length);
10708
10709    for (c = 0; c < inrow.length; ++c) {
10710      var elt = buildGroup$1(inrow[c], options);
10711
10712      if (depth < elt.depth) {
10713        depth = elt.depth;
10714      }
10715
10716      if (height < elt.height) {
10717        height = elt.height;
10718      }
10719
10720      outrow[c] = elt;
10721    }
10722
10723    var rowGap = group.rowGaps[r];
10724    var gap = 0;
10725
10726    if (rowGap) {
10727      gap = calculateSize(rowGap, options);
10728
10729      if (gap > 0) {
10730        // \@argarraycr
10731        gap += arstrutDepth;
10732
10733        if (depth < gap) {
10734          depth = gap; // \@xargarraycr
10735        }
10736
10737        gap = 0;
10738      }
10739    } // In AMS multiline environments such as aligned and gathered, rows
10740    // correspond to lines that have additional \jot added to the
10741    // \baselineskip via \openup.
10742
10743
10744    if (group.addJot) {
10745      depth += jot;
10746    }
10747
10748    outrow.height = height;
10749    outrow.depth = depth;
10750    totalHeight += height;
10751    outrow.pos = totalHeight;
10752    totalHeight += depth + gap; // \@yargarraycr
10753
10754    body[r] = outrow; // Set a position for \hline(s), if any.
10755
10756    setHLinePos(hLinesBeforeRow[r + 1]);
10757  }
10758
10759  var offset = totalHeight / 2 + options.fontMetrics().axisHeight;
10760  var colDescriptions = group.cols || [];
10761  var cols = [];
10762  var colSep;
10763  var colDescrNum;
10764  var tagSpans = [];
10765
10766  if (group.tags && group.tags.some(tag => tag)) {
10767    // An environment with manual tags and/or automatic equation numbers.
10768    // Create node(s), the latter of which trigger CSS counter increment.
10769    for (r = 0; r < nr; ++r) {
10770      var rw = body[r];
10771      var shift = rw.pos - offset;
10772      var tag = group.tags[r];
10773      var tagSpan = void 0;
10774
10775      if (tag === true) {
10776        // automatic numbering
10777        tagSpan = buildCommon.makeSpan(["eqn-num"], [], options);
10778      } else if (tag === false) {
10779        // \nonumber/\notag or starred environment
10780        tagSpan = buildCommon.makeSpan([], [], options);
10781      } else {
10782        // manual \tag
10783        tagSpan = buildCommon.makeSpan([], buildExpression$1(tag, options, true), options);
10784      }
10785
10786      tagSpan.depth = rw.depth;
10787      tagSpan.height = rw.height;
10788      tagSpans.push({
10789        type: "elem",
10790        elem: tagSpan,
10791        shift
10792      });
10793    }
10794  }
10795
10796  for (c = 0, colDescrNum = 0; // Continue while either there are more columns or more column
10797  // descriptions, so trailing separators don't get lost.
10798  c < nc || colDescrNum < colDescriptions.length; ++c, ++colDescrNum) {
10799    var colDescr = colDescriptions[colDescrNum] || {};
10800    var firstSeparator = true;
10801
10802    while (colDescr.type === "separator") {
10803      // If there is more than one separator in a row, add a space
10804      // between them.
10805      if (!firstSeparator) {
10806        colSep = buildCommon.makeSpan(["arraycolsep"], []);
10807        colSep.style.width = makeEm(options.fontMetrics().doubleRuleSep);
10808        cols.push(colSep);
10809      }
10810
10811      if (colDescr.separator === "|" || colDescr.separator === ":") {
10812        var lineType = colDescr.separator === "|" ? "solid" : "dashed";
10813        var separator = buildCommon.makeSpan(["vertical-separator"], [], options);
10814        separator.style.height = makeEm(totalHeight);
10815        separator.style.borderRightWidth = makeEm(ruleThickness);
10816        separator.style.borderRightStyle = lineType;
10817        separator.style.margin = "0 " + makeEm(-ruleThickness / 2);
10818
10819        var _shift = totalHeight - offset;
10820
10821        if (_shift) {
10822          separator.style.verticalAlign = makeEm(-_shift);
10823        }
10824
10825        cols.push(separator);
10826      } else {
10827        throw new ParseError("Invalid separator type: " + colDescr.separator);
10828      }
10829
10830      colDescrNum++;
10831      colDescr = colDescriptions[colDescrNum] || {};
10832      firstSeparator = false;
10833    }
10834
10835    if (c >= nc) {
10836      continue;
10837    }
10838
10839    var sepwidth = void 0;
10840
10841    if (c > 0 || group.hskipBeforeAndAfter) {
10842      sepwidth = utils.deflt(colDescr.pregap, arraycolsep);
10843
10844      if (sepwidth !== 0) {
10845        colSep = buildCommon.makeSpan(["arraycolsep"], []);
10846        colSep.style.width = makeEm(sepwidth);
10847        cols.push(colSep);
10848      }
10849    }
10850
10851    var col = [];
10852
10853    for (r = 0; r < nr; ++r) {
10854      var row = body[r];
10855      var elem = row[c];
10856
10857      if (!elem) {
10858        continue;
10859      }
10860
10861      var _shift2 = row.pos - offset;
10862
10863      elem.depth = row.depth;
10864      elem.height = row.height;
10865      col.push({
10866        type: "elem",
10867        elem: elem,
10868        shift: _shift2
10869      });
10870    }
10871
10872    col = buildCommon.makeVList({
10873      positionType: "individualShift",
10874      children: col
10875    }, options);
10876    col = buildCommon.makeSpan(["col-align-" + (colDescr.align || "c")], [col]);
10877    cols.push(col);
10878
10879    if (c < nc - 1 || group.hskipBeforeAndAfter) {
10880      sepwidth = utils.deflt(colDescr.postgap, arraycolsep);
10881
10882      if (sepwidth !== 0) {
10883        colSep = buildCommon.makeSpan(["arraycolsep"], []);
10884        colSep.style.width = makeEm(sepwidth);
10885        cols.push(colSep);
10886      }
10887    }
10888  }
10889
10890  body = buildCommon.makeSpan(["mtable"], cols); // Add \hline(s), if any.
10891
10892  if (hlines.length > 0) {
10893    var line = buildCommon.makeLineSpan("hline", options, ruleThickness);
10894    var dashes = buildCommon.makeLineSpan("hdashline", options, ruleThickness);
10895    var vListElems = [{
10896      type: "elem",
10897      elem: body,
10898      shift: 0
10899    }];
10900
10901    while (hlines.length > 0) {
10902      var hline = hlines.pop();
10903      var lineShift = hline.pos - offset;
10904
10905      if (hline.isDashed) {
10906        vListElems.push({
10907          type: "elem",
10908          elem: dashes,
10909          shift: lineShift
10910        });
10911      } else {
10912        vListElems.push({
10913          type: "elem",
10914          elem: line,
10915          shift: lineShift
10916        });
10917      }
10918    }
10919
10920    body = buildCommon.makeVList({
10921      positionType: "individualShift",
10922      children: vListElems
10923    }, options);
10924  }
10925
10926  if (tagSpans.length === 0) {
10927    return buildCommon.makeSpan(["mord"], [body], options);
10928  } else {
10929    var eqnNumCol = buildCommon.makeVList({
10930      positionType: "individualShift",
10931      children: tagSpans
10932    }, options);
10933    eqnNumCol = buildCommon.makeSpan(["tag"], [eqnNumCol], options);
10934    return buildCommon.makeFragment([body, eqnNumCol]);
10935  }
10936};
10937
10938var alignMap = {
10939  c: "center ",
10940  l: "left ",
10941  r: "right "
10942};
10943
10944var mathmlBuilder$5 = function mathmlBuilder(group, options) {
10945  var tbl = [];
10946  var glue = new mathMLTree.MathNode("mtd", [], ["mtr-glue"]);
10947  var tag = new mathMLTree.MathNode("mtd", [], ["mml-eqn-num"]);
10948
10949  for (var i = 0; i < group.body.length; i++) {
10950    var rw = group.body[i];
10951    var row = [];
10952
10953    for (var j = 0; j < rw.length; j++) {
10954      row.push(new mathMLTree.MathNode("mtd", [buildGroup(rw[j], options)]));
10955    }
10956
10957    if (group.tags && group.tags[i]) {
10958      row.unshift(glue);
10959      row.push(glue);
10960
10961      if (group.leqno) {
10962        row.unshift(tag);
10963      } else {
10964        row.push(tag);
10965      }
10966    }
10967
10968    tbl.push(new mathMLTree.MathNode("mtr", row));
10969  }
10970
10971  var table = new mathMLTree.MathNode("mtable", tbl); // Set column alignment, row spacing, column spacing, and
10972  // array lines by setting attributes on the table element.
10973  // Set the row spacing. In MathML, we specify a gap distance.
10974  // We do not use rowGap[] because MathML automatically increases
10975  // cell height with the height/depth of the element content.
10976  // LaTeX \arraystretch multiplies the row baseline-to-baseline distance.
10977  // We simulate this by adding (arraystretch - 1)em to the gap. This
10978  // does a reasonable job of adjusting arrays containing 1 em tall content.
10979  // The 0.16 and 0.09 values are found empirically. They produce an array
10980  // similar to LaTeX and in which content does not interfere with \hlines.
10981
10982  var gap = group.arraystretch === 0.5 ? 0.1 // {smallmatrix}, {subarray}
10983  : 0.16 + group.arraystretch - 1 + (group.addJot ? 0.09 : 0);
10984  table.setAttribute("rowspacing", makeEm(gap)); // MathML table lines go only between cells.
10985  // To place a line on an edge we'll use <menclose>, if necessary.
10986
10987  var menclose = "";
10988  var align = "";
10989
10990  if (group.cols && group.cols.length > 0) {
10991    // Find column alignment, column spacing, and  vertical lines.
10992    var cols = group.cols;
10993    var columnLines = "";
10994    var prevTypeWasAlign = false;
10995    var iStart = 0;
10996    var iEnd = cols.length;
10997
10998    if (cols[0].type === "separator") {
10999      menclose += "top ";
11000      iStart = 1;
11001    }
11002
11003    if (cols[cols.length - 1].type === "separator") {
11004      menclose += "bottom ";
11005      iEnd -= 1;
11006    }
11007
11008    for (var _i = iStart; _i < iEnd; _i++) {
11009      if (cols[_i].type === "align") {
11010        align += alignMap[cols[_i].align];
11011
11012        if (prevTypeWasAlign) {
11013          columnLines += "none ";
11014        }
11015
11016        prevTypeWasAlign = true;
11017      } else if (cols[_i].type === "separator") {
11018        // MathML accepts only single lines between cells.
11019        // So we read only the first of consecutive separators.
11020        if (prevTypeWasAlign) {
11021          columnLines += cols[_i].separator === "|" ? "solid " : "dashed ";
11022          prevTypeWasAlign = false;
11023        }
11024      }
11025    }
11026
11027    table.setAttribute("columnalign", align.trim());
11028
11029    if (/[sd]/.test(columnLines)) {
11030      table.setAttribute("columnlines", columnLines.trim());
11031    }
11032  } // Set column spacing.
11033
11034
11035  if (group.colSeparationType === "align") {
11036    var _cols = group.cols || [];
11037
11038    var spacing = "";
11039
11040    for (var _i2 = 1; _i2 < _cols.length; _i2++) {
11041      spacing += _i2 % 2 ? "0em " : "1em ";
11042    }
11043
11044    table.setAttribute("columnspacing", spacing.trim());
11045  } else if (group.colSeparationType === "alignat" || group.colSeparationType === "gather") {
11046    table.setAttribute("columnspacing", "0em");
11047  } else if (group.colSeparationType === "small") {
11048    table.setAttribute("columnspacing", "0.2778em");
11049  } else if (group.colSeparationType === "CD") {
11050    table.setAttribute("columnspacing", "0.5em");
11051  } else {
11052    table.setAttribute("columnspacing", "1em");
11053  } // Address \hline and \hdashline
11054
11055
11056  var rowLines = "";
11057  var hlines = group.hLinesBeforeRow;
11058  menclose += hlines[0].length > 0 ? "left " : "";
11059  menclose += hlines[hlines.length - 1].length > 0 ? "right " : "";
11060
11061  for (var _i3 = 1; _i3 < hlines.length - 1; _i3++) {
11062    rowLines += hlines[_i3].length === 0 ? "none " // MathML accepts only a single line between rows. Read one element.
11063    : hlines[_i3][0] ? "dashed " : "solid ";
11064  }
11065
11066  if (/[sd]/.test(rowLines)) {
11067    table.setAttribute("rowlines", rowLines.trim());
11068  }
11069
11070  if (menclose !== "") {
11071    table = new mathMLTree.MathNode("menclose", [table]);
11072    table.setAttribute("notation", menclose.trim());
11073  }
11074
11075  if (group.arraystretch && group.arraystretch < 1) {
11076    // A small array. Wrap in scriptstyle so row gap is not too large.
11077    table = new mathMLTree.MathNode("mstyle", [table]);
11078    table.setAttribute("scriptlevel", "1");
11079  }
11080
11081  return table;
11082}; // Convenience function for align, align*, aligned, alignat, alignat*, alignedat.
11083
11084
11085var alignedHandler = function alignedHandler(context, args) {
11086  if (context.envName.indexOf("ed") === -1) {
11087    validateAmsEnvironmentContext(context);
11088  }
11089
11090  var cols = [];
11091  var separationType = context.envName.indexOf("at") > -1 ? "alignat" : "align";
11092  var isSplit = context.envName === "split";
11093  var res = parseArray(context.parser, {
11094    cols,
11095    addJot: true,
11096    autoTag: isSplit ? undefined : getAutoTag(context.envName),
11097    emptySingleRow: true,
11098    colSeparationType: separationType,
11099    maxNumCols: isSplit ? 2 : undefined,
11100    leqno: context.parser.settings.leqno
11101  }, "display"); // Determining number of columns.
11102  // 1. If the first argument is given, we use it as a number of columns,
11103  //    and makes sure that each row doesn't exceed that number.
11104  // 2. Otherwise, just count number of columns = maximum number
11105  //    of cells in each row ("aligned" mode -- isAligned will be true).
11106  //
11107  // At the same time, prepend empty group {} at beginning of every second
11108  // cell in each row (starting with second cell) so that operators become
11109  // binary.  This behavior is implemented in amsmath's \start@aligned.
11110
11111  var numMaths;
11112  var numCols = 0;
11113  var emptyGroup = {
11114    type: "ordgroup",
11115    mode: context.mode,
11116    body: []
11117  };
11118
11119  if (args[0] && args[0].type === "ordgroup") {
11120    var arg0 = "";
11121
11122    for (var i = 0; i < args[0].body.length; i++) {
11123      var textord = assertNodeType(args[0].body[i], "textord");
11124      arg0 += textord.text;
11125    }
11126
11127    numMaths = Number(arg0);
11128    numCols = numMaths * 2;
11129  }
11130
11131  var isAligned = !numCols;
11132  res.body.forEach(function (row) {
11133    for (var _i4 = 1; _i4 < row.length; _i4 += 2) {
11134      // Modify ordgroup node within styling node
11135      var styling = assertNodeType(row[_i4], "styling");
11136      var ordgroup = assertNodeType(styling.body[0], "ordgroup");
11137      ordgroup.body.unshift(emptyGroup);
11138    }
11139
11140    if (!isAligned) {
11141      // Case 1
11142      var curMaths = row.length / 2;
11143
11144      if (numMaths < curMaths) {
11145        throw new ParseError("Too many math in a row: " + ("expected " + numMaths + ", but got " + curMaths), row[0]);
11146      }
11147    } else if (numCols < row.length) {
11148      // Case 2
11149      numCols = row.length;
11150    }
11151  }); // Adjusting alignment.
11152  // In aligned mode, we add one \qquad between columns;
11153  // otherwise we add nothing.
11154
11155  for (var _i5 = 0; _i5 < numCols; ++_i5) {
11156    var align = "r";
11157    var pregap = 0;
11158
11159    if (_i5 % 2 === 1) {
11160      align = "l";
11161    } else if (_i5 > 0 && isAligned) {
11162      // "aligned" mode.
11163      pregap = 1; // add one \quad
11164    }
11165
11166    cols[_i5] = {
11167      type: "align",
11168      align: align,
11169      pregap: pregap,
11170      postgap: 0
11171    };
11172  }
11173
11174  res.colSeparationType = isAligned ? "align" : "alignat";
11175  return res;
11176}; // Arrays are part of LaTeX, defined in lttab.dtx so its documentation
11177// is part of the source2e.pdf file of LaTeX2e source documentation.
11178// {darray} is an {array} environment where cells are set in \displaystyle,
11179// as defined in nccmath.sty.
11180
11181
11182defineEnvironment({
11183  type: "array",
11184  names: ["array", "darray"],
11185  props: {
11186    numArgs: 1
11187  },
11188
11189  handler(context, args) {
11190    // Since no types are specified above, the two possibilities are
11191    // - The argument is wrapped in {} or [], in which case Parser's
11192    //   parseGroup() returns an "ordgroup" wrapping some symbol node.
11193    // - The argument is a bare symbol node.
11194    var symNode = checkSymbolNodeType(args[0]);
11195    var colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body;
11196    var cols = colalign.map(function (nde) {
11197      var node = assertSymbolNodeType(nde);
11198      var ca = node.text;
11199
11200      if ("lcr".indexOf(ca) !== -1) {
11201        return {
11202          type: "align",
11203          align: ca
11204        };
11205      } else if (ca === "|") {
11206        return {
11207          type: "separator",
11208          separator: "|"
11209        };
11210      } else if (ca === ":") {
11211        return {
11212          type: "separator",
11213          separator: ":"
11214        };
11215      }
11216
11217      throw new ParseError("Unknown column alignment: " + ca, nde);
11218    });
11219    var res = {
11220      cols,
11221      hskipBeforeAndAfter: true,
11222      // \@preamble in lttab.dtx
11223      maxNumCols: cols.length
11224    };
11225    return parseArray(context.parser, res, dCellStyle(context.envName));
11226  },
11227
11228  htmlBuilder: htmlBuilder$6,
11229  mathmlBuilder: mathmlBuilder$5
11230}); // The matrix environments of amsmath builds on the array environment
11231// of LaTeX, which is discussed above.
11232// The mathtools package adds starred versions of the same environments.
11233// These have an optional argument to choose left|center|right justification.
11234
11235defineEnvironment({
11236  type: "array",
11237  names: ["matrix", "pmatrix", "bmatrix", "Bmatrix", "vmatrix", "Vmatrix", "matrix*", "pmatrix*", "bmatrix*", "Bmatrix*", "vmatrix*", "Vmatrix*"],
11238  props: {
11239    numArgs: 0
11240  },
11241
11242  handler(context) {
11243    var delimiters = {
11244      "matrix": null,
11245      "pmatrix": ["(", ")"],
11246      "bmatrix": ["[", "]"],
11247      "Bmatrix": ["\\{", "\\}"],
11248      "vmatrix": ["|", "|"],
11249      "Vmatrix": ["\\Vert", "\\Vert"]
11250    }[context.envName.replace("*", "")]; // \hskip -\arraycolsep in amsmath
11251
11252    var colAlign = "c";
11253    var payload = {
11254      hskipBeforeAndAfter: false,
11255      cols: [{
11256        type: "align",
11257        align: colAlign
11258      }]
11259    };
11260
11261    if (context.envName.charAt(context.envName.length - 1) === "*") {
11262      // It's one of the mathtools starred functions.
11263      // Parse the optional alignment argument.
11264      var parser = context.parser;
11265      parser.consumeSpaces();
11266
11267      if (parser.fetch().text === "[") {
11268        parser.consume();
11269        parser.consumeSpaces();
11270        colAlign = parser.fetch().text;
11271
11272        if ("lcr".indexOf(colAlign) === -1) {
11273          throw new ParseError("Expected l or c or r", parser.nextToken);
11274        }
11275
11276        parser.consume();
11277        parser.consumeSpaces();
11278        parser.expect("]");
11279        parser.consume();
11280        payload.cols = [{
11281          type: "align",
11282          align: colAlign
11283        }];
11284      }
11285    }
11286
11287    var res = parseArray(context.parser, payload, dCellStyle(context.envName)); // Populate cols with the correct number of column alignment specs.
11288
11289    var numCols = Math.max(0, ...res.body.map(row => row.length));
11290    res.cols = new Array(numCols).fill({
11291      type: "align",
11292      align: colAlign
11293    });
11294    return delimiters ? {
11295      type: "leftright",
11296      mode: context.mode,
11297      body: [res],
11298      left: delimiters[0],
11299      right: delimiters[1],
11300      rightColor: undefined // \right uninfluenced by \color in array
11301
11302    } : res;
11303  },
11304
11305  htmlBuilder: htmlBuilder$6,
11306  mathmlBuilder: mathmlBuilder$5
11307});
11308defineEnvironment({
11309  type: "array",
11310  names: ["smallmatrix"],
11311  props: {
11312    numArgs: 0
11313  },
11314
11315  handler(context) {
11316    var payload = {
11317      arraystretch: 0.5
11318    };
11319    var res = parseArray(context.parser, payload, "script");
11320    res.colSeparationType = "small";
11321    return res;
11322  },
11323
11324  htmlBuilder: htmlBuilder$6,
11325  mathmlBuilder: mathmlBuilder$5
11326});
11327defineEnvironment({
11328  type: "array",
11329  names: ["subarray"],
11330  props: {
11331    numArgs: 1
11332  },
11333
11334  handler(context, args) {
11335    // Parsing of {subarray} is similar to {array}
11336    var symNode = checkSymbolNodeType(args[0]);
11337    var colalign = symNode ? [args[0]] : assertNodeType(args[0], "ordgroup").body;
11338    var cols = colalign.map(function (nde) {
11339      var node = assertSymbolNodeType(nde);
11340      var ca = node.text; // {subarray} only recognizes "l" & "c"
11341
11342      if ("lc".indexOf(ca) !== -1) {
11343        return {
11344          type: "align",
11345          align: ca
11346        };
11347      }
11348
11349      throw new ParseError("Unknown column alignment: " + ca, nde);
11350    });
11351
11352    if (cols.length > 1) {
11353      throw new ParseError("{subarray} can contain only one column");
11354    }
11355
11356    var res = {
11357      cols,
11358      hskipBeforeAndAfter: false,
11359      arraystretch: 0.5
11360    };
11361    res = parseArray(context.parser, res, "script");
11362
11363    if (res.body.length > 0 && res.body[0].length > 1) {
11364      throw new ParseError("{subarray} can contain only one column");
11365    }
11366
11367    return res;
11368  },
11369
11370  htmlBuilder: htmlBuilder$6,
11371  mathmlBuilder: mathmlBuilder$5
11372}); // A cases environment (in amsmath.sty) is almost equivalent to
11373// \def\arraystretch{1.2}%
11374// \left\{\begin{array}{@{}l@{\quad}l@{}} … \end{array}\right.
11375// {dcases} is a {cases} environment where cells are set in \displaystyle,
11376// as defined in mathtools.sty.
11377// {rcases} is another mathtools environment. It's brace is on the right side.
11378
11379defineEnvironment({
11380  type: "array",
11381  names: ["cases", "dcases", "rcases", "drcases"],
11382  props: {
11383    numArgs: 0
11384  },
11385
11386  handler(context) {
11387    var payload = {
11388      arraystretch: 1.2,
11389      cols: [{
11390        type: "align",
11391        align: "l",
11392        pregap: 0,
11393        // TODO(kevinb) get the current style.
11394        // For now we use the metrics for TEXT style which is what we were
11395        // doing before.  Before attempting to get the current style we
11396        // should look at TeX's behavior especially for \over and matrices.
11397        postgap: 1.0
11398        /* 1em quad */
11399
11400      }, {
11401        type: "align",
11402        align: "l",
11403        pregap: 0,
11404        postgap: 0
11405      }]
11406    };
11407    var res = parseArray(context.parser, payload, dCellStyle(context.envName));
11408    return {
11409      type: "leftright",
11410      mode: context.mode,
11411      body: [res],
11412      left: context.envName.indexOf("r") > -1 ? "." : "\\{",
11413      right: context.envName.indexOf("r") > -1 ? "\\}" : ".",
11414      rightColor: undefined
11415    };
11416  },
11417
11418  htmlBuilder: htmlBuilder$6,
11419  mathmlBuilder: mathmlBuilder$5
11420}); // In the align environment, one uses ampersands, &, to specify number of
11421// columns in each row, and to locate spacing between each column.
11422// align gets automatic numbering. align* and aligned do not.
11423// The alignedat environment can be used in math mode.
11424// Note that we assume \nomallineskiplimit to be zero,
11425// so that \strut@ is the same as \strut.
11426
11427defineEnvironment({
11428  type: "array",
11429  names: ["align", "align*", "aligned", "split"],
11430  props: {
11431    numArgs: 0
11432  },
11433  handler: alignedHandler,
11434  htmlBuilder: htmlBuilder$6,
11435  mathmlBuilder: mathmlBuilder$5
11436}); // A gathered environment is like an array environment with one centered
11437// column, but where rows are considered lines so get \jot line spacing
11438// and contents are set in \displaystyle.
11439
11440defineEnvironment({
11441  type: "array",
11442  names: ["gathered", "gather", "gather*"],
11443  props: {
11444    numArgs: 0
11445  },
11446
11447  handler(context) {
11448    if (utils.contains(["gather", "gather*"], context.envName)) {
11449      validateAmsEnvironmentContext(context);
11450    }
11451
11452    var res = {
11453      cols: [{
11454        type: "align",
11455        align: "c"
11456      }],
11457      addJot: true,
11458      colSeparationType: "gather",
11459      autoTag: getAutoTag(context.envName),
11460      emptySingleRow: true,
11461      leqno: context.parser.settings.leqno
11462    };
11463    return parseArray(context.parser, res, "display");
11464  },
11465
11466  htmlBuilder: htmlBuilder$6,
11467  mathmlBuilder: mathmlBuilder$5
11468}); // alignat environment is like an align environment, but one must explicitly
11469// specify maximum number of columns in each row, and can adjust spacing between
11470// each columns.
11471
11472defineEnvironment({
11473  type: "array",
11474  names: ["alignat", "alignat*", "alignedat"],
11475  props: {
11476    numArgs: 1
11477  },
11478  handler: alignedHandler,
11479  htmlBuilder: htmlBuilder$6,
11480  mathmlBuilder: mathmlBuilder$5
11481});
11482defineEnvironment({
11483  type: "array",
11484  names: ["equation", "equation*"],
11485  props: {
11486    numArgs: 0
11487  },
11488
11489  handler(context) {
11490    validateAmsEnvironmentContext(context);
11491    var res = {
11492      autoTag: getAutoTag(context.envName),
11493      emptySingleRow: true,
11494      singleRow: true,
11495      maxNumCols: 1,
11496      leqno: context.parser.settings.leqno
11497    };
11498    return parseArray(context.parser, res, "display");
11499  },
11500
11501  htmlBuilder: htmlBuilder$6,
11502  mathmlBuilder: mathmlBuilder$5
11503});
11504defineEnvironment({
11505  type: "array",
11506  names: ["CD"],
11507  props: {
11508    numArgs: 0
11509  },
11510
11511  handler(context) {
11512    validateAmsEnvironmentContext(context);
11513    return parseCD(context.parser);
11514  },
11515
11516  htmlBuilder: htmlBuilder$6,
11517  mathmlBuilder: mathmlBuilder$5
11518});
11519defineMacro("\\nonumber", "\\gdef\\@eqnsw{0}");
11520defineMacro("\\notag", "\\nonumber"); // Catch \hline outside array environment
11521
11522defineFunction({
11523  type: "text",
11524  // Doesn't matter what this is.
11525  names: ["\\hline", "\\hdashline"],
11526  props: {
11527    numArgs: 0,
11528    allowedInText: true,
11529    allowedInMath: true
11530  },
11531
11532  handler(context, args) {
11533    throw new ParseError(context.funcName + " valid only within array environment");
11534  }
11535
11536});
11537
11538var environments = _environments;
11539
11540// defineEnvironment definitions.
11541
11542defineFunction({
11543  type: "environment",
11544  names: ["\\begin", "\\end"],
11545  props: {
11546    numArgs: 1,
11547    argTypes: ["text"]
11548  },
11549
11550  handler(_ref, args) {
11551    var {
11552      parser,
11553      funcName
11554    } = _ref;
11555    var nameGroup = args[0];
11556
11557    if (nameGroup.type !== "ordgroup") {
11558      throw new ParseError("Invalid environment name", nameGroup);
11559    }
11560
11561    var envName = "";
11562
11563    for (var i = 0; i < nameGroup.body.length; ++i) {
11564      envName += assertNodeType(nameGroup.body[i], "textord").text;
11565    }
11566
11567    if (funcName === "\\begin") {
11568      // begin...end is similar to left...right
11569      if (!environments.hasOwnProperty(envName)) {
11570        throw new ParseError("No such environment: " + envName, nameGroup);
11571      } // Build the environment object. Arguments and other information will
11572      // be made available to the begin and end methods using properties.
11573
11574
11575      var env = environments[envName];
11576      var {
11577        args: _args,
11578        optArgs
11579      } = parser.parseArguments("\\begin{" + envName + "}", env);
11580      var context = {
11581        mode: parser.mode,
11582        envName,
11583        parser
11584      };
11585      var result = env.handler(context, _args, optArgs);
11586      parser.expect("\\end", false);
11587      var endNameToken = parser.nextToken;
11588      var end = assertNodeType(parser.parseFunction(), "environment");
11589
11590      if (end.name !== envName) {
11591        throw new ParseError("Mismatch: \\begin{" + envName + "} matched by \\end{" + end.name + "}", endNameToken);
11592      } // $FlowFixMe, "environment" handler returns an environment ParseNode
11593
11594
11595      return result;
11596    }
11597
11598    return {
11599      type: "environment",
11600      mode: parser.mode,
11601      name: envName,
11602      nameGroup
11603    };
11604  }
11605
11606});
11607
11608// TODO(kevinb): implement \\sl and \\sc
11609
11610var htmlBuilder$5 = (group, options) => {
11611  var font = group.font;
11612  var newOptions = options.withFont(font);
11613  return buildGroup$1(group.body, newOptions);
11614};
11615
11616var mathmlBuilder$4 = (group, options) => {
11617  var font = group.font;
11618  var newOptions = options.withFont(font);
11619  return buildGroup(group.body, newOptions);
11620};
11621
11622var fontAliases = {
11623  "\\Bbb": "\\mathbb",
11624  "\\bold": "\\mathbf",
11625  "\\frak": "\\mathfrak",
11626  "\\bm": "\\boldsymbol"
11627};
11628defineFunction({
11629  type: "font",
11630  names: [// styles, except \boldsymbol defined below
11631  "\\mathrm", "\\mathit", "\\mathbf", "\\mathnormal", "\\mathsfit", // families
11632  "\\mathbb", "\\mathcal", "\\mathfrak", "\\mathscr", "\\mathsf", "\\mathtt", // aliases, except \bm defined below
11633  "\\Bbb", "\\bold", "\\frak"],
11634  props: {
11635    numArgs: 1,
11636    allowedInArgument: true
11637  },
11638  handler: (_ref, args) => {
11639    var {
11640      parser,
11641      funcName
11642    } = _ref;
11643    var body = normalizeArgument(args[0]);
11644    var func = funcName;
11645
11646    if (func in fontAliases) {
11647      func = fontAliases[func];
11648    }
11649
11650    return {
11651      type: "font",
11652      mode: parser.mode,
11653      font: func.slice(1),
11654      body
11655    };
11656  },
11657  htmlBuilder: htmlBuilder$5,
11658  mathmlBuilder: mathmlBuilder$4
11659});
11660defineFunction({
11661  type: "mclass",
11662  names: ["\\boldsymbol", "\\bm"],
11663  props: {
11664    numArgs: 1
11665  },
11666  handler: (_ref2, args) => {
11667    var {
11668      parser
11669    } = _ref2;
11670    var body = args[0];
11671    var isCharacterBox = utils.isCharacterBox(body); // amsbsy.sty's \boldsymbol uses \binrel spacing to inherit the
11672    // argument's bin|rel|ord status
11673
11674    return {
11675      type: "mclass",
11676      mode: parser.mode,
11677      mclass: binrelClass(body),
11678      body: [{
11679        type: "font",
11680        mode: parser.mode,
11681        font: "boldsymbol",
11682        body
11683      }],
11684      isCharacterBox: isCharacterBox
11685    };
11686  }
11687}); // Old font changing functions
11688
11689defineFunction({
11690  type: "font",
11691  names: ["\\rm", "\\sf", "\\tt", "\\bf", "\\it", "\\cal"],
11692  props: {
11693    numArgs: 0,
11694    allowedInText: true
11695  },
11696  handler: (_ref3, args) => {
11697    var {
11698      parser,
11699      funcName,
11700      breakOnTokenText
11701    } = _ref3;
11702    var {
11703      mode
11704    } = parser;
11705    var body = parser.parseExpression(true, breakOnTokenText);
11706    var style = "math" + funcName.slice(1);
11707    return {
11708      type: "font",
11709      mode: mode,
11710      font: style,
11711      body: {
11712        type: "ordgroup",
11713        mode: parser.mode,
11714        body
11715      }
11716    };
11717  },
11718  htmlBuilder: htmlBuilder$5,
11719  mathmlBuilder: mathmlBuilder$4
11720});
11721
11722var adjustStyle = (size, originalStyle) => {
11723  // Figure out what style this fraction should be in based on the
11724  // function used
11725  var style = originalStyle;
11726
11727  if (size === "display") {
11728    // Get display style as a default.
11729    // If incoming style is sub/sup, use style.text() to get correct size.
11730    style = style.id >= Style$1.SCRIPT.id ? style.text() : Style$1.DISPLAY;
11731  } else if (size === "text" && style.size === Style$1.DISPLAY.size) {
11732    // We're in a \tfrac but incoming style is displaystyle, so:
11733    style = Style$1.TEXT;
11734  } else if (size === "script") {
11735    style = Style$1.SCRIPT;
11736  } else if (size === "scriptscript") {
11737    style = Style$1.SCRIPTSCRIPT;
11738  }
11739
11740  return style;
11741};
11742
11743var htmlBuilder$4 = (group, options) => {
11744  // Fractions are handled in the TeXbook on pages 444-445, rules 15(a-e).
11745  var style = adjustStyle(group.size, options.style);
11746  var nstyle = style.fracNum();
11747  var dstyle = style.fracDen();
11748  var newOptions;
11749  newOptions = options.havingStyle(nstyle);
11750  var numerm = buildGroup$1(group.numer, newOptions, options);
11751
11752  if (group.continued) {
11753    // \cfrac inserts a \strut into the numerator.
11754    // Get \strut dimensions from TeXbook page 353.
11755    var hStrut = 8.5 / options.fontMetrics().ptPerEm;
11756    var dStrut = 3.5 / options.fontMetrics().ptPerEm;
11757    numerm.height = numerm.height < hStrut ? hStrut : numerm.height;
11758    numerm.depth = numerm.depth < dStrut ? dStrut : numerm.depth;
11759  }
11760
11761  newOptions = options.havingStyle(dstyle);
11762  var denomm = buildGroup$1(group.denom, newOptions, options);
11763  var rule;
11764  var ruleWidth;
11765  var ruleSpacing;
11766
11767  if (group.hasBarLine) {
11768    if (group.barSize) {
11769      ruleWidth = calculateSize(group.barSize, options);
11770      rule = buildCommon.makeLineSpan("frac-line", options, ruleWidth);
11771    } else {
11772      rule = buildCommon.makeLineSpan("frac-line", options);
11773    }
11774
11775    ruleWidth = rule.height;
11776    ruleSpacing = rule.height;
11777  } else {
11778    rule = null;
11779    ruleWidth = 0;
11780    ruleSpacing = options.fontMetrics().defaultRuleThickness;
11781  } // Rule 15b
11782
11783
11784  var numShift;
11785  var clearance;
11786  var denomShift;
11787
11788  if (style.size === Style$1.DISPLAY.size || group.size === "display") {
11789    numShift = options.fontMetrics().num1;
11790
11791    if (ruleWidth > 0) {
11792      clearance = 3 * ruleSpacing;
11793    } else {
11794      clearance = 7 * ruleSpacing;
11795    }
11796
11797    denomShift = options.fontMetrics().denom1;
11798  } else {
11799    if (ruleWidth > 0) {
11800      numShift = options.fontMetrics().num2;
11801      clearance = ruleSpacing;
11802    } else {
11803      numShift = options.fontMetrics().num3;
11804      clearance = 3 * ruleSpacing;
11805    }
11806
11807    denomShift = options.fontMetrics().denom2;
11808  }
11809
11810  var frac;
11811
11812  if (!rule) {
11813    // Rule 15c
11814    var candidateClearance = numShift - numerm.depth - (denomm.height - denomShift);
11815
11816    if (candidateClearance < clearance) {
11817      numShift += 0.5 * (clearance - candidateClearance);
11818      denomShift += 0.5 * (clearance - candidateClearance);
11819    }
11820
11821    frac = buildCommon.makeVList({
11822      positionType: "individualShift",
11823      children: [{
11824        type: "elem",
11825        elem: denomm,
11826        shift: denomShift
11827      }, {
11828        type: "elem",
11829        elem: numerm,
11830        shift: -numShift
11831      }]
11832    }, options);
11833  } else {
11834    // Rule 15d
11835    var axisHeight = options.fontMetrics().axisHeight;
11836
11837    if (numShift - numerm.depth - (axisHeight + 0.5 * ruleWidth) < clearance) {
11838      numShift += clearance - (numShift - numerm.depth - (axisHeight + 0.5 * ruleWidth));
11839    }
11840
11841    if (axisHeight - 0.5 * ruleWidth - (denomm.height - denomShift) < clearance) {
11842      denomShift += clearance - (axisHeight - 0.5 * ruleWidth - (denomm.height - denomShift));
11843    }
11844
11845    var midShift = -(axisHeight - 0.5 * ruleWidth);
11846    frac = buildCommon.makeVList({
11847      positionType: "individualShift",
11848      children: [{
11849        type: "elem",
11850        elem: denomm,
11851        shift: denomShift
11852      }, {
11853        type: "elem",
11854        elem: rule,
11855        shift: midShift
11856      }, {
11857        type: "elem",
11858        elem: numerm,
11859        shift: -numShift
11860      }]
11861    }, options);
11862  } // Since we manually change the style sometimes (with \dfrac or \tfrac),
11863  // account for the possible size change here.
11864
11865
11866  newOptions = options.havingStyle(style);
11867  frac.height *= newOptions.sizeMultiplier / options.sizeMultiplier;
11868  frac.depth *= newOptions.sizeMultiplier / options.sizeMultiplier; // Rule 15e
11869
11870  var delimSize;
11871
11872  if (style.size === Style$1.DISPLAY.size) {
11873    delimSize = options.fontMetrics().delim1;
11874  } else if (style.size === Style$1.SCRIPTSCRIPT.size) {
11875    delimSize = options.havingStyle(Style$1.SCRIPT).fontMetrics().delim2;
11876  } else {
11877    delimSize = options.fontMetrics().delim2;
11878  }
11879
11880  var leftDelim;
11881  var rightDelim;
11882
11883  if (group.leftDelim == null) {
11884    leftDelim = makeNullDelimiter(options, ["mopen"]);
11885  } else {
11886    leftDelim = delimiter.customSizedDelim(group.leftDelim, delimSize, true, options.havingStyle(style), group.mode, ["mopen"]);
11887  }
11888
11889  if (group.continued) {
11890    rightDelim = buildCommon.makeSpan([]); // zero width for \cfrac
11891  } else if (group.rightDelim == null) {
11892    rightDelim = makeNullDelimiter(options, ["mclose"]);
11893  } else {
11894    rightDelim = delimiter.customSizedDelim(group.rightDelim, delimSize, true, options.havingStyle(style), group.mode, ["mclose"]);
11895  }
11896
11897  return buildCommon.makeSpan(["mord"].concat(newOptions.sizingClasses(options)), [leftDelim, buildCommon.makeSpan(["mfrac"], [frac]), rightDelim], options);
11898};
11899
11900var mathmlBuilder$3 = (group, options) => {
11901  var node = new mathMLTree.MathNode("mfrac", [buildGroup(group.numer, options), buildGroup(group.denom, options)]);
11902
11903  if (!group.hasBarLine) {
11904    node.setAttribute("linethickness", "0px");
11905  } else if (group.barSize) {
11906    var ruleWidth = calculateSize(group.barSize, options);
11907    node.setAttribute("linethickness", makeEm(ruleWidth));
11908  }
11909
11910  var style = adjustStyle(group.size, options.style);
11911
11912  if (style.size !== options.style.size) {
11913    node = new mathMLTree.MathNode("mstyle", [node]);
11914    var isDisplay = style.size === Style$1.DISPLAY.size ? "true" : "false";
11915    node.setAttribute("displaystyle", isDisplay);
11916    node.setAttribute("scriptlevel", "0");
11917  }
11918
11919  if (group.leftDelim != null || group.rightDelim != null) {
11920    var withDelims = [];
11921
11922    if (group.leftDelim != null) {
11923      var leftOp = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(group.leftDelim.replace("\\", ""))]);
11924      leftOp.setAttribute("fence", "true");
11925      withDelims.push(leftOp);
11926    }
11927
11928    withDelims.push(node);
11929
11930    if (group.rightDelim != null) {
11931      var rightOp = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode(group.rightDelim.replace("\\", ""))]);
11932      rightOp.setAttribute("fence", "true");
11933      withDelims.push(rightOp);
11934    }
11935
11936    return makeRow(withDelims);
11937  }
11938
11939  return node;
11940};
11941
11942defineFunction({
11943  type: "genfrac",
11944  names: ["\\dfrac", "\\frac", "\\tfrac", "\\dbinom", "\\binom", "\\tbinom", "\\\\atopfrac", // can’t be entered directly
11945  "\\\\bracefrac", "\\\\brackfrac" // ditto
11946  ],
11947  props: {
11948    numArgs: 2,
11949    allowedInArgument: true
11950  },
11951  handler: (_ref, args) => {
11952    var {
11953      parser,
11954      funcName
11955    } = _ref;
11956    var numer = args[0];
11957    var denom = args[1];
11958    var hasBarLine;
11959    var leftDelim = null;
11960    var rightDelim = null;
11961    var size = "auto";
11962
11963    switch (funcName) {
11964      case "\\dfrac":
11965      case "\\frac":
11966      case "\\tfrac":
11967        hasBarLine = true;
11968        break;
11969
11970      case "\\\\atopfrac":
11971        hasBarLine = false;
11972        break;
11973
11974      case "\\dbinom":
11975      case "\\binom":
11976      case "\\tbinom":
11977        hasBarLine = false;
11978        leftDelim = "(";
11979        rightDelim = ")";
11980        break;
11981
11982      case "\\\\bracefrac":
11983        hasBarLine = false;
11984        leftDelim = "\\{";
11985        rightDelim = "\\}";
11986        break;
11987
11988      case "\\\\brackfrac":
11989        hasBarLine = false;
11990        leftDelim = "[";
11991        rightDelim = "]";
11992        break;
11993
11994      default:
11995        throw new Error("Unrecognized genfrac command");
11996    }
11997
11998    switch (funcName) {
11999      case "\\dfrac":
12000      case "\\dbinom":
12001        size = "display";
12002        break;
12003
12004      case "\\tfrac":
12005      case "\\tbinom":
12006        size = "text";
12007        break;
12008    }
12009
12010    return {
12011      type: "genfrac",
12012      mode: parser.mode,
12013      continued: false,
12014      numer,
12015      denom,
12016      hasBarLine,
12017      leftDelim,
12018      rightDelim,
12019      size,
12020      barSize: null
12021    };
12022  },
12023  htmlBuilder: htmlBuilder$4,
12024  mathmlBuilder: mathmlBuilder$3
12025});
12026defineFunction({
12027  type: "genfrac",
12028  names: ["\\cfrac"],
12029  props: {
12030    numArgs: 2
12031  },
12032  handler: (_ref2, args) => {
12033    var {
12034      parser,
12035      funcName
12036    } = _ref2;
12037    var numer = args[0];
12038    var denom = args[1];
12039    return {
12040      type: "genfrac",
12041      mode: parser.mode,
12042      continued: true,
12043      numer,
12044      denom,
12045      hasBarLine: true,
12046      leftDelim: null,
12047      rightDelim: null,
12048      size: "display",
12049      barSize: null
12050    };
12051  }
12052}); // Infix generalized fractions -- these are not rendered directly, but replaced
12053// immediately by one of the variants above.
12054
12055defineFunction({
12056  type: "infix",
12057  names: ["\\over", "\\choose", "\\atop", "\\brace", "\\brack"],
12058  props: {
12059    numArgs: 0,
12060    infix: true
12061  },
12062
12063  handler(_ref3) {
12064    var {
12065      parser,
12066      funcName,
12067      token
12068    } = _ref3;
12069    var replaceWith;
12070
12071    switch (funcName) {
12072      case "\\over":
12073        replaceWith = "\\frac";
12074        break;
12075
12076      case "\\choose":
12077        replaceWith = "\\binom";
12078        break;
12079
12080      case "\\atop":
12081        replaceWith = "\\\\atopfrac";
12082        break;
12083
12084      case "\\brace":
12085        replaceWith = "\\\\bracefrac";
12086        break;
12087
12088      case "\\brack":
12089        replaceWith = "\\\\brackfrac";
12090        break;
12091
12092      default:
12093        throw new Error("Unrecognized infix genfrac command");
12094    }
12095
12096    return {
12097      type: "infix",
12098      mode: parser.mode,
12099      replaceWith,
12100      token
12101    };
12102  }
12103
12104});
12105var stylArray = ["display", "text", "script", "scriptscript"];
12106
12107var delimFromValue = function delimFromValue(delimString) {
12108  var delim = null;
12109
12110  if (delimString.length > 0) {
12111    delim = delimString;
12112    delim = delim === "." ? null : delim;
12113  }
12114
12115  return delim;
12116};
12117
12118defineFunction({
12119  type: "genfrac",
12120  names: ["\\genfrac"],
12121  props: {
12122    numArgs: 6,
12123    allowedInArgument: true,
12124    argTypes: ["math", "math", "size", "text", "math", "math"]
12125  },
12126
12127  handler(_ref4, args) {
12128    var {
12129      parser
12130    } = _ref4;
12131    var numer = args[4];
12132    var denom = args[5]; // Look into the parse nodes to get the desired delimiters.
12133
12134    var leftNode = normalizeArgument(args[0]);
12135    var leftDelim = leftNode.type === "atom" && leftNode.family === "open" ? delimFromValue(leftNode.text) : null;
12136    var rightNode = normalizeArgument(args[1]);
12137    var rightDelim = rightNode.type === "atom" && rightNode.family === "close" ? delimFromValue(rightNode.text) : null;
12138    var barNode = assertNodeType(args[2], "size");
12139    var hasBarLine;
12140    var barSize = null;
12141
12142    if (barNode.isBlank) {
12143      // \genfrac acts differently than \above.
12144      // \genfrac treats an empty size group as a signal to use a
12145      // standard bar size. \above would see size = 0 and omit the bar.
12146      hasBarLine = true;
12147    } else {
12148      barSize = barNode.value;
12149      hasBarLine = barSize.number > 0;
12150    } // Find out if we want displaystyle, textstyle, etc.
12151
12152
12153    var size = "auto";
12154    var styl = args[3];
12155
12156    if (styl.type === "ordgroup") {
12157      if (styl.body.length > 0) {
12158        var textOrd = assertNodeType(styl.body[0], "textord");
12159        size = stylArray[Number(textOrd.text)];
12160      }
12161    } else {
12162      styl = assertNodeType(styl, "textord");
12163      size = stylArray[Number(styl.text)];
12164    }
12165
12166    return {
12167      type: "genfrac",
12168      mode: parser.mode,
12169      numer,
12170      denom,
12171      continued: false,
12172      hasBarLine,
12173      barSize,
12174      leftDelim,
12175      rightDelim,
12176      size
12177    };
12178  },
12179
12180  htmlBuilder: htmlBuilder$4,
12181  mathmlBuilder: mathmlBuilder$3
12182}); // \above is an infix fraction that also defines a fraction bar size.
12183
12184defineFunction({
12185  type: "infix",
12186  names: ["\\above"],
12187  props: {
12188    numArgs: 1,
12189    argTypes: ["size"],
12190    infix: true
12191  },
12192
12193  handler(_ref5, args) {
12194    var {
12195      parser,
12196      funcName,
12197      token
12198    } = _ref5;
12199    return {
12200      type: "infix",
12201      mode: parser.mode,
12202      replaceWith: "\\\\abovefrac",
12203      size: assertNodeType(args[0], "size").value,
12204      token
12205    };
12206  }
12207
12208});
12209defineFunction({
12210  type: "genfrac",
12211  names: ["\\\\abovefrac"],
12212  props: {
12213    numArgs: 3,
12214    argTypes: ["math", "size", "math"]
12215  },
12216  handler: (_ref6, args) => {
12217    var {
12218      parser,
12219      funcName
12220    } = _ref6;
12221    var numer = args[0];
12222    var barSize = assert(assertNodeType(args[1], "infix").size);
12223    var denom = args[2];
12224    var hasBarLine = barSize.number > 0;
12225    return {
12226      type: "genfrac",
12227      mode: parser.mode,
12228      numer,
12229      denom,
12230      continued: false,
12231      hasBarLine,
12232      barSize,
12233      leftDelim: null,
12234      rightDelim: null,
12235      size: "auto"
12236    };
12237  },
12238  htmlBuilder: htmlBuilder$4,
12239  mathmlBuilder: mathmlBuilder$3
12240});
12241
12242// NOTE: Unlike most `htmlBuilder`s, this one handles not only "horizBrace", but
12243// also "supsub" since an over/underbrace can affect super/subscripting.
12244var htmlBuilder$3 = (grp, options) => {
12245  var style = options.style; // Pull out the `ParseNode<"horizBrace">` if `grp` is a "supsub" node.
12246
12247  var supSubGroup;
12248  var group;
12249
12250  if (grp.type === "supsub") {
12251    // Ref: LaTeX source2e: }}}}\limits}
12252    // i.e. LaTeX treats the brace similar to an op and passes it
12253    // with \limits, so we need to assign supsub style.
12254    supSubGroup = grp.sup ? buildGroup$1(grp.sup, options.havingStyle(style.sup()), options) : buildGroup$1(grp.sub, options.havingStyle(style.sub()), options);
12255    group = assertNodeType(grp.base, "horizBrace");
12256  } else {
12257    group = assertNodeType(grp, "horizBrace");
12258  } // Build the base group
12259
12260
12261  var body = buildGroup$1(group.base, options.havingBaseStyle(Style$1.DISPLAY)); // Create the stretchy element
12262
12263  var braceBody = stretchy.svgSpan(group, options); // Generate the vlist, with the appropriate kerns        ┏━━━━━━━━┓
12264  // This first vlist contains the content and the brace:   equation
12265
12266  var vlist;
12267
12268  if (group.isOver) {
12269    vlist = buildCommon.makeVList({
12270      positionType: "firstBaseline",
12271      children: [{
12272        type: "elem",
12273        elem: body
12274      }, {
12275        type: "kern",
12276        size: 0.1
12277      }, {
12278        type: "elem",
12279        elem: braceBody
12280      }]
12281    }, options); // $FlowFixMe: Replace this with passing "svg-align" into makeVList.
12282
12283    vlist.children[0].children[0].children[1].classes.push("svg-align");
12284  } else {
12285    vlist = buildCommon.makeVList({
12286      positionType: "bottom",
12287      positionData: body.depth + 0.1 + braceBody.height,
12288      children: [{
12289        type: "elem",
12290        elem: braceBody
12291      }, {
12292        type: "kern",
12293        size: 0.1
12294      }, {
12295        type: "elem",
12296        elem: body
12297      }]
12298    }, options); // $FlowFixMe: Replace this with passing "svg-align" into makeVList.
12299
12300    vlist.children[0].children[0].children[0].classes.push("svg-align");
12301  }
12302
12303  if (supSubGroup) {
12304    // To write the supsub, wrap the first vlist in another vlist:
12305    // They can't all go in the same vlist, because the note might be
12306    // wider than the equation. We want the equation to control the
12307    // brace width.
12308    //      note          long note           long note
12309    //   ┏━━━━━━━━┓   or    ┏━━━┓     not    ┏━━━━━━━━━┓
12310    //    equation           eqn                 eqn
12311    var vSpan = buildCommon.makeSpan(["mord", group.isOver ? "mover" : "munder"], [vlist], options);
12312
12313    if (group.isOver) {
12314      vlist = buildCommon.makeVList({
12315        positionType: "firstBaseline",
12316        children: [{
12317          type: "elem",
12318          elem: vSpan
12319        }, {
12320          type: "kern",
12321          size: 0.2
12322        }, {
12323          type: "elem",
12324          elem: supSubGroup
12325        }]
12326      }, options);
12327    } else {
12328      vlist = buildCommon.makeVList({
12329        positionType: "bottom",
12330        positionData: vSpan.depth + 0.2 + supSubGroup.height + supSubGroup.depth,
12331        children: [{
12332          type: "elem",
12333          elem: supSubGroup
12334        }, {
12335          type: "kern",
12336          size: 0.2
12337        }, {
12338          type: "elem",
12339          elem: vSpan
12340        }]
12341      }, options);
12342    }
12343  }
12344
12345  return buildCommon.makeSpan(["mord", group.isOver ? "mover" : "munder"], [vlist], options);
12346};
12347
12348var mathmlBuilder$2 = (group, options) => {
12349  var accentNode = stretchy.mathMLnode(group.label);
12350  return new mathMLTree.MathNode(group.isOver ? "mover" : "munder", [buildGroup(group.base, options), accentNode]);
12351}; // Horizontal stretchy braces
12352
12353
12354defineFunction({
12355  type: "horizBrace",
12356  names: ["\\overbrace", "\\underbrace"],
12357  props: {
12358    numArgs: 1
12359  },
12360
12361  handler(_ref, args) {
12362    var {
12363      parser,
12364      funcName
12365    } = _ref;
12366    return {
12367      type: "horizBrace",
12368      mode: parser.mode,
12369      label: funcName,
12370      isOver: /^\\over/.test(funcName),
12371      base: args[0]
12372    };
12373  },
12374
12375  htmlBuilder: htmlBuilder$3,
12376  mathmlBuilder: mathmlBuilder$2
12377});
12378
12379defineFunction({
12380  type: "href",
12381  names: ["\\href"],
12382  props: {
12383    numArgs: 2,
12384    argTypes: ["url", "original"],
12385    allowedInText: true
12386  },
12387  handler: (_ref, args) => {
12388    var {
12389      parser
12390    } = _ref;
12391    var body = args[1];
12392    var href = assertNodeType(args[0], "url").url;
12393
12394    if (!parser.settings.isTrusted({
12395      command: "\\href",
12396      url: href
12397    })) {
12398      return parser.formatUnsupportedCmd("\\href");
12399    }
12400
12401    return {
12402      type: "href",
12403      mode: parser.mode,
12404      href,
12405      body: ordargument(body)
12406    };
12407  },
12408  htmlBuilder: (group, options) => {
12409    var elements = buildExpression$1(group.body, options, false);
12410    return buildCommon.makeAnchor(group.href, [], elements, options);
12411  },
12412  mathmlBuilder: (group, options) => {
12413    var math = buildExpressionRow(group.body, options);
12414
12415    if (!(math instanceof MathNode)) {
12416      math = new MathNode("mrow", [math]);
12417    }
12418
12419    math.setAttribute("href", group.href);
12420    return math;
12421  }
12422});
12423defineFunction({
12424  type: "href",
12425  names: ["\\url"],
12426  props: {
12427    numArgs: 1,
12428    argTypes: ["url"],
12429    allowedInText: true
12430  },
12431  handler: (_ref2, args) => {
12432    var {
12433      parser
12434    } = _ref2;
12435    var href = assertNodeType(args[0], "url").url;
12436
12437    if (!parser.settings.isTrusted({
12438      command: "\\url",
12439      url: href
12440    })) {
12441      return parser.formatUnsupportedCmd("\\url");
12442    }
12443
12444    var chars = [];
12445
12446    for (var i = 0; i < href.length; i++) {
12447      var c = href[i];
12448
12449      if (c === "~") {
12450        c = "\\textasciitilde";
12451      }
12452
12453      chars.push({
12454        type: "textord",
12455        mode: "text",
12456        text: c
12457      });
12458    }
12459
12460    var body = {
12461      type: "text",
12462      mode: parser.mode,
12463      font: "\\texttt",
12464      body: chars
12465    };
12466    return {
12467      type: "href",
12468      mode: parser.mode,
12469      href,
12470      body: ordargument(body)
12471    };
12472  }
12473});
12474
12475// In LaTeX, \vcenter can act only on a box, as in
12476// \vcenter{\hbox{$\frac{a+b}{\dfrac{c}{d}}$}}
12477// This function by itself doesn't do anything but prevent a soft line break.
12478
12479defineFunction({
12480  type: "hbox",
12481  names: ["\\hbox"],
12482  props: {
12483    numArgs: 1,
12484    argTypes: ["text"],
12485    allowedInText: true,
12486    primitive: true
12487  },
12488
12489  handler(_ref, args) {
12490    var {
12491      parser
12492    } = _ref;
12493    return {
12494      type: "hbox",
12495      mode: parser.mode,
12496      body: ordargument(args[0])
12497    };
12498  },
12499
12500  htmlBuilder(group, options) {
12501    var elements = buildExpression$1(group.body, options, false);
12502    return buildCommon.makeFragment(elements);
12503  },
12504
12505  mathmlBuilder(group, options) {
12506    return new mathMLTree.MathNode("mrow", buildExpression(group.body, options));
12507  }
12508
12509});
12510
12511defineFunction({
12512  type: "html",
12513  names: ["\\htmlClass", "\\htmlId", "\\htmlStyle", "\\htmlData"],
12514  props: {
12515    numArgs: 2,
12516    argTypes: ["raw", "original"],
12517    allowedInText: true
12518  },
12519  handler: (_ref, args) => {
12520    var {
12521      parser,
12522      funcName,
12523      token
12524    } = _ref;
12525    var value = assertNodeType(args[0], "raw").string;
12526    var body = args[1];
12527
12528    if (parser.settings.strict) {
12529      parser.settings.reportNonstrict("htmlExtension", "HTML extension is disabled on strict mode");
12530    }
12531
12532    var trustContext;
12533    var attributes = {};
12534
12535    switch (funcName) {
12536      case "\\htmlClass":
12537        attributes.class = value;
12538        trustContext = {
12539          command: "\\htmlClass",
12540          class: value
12541        };
12542        break;
12543
12544      case "\\htmlId":
12545        attributes.id = value;
12546        trustContext = {
12547          command: "\\htmlId",
12548          id: value
12549        };
12550        break;
12551
12552      case "\\htmlStyle":
12553        attributes.style = value;
12554        trustContext = {
12555          command: "\\htmlStyle",
12556          style: value
12557        };
12558        break;
12559
12560      case "\\htmlData":
12561        {
12562          var data = value.split(",");
12563
12564          for (var i = 0; i < data.length; i++) {
12565            var keyVal = data[i].split("=");
12566
12567            if (keyVal.length !== 2) {
12568              throw new ParseError("Error parsing key-value for \\htmlData");
12569            }
12570
12571            attributes["data-" + keyVal[0].trim()] = keyVal[1].trim();
12572          }
12573
12574          trustContext = {
12575            command: "\\htmlData",
12576            attributes
12577          };
12578          break;
12579        }
12580
12581      default:
12582        throw new Error("Unrecognized html command");
12583    }
12584
12585    if (!parser.settings.isTrusted(trustContext)) {
12586      return parser.formatUnsupportedCmd(funcName);
12587    }
12588
12589    return {
12590      type: "html",
12591      mode: parser.mode,
12592      attributes,
12593      body: ordargument(body)
12594    };
12595  },
12596  htmlBuilder: (group, options) => {
12597    var elements = buildExpression$1(group.body, options, false);
12598    var classes = ["enclosing"];
12599
12600    if (group.attributes.class) {
12601      classes.push(...group.attributes.class.trim().split(/\s+/));
12602    }
12603
12604    var span = buildCommon.makeSpan(classes, elements, options);
12605
12606    for (var attr in group.attributes) {
12607      if (attr !== "class" && group.attributes.hasOwnProperty(attr)) {
12608        span.setAttribute(attr, group.attributes[attr]);
12609      }
12610    }
12611
12612    return span;
12613  },
12614  mathmlBuilder: (group, options) => {
12615    return buildExpressionRow(group.body, options);
12616  }
12617});
12618
12619defineFunction({
12620  type: "htmlmathml",
12621  names: ["\\html@mathml"],
12622  props: {
12623    numArgs: 2,
12624    allowedInText: true
12625  },
12626  handler: (_ref, args) => {
12627    var {
12628      parser
12629    } = _ref;
12630    return {
12631      type: "htmlmathml",
12632      mode: parser.mode,
12633      html: ordargument(args[0]),
12634      mathml: ordargument(args[1])
12635    };
12636  },
12637  htmlBuilder: (group, options) => {
12638    var elements = buildExpression$1(group.html, options, false);
12639    return buildCommon.makeFragment(elements);
12640  },
12641  mathmlBuilder: (group, options) => {
12642    return buildExpressionRow(group.mathml, options);
12643  }
12644});
12645
12646var sizeData = function sizeData(str) {
12647  if (/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(str)) {
12648    // str is a number with no unit specified.
12649    // default unit is bp, per graphix package.
12650    return {
12651      number: +str,
12652      unit: "bp"
12653    };
12654  } else {
12655    var match = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(str);
12656
12657    if (!match) {
12658      throw new ParseError("Invalid size: '" + str + "' in \\includegraphics");
12659    }
12660
12661    var data = {
12662      number: +(match[1] + match[2]),
12663      // sign + magnitude, cast to number
12664      unit: match[3]
12665    };
12666
12667    if (!validUnit(data)) {
12668      throw new ParseError("Invalid unit: '" + data.unit + "' in \\includegraphics.");
12669    }
12670
12671    return data;
12672  }
12673};
12674
12675defineFunction({
12676  type: "includegraphics",
12677  names: ["\\includegraphics"],
12678  props: {
12679    numArgs: 1,
12680    numOptionalArgs: 1,
12681    argTypes: ["raw", "url"],
12682    allowedInText: false
12683  },
12684  handler: (_ref, args, optArgs) => {
12685    var {
12686      parser
12687    } = _ref;
12688    var width = {
12689      number: 0,
12690      unit: "em"
12691    };
12692    var height = {
12693      number: 0.9,
12694      unit: "em"
12695    }; // sorta character sized.
12696
12697    var totalheight = {
12698      number: 0,
12699      unit: "em"
12700    };
12701    var alt = "";
12702
12703    if (optArgs[0]) {
12704      var attributeStr = assertNodeType(optArgs[0], "raw").string; // Parser.js does not parse key/value pairs. We get a string.
12705
12706      var attributes = attributeStr.split(",");
12707
12708      for (var i = 0; i < attributes.length; i++) {
12709        var keyVal = attributes[i].split("=");
12710
12711        if (keyVal.length === 2) {
12712          var str = keyVal[1].trim();
12713
12714          switch (keyVal[0].trim()) {
12715            case "alt":
12716              alt = str;
12717              break;
12718
12719            case "width":
12720              width = sizeData(str);
12721              break;
12722
12723            case "height":
12724              height = sizeData(str);
12725              break;
12726
12727            case "totalheight":
12728              totalheight = sizeData(str);
12729              break;
12730
12731            default:
12732              throw new ParseError("Invalid key: '" + keyVal[0] + "' in \\includegraphics.");
12733          }
12734        }
12735      }
12736    }
12737
12738    var src = assertNodeType(args[0], "url").url;
12739
12740    if (alt === "") {
12741      // No alt given. Use the file name. Strip away the path.
12742      alt = src;
12743      alt = alt.replace(/^.*[\\/]/, '');
12744      alt = alt.substring(0, alt.lastIndexOf('.'));
12745    }
12746
12747    if (!parser.settings.isTrusted({
12748      command: "\\includegraphics",
12749      url: src
12750    })) {
12751      return parser.formatUnsupportedCmd("\\includegraphics");
12752    }
12753
12754    return {
12755      type: "includegraphics",
12756      mode: parser.mode,
12757      alt: alt,
12758      width: width,
12759      height: height,
12760      totalheight: totalheight,
12761      src: src
12762    };
12763  },
12764  htmlBuilder: (group, options) => {
12765    var height = calculateSize(group.height, options);
12766    var depth = 0;
12767
12768    if (group.totalheight.number > 0) {
12769      depth = calculateSize(group.totalheight, options) - height;
12770    }
12771
12772    var width = 0;
12773
12774    if (group.width.number > 0) {
12775      width = calculateSize(group.width, options);
12776    }
12777
12778    var style = {
12779      height: makeEm(height + depth)
12780    };
12781
12782    if (width > 0) {
12783      style.width = makeEm(width);
12784    }
12785
12786    if (depth > 0) {
12787      style.verticalAlign = makeEm(-depth);
12788    }
12789
12790    var node = new Img(group.src, group.alt, style);
12791    node.height = height;
12792    node.depth = depth;
12793    return node;
12794  },
12795  mathmlBuilder: (group, options) => {
12796    var node = new mathMLTree.MathNode("mglyph", []);
12797    node.setAttribute("alt", group.alt);
12798    var height = calculateSize(group.height, options);
12799    var depth = 0;
12800
12801    if (group.totalheight.number > 0) {
12802      depth = calculateSize(group.totalheight, options) - height;
12803      node.setAttribute("valign", makeEm(-depth));
12804    }
12805
12806    node.setAttribute("height", makeEm(height + depth));
12807
12808    if (group.width.number > 0) {
12809      var width = calculateSize(group.width, options);
12810      node.setAttribute("width", makeEm(width));
12811    }
12812
12813    node.setAttribute("src", group.src);
12814    return node;
12815  }
12816});
12817
12818// Horizontal spacing commands
12819
12820defineFunction({
12821  type: "kern",
12822  names: ["\\kern", "\\mkern", "\\hskip", "\\mskip"],
12823  props: {
12824    numArgs: 1,
12825    argTypes: ["size"],
12826    primitive: true,
12827    allowedInText: true
12828  },
12829
12830  handler(_ref, args) {
12831    var {
12832      parser,
12833      funcName
12834    } = _ref;
12835    var size = assertNodeType(args[0], "size");
12836
12837    if (parser.settings.strict) {
12838      var mathFunction = funcName[1] === 'm'; // \mkern, \mskip
12839
12840      var muUnit = size.value.unit === 'mu';
12841
12842      if (mathFunction) {
12843        if (!muUnit) {
12844          parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " supports only mu units, " + ("not " + size.value.unit + " units"));
12845        }
12846
12847        if (parser.mode !== "math") {
12848          parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " works only in math mode");
12849        }
12850      } else {
12851        // !mathFunction
12852        if (muUnit) {
12853          parser.settings.reportNonstrict("mathVsTextUnits", "LaTeX's " + funcName + " doesn't support mu units");
12854        }
12855      }
12856    }
12857
12858    return {
12859      type: "kern",
12860      mode: parser.mode,
12861      dimension: size.value
12862    };
12863  },
12864
12865  htmlBuilder(group, options) {
12866    return buildCommon.makeGlue(group.dimension, options);
12867  },
12868
12869  mathmlBuilder(group, options) {
12870    var dimension = calculateSize(group.dimension, options);
12871    return new mathMLTree.SpaceNode(dimension);
12872  }
12873
12874});
12875
12876// Horizontal overlap functions
12877defineFunction({
12878  type: "lap",
12879  names: ["\\mathllap", "\\mathrlap", "\\mathclap"],
12880  props: {
12881    numArgs: 1,
12882    allowedInText: true
12883  },
12884  handler: (_ref, args) => {
12885    var {
12886      parser,
12887      funcName
12888    } = _ref;
12889    var body = args[0];
12890    return {
12891      type: "lap",
12892      mode: parser.mode,
12893      alignment: funcName.slice(5),
12894      body
12895    };
12896  },
12897  htmlBuilder: (group, options) => {
12898    // mathllap, mathrlap, mathclap
12899    var inner;
12900
12901    if (group.alignment === "clap") {
12902      // ref: https://www.math.lsu.edu/~aperlis/publications/mathclap/
12903      inner = buildCommon.makeSpan([], [buildGroup$1(group.body, options)]); // wrap, since CSS will center a .clap > .inner > span
12904
12905      inner = buildCommon.makeSpan(["inner"], [inner], options);
12906    } else {
12907      inner = buildCommon.makeSpan(["inner"], [buildGroup$1(group.body, options)]);
12908    }
12909
12910    var fix = buildCommon.makeSpan(["fix"], []);
12911    var node = buildCommon.makeSpan([group.alignment], [inner, fix], options); // At this point, we have correctly set horizontal alignment of the
12912    // two items involved in the lap.
12913    // Next, use a strut to set the height of the HTML bounding box.
12914    // Otherwise, a tall argument may be misplaced.
12915    // This code resolved issue #1153
12916
12917    var strut = buildCommon.makeSpan(["strut"]);
12918    strut.style.height = makeEm(node.height + node.depth);
12919
12920    if (node.depth) {
12921      strut.style.verticalAlign = makeEm(-node.depth);
12922    }
12923
12924    node.children.unshift(strut); // Next, prevent vertical misplacement when next to something tall.
12925    // This code resolves issue #1234
12926
12927    node = buildCommon.makeSpan(["thinbox"], [node], options);
12928    return buildCommon.makeSpan(["mord", "vbox"], [node], options);
12929  },
12930  mathmlBuilder: (group, options) => {
12931    // mathllap, mathrlap, mathclap
12932    var node = new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)]);
12933
12934    if (group.alignment !== "rlap") {
12935      var offset = group.alignment === "llap" ? "-1" : "-0.5";
12936      node.setAttribute("lspace", offset + "width");
12937    }
12938
12939    node.setAttribute("width", "0px");
12940    return node;
12941  }
12942});
12943
12944defineFunction({
12945  type: "styling",
12946  names: ["\\(", "$"],
12947  props: {
12948    numArgs: 0,
12949    allowedInText: true,
12950    allowedInMath: false
12951  },
12952
12953  handler(_ref, args) {
12954    var {
12955      funcName,
12956      parser
12957    } = _ref;
12958    var outerMode = parser.mode;
12959    parser.switchMode("math");
12960    var close = funcName === "\\(" ? "\\)" : "$";
12961    var body = parser.parseExpression(false, close);
12962    parser.expect(close);
12963    parser.switchMode(outerMode);
12964    return {
12965      type: "styling",
12966      mode: parser.mode,
12967      style: "text",
12968      body
12969    };
12970  }
12971
12972}); // Check for extra closing math delimiters
12973
12974defineFunction({
12975  type: "text",
12976  // Doesn't matter what this is.
12977  names: ["\\)", "\\]"],
12978  props: {
12979    numArgs: 0,
12980    allowedInText: true,
12981    allowedInMath: false
12982  },
12983
12984  handler(context, args) {
12985    throw new ParseError("Mismatched " + context.funcName);
12986  }
12987
12988});
12989
12990var chooseMathStyle = (group, options) => {
12991  switch (options.style.size) {
12992    case Style$1.DISPLAY.size:
12993      return group.display;
12994
12995    case Style$1.TEXT.size:
12996      return group.text;
12997
12998    case Style$1.SCRIPT.size:
12999      return group.script;
13000
13001    case Style$1.SCRIPTSCRIPT.size:
13002      return group.scriptscript;
13003
13004    default:
13005      return group.text;
13006  }
13007};
13008
13009defineFunction({
13010  type: "mathchoice",
13011  names: ["\\mathchoice"],
13012  props: {
13013    numArgs: 4,
13014    primitive: true
13015  },
13016  handler: (_ref, args) => {
13017    var {
13018      parser
13019    } = _ref;
13020    return {
13021      type: "mathchoice",
13022      mode: parser.mode,
13023      display: ordargument(args[0]),
13024      text: ordargument(args[1]),
13025      script: ordargument(args[2]),
13026      scriptscript: ordargument(args[3])
13027    };
13028  },
13029  htmlBuilder: (group, options) => {
13030    var body = chooseMathStyle(group, options);
13031    var elements = buildExpression$1(body, options, false);
13032    return buildCommon.makeFragment(elements);
13033  },
13034  mathmlBuilder: (group, options) => {
13035    var body = chooseMathStyle(group, options);
13036    return buildExpressionRow(body, options);
13037  }
13038});
13039
13040var assembleSupSub = (base, supGroup, subGroup, options, style, slant, baseShift) => {
13041  base = buildCommon.makeSpan([], [base]);
13042  var subIsSingleCharacter = subGroup && utils.isCharacterBox(subGroup);
13043  var sub;
13044  var sup; // We manually have to handle the superscripts and subscripts. This,
13045  // aside from the kern calculations, is copied from supsub.
13046
13047  if (supGroup) {
13048    var elem = buildGroup$1(supGroup, options.havingStyle(style.sup()), options);
13049    sup = {
13050      elem,
13051      kern: Math.max(options.fontMetrics().bigOpSpacing1, options.fontMetrics().bigOpSpacing3 - elem.depth)
13052    };
13053  }
13054
13055  if (subGroup) {
13056    var _elem = buildGroup$1(subGroup, options.havingStyle(style.sub()), options);
13057
13058    sub = {
13059      elem: _elem,
13060      kern: Math.max(options.fontMetrics().bigOpSpacing2, options.fontMetrics().bigOpSpacing4 - _elem.height)
13061    };
13062  } // Build the final group as a vlist of the possible subscript, base,
13063  // and possible superscript.
13064
13065
13066  var finalGroup;
13067
13068  if (sup && sub) {
13069    var bottom = options.fontMetrics().bigOpSpacing5 + sub.elem.height + sub.elem.depth + sub.kern + base.depth + baseShift;
13070    finalGroup = buildCommon.makeVList({
13071      positionType: "bottom",
13072      positionData: bottom,
13073      children: [{
13074        type: "kern",
13075        size: options.fontMetrics().bigOpSpacing5
13076      }, {
13077        type: "elem",
13078        elem: sub.elem,
13079        marginLeft: makeEm(-slant)
13080      }, {
13081        type: "kern",
13082        size: sub.kern
13083      }, {
13084        type: "elem",
13085        elem: base
13086      }, {
13087        type: "kern",
13088        size: sup.kern
13089      }, {
13090        type: "elem",
13091        elem: sup.elem,
13092        marginLeft: makeEm(slant)
13093      }, {
13094        type: "kern",
13095        size: options.fontMetrics().bigOpSpacing5
13096      }]
13097    }, options);
13098  } else if (sub) {
13099    var top = base.height - baseShift; // Shift the limits by the slant of the symbol. Note
13100    // that we are supposed to shift the limits by 1/2 of the slant,
13101    // but since we are centering the limits adding a full slant of
13102    // margin will shift by 1/2 that.
13103
13104    finalGroup = buildCommon.makeVList({
13105      positionType: "top",
13106      positionData: top,
13107      children: [{
13108        type: "kern",
13109        size: options.fontMetrics().bigOpSpacing5
13110      }, {
13111        type: "elem",
13112        elem: sub.elem,
13113        marginLeft: makeEm(-slant)
13114      }, {
13115        type: "kern",
13116        size: sub.kern
13117      }, {
13118        type: "elem",
13119        elem: base
13120      }]
13121    }, options);
13122  } else if (sup) {
13123    var _bottom = base.depth + baseShift;
13124
13125    finalGroup = buildCommon.makeVList({
13126      positionType: "bottom",
13127      positionData: _bottom,
13128      children: [{
13129        type: "elem",
13130        elem: base
13131      }, {
13132        type: "kern",
13133        size: sup.kern
13134      }, {
13135        type: "elem",
13136        elem: sup.elem,
13137        marginLeft: makeEm(slant)
13138      }, {
13139        type: "kern",
13140        size: options.fontMetrics().bigOpSpacing5
13141      }]
13142    }, options);
13143  } else {
13144    // This case probably shouldn't occur (this would mean the
13145    // supsub was sending us a group with no superscript or
13146    // subscript) but be safe.
13147    return base;
13148  }
13149
13150  var parts = [finalGroup];
13151
13152  if (sub && slant !== 0 && !subIsSingleCharacter) {
13153    // A negative margin-left was applied to the lower limit.
13154    // Avoid an overlap by placing a spacer on the left on the group.
13155    var spacer = buildCommon.makeSpan(["mspace"], [], options);
13156    spacer.style.marginRight = makeEm(slant);
13157    parts.unshift(spacer);
13158  }
13159
13160  return buildCommon.makeSpan(["mop", "op-limits"], parts, options);
13161};
13162
13163// Limits, symbols
13164// Most operators have a large successor symbol, but these don't.
13165var noSuccessor = ["\\smallint"]; // NOTE: Unlike most `htmlBuilder`s, this one handles not only "op", but also
13166// "supsub" since some of them (like \int) can affect super/subscripting.
13167
13168var htmlBuilder$2 = (grp, options) => {
13169  // Operators are handled in the TeXbook pg. 443-444, rule 13(a).
13170  var supGroup;
13171  var subGroup;
13172  var hasLimits = false;
13173  var group;
13174
13175  if (grp.type === "supsub") {
13176    // If we have limits, supsub will pass us its group to handle. Pull
13177    // out the superscript and subscript and set the group to the op in
13178    // its base.
13179    supGroup = grp.sup;
13180    subGroup = grp.sub;
13181    group = assertNodeType(grp.base, "op");
13182    hasLimits = true;
13183  } else {
13184    group = assertNodeType(grp, "op");
13185  }
13186
13187  var style = options.style;
13188  var large = false;
13189
13190  if (style.size === Style$1.DISPLAY.size && group.symbol && !utils.contains(noSuccessor, group.name)) {
13191    // Most symbol operators get larger in displaystyle (rule 13)
13192    large = true;
13193  }
13194
13195  var base;
13196
13197  if (group.symbol) {
13198    // If this is a symbol, create the symbol.
13199    var fontName = large ? "Size2-Regular" : "Size1-Regular";
13200    var stash = "";
13201
13202    if (group.name === "\\oiint" || group.name === "\\oiiint") {
13203      // No font glyphs yet, so use a glyph w/o the oval.
13204      // TODO: When font glyphs are available, delete this code.
13205      stash = group.name.slice(1);
13206      group.name = stash === "oiint" ? "\\iint" : "\\iiint";
13207    }
13208
13209    base = buildCommon.makeSymbol(group.name, fontName, "math", options, ["mop", "op-symbol", large ? "large-op" : "small-op"]);
13210
13211    if (stash.length > 0) {
13212      // We're in \oiint or \oiiint. Overlay the oval.
13213      // TODO: When font glyphs are available, delete this code.
13214      var italic = base.italic;
13215      var oval = buildCommon.staticSvg(stash + "Size" + (large ? "2" : "1"), options);
13216      base = buildCommon.makeVList({
13217        positionType: "individualShift",
13218        children: [{
13219          type: "elem",
13220          elem: base,
13221          shift: 0
13222        }, {
13223          type: "elem",
13224          elem: oval,
13225          shift: large ? 0.08 : 0
13226        }]
13227      }, options);
13228      group.name = "\\" + stash;
13229      base.classes.unshift("mop"); // $FlowFixMe
13230
13231      base.italic = italic;
13232    }
13233  } else if (group.body) {
13234    // If this is a list, compose that list.
13235    var inner = buildExpression$1(group.body, options, true);
13236
13237    if (inner.length === 1 && inner[0] instanceof SymbolNode) {
13238      base = inner[0];
13239      base.classes[0] = "mop"; // replace old mclass
13240    } else {
13241      base = buildCommon.makeSpan(["mop"], inner, options);
13242    }
13243  } else {
13244    // Otherwise, this is a text operator. Build the text from the
13245    // operator's name.
13246    var output = [];
13247
13248    for (var i = 1; i < group.name.length; i++) {
13249      output.push(buildCommon.mathsym(group.name[i], group.mode, options));
13250    }
13251
13252    base = buildCommon.makeSpan(["mop"], output, options);
13253  } // If content of op is a single symbol, shift it vertically.
13254
13255
13256  var baseShift = 0;
13257  var slant = 0;
13258
13259  if ((base instanceof SymbolNode || group.name === "\\oiint" || group.name === "\\oiiint") && !group.suppressBaseShift) {
13260    // We suppress the shift of the base of \overset and \underset. Otherwise,
13261    // shift the symbol so its center lies on the axis (rule 13). It
13262    // appears that our fonts have the centers of the symbols already
13263    // almost on the axis, so these numbers are very small. Note we
13264    // don't actually apply this here, but instead it is used either in
13265    // the vlist creation or separately when there are no limits.
13266    baseShift = (base.height - base.depth) / 2 - options.fontMetrics().axisHeight; // The slant of the symbol is just its italic correction.
13267    // $FlowFixMe
13268
13269    slant = base.italic;
13270  }
13271
13272  if (hasLimits) {
13273    return assembleSupSub(base, supGroup, subGroup, options, style, slant, baseShift);
13274  } else {
13275    if (baseShift) {
13276      base.style.position = "relative";
13277      base.style.top = makeEm(baseShift);
13278    }
13279
13280    return base;
13281  }
13282};
13283
13284var mathmlBuilder$1 = (group, options) => {
13285  var node;
13286
13287  if (group.symbol) {
13288    // This is a symbol. Just add the symbol.
13289    node = new MathNode("mo", [makeText(group.name, group.mode)]);
13290
13291    if (utils.contains(noSuccessor, group.name)) {
13292      node.setAttribute("largeop", "false");
13293    }
13294  } else if (group.body) {
13295    // This is an operator with children. Add them.
13296    node = new MathNode("mo", buildExpression(group.body, options));
13297  } else {
13298    // This is a text operator. Add all of the characters from the
13299    // operator's name.
13300    node = new MathNode("mi", [new TextNode(group.name.slice(1))]); // Append an <mo>&ApplyFunction;</mo>.
13301    // ref: https://www.w3.org/TR/REC-MathML/chap3_2.html#sec3.2.4
13302
13303    var operator = new MathNode("mo", [makeText("\u2061", "text")]);
13304
13305    if (group.parentIsSupSub) {
13306      node = new MathNode("mrow", [node, operator]);
13307    } else {
13308      node = newDocumentFragment([node, operator]);
13309    }
13310  }
13311
13312  return node;
13313};
13314
13315var singleCharBigOps = {
13316  "\u220F": "\\prod",
13317  "\u2210": "\\coprod",
13318  "\u2211": "\\sum",
13319  "\u22c0": "\\bigwedge",
13320  "\u22c1": "\\bigvee",
13321  "\u22c2": "\\bigcap",
13322  "\u22c3": "\\bigcup",
13323  "\u2a00": "\\bigodot",
13324  "\u2a01": "\\bigoplus",
13325  "\u2a02": "\\bigotimes",
13326  "\u2a04": "\\biguplus",
13327  "\u2a06": "\\bigsqcup"
13328};
13329defineFunction({
13330  type: "op",
13331  names: ["\\coprod", "\\bigvee", "\\bigwedge", "\\biguplus", "\\bigcap", "\\bigcup", "\\intop", "\\prod", "\\sum", "\\bigotimes", "\\bigoplus", "\\bigodot", "\\bigsqcup", "\\smallint", "\u220F", "\u2210", "\u2211", "\u22c0", "\u22c1", "\u22c2", "\u22c3", "\u2a00", "\u2a01", "\u2a02", "\u2a04", "\u2a06"],
13332  props: {
13333    numArgs: 0
13334  },
13335  handler: (_ref, args) => {
13336    var {
13337      parser,
13338      funcName
13339    } = _ref;
13340    var fName = funcName;
13341
13342    if (fName.length === 1) {
13343      fName = singleCharBigOps[fName];
13344    }
13345
13346    return {
13347      type: "op",
13348      mode: parser.mode,
13349      limits: true,
13350      parentIsSupSub: false,
13351      symbol: true,
13352      name: fName
13353    };
13354  },
13355  htmlBuilder: htmlBuilder$2,
13356  mathmlBuilder: mathmlBuilder$1
13357}); // Note: calling defineFunction with a type that's already been defined only
13358// works because the same htmlBuilder and mathmlBuilder are being used.
13359
13360defineFunction({
13361  type: "op",
13362  names: ["\\mathop"],
13363  props: {
13364    numArgs: 1,
13365    primitive: true
13366  },
13367  handler: (_ref2, args) => {
13368    var {
13369      parser
13370    } = _ref2;
13371    var body = args[0];
13372    return {
13373      type: "op",
13374      mode: parser.mode,
13375      limits: false,
13376      parentIsSupSub: false,
13377      symbol: false,
13378      body: ordargument(body)
13379    };
13380  },
13381  htmlBuilder: htmlBuilder$2,
13382  mathmlBuilder: mathmlBuilder$1
13383}); // There are 2 flags for operators; whether they produce limits in
13384// displaystyle, and whether they are symbols and should grow in
13385// displaystyle. These four groups cover the four possible choices.
13386
13387var singleCharIntegrals = {
13388  "\u222b": "\\int",
13389  "\u222c": "\\iint",
13390  "\u222d": "\\iiint",
13391  "\u222e": "\\oint",
13392  "\u222f": "\\oiint",
13393  "\u2230": "\\oiiint"
13394}; // No limits, not symbols
13395
13396defineFunction({
13397  type: "op",
13398  names: ["\\arcsin", "\\arccos", "\\arctan", "\\arctg", "\\arcctg", "\\arg", "\\ch", "\\cos", "\\cosec", "\\cosh", "\\cot", "\\cotg", "\\coth", "\\csc", "\\ctg", "\\cth", "\\deg", "\\dim", "\\exp", "\\hom", "\\ker", "\\lg", "\\ln", "\\log", "\\sec", "\\sin", "\\sinh", "\\sh", "\\tan", "\\tanh", "\\tg", "\\th"],
13399  props: {
13400    numArgs: 0
13401  },
13402
13403  handler(_ref3) {
13404    var {
13405      parser,
13406      funcName
13407    } = _ref3;
13408    return {
13409      type: "op",
13410      mode: parser.mode,
13411      limits: false,
13412      parentIsSupSub: false,
13413      symbol: false,
13414      name: funcName
13415    };
13416  },
13417
13418  htmlBuilder: htmlBuilder$2,
13419  mathmlBuilder: mathmlBuilder$1
13420}); // Limits, not symbols
13421
13422defineFunction({
13423  type: "op",
13424  names: ["\\det", "\\gcd", "\\inf", "\\lim", "\\max", "\\min", "\\Pr", "\\sup"],
13425  props: {
13426    numArgs: 0
13427  },
13428
13429  handler(_ref4) {
13430    var {
13431      parser,
13432      funcName
13433    } = _ref4;
13434    return {
13435      type: "op",
13436      mode: parser.mode,
13437      limits: true,
13438      parentIsSupSub: false,
13439      symbol: false,
13440      name: funcName
13441    };
13442  },
13443
13444  htmlBuilder: htmlBuilder$2,
13445  mathmlBuilder: mathmlBuilder$1
13446}); // No limits, symbols
13447
13448defineFunction({
13449  type: "op",
13450  names: ["\\int", "\\iint", "\\iiint", "\\oint", "\\oiint", "\\oiiint", "\u222b", "\u222c", "\u222d", "\u222e", "\u222f", "\u2230"],
13451  props: {
13452    numArgs: 0
13453  },
13454
13455  handler(_ref5) {
13456    var {
13457      parser,
13458      funcName
13459    } = _ref5;
13460    var fName = funcName;
13461
13462    if (fName.length === 1) {
13463      fName = singleCharIntegrals[fName];
13464    }
13465
13466    return {
13467      type: "op",
13468      mode: parser.mode,
13469      limits: false,
13470      parentIsSupSub: false,
13471      symbol: true,
13472      name: fName
13473    };
13474  },
13475
13476  htmlBuilder: htmlBuilder$2,
13477  mathmlBuilder: mathmlBuilder$1
13478});
13479
13480// NOTE: Unlike most `htmlBuilder`s, this one handles not only
13481// "operatorname", but also  "supsub" since \operatorname* can
13482// affect super/subscripting.
13483var htmlBuilder$1 = (grp, options) => {
13484  // Operators are handled in the TeXbook pg. 443-444, rule 13(a).
13485  var supGroup;
13486  var subGroup;
13487  var hasLimits = false;
13488  var group;
13489
13490  if (grp.type === "supsub") {
13491    // If we have limits, supsub will pass us its group to handle. Pull
13492    // out the superscript and subscript and set the group to the op in
13493    // its base.
13494    supGroup = grp.sup;
13495    subGroup = grp.sub;
13496    group = assertNodeType(grp.base, "operatorname");
13497    hasLimits = true;
13498  } else {
13499    group = assertNodeType(grp, "operatorname");
13500  }
13501
13502  var base;
13503
13504  if (group.body.length > 0) {
13505    var body = group.body.map(child => {
13506      // $FlowFixMe: Check if the node has a string `text` property.
13507      var childText = child.text;
13508
13509      if (typeof childText === "string") {
13510        return {
13511          type: "textord",
13512          mode: child.mode,
13513          text: childText
13514        };
13515      } else {
13516        return child;
13517      }
13518    }); // Consolidate function names into symbol characters.
13519
13520    var expression = buildExpression$1(body, options.withFont("mathrm"), true);
13521
13522    for (var i = 0; i < expression.length; i++) {
13523      var child = expression[i];
13524
13525      if (child instanceof SymbolNode) {
13526        // Per amsopn package,
13527        // change minus to hyphen and \ast to asterisk
13528        child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*");
13529      }
13530    }
13531
13532    base = buildCommon.makeSpan(["mop"], expression, options);
13533  } else {
13534    base = buildCommon.makeSpan(["mop"], [], options);
13535  }
13536
13537  if (hasLimits) {
13538    return assembleSupSub(base, supGroup, subGroup, options, options.style, 0, 0);
13539  } else {
13540    return base;
13541  }
13542};
13543
13544var mathmlBuilder = (group, options) => {
13545  // The steps taken here are similar to the html version.
13546  var expression = buildExpression(group.body, options.withFont("mathrm")); // Is expression a string or has it something like a fraction?
13547
13548  var isAllString = true; // default
13549
13550  for (var i = 0; i < expression.length; i++) {
13551    var node = expression[i];
13552
13553    if (node instanceof mathMLTree.SpaceNode) ; else if (node instanceof mathMLTree.MathNode) {
13554      switch (node.type) {
13555        case "mi":
13556        case "mn":
13557        case "ms":
13558        case "mspace":
13559        case "mtext":
13560          break;
13561        // Do nothing yet.
13562
13563        case "mo":
13564          {
13565            var child = node.children[0];
13566
13567            if (node.children.length === 1 && child instanceof mathMLTree.TextNode) {
13568              child.text = child.text.replace(/\u2212/, "-").replace(/\u2217/, "*");
13569            } else {
13570              isAllString = false;
13571            }
13572
13573            break;
13574          }
13575
13576        default:
13577          isAllString = false;
13578      }
13579    } else {
13580      isAllString = false;
13581    }
13582  }
13583
13584  if (isAllString) {
13585    // Write a single TextNode instead of multiple nested tags.
13586    var word = expression.map(node => node.toText()).join("");
13587    expression = [new mathMLTree.TextNode(word)];
13588  }
13589
13590  var identifier = new mathMLTree.MathNode("mi", expression);
13591  identifier.setAttribute("mathvariant", "normal"); // \u2061 is the same as &ApplyFunction;
13592  // ref: https://www.w3schools.com/charsets/ref_html_entities_a.asp
13593
13594  var operator = new mathMLTree.MathNode("mo", [makeText("\u2061", "text")]);
13595
13596  if (group.parentIsSupSub) {
13597    return new mathMLTree.MathNode("mrow", [identifier, operator]);
13598  } else {
13599    return mathMLTree.newDocumentFragment([identifier, operator]);
13600  }
13601}; // \operatorname
13602// amsopn.dtx: \mathop{#1\kern\z@\operator@font#3}\newmcodes@
13603
13604
13605defineFunction({
13606  type: "operatorname",
13607  names: ["\\operatorname@", "\\operatornamewithlimits"],
13608  props: {
13609    numArgs: 1
13610  },
13611  handler: (_ref, args) => {
13612    var {
13613      parser,
13614      funcName
13615    } = _ref;
13616    var body = args[0];
13617    return {
13618      type: "operatorname",
13619      mode: parser.mode,
13620      body: ordargument(body),
13621      alwaysHandleSupSub: funcName === "\\operatornamewithlimits",
13622      limits: false,
13623      parentIsSupSub: false
13624    };
13625  },
13626  htmlBuilder: htmlBuilder$1,
13627  mathmlBuilder
13628});
13629defineMacro("\\operatorname", "\\@ifstar\\operatornamewithlimits\\operatorname@");
13630
13631defineFunctionBuilders({
13632  type: "ordgroup",
13633
13634  htmlBuilder(group, options) {
13635    if (group.semisimple) {
13636      return buildCommon.makeFragment(buildExpression$1(group.body, options, false));
13637    }
13638
13639    return buildCommon.makeSpan(["mord"], buildExpression$1(group.body, options, true), options);
13640  },
13641
13642  mathmlBuilder(group, options) {
13643    return buildExpressionRow(group.body, options, true);
13644  }
13645
13646});
13647
13648defineFunction({
13649  type: "overline",
13650  names: ["\\overline"],
13651  props: {
13652    numArgs: 1
13653  },
13654
13655  handler(_ref, args) {
13656    var {
13657      parser
13658    } = _ref;
13659    var body = args[0];
13660    return {
13661      type: "overline",
13662      mode: parser.mode,
13663      body
13664    };
13665  },
13666
13667  htmlBuilder(group, options) {
13668    // Overlines are handled in the TeXbook pg 443, Rule 9.
13669    // Build the inner group in the cramped style.
13670    var innerGroup = buildGroup$1(group.body, options.havingCrampedStyle()); // Create the line above the body
13671
13672    var line = buildCommon.makeLineSpan("overline-line", options); // Generate the vlist, with the appropriate kerns
13673
13674    var defaultRuleThickness = options.fontMetrics().defaultRuleThickness;
13675    var vlist = buildCommon.makeVList({
13676      positionType: "firstBaseline",
13677      children: [{
13678        type: "elem",
13679        elem: innerGroup
13680      }, {
13681        type: "kern",
13682        size: 3 * defaultRuleThickness
13683      }, {
13684        type: "elem",
13685        elem: line
13686      }, {
13687        type: "kern",
13688        size: defaultRuleThickness
13689      }]
13690    }, options);
13691    return buildCommon.makeSpan(["mord", "overline"], [vlist], options);
13692  },
13693
13694  mathmlBuilder(group, options) {
13695    var operator = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode("\u203e")]);
13696    operator.setAttribute("stretchy", "true");
13697    var node = new mathMLTree.MathNode("mover", [buildGroup(group.body, options), operator]);
13698    node.setAttribute("accent", "true");
13699    return node;
13700  }
13701
13702});
13703
13704defineFunction({
13705  type: "phantom",
13706  names: ["\\phantom"],
13707  props: {
13708    numArgs: 1,
13709    allowedInText: true
13710  },
13711  handler: (_ref, args) => {
13712    var {
13713      parser
13714    } = _ref;
13715    var body = args[0];
13716    return {
13717      type: "phantom",
13718      mode: parser.mode,
13719      body: ordargument(body)
13720    };
13721  },
13722  htmlBuilder: (group, options) => {
13723    var elements = buildExpression$1(group.body, options.withPhantom(), false); // \phantom isn't supposed to affect the elements it contains.
13724    // See "color" for more details.
13725
13726    return buildCommon.makeFragment(elements);
13727  },
13728  mathmlBuilder: (group, options) => {
13729    var inner = buildExpression(group.body, options);
13730    return new mathMLTree.MathNode("mphantom", inner);
13731  }
13732});
13733defineFunction({
13734  type: "hphantom",
13735  names: ["\\hphantom"],
13736  props: {
13737    numArgs: 1,
13738    allowedInText: true
13739  },
13740  handler: (_ref2, args) => {
13741    var {
13742      parser
13743    } = _ref2;
13744    var body = args[0];
13745    return {
13746      type: "hphantom",
13747      mode: parser.mode,
13748      body
13749    };
13750  },
13751  htmlBuilder: (group, options) => {
13752    var node = buildCommon.makeSpan([], [buildGroup$1(group.body, options.withPhantom())]);
13753    node.height = 0;
13754    node.depth = 0;
13755
13756    if (node.children) {
13757      for (var i = 0; i < node.children.length; i++) {
13758        node.children[i].height = 0;
13759        node.children[i].depth = 0;
13760      }
13761    } // See smash for comment re: use of makeVList
13762
13763
13764    node = buildCommon.makeVList({
13765      positionType: "firstBaseline",
13766      children: [{
13767        type: "elem",
13768        elem: node
13769      }]
13770    }, options); // For spacing, TeX treats \smash as a math group (same spacing as ord).
13771
13772    return buildCommon.makeSpan(["mord"], [node], options);
13773  },
13774  mathmlBuilder: (group, options) => {
13775    var inner = buildExpression(ordargument(group.body), options);
13776    var phantom = new mathMLTree.MathNode("mphantom", inner);
13777    var node = new mathMLTree.MathNode("mpadded", [phantom]);
13778    node.setAttribute("height", "0px");
13779    node.setAttribute("depth", "0px");
13780    return node;
13781  }
13782});
13783defineFunction({
13784  type: "vphantom",
13785  names: ["\\vphantom"],
13786  props: {
13787    numArgs: 1,
13788    allowedInText: true
13789  },
13790  handler: (_ref3, args) => {
13791    var {
13792      parser
13793    } = _ref3;
13794    var body = args[0];
13795    return {
13796      type: "vphantom",
13797      mode: parser.mode,
13798      body
13799    };
13800  },
13801  htmlBuilder: (group, options) => {
13802    var inner = buildCommon.makeSpan(["inner"], [buildGroup$1(group.body, options.withPhantom())]);
13803    var fix = buildCommon.makeSpan(["fix"], []);
13804    return buildCommon.makeSpan(["mord", "rlap"], [inner, fix], options);
13805  },
13806  mathmlBuilder: (group, options) => {
13807    var inner = buildExpression(ordargument(group.body), options);
13808    var phantom = new mathMLTree.MathNode("mphantom", inner);
13809    var node = new mathMLTree.MathNode("mpadded", [phantom]);
13810    node.setAttribute("width", "0px");
13811    return node;
13812  }
13813});
13814
13815defineFunction({
13816  type: "raisebox",
13817  names: ["\\raisebox"],
13818  props: {
13819    numArgs: 2,
13820    argTypes: ["size", "hbox"],
13821    allowedInText: true
13822  },
13823
13824  handler(_ref, args) {
13825    var {
13826      parser
13827    } = _ref;
13828    var amount = assertNodeType(args[0], "size").value;
13829    var body = args[1];
13830    return {
13831      type: "raisebox",
13832      mode: parser.mode,
13833      dy: amount,
13834      body
13835    };
13836  },
13837
13838  htmlBuilder(group, options) {
13839    var body = buildGroup$1(group.body, options);
13840    var dy = calculateSize(group.dy, options);
13841    return buildCommon.makeVList({
13842      positionType: "shift",
13843      positionData: -dy,
13844      children: [{
13845        type: "elem",
13846        elem: body
13847      }]
13848    }, options);
13849  },
13850
13851  mathmlBuilder(group, options) {
13852    var node = new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)]);
13853    var dy = group.dy.number + group.dy.unit;
13854    node.setAttribute("voffset", dy);
13855    return node;
13856  }
13857
13858});
13859
13860defineFunction({
13861  type: "internal",
13862  names: ["\\relax"],
13863  props: {
13864    numArgs: 0,
13865    allowedInText: true
13866  },
13867
13868  handler(_ref) {
13869    var {
13870      parser
13871    } = _ref;
13872    return {
13873      type: "internal",
13874      mode: parser.mode
13875    };
13876  }
13877
13878});
13879
13880defineFunction({
13881  type: "rule",
13882  names: ["\\rule"],
13883  props: {
13884    numArgs: 2,
13885    numOptionalArgs: 1,
13886    allowedInText: true,
13887    allowedInMath: true,
13888    argTypes: ["size", "size", "size"]
13889  },
13890
13891  handler(_ref, args, optArgs) {
13892    var {
13893      parser
13894    } = _ref;
13895    var shift = optArgs[0];
13896    var width = assertNodeType(args[0], "size");
13897    var height = assertNodeType(args[1], "size");
13898    return {
13899      type: "rule",
13900      mode: parser.mode,
13901      shift: shift && assertNodeType(shift, "size").value,
13902      width: width.value,
13903      height: height.value
13904    };
13905  },
13906
13907  htmlBuilder(group, options) {
13908    // Make an empty span for the rule
13909    var rule = buildCommon.makeSpan(["mord", "rule"], [], options); // Calculate the shift, width, and height of the rule, and account for units
13910
13911    var width = calculateSize(group.width, options);
13912    var height = calculateSize(group.height, options);
13913    var shift = group.shift ? calculateSize(group.shift, options) : 0; // Style the rule to the right size
13914
13915    rule.style.borderRightWidth = makeEm(width);
13916    rule.style.borderTopWidth = makeEm(height);
13917    rule.style.bottom = makeEm(shift); // Record the height and width
13918
13919    rule.width = width;
13920    rule.height = height + shift;
13921    rule.depth = -shift; // Font size is the number large enough that the browser will
13922    // reserve at least `absHeight` space above the baseline.
13923    // The 1.125 factor was empirically determined
13924
13925    rule.maxFontSize = height * 1.125 * options.sizeMultiplier;
13926    return rule;
13927  },
13928
13929  mathmlBuilder(group, options) {
13930    var width = calculateSize(group.width, options);
13931    var height = calculateSize(group.height, options);
13932    var shift = group.shift ? calculateSize(group.shift, options) : 0;
13933    var color = options.color && options.getColor() || "black";
13934    var rule = new mathMLTree.MathNode("mspace");
13935    rule.setAttribute("mathbackground", color);
13936    rule.setAttribute("width", makeEm(width));
13937    rule.setAttribute("height", makeEm(height));
13938    var wrapper = new mathMLTree.MathNode("mpadded", [rule]);
13939
13940    if (shift >= 0) {
13941      wrapper.setAttribute("height", makeEm(shift));
13942    } else {
13943      wrapper.setAttribute("height", makeEm(shift));
13944      wrapper.setAttribute("depth", makeEm(-shift));
13945    }
13946
13947    wrapper.setAttribute("voffset", makeEm(shift));
13948    return wrapper;
13949  }
13950
13951});
13952
13953function sizingGroup(value, options, baseOptions) {
13954  var inner = buildExpression$1(value, options, false);
13955  var multiplier = options.sizeMultiplier / baseOptions.sizeMultiplier; // Add size-resetting classes to the inner list and set maxFontSize
13956  // manually. Handle nested size changes.
13957
13958  for (var i = 0; i < inner.length; i++) {
13959    var pos = inner[i].classes.indexOf("sizing");
13960
13961    if (pos < 0) {
13962      Array.prototype.push.apply(inner[i].classes, options.sizingClasses(baseOptions));
13963    } else if (inner[i].classes[pos + 1] === "reset-size" + options.size) {
13964      // This is a nested size change: e.g., inner[i] is the "b" in
13965      // `\Huge a \small b`. Override the old size (the `reset-` class)
13966      // but not the new size.
13967      inner[i].classes[pos + 1] = "reset-size" + baseOptions.size;
13968    }
13969
13970    inner[i].height *= multiplier;
13971    inner[i].depth *= multiplier;
13972  }
13973
13974  return buildCommon.makeFragment(inner);
13975}
13976var sizeFuncs = ["\\tiny", "\\sixptsize", "\\scriptsize", "\\footnotesize", "\\small", "\\normalsize", "\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge"];
13977var htmlBuilder = (group, options) => {
13978  // Handle sizing operators like \Huge. Real TeX doesn't actually allow
13979  // these functions inside of math expressions, so we do some special
13980  // handling.
13981  var newOptions = options.havingSize(group.size);
13982  return sizingGroup(group.body, newOptions, options);
13983};
13984defineFunction({
13985  type: "sizing",
13986  names: sizeFuncs,
13987  props: {
13988    numArgs: 0,
13989    allowedInText: true
13990  },
13991  handler: (_ref, args) => {
13992    var {
13993      breakOnTokenText,
13994      funcName,
13995      parser
13996    } = _ref;
13997    var body = parser.parseExpression(false, breakOnTokenText);
13998    return {
13999      type: "sizing",
14000      mode: parser.mode,
14001      // Figure out what size to use based on the list of functions above
14002      size: sizeFuncs.indexOf(funcName) + 1,
14003      body
14004    };
14005  },
14006  htmlBuilder,
14007  mathmlBuilder: (group, options) => {
14008    var newOptions = options.havingSize(group.size);
14009    var inner = buildExpression(group.body, newOptions);
14010    var node = new mathMLTree.MathNode("mstyle", inner); // TODO(emily): This doesn't produce the correct size for nested size
14011    // changes, because we don't keep state of what style we're currently
14012    // in, so we can't reset the size to normal before changing it.  Now
14013    // that we're passing an options parameter we should be able to fix
14014    // this.
14015
14016    node.setAttribute("mathsize", makeEm(newOptions.sizeMultiplier));
14017    return node;
14018  }
14019});
14020
14021// smash, with optional [tb], as in AMS
14022defineFunction({
14023  type: "smash",
14024  names: ["\\smash"],
14025  props: {
14026    numArgs: 1,
14027    numOptionalArgs: 1,
14028    allowedInText: true
14029  },
14030  handler: (_ref, args, optArgs) => {
14031    var {
14032      parser
14033    } = _ref;
14034    var smashHeight = false;
14035    var smashDepth = false;
14036    var tbArg = optArgs[0] && assertNodeType(optArgs[0], "ordgroup");
14037
14038    if (tbArg) {
14039      // Optional [tb] argument is engaged.
14040      // ref: amsmath: \renewcommand{\smash}[1][tb]{%
14041      //               def\mb@t{\ht}\def\mb@b{\dp}\def\mb@tb{\ht\z@\z@\dp}%
14042      var letter = "";
14043
14044      for (var i = 0; i < tbArg.body.length; ++i) {
14045        var node = tbArg.body[i]; // $FlowFixMe: Not every node type has a `text` property.
14046
14047        letter = node.text;
14048
14049        if (letter === "t") {
14050          smashHeight = true;
14051        } else if (letter === "b") {
14052          smashDepth = true;
14053        } else {
14054          smashHeight = false;
14055          smashDepth = false;
14056          break;
14057        }
14058      }
14059    } else {
14060      smashHeight = true;
14061      smashDepth = true;
14062    }
14063
14064    var body = args[0];
14065    return {
14066      type: "smash",
14067      mode: parser.mode,
14068      body,
14069      smashHeight,
14070      smashDepth
14071    };
14072  },
14073  htmlBuilder: (group, options) => {
14074    var node = buildCommon.makeSpan([], [buildGroup$1(group.body, options)]);
14075
14076    if (!group.smashHeight && !group.smashDepth) {
14077      return node;
14078    }
14079
14080    if (group.smashHeight) {
14081      node.height = 0; // In order to influence makeVList, we have to reset the children.
14082
14083      if (node.children) {
14084        for (var i = 0; i < node.children.length; i++) {
14085          node.children[i].height = 0;
14086        }
14087      }
14088    }
14089
14090    if (group.smashDepth) {
14091      node.depth = 0;
14092
14093      if (node.children) {
14094        for (var _i = 0; _i < node.children.length; _i++) {
14095          node.children[_i].depth = 0;
14096        }
14097      }
14098    } // At this point, we've reset the TeX-like height and depth values.
14099    // But the span still has an HTML line height.
14100    // makeVList applies "display: table-cell", which prevents the browser
14101    // from acting on that line height. So we'll call makeVList now.
14102
14103
14104    var smashedNode = buildCommon.makeVList({
14105      positionType: "firstBaseline",
14106      children: [{
14107        type: "elem",
14108        elem: node
14109      }]
14110    }, options); // For spacing, TeX treats \hphantom as a math group (same spacing as ord).
14111
14112    return buildCommon.makeSpan(["mord"], [smashedNode], options);
14113  },
14114  mathmlBuilder: (group, options) => {
14115    var node = new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)]);
14116
14117    if (group.smashHeight) {
14118      node.setAttribute("height", "0px");
14119    }
14120
14121    if (group.smashDepth) {
14122      node.setAttribute("depth", "0px");
14123    }
14124
14125    return node;
14126  }
14127});
14128
14129defineFunction({
14130  type: "sqrt",
14131  names: ["\\sqrt"],
14132  props: {
14133    numArgs: 1,
14134    numOptionalArgs: 1
14135  },
14136
14137  handler(_ref, args, optArgs) {
14138    var {
14139      parser
14140    } = _ref;
14141    var index = optArgs[0];
14142    var body = args[0];
14143    return {
14144      type: "sqrt",
14145      mode: parser.mode,
14146      body,
14147      index
14148    };
14149  },
14150
14151  htmlBuilder(group, options) {
14152    // Square roots are handled in the TeXbook pg. 443, Rule 11.
14153    // First, we do the same steps as in overline to build the inner group
14154    // and line
14155    var inner = buildGroup$1(group.body, options.havingCrampedStyle());
14156
14157    if (inner.height === 0) {
14158      // Render a small surd.
14159      inner.height = options.fontMetrics().xHeight;
14160    } // Some groups can return document fragments.  Handle those by wrapping
14161    // them in a span.
14162
14163
14164    inner = buildCommon.wrapFragment(inner, options); // Calculate the minimum size for the \surd delimiter
14165
14166    var metrics = options.fontMetrics();
14167    var theta = metrics.defaultRuleThickness;
14168    var phi = theta;
14169
14170    if (options.style.id < Style$1.TEXT.id) {
14171      phi = options.fontMetrics().xHeight;
14172    } // Calculate the clearance between the body and line
14173
14174
14175    var lineClearance = theta + phi / 4;
14176    var minDelimiterHeight = inner.height + inner.depth + lineClearance + theta; // Create a sqrt SVG of the required minimum size
14177
14178    var {
14179      span: img,
14180      ruleWidth,
14181      advanceWidth
14182    } = delimiter.sqrtImage(minDelimiterHeight, options);
14183    var delimDepth = img.height - ruleWidth; // Adjust the clearance based on the delimiter size
14184
14185    if (delimDepth > inner.height + inner.depth + lineClearance) {
14186      lineClearance = (lineClearance + delimDepth - inner.height - inner.depth) / 2;
14187    } // Shift the sqrt image
14188
14189
14190    var imgShift = img.height - inner.height - lineClearance - ruleWidth;
14191    inner.style.paddingLeft = makeEm(advanceWidth); // Overlay the image and the argument.
14192
14193    var body = buildCommon.makeVList({
14194      positionType: "firstBaseline",
14195      children: [{
14196        type: "elem",
14197        elem: inner,
14198        wrapperClasses: ["svg-align"]
14199      }, {
14200        type: "kern",
14201        size: -(inner.height + imgShift)
14202      }, {
14203        type: "elem",
14204        elem: img
14205      }, {
14206        type: "kern",
14207        size: ruleWidth
14208      }]
14209    }, options);
14210
14211    if (!group.index) {
14212      return buildCommon.makeSpan(["mord", "sqrt"], [body], options);
14213    } else {
14214      // Handle the optional root index
14215      // The index is always in scriptscript style
14216      var newOptions = options.havingStyle(Style$1.SCRIPTSCRIPT);
14217      var rootm = buildGroup$1(group.index, newOptions, options); // The amount the index is shifted by. This is taken from the TeX
14218      // source, in the definition of `\r@@t`.
14219
14220      var toShift = 0.6 * (body.height - body.depth); // Build a VList with the superscript shifted up correctly
14221
14222      var rootVList = buildCommon.makeVList({
14223        positionType: "shift",
14224        positionData: -toShift,
14225        children: [{
14226          type: "elem",
14227          elem: rootm
14228        }]
14229      }, options); // Add a class surrounding it so we can add on the appropriate
14230      // kerning
14231
14232      var rootVListWrap = buildCommon.makeSpan(["root"], [rootVList]);
14233      return buildCommon.makeSpan(["mord", "sqrt"], [rootVListWrap, body], options);
14234    }
14235  },
14236
14237  mathmlBuilder(group, options) {
14238    var {
14239      body,
14240      index
14241    } = group;
14242    return index ? new mathMLTree.MathNode("mroot", [buildGroup(body, options), buildGroup(index, options)]) : new mathMLTree.MathNode("msqrt", [buildGroup(body, options)]);
14243  }
14244
14245});
14246
14247var styleMap = {
14248  "display": Style$1.DISPLAY,
14249  "text": Style$1.TEXT,
14250  "script": Style$1.SCRIPT,
14251  "scriptscript": Style$1.SCRIPTSCRIPT
14252};
14253defineFunction({
14254  type: "styling",
14255  names: ["\\displaystyle", "\\textstyle", "\\scriptstyle", "\\scriptscriptstyle"],
14256  props: {
14257    numArgs: 0,
14258    allowedInText: true,
14259    primitive: true
14260  },
14261
14262  handler(_ref, args) {
14263    var {
14264      breakOnTokenText,
14265      funcName,
14266      parser
14267    } = _ref;
14268    // parse out the implicit body
14269    var body = parser.parseExpression(true, breakOnTokenText); // TODO: Refactor to avoid duplicating styleMap in multiple places (e.g.
14270    // here and in buildHTML and de-dupe the enumeration of all the styles).
14271    // $FlowFixMe: The names above exactly match the styles.
14272
14273    var style = funcName.slice(1, funcName.length - 5);
14274    return {
14275      type: "styling",
14276      mode: parser.mode,
14277      // Figure out what style to use by pulling out the style from
14278      // the function name
14279      style,
14280      body
14281    };
14282  },
14283
14284  htmlBuilder(group, options) {
14285    // Style changes are handled in the TeXbook on pg. 442, Rule 3.
14286    var newStyle = styleMap[group.style];
14287    var newOptions = options.havingStyle(newStyle).withFont('');
14288    return sizingGroup(group.body, newOptions, options);
14289  },
14290
14291  mathmlBuilder(group, options) {
14292    // Figure out what style we're changing to.
14293    var newStyle = styleMap[group.style];
14294    var newOptions = options.havingStyle(newStyle);
14295    var inner = buildExpression(group.body, newOptions);
14296    var node = new mathMLTree.MathNode("mstyle", inner);
14297    var styleAttributes = {
14298      "display": ["0", "true"],
14299      "text": ["0", "false"],
14300      "script": ["1", "false"],
14301      "scriptscript": ["2", "false"]
14302    };
14303    var attr = styleAttributes[group.style];
14304    node.setAttribute("scriptlevel", attr[0]);
14305    node.setAttribute("displaystyle", attr[1]);
14306    return node;
14307  }
14308
14309});
14310
14311/**
14312 * Sometimes, groups perform special rules when they have superscripts or
14313 * subscripts attached to them. This function lets the `supsub` group know that
14314 * Sometimes, groups perform special rules when they have superscripts or
14315 * its inner element should handle the superscripts and subscripts instead of
14316 * handling them itself.
14317 */
14318var htmlBuilderDelegate = function htmlBuilderDelegate(group, options) {
14319  var base = group.base;
14320
14321  if (!base) {
14322    return null;
14323  } else if (base.type === "op") {
14324    // Operators handle supsubs differently when they have limits
14325    // (e.g. `\displaystyle\sum_2^3`)
14326    var delegate = base.limits && (options.style.size === Style$1.DISPLAY.size || base.alwaysHandleSupSub);
14327    return delegate ? htmlBuilder$2 : null;
14328  } else if (base.type === "operatorname") {
14329    var _delegate = base.alwaysHandleSupSub && (options.style.size === Style$1.DISPLAY.size || base.limits);
14330
14331    return _delegate ? htmlBuilder$1 : null;
14332  } else if (base.type === "accent") {
14333    return utils.isCharacterBox(base.base) ? htmlBuilder$a : null;
14334  } else if (base.type === "horizBrace") {
14335    var isSup = !group.sub;
14336    return isSup === base.isOver ? htmlBuilder$3 : null;
14337  } else {
14338    return null;
14339  }
14340}; // Super scripts and subscripts, whose precise placement can depend on other
14341// functions that precede them.
14342
14343
14344defineFunctionBuilders({
14345  type: "supsub",
14346
14347  htmlBuilder(group, options) {
14348    // Superscript and subscripts are handled in the TeXbook on page
14349    // 445-446, rules 18(a-f).
14350    // Here is where we defer to the inner group if it should handle
14351    // superscripts and subscripts itself.
14352    var builderDelegate = htmlBuilderDelegate(group, options);
14353
14354    if (builderDelegate) {
14355      return builderDelegate(group, options);
14356    }
14357
14358    var {
14359      base: valueBase,
14360      sup: valueSup,
14361      sub: valueSub
14362    } = group;
14363    var base = buildGroup$1(valueBase, options);
14364    var supm;
14365    var subm;
14366    var metrics = options.fontMetrics(); // Rule 18a
14367
14368    var supShift = 0;
14369    var subShift = 0;
14370    var isCharacterBox = valueBase && utils.isCharacterBox(valueBase);
14371
14372    if (valueSup) {
14373      var newOptions = options.havingStyle(options.style.sup());
14374      supm = buildGroup$1(valueSup, newOptions, options);
14375
14376      if (!isCharacterBox) {
14377        supShift = base.height - newOptions.fontMetrics().supDrop * newOptions.sizeMultiplier / options.sizeMultiplier;
14378      }
14379    }
14380
14381    if (valueSub) {
14382      var _newOptions = options.havingStyle(options.style.sub());
14383
14384      subm = buildGroup$1(valueSub, _newOptions, options);
14385
14386      if (!isCharacterBox) {
14387        subShift = base.depth + _newOptions.fontMetrics().subDrop * _newOptions.sizeMultiplier / options.sizeMultiplier;
14388      }
14389    } // Rule 18c
14390
14391
14392    var minSupShift;
14393
14394    if (options.style === Style$1.DISPLAY) {
14395      minSupShift = metrics.sup1;
14396    } else if (options.style.cramped) {
14397      minSupShift = metrics.sup3;
14398    } else {
14399      minSupShift = metrics.sup2;
14400    } // scriptspace is a font-size-independent size, so scale it
14401    // appropriately for use as the marginRight.
14402
14403
14404    var multiplier = options.sizeMultiplier;
14405    var marginRight = makeEm(0.5 / metrics.ptPerEm / multiplier);
14406    var marginLeft = null;
14407
14408    if (subm) {
14409      // Subscripts shouldn't be shifted by the base's italic correction.
14410      // Account for that by shifting the subscript back the appropriate
14411      // amount. Note we only do this when the base is a single symbol.
14412      var isOiint = group.base && group.base.type === "op" && group.base.name && (group.base.name === "\\oiint" || group.base.name === "\\oiiint");
14413
14414      if (base instanceof SymbolNode || isOiint) {
14415        // $FlowFixMe
14416        marginLeft = makeEm(-base.italic);
14417      }
14418    }
14419
14420    var supsub;
14421
14422    if (supm && subm) {
14423      supShift = Math.max(supShift, minSupShift, supm.depth + 0.25 * metrics.xHeight);
14424      subShift = Math.max(subShift, metrics.sub2);
14425      var ruleWidth = metrics.defaultRuleThickness; // Rule 18e
14426
14427      var maxWidth = 4 * ruleWidth;
14428
14429      if (supShift - supm.depth - (subm.height - subShift) < maxWidth) {
14430        subShift = maxWidth - (supShift - supm.depth) + subm.height;
14431        var psi = 0.8 * metrics.xHeight - (supShift - supm.depth);
14432
14433        if (psi > 0) {
14434          supShift += psi;
14435          subShift -= psi;
14436        }
14437      }
14438
14439      var vlistElem = [{
14440        type: "elem",
14441        elem: subm,
14442        shift: subShift,
14443        marginRight,
14444        marginLeft
14445      }, {
14446        type: "elem",
14447        elem: supm,
14448        shift: -supShift,
14449        marginRight
14450      }];
14451      supsub = buildCommon.makeVList({
14452        positionType: "individualShift",
14453        children: vlistElem
14454      }, options);
14455    } else if (subm) {
14456      // Rule 18b
14457      subShift = Math.max(subShift, metrics.sub1, subm.height - 0.8 * metrics.xHeight);
14458      var _vlistElem = [{
14459        type: "elem",
14460        elem: subm,
14461        marginLeft,
14462        marginRight
14463      }];
14464      supsub = buildCommon.makeVList({
14465        positionType: "shift",
14466        positionData: subShift,
14467        children: _vlistElem
14468      }, options);
14469    } else if (supm) {
14470      // Rule 18c, d
14471      supShift = Math.max(supShift, minSupShift, supm.depth + 0.25 * metrics.xHeight);
14472      supsub = buildCommon.makeVList({
14473        positionType: "shift",
14474        positionData: -supShift,
14475        children: [{
14476          type: "elem",
14477          elem: supm,
14478          marginRight
14479        }]
14480      }, options);
14481    } else {
14482      throw new Error("supsub must have either sup or sub.");
14483    } // Wrap the supsub vlist in a span.msupsub to reset text-align.
14484
14485
14486    var mclass = getTypeOfDomTree(base, "right") || "mord";
14487    return buildCommon.makeSpan([mclass], [base, buildCommon.makeSpan(["msupsub"], [supsub])], options);
14488  },
14489
14490  mathmlBuilder(group, options) {
14491    // Is the inner group a relevant horizonal brace?
14492    var isBrace = false;
14493    var isOver;
14494    var isSup;
14495
14496    if (group.base && group.base.type === "horizBrace") {
14497      isSup = !!group.sup;
14498
14499      if (isSup === group.base.isOver) {
14500        isBrace = true;
14501        isOver = group.base.isOver;
14502      }
14503    }
14504
14505    if (group.base && (group.base.type === "op" || group.base.type === "operatorname")) {
14506      group.base.parentIsSupSub = true;
14507    }
14508
14509    var children = [buildGroup(group.base, options)];
14510
14511    if (group.sub) {
14512      children.push(buildGroup(group.sub, options));
14513    }
14514
14515    if (group.sup) {
14516      children.push(buildGroup(group.sup, options));
14517    }
14518
14519    var nodeType;
14520
14521    if (isBrace) {
14522      nodeType = isOver ? "mover" : "munder";
14523    } else if (!group.sub) {
14524      var base = group.base;
14525
14526      if (base && base.type === "op" && base.limits && (options.style === Style$1.DISPLAY || base.alwaysHandleSupSub)) {
14527        nodeType = "mover";
14528      } else if (base && base.type === "operatorname" && base.alwaysHandleSupSub && (base.limits || options.style === Style$1.DISPLAY)) {
14529        nodeType = "mover";
14530      } else {
14531        nodeType = "msup";
14532      }
14533    } else if (!group.sup) {
14534      var _base = group.base;
14535
14536      if (_base && _base.type === "op" && _base.limits && (options.style === Style$1.DISPLAY || _base.alwaysHandleSupSub)) {
14537        nodeType = "munder";
14538      } else if (_base && _base.type === "operatorname" && _base.alwaysHandleSupSub && (_base.limits || options.style === Style$1.DISPLAY)) {
14539        nodeType = "munder";
14540      } else {
14541        nodeType = "msub";
14542      }
14543    } else {
14544      var _base2 = group.base;
14545
14546      if (_base2 && _base2.type === "op" && _base2.limits && options.style === Style$1.DISPLAY) {
14547        nodeType = "munderover";
14548      } else if (_base2 && _base2.type === "operatorname" && _base2.alwaysHandleSupSub && (options.style === Style$1.DISPLAY || _base2.limits)) {
14549        nodeType = "munderover";
14550      } else {
14551        nodeType = "msubsup";
14552      }
14553    }
14554
14555    return new mathMLTree.MathNode(nodeType, children);
14556  }
14557
14558});
14559
14560defineFunctionBuilders({
14561  type: "atom",
14562
14563  htmlBuilder(group, options) {
14564    return buildCommon.mathsym(group.text, group.mode, options, ["m" + group.family]);
14565  },
14566
14567  mathmlBuilder(group, options) {
14568    var node = new mathMLTree.MathNode("mo", [makeText(group.text, group.mode)]);
14569
14570    if (group.family === "bin") {
14571      var variant = getVariant(group, options);
14572
14573      if (variant === "bold-italic") {
14574        node.setAttribute("mathvariant", variant);
14575      }
14576    } else if (group.family === "punct") {
14577      node.setAttribute("separator", "true");
14578    } else if (group.family === "open" || group.family === "close") {
14579      // Delims built here should not stretch vertically.
14580      // See delimsizing.js for stretchy delims.
14581      node.setAttribute("stretchy", "false");
14582    }
14583
14584    return node;
14585  }
14586
14587});
14588
14589// "mathord" and "textord" ParseNodes created in Parser.js from symbol Groups in
14590// src/symbols.js.
14591var defaultVariant = {
14592  "mi": "italic",
14593  "mn": "normal",
14594  "mtext": "normal"
14595};
14596defineFunctionBuilders({
14597  type: "mathord",
14598
14599  htmlBuilder(group, options) {
14600    return buildCommon.makeOrd(group, options, "mathord");
14601  },
14602
14603  mathmlBuilder(group, options) {
14604    var node = new mathMLTree.MathNode("mi", [makeText(group.text, group.mode, options)]);
14605    var variant = getVariant(group, options) || "italic";
14606
14607    if (variant !== defaultVariant[node.type]) {
14608      node.setAttribute("mathvariant", variant);
14609    }
14610
14611    return node;
14612  }
14613
14614});
14615defineFunctionBuilders({
14616  type: "textord",
14617
14618  htmlBuilder(group, options) {
14619    return buildCommon.makeOrd(group, options, "textord");
14620  },
14621
14622  mathmlBuilder(group, options) {
14623    var text = makeText(group.text, group.mode, options);
14624    var variant = getVariant(group, options) || "normal";
14625    var node;
14626
14627    if (group.mode === 'text') {
14628      node = new mathMLTree.MathNode("mtext", [text]);
14629    } else if (/[0-9]/.test(group.text)) {
14630      node = new mathMLTree.MathNode("mn", [text]);
14631    } else if (group.text === "\\prime") {
14632      node = new mathMLTree.MathNode("mo", [text]);
14633    } else {
14634      node = new mathMLTree.MathNode("mi", [text]);
14635    }
14636
14637    if (variant !== defaultVariant[node.type]) {
14638      node.setAttribute("mathvariant", variant);
14639    }
14640
14641    return node;
14642  }
14643
14644});
14645
14646var cssSpace = {
14647  "\\nobreak": "nobreak",
14648  "\\allowbreak": "allowbreak"
14649}; // A lookup table to determine whether a spacing function/symbol should be
14650// treated like a regular space character.  If a symbol or command is a key
14651// in this table, then it should be a regular space character.  Furthermore,
14652// the associated value may have a `className` specifying an extra CSS class
14653// to add to the created `span`.
14654
14655var regularSpace = {
14656  " ": {},
14657  "\\ ": {},
14658  "~": {
14659    className: "nobreak"
14660  },
14661  "\\space": {},
14662  "\\nobreakspace": {
14663    className: "nobreak"
14664  }
14665}; // ParseNode<"spacing"> created in Parser.js from the "spacing" symbol Groups in
14666// src/symbols.js.
14667
14668defineFunctionBuilders({
14669  type: "spacing",
14670
14671  htmlBuilder(group, options) {
14672    if (regularSpace.hasOwnProperty(group.text)) {
14673      var className = regularSpace[group.text].className || ""; // Spaces are generated by adding an actual space. Each of these
14674      // things has an entry in the symbols table, so these will be turned
14675      // into appropriate outputs.
14676
14677      if (group.mode === "text") {
14678        var ord = buildCommon.makeOrd(group, options, "textord");
14679        ord.classes.push(className);
14680        return ord;
14681      } else {
14682        return buildCommon.makeSpan(["mspace", className], [buildCommon.mathsym(group.text, group.mode, options)], options);
14683      }
14684    } else if (cssSpace.hasOwnProperty(group.text)) {
14685      // Spaces based on just a CSS class.
14686      return buildCommon.makeSpan(["mspace", cssSpace[group.text]], [], options);
14687    } else {
14688      throw new ParseError("Unknown type of space \"" + group.text + "\"");
14689    }
14690  },
14691
14692  mathmlBuilder(group, options) {
14693    var node;
14694
14695    if (regularSpace.hasOwnProperty(group.text)) {
14696      node = new mathMLTree.MathNode("mtext", [new mathMLTree.TextNode("\u00a0")]);
14697    } else if (cssSpace.hasOwnProperty(group.text)) {
14698      // CSS-based MathML spaces (\nobreak, \allowbreak) are ignored
14699      return new mathMLTree.MathNode("mspace");
14700    } else {
14701      throw new ParseError("Unknown type of space \"" + group.text + "\"");
14702    }
14703
14704    return node;
14705  }
14706
14707});
14708
14709var pad = () => {
14710  var padNode = new mathMLTree.MathNode("mtd", []);
14711  padNode.setAttribute("width", "50%");
14712  return padNode;
14713};
14714
14715defineFunctionBuilders({
14716  type: "tag",
14717
14718  mathmlBuilder(group, options) {
14719    var table = new mathMLTree.MathNode("mtable", [new mathMLTree.MathNode("mtr", [pad(), new mathMLTree.MathNode("mtd", [buildExpressionRow(group.body, options)]), pad(), new mathMLTree.MathNode("mtd", [buildExpressionRow(group.tag, options)])])]);
14720    table.setAttribute("width", "100%");
14721    return table; // TODO: Left-aligned tags.
14722    // Currently, the group and options passed here do not contain
14723    // enough info to set tag alignment. `leqno` is in Settings but it is
14724    // not passed to Options. On the HTML side, leqno is
14725    // set by a CSS class applied in buildTree.js. That would have worked
14726    // in MathML if browsers supported <mlabeledtr>. Since they don't, we
14727    // need to rewrite the way this function is called.
14728  }
14729
14730});
14731
14732var textFontFamilies = {
14733  "\\text": undefined,
14734  "\\textrm": "textrm",
14735  "\\textsf": "textsf",
14736  "\\texttt": "texttt",
14737  "\\textnormal": "textrm"
14738};
14739var textFontWeights = {
14740  "\\textbf": "textbf",
14741  "\\textmd": "textmd"
14742};
14743var textFontShapes = {
14744  "\\textit": "textit",
14745  "\\textup": "textup"
14746};
14747
14748var optionsWithFont = (group, options) => {
14749  var font = group.font; // Checks if the argument is a font family or a font style.
14750
14751  if (!font) {
14752    return options;
14753  } else if (textFontFamilies[font]) {
14754    return options.withTextFontFamily(textFontFamilies[font]);
14755  } else if (textFontWeights[font]) {
14756    return options.withTextFontWeight(textFontWeights[font]);
14757  } else if (font === "\\emph") {
14758    return options.fontShape === "textit" ? options.withTextFontShape("textup") : options.withTextFontShape("textit");
14759  }
14760
14761  return options.withTextFontShape(textFontShapes[font]);
14762};
14763
14764defineFunction({
14765  type: "text",
14766  names: [// Font families
14767  "\\text", "\\textrm", "\\textsf", "\\texttt", "\\textnormal", // Font weights
14768  "\\textbf", "\\textmd", // Font Shapes
14769  "\\textit", "\\textup", "\\emph"],
14770  props: {
14771    numArgs: 1,
14772    argTypes: ["text"],
14773    allowedInArgument: true,
14774    allowedInText: true
14775  },
14776
14777  handler(_ref, args) {
14778    var {
14779      parser,
14780      funcName
14781    } = _ref;
14782    var body = args[0];
14783    return {
14784      type: "text",
14785      mode: parser.mode,
14786      body: ordargument(body),
14787      font: funcName
14788    };
14789  },
14790
14791  htmlBuilder(group, options) {
14792    var newOptions = optionsWithFont(group, options);
14793    var inner = buildExpression$1(group.body, newOptions, true);
14794    return buildCommon.makeSpan(["mord", "text"], inner, newOptions);
14795  },
14796
14797  mathmlBuilder(group, options) {
14798    var newOptions = optionsWithFont(group, options);
14799    return buildExpressionRow(group.body, newOptions);
14800  }
14801
14802});
14803
14804defineFunction({
14805  type: "underline",
14806  names: ["\\underline"],
14807  props: {
14808    numArgs: 1,
14809    allowedInText: true
14810  },
14811
14812  handler(_ref, args) {
14813    var {
14814      parser
14815    } = _ref;
14816    return {
14817      type: "underline",
14818      mode: parser.mode,
14819      body: args[0]
14820    };
14821  },
14822
14823  htmlBuilder(group, options) {
14824    // Underlines are handled in the TeXbook pg 443, Rule 10.
14825    // Build the inner group.
14826    var innerGroup = buildGroup$1(group.body, options); // Create the line to go below the body
14827
14828    var line = buildCommon.makeLineSpan("underline-line", options); // Generate the vlist, with the appropriate kerns
14829
14830    var defaultRuleThickness = options.fontMetrics().defaultRuleThickness;
14831    var vlist = buildCommon.makeVList({
14832      positionType: "top",
14833      positionData: innerGroup.height,
14834      children: [{
14835        type: "kern",
14836        size: defaultRuleThickness
14837      }, {
14838        type: "elem",
14839        elem: line
14840      }, {
14841        type: "kern",
14842        size: 3 * defaultRuleThickness
14843      }, {
14844        type: "elem",
14845        elem: innerGroup
14846      }]
14847    }, options);
14848    return buildCommon.makeSpan(["mord", "underline"], [vlist], options);
14849  },
14850
14851  mathmlBuilder(group, options) {
14852    var operator = new mathMLTree.MathNode("mo", [new mathMLTree.TextNode("\u203e")]);
14853    operator.setAttribute("stretchy", "true");
14854    var node = new mathMLTree.MathNode("munder", [buildGroup(group.body, options), operator]);
14855    node.setAttribute("accentunder", "true");
14856    return node;
14857  }
14858
14859});
14860
14861defineFunction({
14862  type: "vcenter",
14863  names: ["\\vcenter"],
14864  props: {
14865    numArgs: 1,
14866    argTypes: ["original"],
14867    // In LaTeX, \vcenter can act only on a box.
14868    allowedInText: false
14869  },
14870
14871  handler(_ref, args) {
14872    var {
14873      parser
14874    } = _ref;
14875    return {
14876      type: "vcenter",
14877      mode: parser.mode,
14878      body: args[0]
14879    };
14880  },
14881
14882  htmlBuilder(group, options) {
14883    var body = buildGroup$1(group.body, options);
14884    var axisHeight = options.fontMetrics().axisHeight;
14885    var dy = 0.5 * (body.height - axisHeight - (body.depth + axisHeight));
14886    return buildCommon.makeVList({
14887      positionType: "shift",
14888      positionData: dy,
14889      children: [{
14890        type: "elem",
14891        elem: body
14892      }]
14893    }, options);
14894  },
14895
14896  mathmlBuilder(group, options) {
14897    // There is no way to do this in MathML.
14898    // Write a class as a breadcrumb in case some post-processor wants
14899    // to perform a vcenter adjustment.
14900    return new mathMLTree.MathNode("mpadded", [buildGroup(group.body, options)], ["vcenter"]);
14901  }
14902
14903});
14904
14905defineFunction({
14906  type: "verb",
14907  names: ["\\verb"],
14908  props: {
14909    numArgs: 0,
14910    allowedInText: true
14911  },
14912
14913  handler(context, args, optArgs) {
14914    // \verb and \verb* are dealt with directly in Parser.js.
14915    // If we end up here, it's because of a failure to match the two delimiters
14916    // in the regex in Lexer.js.  LaTeX raises the following error when \verb is
14917    // terminated by end of line (or file).
14918    throw new ParseError("\\verb ended by end of line instead of matching delimiter");
14919  },
14920
14921  htmlBuilder(group, options) {
14922    var text = makeVerb(group);
14923    var body = []; // \verb enters text mode and therefore is sized like \textstyle
14924
14925    var newOptions = options.havingStyle(options.style.text());
14926
14927    for (var i = 0; i < text.length; i++) {
14928      var c = text[i];
14929
14930      if (c === '~') {
14931        c = '\\textasciitilde';
14932      }
14933
14934      body.push(buildCommon.makeSymbol(c, "Typewriter-Regular", group.mode, newOptions, ["mord", "texttt"]));
14935    }
14936
14937    return buildCommon.makeSpan(["mord", "text"].concat(newOptions.sizingClasses(options)), buildCommon.tryCombineChars(body), newOptions);
14938  },
14939
14940  mathmlBuilder(group, options) {
14941    var text = new mathMLTree.TextNode(makeVerb(group));
14942    var node = new mathMLTree.MathNode("mtext", [text]);
14943    node.setAttribute("mathvariant", "monospace");
14944    return node;
14945  }
14946
14947});
14948/**
14949 * Converts verb group into body string.
14950 *
14951 * \verb* replaces each space with an open box \u2423
14952 * \verb replaces each space with a no-break space \xA0
14953 */
14954
14955var makeVerb = group => group.body.replace(/ /g, group.star ? '\u2423' : '\xA0');
14956
14957/** Include this to ensure that all functions are defined. */
14958var functions = _functions;
14959
14960/**
14961 * The Lexer class handles tokenizing the input in various ways. Since our
14962 * parser expects us to be able to backtrack, the lexer allows lexing from any
14963 * given starting point.
14964 *
14965 * Its main exposed function is the `lex` function, which takes a position to
14966 * lex from and a type of token to lex. It defers to the appropriate `_innerLex`
14967 * function.
14968 *
14969 * The various `_innerLex` functions perform the actual lexing of different
14970 * kinds.
14971 */
14972
14973/* The following tokenRegex
14974 * - matches typical whitespace (but not NBSP etc.) using its first group
14975 * - does not match any control character \x00-\x1f except whitespace
14976 * - does not match a bare backslash
14977 * - matches any ASCII character except those just mentioned
14978 * - does not match the BMP private use area \uE000-\uF8FF
14979 * - does not match bare surrogate code units
14980 * - matches any BMP character except for those just described
14981 * - matches any valid Unicode surrogate pair
14982 * - matches a backslash followed by one or more whitespace characters
14983 * - matches a backslash followed by one or more letters then whitespace
14984 * - matches a backslash followed by any BMP character
14985 * Capturing groups:
14986 *   [1] regular whitespace
14987 *   [2] backslash followed by whitespace
14988 *   [3] anything else, which may include:
14989 *     [4] left character of \verb*
14990 *     [5] left character of \verb
14991 *     [6] backslash followed by word, excluding any trailing whitespace
14992 * Just because the Lexer matches something doesn't mean it's valid input:
14993 * If there is no matching function or symbol definition, the Parser will
14994 * still reject the input.
14995 */
14996var spaceRegexString = "[ \r\n\t]";
14997var controlWordRegexString = "\\\\[a-zA-Z@]+";
14998var controlSymbolRegexString = "\\\\[^\uD800-\uDFFF]";
14999var controlWordWhitespaceRegexString = "(" + controlWordRegexString + ")" + spaceRegexString + "*";
15000var controlSpaceRegexString = "\\\\(\n|[ \r\t]+\n?)[ \r\t]*";
15001var combiningDiacriticalMarkString = "[\u0300-\u036f]";
15002var combiningDiacriticalMarksEndRegex = new RegExp(combiningDiacriticalMarkString + "+$");
15003var tokenRegexString = "(" + spaceRegexString + "+)|" + ( // whitespace
15004controlSpaceRegexString + "|") + // \whitespace
15005"([!-\\[\\]-\u2027\u202A-\uD7FF\uF900-\uFFFF]" + ( // single codepoint
15006combiningDiacriticalMarkString + "*") + // ...plus accents
15007"|[\uD800-\uDBFF][\uDC00-\uDFFF]" + ( // surrogate pair
15008combiningDiacriticalMarkString + "*") + // ...plus accents
15009"|\\\\verb\\*([^]).*?\\4" + // \verb*
15010"|\\\\verb([^*a-zA-Z]).*?\\5" + ( // \verb unstarred
15011"|" + controlWordWhitespaceRegexString) + ( // \macroName + spaces
15012"|" + controlSymbolRegexString + ")"); // \\, \', etc.
15013
15014/** Main Lexer class */
15015
15016class Lexer {
15017  // Category codes. The lexer only supports comment characters (14) for now.
15018  // MacroExpander additionally distinguishes active (13).
15019  constructor(input, settings) {
15020    this.input = void 0;
15021    this.settings = void 0;
15022    this.tokenRegex = void 0;
15023    this.catcodes = void 0;
15024    // Separate accents from characters
15025    this.input = input;
15026    this.settings = settings;
15027    this.tokenRegex = new RegExp(tokenRegexString, 'g');
15028    this.catcodes = {
15029      "%": 14,
15030      // comment character
15031      "~": 13 // active character
15032
15033    };
15034  }
15035
15036  setCatcode(char, code) {
15037    this.catcodes[char] = code;
15038  }
15039  /**
15040   * This function lexes a single token.
15041   */
15042
15043
15044  lex() {
15045    var input = this.input;
15046    var pos = this.tokenRegex.lastIndex;
15047
15048    if (pos === input.length) {
15049      return new Token("EOF", new SourceLocation(this, pos, pos));
15050    }
15051
15052    var match = this.tokenRegex.exec(input);
15053
15054    if (match === null || match.index !== pos) {
15055      throw new ParseError("Unexpected character: '" + input[pos] + "'", new Token(input[pos], new SourceLocation(this, pos, pos + 1)));
15056    }
15057
15058    var text = match[6] || match[3] || (match[2] ? "\\ " : " ");
15059
15060    if (this.catcodes[text] === 14) {
15061      // comment character
15062      var nlIndex = input.indexOf('\n', this.tokenRegex.lastIndex);
15063
15064      if (nlIndex === -1) {
15065        this.tokenRegex.lastIndex = input.length; // EOF
15066
15067        this.settings.reportNonstrict("commentAtEnd", "% comment has no terminating newline; LaTeX would " + "fail because of commenting the end of math mode (e.g. $)");
15068      } else {
15069        this.tokenRegex.lastIndex = nlIndex + 1;
15070      }
15071
15072      return this.lex();
15073    }
15074
15075    return new Token(text, new SourceLocation(this, pos, this.tokenRegex.lastIndex));
15076  }
15077
15078}
15079
15080/**
15081 * A `Namespace` refers to a space of nameable things like macros or lengths,
15082 * which can be `set` either globally or local to a nested group, using an
15083 * undo stack similar to how TeX implements this functionality.
15084 * Performance-wise, `get` and local `set` take constant time, while global
15085 * `set` takes time proportional to the depth of group nesting.
15086 */
15087class Namespace {
15088  /**
15089   * Both arguments are optional.  The first argument is an object of
15090   * built-in mappings which never change.  The second argument is an object
15091   * of initial (global-level) mappings, which will constantly change
15092   * according to any global/top-level `set`s done.
15093   */
15094  constructor(builtins, globalMacros) {
15095    if (builtins === void 0) {
15096      builtins = {};
15097    }
15098
15099    if (globalMacros === void 0) {
15100      globalMacros = {};
15101    }
15102
15103    this.current = void 0;
15104    this.builtins = void 0;
15105    this.undefStack = void 0;
15106    this.current = globalMacros;
15107    this.builtins = builtins;
15108    this.undefStack = [];
15109  }
15110  /**
15111   * Start a new nested group, affecting future local `set`s.
15112   */
15113
15114
15115  beginGroup() {
15116    this.undefStack.push({});
15117  }
15118  /**
15119   * End current nested group, restoring values before the group began.
15120   */
15121
15122
15123  endGroup() {
15124    if (this.undefStack.length === 0) {
15125      throw new ParseError("Unbalanced namespace destruction: attempt " + "to pop global namespace; please report this as a bug");
15126    }
15127
15128    var undefs = this.undefStack.pop();
15129
15130    for (var undef in undefs) {
vendor: 7,756 bytes, lines 15131-15409
15131      if (undefs.hasOwnProperty(undef)) {
15132        if (undefs[undef] == null) {
15133          delete this.current[undef];
15134        } else {
15135          this.current[undef] = undefs[undef];
15136        }
15137      }
15138    }
15139  }
15140  /**
15141   * Ends all currently nested groups (if any), restoring values before the
15142   * groups began.  Useful in case of an error in the middle of parsing.
15143   */
15144
15145
15146  endGroups() {
15147    while (this.undefStack.length > 0) {
15148      this.endGroup();
15149    }
15150  }
15151  /**
15152   * Detect whether `name` has a definition.  Equivalent to
15153   * `get(name) != null`.
15154   */
15155
15156
15157  has(name) {
15158    return this.current.hasOwnProperty(name) || this.builtins.hasOwnProperty(name);
15159  }
15160  /**
15161   * Get the current value of a name, or `undefined` if there is no value.
15162   *
15163   * Note: Do not use `if (namespace.get(...))` to detect whether a macro
15164   * is defined, as the definition may be the empty string which evaluates
15165   * to `false` in JavaScript.  Use `if (namespace.get(...) != null)` or
15166   * `if (namespace.has(...))`.
15167   */
15168
15169
15170  get(name) {
15171    if (this.current.hasOwnProperty(name)) {
15172      return this.current[name];
15173    } else {
15174      return this.builtins[name];
15175    }
15176  }
15177  /**
15178   * Set the current value of a name, and optionally set it globally too.
15179   * Local set() sets the current value and (when appropriate) adds an undo
15180   * operation to the undo stack.  Global set() may change the undo
15181   * operation at every level, so takes time linear in their number.
15182   * A value of undefined means to delete existing definitions.
15183   */
15184
15185
15186  set(name, value, global) {
15187    if (global === void 0) {
15188      global = false;
15189    }
15190
15191    if (global) {
15192      // Global set is equivalent to setting in all groups.  Simulate this
15193      // by destroying any undos currently scheduled for this name,
15194      // and adding an undo with the *new* value (in case it later gets
15195      // locally reset within this environment).
15196      for (var i = 0; i < this.undefStack.length; i++) {
15197        delete this.undefStack[i][name];
15198      }
15199
15200      if (this.undefStack.length > 0) {
15201        this.undefStack[this.undefStack.length - 1][name] = value;
15202      }
15203    } else {
15204      // Undo this set at end of this group (possibly to `undefined`),
15205      // unless an undo is already in place, in which case that older
15206      // value is the correct one.
15207      var top = this.undefStack[this.undefStack.length - 1];
15208
15209      if (top && !top.hasOwnProperty(name)) {
15210        top[name] = this.current[name];
15211      }
15212    }
15213
15214    if (value == null) {
15215      delete this.current[name];
15216    } else {
15217      this.current[name] = value;
15218    }
15219  }
15220
15221}
15222
15223/**
15224 * Predefined macros for KaTeX.
15225 * This can be used to define some commands in terms of others.
15226 */
15227var macros = _macros;
15228// macro tools
15229
15230defineMacro("\\noexpand", function (context) {
15231  // The expansion is the token itself; but that token is interpreted
15232  // as if its meaning were ‘\relax’ if it is a control sequence that
15233  // would ordinarily be expanded by TeX’s expansion rules.
15234  var t = context.popToken();
15235
15236  if (context.isExpandable(t.text)) {
15237    t.noexpand = true;
15238    t.treatAsRelax = true;
15239  }
15240
15241  return {
15242    tokens: [t],
15243    numArgs: 0
15244  };
15245});
15246defineMacro("\\expandafter", function (context) {
15247  // TeX first reads the token that comes immediately after \expandafter,
15248  // without expanding it; let’s call this token t. Then TeX reads the
15249  // token that comes after t (and possibly more tokens, if that token
15250  // has an argument), replacing it by its expansion. Finally TeX puts
15251  // t back in front of that expansion.
15252  var t = context.popToken();
15253  context.expandOnce(true); // expand only an expandable token
15254
15255  return {
15256    tokens: [t],
15257    numArgs: 0
15258  };
15259}); // LaTeX's \@firstoftwo{#1}{#2} expands to #1, skipping #2
15260// TeX source: \long\def\@firstoftwo#1#2{#1}
15261
15262defineMacro("\\@firstoftwo", function (context) {
15263  var args = context.consumeArgs(2);
15264  return {
15265    tokens: args[0],
15266    numArgs: 0
15267  };
15268}); // LaTeX's \@secondoftwo{#1}{#2} expands to #2, skipping #1
15269// TeX source: \long\def\@secondoftwo#1#2{#2}
15270
15271defineMacro("\\@secondoftwo", function (context) {
15272  var args = context.consumeArgs(2);
15273  return {
15274    tokens: args[1],
15275    numArgs: 0
15276  };
15277}); // LaTeX's \@ifnextchar{#1}{#2}{#3} looks ahead to the next (unexpanded)
15278// symbol that isn't a space, consuming any spaces but not consuming the
15279// first nonspace character.  If that nonspace character matches #1, then
15280// the macro expands to #2; otherwise, it expands to #3.
15281
15282defineMacro("\\@ifnextchar", function (context) {
15283  var args = context.consumeArgs(3); // symbol, if, else
15284
15285  context.consumeSpaces();
15286  var nextToken = context.future();
15287
15288  if (args[0].length === 1 && args[0][0].text === nextToken.text) {
15289    return {
15290      tokens: args[1],
15291      numArgs: 0
15292    };
15293  } else {
15294    return {
15295      tokens: args[2],
15296      numArgs: 0
15297    };
15298  }
15299}); // LaTeX's \@ifstar{#1}{#2} looks ahead to the next (unexpanded) symbol.
15300// If it is `*`, then it consumes the symbol, and the macro expands to #1;
15301// otherwise, the macro expands to #2 (without consuming the symbol).
15302// TeX source: \def\@ifstar#1{\@ifnextchar *{\@firstoftwo{#1}}}
15303
15304defineMacro("\\@ifstar", "\\@ifnextchar *{\\@firstoftwo{#1}}"); // LaTeX's \TextOrMath{#1}{#2} expands to #1 in text mode, #2 in math mode
15305
15306defineMacro("\\TextOrMath", function (context) {
15307  var args = context.consumeArgs(2);
15308
15309  if (context.mode === 'text') {
15310    return {
15311      tokens: args[0],
15312      numArgs: 0
15313    };
15314  } else {
15315    return {
15316      tokens: args[1],
15317      numArgs: 0
15318    };
15319  }
15320}); // Lookup table for parsing numbers in base 8 through 16
15321
15322var digitToNumber = {
15323  "0": 0,
15324  "1": 1,
15325  "2": 2,
15326  "3": 3,
15327  "4": 4,
15328  "5": 5,
15329  "6": 6,
15330  "7": 7,
15331  "8": 8,
15332  "9": 9,
15333  "a": 10,
15334  "A": 10,
15335  "b": 11,
15336  "B": 11,
15337  "c": 12,
15338  "C": 12,
15339  "d": 13,
15340  "D": 13,
15341  "e": 14,
15342  "E": 14,
15343  "f": 15,
15344  "F": 15
15345}; // TeX \char makes a literal character (catcode 12) using the following forms:
15346// (see The TeXBook, p. 43)
15347//   \char123  -- decimal
15348//   \char'123 -- octal
15349//   \char"123 -- hex
15350//   \char`x   -- character that can be written (i.e. isn't active)
15351//   \char`\x  -- character that cannot be written (e.g. %)
15352// These all refer to characters from the font, so we turn them into special
15353// calls to a function \@char dealt with in the Parser.
15354
15355defineMacro("\\char", function (context) {
15356  var token = context.popToken();
15357  var base;
15358  var number = '';
15359
15360  if (token.text === "'") {
15361    base = 8;
15362    token = context.popToken();
15363  } else if (token.text === '"') {
15364    base = 16;
15365    token = context.popToken();
15366  } else if (token.text === "`") {
15367    token = context.popToken();
15368
15369    if (token.text[0] === "\\") {
15370      number = token.text.charCodeAt(1);
15371    } else if (token.text === "EOF") {
15372      throw new ParseError("\\char` missing argument");
15373    } else {
15374      number = token.text.charCodeAt(0);
15375    }
15376  } else {
15377    base = 10;
15378  }
15379
15380  if (base) {
15381    // Parse a number in the given base, starting with first `token`.
15382    number = digitToNumber[token.text];
15383
15384    if (number == null || number >= base) {
15385      throw new ParseError("Invalid base-" + base + " digit " + token.text);
15386    }
15387
15388    var digit;
15389
15390    while ((digit = digitToNumber[context.future().text]) != null && digit < base) {
15391      number *= base;
15392      number += digit;
15393      context.popToken();
15394    }
15395  }
15396
15397  return "\\@char{" + number + "}";
15398}); // \newcommand{\macro}[args]{definition}
15399// \renewcommand{\macro}[args]{definition}
15400// TODO: Optional arguments: \newcommand{\macro}[args][default]{definition}
15401
15402var newcommand = (context, existsOK, nonexistsOK, skipIfExists) => {
15403  var arg = context.consumeArg().tokens;
15404
15405  if (arg.length !== 1) {
15406    throw new ParseError("\\newcommand's first argument must be a macro name");
15407  }
15408
15409  var name = arg[0].text;
vendor: 4,885 bytes, lines 15410-15538
15410  var exists = context.isDefined(name);
15411
15412  if (exists && !existsOK) {
15413    throw new ParseError("\\newcommand{" + name + "} attempting to redefine " + (name + "; use \\renewcommand"));
15414  }
15415
15416  if (!exists && !nonexistsOK) {
15417    throw new ParseError("\\renewcommand{" + name + "} when command " + name + " " + "does not yet exist; use \\newcommand");
15418  }
15419
15420  var numArgs = 0;
15421  arg = context.consumeArg().tokens;
15422
15423  if (arg.length === 1 && arg[0].text === "[") {
15424    var argText = '';
15425    var token = context.expandNextToken();
15426
15427    while (token.text !== "]" && token.text !== "EOF") {
15428      // TODO: Should properly expand arg, e.g., ignore {}s
15429      argText += token.text;
15430      token = context.expandNextToken();
15431    }
15432
15433    if (!argText.match(/^\s*[0-9]+\s*$/)) {
15434      throw new ParseError("Invalid number of arguments: " + argText);
15435    }
15436
15437    numArgs = parseInt(argText);
15438    arg = context.consumeArg().tokens;
15439  }
15440
15441  if (!(exists && skipIfExists)) {
15442    // Final arg is the expansion of the macro
15443    context.macros.set(name, {
15444      tokens: arg,
15445      numArgs
15446    });
15447  }
15448
15449  return '';
15450};
15451
15452defineMacro("\\newcommand", context => newcommand(context, false, true, false));
15453defineMacro("\\renewcommand", context => newcommand(context, true, false, false));
15454defineMacro("\\providecommand", context => newcommand(context, true, true, true)); // terminal (console) tools
15455
15456defineMacro("\\message", context => {
15457  var arg = context.consumeArgs(1)[0]; // eslint-disable-next-line no-console
15458
15459  console.log(arg.reverse().map(token => token.text).join(""));
15460  return '';
15461});
15462defineMacro("\\errmessage", context => {
15463  var arg = context.consumeArgs(1)[0]; // eslint-disable-next-line no-console
15464
15465  console.error(arg.reverse().map(token => token.text).join(""));
15466  return '';
15467});
15468defineMacro("\\show", context => {
15469  var tok = context.popToken();
15470  var name = tok.text; // eslint-disable-next-line no-console
15471
15472  console.log(tok, context.macros.get(name), functions[name], symbols.math[name], symbols.text[name]);
15473  return '';
15474}); //////////////////////////////////////////////////////////////////////
15475// Grouping
15476// \let\bgroup={ \let\egroup=}
15477
15478defineMacro("\\bgroup", "{");
15479defineMacro("\\egroup", "}"); // Symbols from latex.ltx:
15480// \def~{\nobreakspace{}}
15481// \def\lq{`}
15482// \def\rq{'}
15483// \def \aa {\r a}
15484// \def \AA {\r A}
15485
15486defineMacro("~", "\\nobreakspace");
15487defineMacro("\\lq", "`");
15488defineMacro("\\rq", "'");
15489defineMacro("\\aa", "\\r a");
15490defineMacro("\\AA", "\\r A"); // Copyright (C) and registered (R) symbols. Use raw symbol in MathML.
15491// \DeclareTextCommandDefault{\textcopyright}{\textcircled{c}}
15492// \DeclareTextCommandDefault{\textregistered}{\textcircled{%
15493//      \check@mathfonts\fontsize\sf@size\z@\math@fontsfalse\selectfont R}}
15494// \DeclareRobustCommand{\copyright}{%
15495//    \ifmmode{\nfss@text{\textcopyright}}\else\textcopyright\fi}
15496
15497defineMacro("\\textcopyright", "\\html@mathml{\\textcircled{c}}{\\char`©}");
15498defineMacro("\\copyright", "\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}");
15499defineMacro("\\textregistered", "\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`®}"); // Characters omitted from Unicode range 1D400–1D7FF
15500
15501defineMacro("\u212C", "\\mathscr{B}"); // script
15502
15503defineMacro("\u2130", "\\mathscr{E}");
15504defineMacro("\u2131", "\\mathscr{F}");
15505defineMacro("\u210B", "\\mathscr{H}");
15506defineMacro("\u2110", "\\mathscr{I}");
15507defineMacro("\u2112", "\\mathscr{L}");
15508defineMacro("\u2133", "\\mathscr{M}");
15509defineMacro("\u211B", "\\mathscr{R}");
15510defineMacro("\u212D", "\\mathfrak{C}"); // Fraktur
15511
15512defineMacro("\u210C", "\\mathfrak{H}");
15513defineMacro("\u2128", "\\mathfrak{Z}"); // Define \Bbbk with a macro that works in both HTML and MathML.
15514
15515defineMacro("\\Bbbk", "\\Bbb{k}"); // Unicode middle dot
15516// The KaTeX fonts do not contain U+00B7. Instead, \cdotp displays
15517// the dot at U+22C5 and gives it punct spacing.
15518
15519defineMacro("\u00b7", "\\cdotp"); // \llap and \rlap render their contents in text mode
15520
15521defineMacro("\\llap", "\\mathllap{\\textrm{#1}}");
15522defineMacro("\\rlap", "\\mathrlap{\\textrm{#1}}");
15523defineMacro("\\clap", "\\mathclap{\\textrm{#1}}"); // \mathstrut from the TeXbook, p 360
15524
15525defineMacro("\\mathstrut", "\\vphantom{(}"); // \underbar from TeXbook p 353
15526
15527defineMacro("\\underbar", "\\underline{\\text{#1}}"); // \not is defined by base/fontmath.ltx via
15528// \DeclareMathSymbol{\not}{\mathrel}{symbols}{"36}
15529// It's thus treated like a \mathrel, but defined by a symbol that has zero
15530// width but extends to the right.  We use \rlap to get that spacing.
15531// For MathML we write U+0338 here. buildMathML.js will then do the overlay.
15532
15533defineMacro("\\not", '\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'); // Negated symbols from base/fontmath.ltx:
15534// \def\neq{\not=} \let\ne=\neq
15535// \DeclareRobustCommand
15536//   \notin{\mathrel{\m@th\mathpalette\c@ncel\in}}
15537// \def\c@ncel#1#2{\m@th\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}}
15538
vendor: 6,725 bytes, lines 15539-15695
15539defineMacro("\\neq", "\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`≠}}");
15540defineMacro("\\ne", "\\neq");
15541defineMacro("\u2260", "\\neq");
15542defineMacro("\\notin", "\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}" + "{\\mathrel{\\char`∉}}");
15543defineMacro("\u2209", "\\notin"); // Unicode stacked relations
15544
15545defineMacro("\u2258", "\\html@mathml{" + "\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}" + "}{\\mathrel{\\char`\u2258}}");
15546defineMacro("\u2259", "\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}");
15547defineMacro("\u225A", "\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225A}}");
15548defineMacro("\u225B", "\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}" + "{\\mathrel{\\char`\u225B}}");
15549defineMacro("\u225D", "\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}" + "{\\mathrel{\\char`\u225D}}");
15550defineMacro("\u225E", "\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}" + "{\\mathrel{\\char`\u225E}}");
15551defineMacro("\u225F", "\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225F}}"); // Misc Unicode
15552
15553defineMacro("\u27C2", "\\perp");
15554defineMacro("\u203C", "\\mathclose{!\\mkern-0.8mu!}");
15555defineMacro("\u220C", "\\notni");
15556defineMacro("\u231C", "\\ulcorner");
15557defineMacro("\u231D", "\\urcorner");
15558defineMacro("\u231E", "\\llcorner");
15559defineMacro("\u231F", "\\lrcorner");
15560defineMacro("\u00A9", "\\copyright");
15561defineMacro("\u00AE", "\\textregistered");
15562defineMacro("\uFE0F", "\\textregistered"); // The KaTeX fonts have corners at codepoints that don't match Unicode.
15563// For MathML purposes, use the Unicode code point.
15564
15565defineMacro("\\ulcorner", "\\html@mathml{\\@ulcorner}{\\mathop{\\char\"231c}}");
15566defineMacro("\\urcorner", "\\html@mathml{\\@urcorner}{\\mathop{\\char\"231d}}");
15567defineMacro("\\llcorner", "\\html@mathml{\\@llcorner}{\\mathop{\\char\"231e}}");
15568defineMacro("\\lrcorner", "\\html@mathml{\\@lrcorner}{\\mathop{\\char\"231f}}"); //////////////////////////////////////////////////////////////////////
15569// LaTeX_2ε
15570// \vdots{\vbox{\baselineskip4\p@  \lineskiplimit\z@
15571// \kern6\p@\hbox{.}\hbox{.}\hbox{.}}}
15572// We'll call \varvdots, which gets a glyph from symbols.js.
15573// The zero-width rule gets us an equivalent to the vertical 6pt kern.
15574
15575defineMacro("\\vdots", "{\\varvdots\\rule{0pt}{15pt}}");
15576defineMacro("\u22ee", "\\vdots"); //////////////////////////////////////////////////////////////////////
15577// amsmath.sty
15578// http://mirrors.concertpass.com/tex-archive/macros/latex/required/amsmath/amsmath.pdf
15579// Italic Greek capital letters.  AMS defines these with \DeclareMathSymbol,
15580// but they are equivalent to \mathit{\Letter}.
15581
15582defineMacro("\\varGamma", "\\mathit{\\Gamma}");
15583defineMacro("\\varDelta", "\\mathit{\\Delta}");
15584defineMacro("\\varTheta", "\\mathit{\\Theta}");
15585defineMacro("\\varLambda", "\\mathit{\\Lambda}");
15586defineMacro("\\varXi", "\\mathit{\\Xi}");
15587defineMacro("\\varPi", "\\mathit{\\Pi}");
15588defineMacro("\\varSigma", "\\mathit{\\Sigma}");
15589defineMacro("\\varUpsilon", "\\mathit{\\Upsilon}");
15590defineMacro("\\varPhi", "\\mathit{\\Phi}");
15591defineMacro("\\varPsi", "\\mathit{\\Psi}");
15592defineMacro("\\varOmega", "\\mathit{\\Omega}"); //\newcommand{\substack}[1]{\subarray{c}#1\endsubarray}
15593
15594defineMacro("\\substack", "\\begin{subarray}{c}#1\\end{subarray}"); // \renewcommand{\colon}{\nobreak\mskip2mu\mathpunct{}\nonscript
15595// \mkern-\thinmuskip{:}\mskip6muplus1mu\relax}
15596
15597defineMacro("\\colon", "\\nobreak\\mskip2mu\\mathpunct{}" + "\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"); // \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}}
15598
15599defineMacro("\\boxed", "\\fbox{$\\displaystyle{#1}$}"); // \def\iff{\DOTSB\;\Longleftrightarrow\;}
15600// \def\implies{\DOTSB\;\Longrightarrow\;}
15601// \def\impliedby{\DOTSB\;\Longleftarrow\;}
15602
15603defineMacro("\\iff", "\\DOTSB\\;\\Longleftrightarrow\\;");
15604defineMacro("\\implies", "\\DOTSB\\;\\Longrightarrow\\;");
15605defineMacro("\\impliedby", "\\DOTSB\\;\\Longleftarrow\\;"); // \def\dddot#1{{\mathop{#1}\limits^{\vbox to-1.4\ex@{\kern-\tw@\ex@
15606//  \hbox{\normalfont ...}\vss}}}}
15607// We use \overset which avoids the vertical shift of \mathop.
15608
15609defineMacro("\\dddot", "{\\overset{\\raisebox{-0.1ex}{\\normalsize ...}}{#1}}");
15610defineMacro("\\ddddot", "{\\overset{\\raisebox{-0.1ex}{\\normalsize ....}}{#1}}"); // AMSMath's automatic \dots, based on \mdots@@ macro.
15611
15612var dotsByToken = {
15613  ',': '\\dotsc',
15614  '\\not': '\\dotsb',
15615  // \keybin@ checks for the following:
15616  '+': '\\dotsb',
15617  '=': '\\dotsb',
15618  '<': '\\dotsb',
15619  '>': '\\dotsb',
15620  '-': '\\dotsb',
15621  '*': '\\dotsb',
15622  ':': '\\dotsb',
15623  // Symbols whose definition starts with \DOTSB:
15624  '\\DOTSB': '\\dotsb',
15625  '\\coprod': '\\dotsb',
15626  '\\bigvee': '\\dotsb',
15627  '\\bigwedge': '\\dotsb',
15628  '\\biguplus': '\\dotsb',
15629  '\\bigcap': '\\dotsb',
15630  '\\bigcup': '\\dotsb',
15631  '\\prod': '\\dotsb',
15632  '\\sum': '\\dotsb',
15633  '\\bigotimes': '\\dotsb',
15634  '\\bigoplus': '\\dotsb',
15635  '\\bigodot': '\\dotsb',
15636  '\\bigsqcup': '\\dotsb',
15637  '\\And': '\\dotsb',
15638  '\\longrightarrow': '\\dotsb',
15639  '\\Longrightarrow': '\\dotsb',
15640  '\\longleftarrow': '\\dotsb',
15641  '\\Longleftarrow': '\\dotsb',
15642  '\\longleftrightarrow': '\\dotsb',
15643  '\\Longleftrightarrow': '\\dotsb',
15644  '\\mapsto': '\\dotsb',
15645  '\\longmapsto': '\\dotsb',
15646  '\\hookrightarrow': '\\dotsb',
15647  '\\doteq': '\\dotsb',
15648  // Symbols whose definition starts with \mathbin:
15649  '\\mathbin': '\\dotsb',
15650  // Symbols whose definition starts with \mathrel:
15651  '\\mathrel': '\\dotsb',
15652  '\\relbar': '\\dotsb',
15653  '\\Relbar': '\\dotsb',
15654  '\\xrightarrow': '\\dotsb',
15655  '\\xleftarrow': '\\dotsb',
15656  // Symbols whose definition starts with \DOTSI:
15657  '\\DOTSI': '\\dotsi',
15658  '\\int': '\\dotsi',
15659  '\\oint': '\\dotsi',
15660  '\\iint': '\\dotsi',
15661  '\\iiint': '\\dotsi',
15662  '\\iiiint': '\\dotsi',
15663  '\\idotsint': '\\dotsi',
15664  // Symbols whose definition starts with \DOTSX:
15665  '\\DOTSX': '\\dotsx'
15666};
15667defineMacro("\\dots", function (context) {
15668  // TODO: If used in text mode, should expand to \textellipsis.
15669  // However, in KaTeX, \textellipsis and \ldots behave the same
15670  // (in text mode), and it's unlikely we'd see any of the math commands
15671  // that affect the behavior of \dots when in text mode.  So fine for now
15672  // (until we support \ifmmode ... \else ... \fi).
15673  var thedots = '\\dotso';
15674  var next = context.expandAfterFuture().text;
15675
15676  if (next in dotsByToken) {
15677    thedots = dotsByToken[next];
15678  } else if (next.slice(0, 4) === '\\not') {
15679    thedots = '\\dotsb';
15680  } else if (next in symbols.math) {
15681    if (utils.contains(['bin', 'rel'], symbols.math[next].group)) {
15682      thedots = '\\dotsb';
15683    }
15684  }
15685
15686  return thedots;
15687});
15688var spaceAfterDots = {
15689  // \rightdelim@ checks for the following:
15690  ')': true,
15691  ']': true,
15692  '\\rbrack': true,
15693  '\\}': true,
15694  '\\rbrace': true,
15695  '\\rangle': true,
vendor: 10,049 bytes, lines 15696-15896
15696  '\\rceil': true,
15697  '\\rfloor': true,
15698  '\\rgroup': true,
15699  '\\rmoustache': true,
15700  '\\right': true,
15701  '\\bigr': true,
15702  '\\biggr': true,
15703  '\\Bigr': true,
15704  '\\Biggr': true,
15705  // \extra@ also tests for the following:
15706  '$': true,
15707  // \extrap@ checks for the following:
15708  ';': true,
15709  '.': true,
15710  ',': true
15711};
15712defineMacro("\\dotso", function (context) {
15713  var next = context.future().text;
15714
15715  if (next in spaceAfterDots) {
15716    return "\\ldots\\,";
15717  } else {
15718    return "\\ldots";
15719  }
15720});
15721defineMacro("\\dotsc", function (context) {
15722  var next = context.future().text; // \dotsc uses \extra@ but not \extrap@, instead specially checking for
15723  // ';' and '.', but doesn't check for ','.
15724
15725  if (next in spaceAfterDots && next !== ',') {
15726    return "\\ldots\\,";
15727  } else {
15728    return "\\ldots";
15729  }
15730});
15731defineMacro("\\cdots", function (context) {
15732  var next = context.future().text;
15733
15734  if (next in spaceAfterDots) {
15735    return "\\@cdots\\,";
15736  } else {
15737    return "\\@cdots";
15738  }
15739});
15740defineMacro("\\dotsb", "\\cdots");
15741defineMacro("\\dotsm", "\\cdots");
15742defineMacro("\\dotsi", "\\!\\cdots"); // amsmath doesn't actually define \dotsx, but \dots followed by a macro
15743// starting with \DOTSX implies \dotso, and then \extra@ detects this case
15744// and forces the added `\,`.
15745
15746defineMacro("\\dotsx", "\\ldots\\,"); // \let\DOTSI\relax
15747// \let\DOTSB\relax
15748// \let\DOTSX\relax
15749
15750defineMacro("\\DOTSI", "\\relax");
15751defineMacro("\\DOTSB", "\\relax");
15752defineMacro("\\DOTSX", "\\relax"); // Spacing, based on amsmath.sty's override of LaTeX defaults
15753// \DeclareRobustCommand{\tmspace}[3]{%
15754//   \ifmmode\mskip#1#2\else\kern#1#3\fi\relax}
15755
15756defineMacro("\\tmspace", "\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"); // \renewcommand{\,}{\tmspace+\thinmuskip{.1667em}}
15757// TODO: math mode should use \thinmuskip
15758
15759defineMacro("\\,", "\\tmspace+{3mu}{.1667em}"); // \let\thinspace\,
15760
15761defineMacro("\\thinspace", "\\,"); // \def\>{\mskip\medmuskip}
15762// \renewcommand{\:}{\tmspace+\medmuskip{.2222em}}
15763// TODO: \> and math mode of \: should use \medmuskip = 4mu plus 2mu minus 4mu
15764
15765defineMacro("\\>", "\\mskip{4mu}");
15766defineMacro("\\:", "\\tmspace+{4mu}{.2222em}"); // \let\medspace\:
15767
15768defineMacro("\\medspace", "\\:"); // \renewcommand{\;}{\tmspace+\thickmuskip{.2777em}}
15769// TODO: math mode should use \thickmuskip = 5mu plus 5mu
15770
15771defineMacro("\\;", "\\tmspace+{5mu}{.2777em}"); // \let\thickspace\;
15772
15773defineMacro("\\thickspace", "\\;"); // \renewcommand{\!}{\tmspace-\thinmuskip{.1667em}}
15774// TODO: math mode should use \thinmuskip
15775
15776defineMacro("\\!", "\\tmspace-{3mu}{.1667em}"); // \let\negthinspace\!
15777
15778defineMacro("\\negthinspace", "\\!"); // \newcommand{\negmedspace}{\tmspace-\medmuskip{.2222em}}
15779// TODO: math mode should use \medmuskip
15780
15781defineMacro("\\negmedspace", "\\tmspace-{4mu}{.2222em}"); // \newcommand{\negthickspace}{\tmspace-\thickmuskip{.2777em}}
15782// TODO: math mode should use \thickmuskip
15783
15784defineMacro("\\negthickspace", "\\tmspace-{5mu}{.277em}"); // \def\enspace{\kern.5em }
15785
15786defineMacro("\\enspace", "\\kern.5em "); // \def\enskip{\hskip.5em\relax}
15787
15788defineMacro("\\enskip", "\\hskip.5em\\relax"); // \def\quad{\hskip1em\relax}
15789
15790defineMacro("\\quad", "\\hskip1em\\relax"); // \def\qquad{\hskip2em\relax}
15791
15792defineMacro("\\qquad", "\\hskip2em\\relax"); // \tag@in@display form of \tag
15793
15794defineMacro("\\tag", "\\@ifstar\\tag@literal\\tag@paren");
15795defineMacro("\\tag@paren", "\\tag@literal{({#1})}");
15796defineMacro("\\tag@literal", context => {
15797  if (context.macros.get("\\df@tag")) {
15798    throw new ParseError("Multiple \\tag");
15799  }
15800
15801  return "\\gdef\\df@tag{\\text{#1}}";
15802}); // \renewcommand{\bmod}{\nonscript\mskip-\medmuskip\mkern5mu\mathbin
15803//   {\operator@font mod}\penalty900
15804//   \mkern5mu\nonscript\mskip-\medmuskip}
15805// \newcommand{\pod}[1]{\allowbreak
15806//   \if@display\mkern18mu\else\mkern8mu\fi(#1)}
15807// \renewcommand{\pmod}[1]{\pod{{\operator@font mod}\mkern6mu#1}}
15808// \newcommand{\mod}[1]{\allowbreak\if@display\mkern18mu
15809//   \else\mkern12mu\fi{\operator@font mod}\,\,#1}
15810// TODO: math mode should use \medmuskip = 4mu plus 2mu minus 4mu
15811
15812defineMacro("\\bmod", "\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}" + "\\mathbin{\\rm mod}" + "\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}");
15813defineMacro("\\pod", "\\allowbreak" + "\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)");
15814defineMacro("\\pmod", "\\pod{{\\rm mod}\\mkern6mu#1}");
15815defineMacro("\\mod", "\\allowbreak" + "\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}" + "{\\rm mod}\\,\\,#1"); //////////////////////////////////////////////////////////////////////
15816// LaTeX source2e
15817// \expandafter\let\expandafter\@normalcr
15818//     \csname\expandafter\@gobble\string\\ \endcsname
15819// \DeclareRobustCommand\newline{\@normalcr\relax}
15820
15821defineMacro("\\newline", "\\\\\\relax"); // \def\TeX{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX\@}
15822// TODO: Doesn't normally work in math mode because \@ fails.  KaTeX doesn't
15823// support \@ yet, so that's omitted, and we add \text so that the result
15824// doesn't look funny in math mode.
15825
15826defineMacro("\\TeX", "\\textrm{\\html@mathml{" + "T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX" + "}{TeX}}"); // \DeclareRobustCommand{\LaTeX}{L\kern-.36em%
15827//         {\sbox\z@ T%
15828//          \vbox to\ht\z@{\hbox{\check@mathfonts
15829//                               \fontsize\sf@size\z@
15830//                               \math@fontsfalse\selectfont
15831//                               A}%
15832//                         \vss}%
15833//         }%
15834//         \kern-.15em%
15835//         \TeX}
15836// This code aligns the top of the A with the T (from the perspective of TeX's
15837// boxes, though visually the A appears to extend above slightly).
15838// We compute the corresponding \raisebox when A is rendered in \normalsize
15839// \scriptstyle, which has a scale factor of 0.7 (see Options.js).
15840
15841var latexRaiseA = makeEm(fontMetricsData['Main-Regular']["T".charCodeAt(0)][1] - 0.7 * fontMetricsData['Main-Regular']["A".charCodeAt(0)][1]);
15842defineMacro("\\LaTeX", "\\textrm{\\html@mathml{" + ("L\\kern-.36em\\raisebox{" + latexRaiseA + "}{\\scriptstyle A}") + "\\kern-.15em\\TeX}{LaTeX}}"); // New KaTeX logo based on tweaking LaTeX logo
15843
15844defineMacro("\\KaTeX", "\\textrm{\\html@mathml{" + ("K\\kern-.17em\\raisebox{" + latexRaiseA + "}{\\scriptstyle A}") + "\\kern-.15em\\TeX}{KaTeX}}"); // \DeclareRobustCommand\hspace{\@ifstar\@hspacer\@hspace}
15845// \def\@hspace#1{\hskip  #1\relax}
15846// \def\@hspacer#1{\vrule \@width\z@\nobreak
15847//                 \hskip #1\hskip \z@skip}
15848
15849defineMacro("\\hspace", "\\@ifstar\\@hspacer\\@hspace");
15850defineMacro("\\@hspace", "\\hskip #1\\relax");
15851defineMacro("\\@hspacer", "\\rule{0pt}{0pt}\\hskip #1\\relax"); //////////////////////////////////////////////////////////////////////
15852// mathtools.sty
15853//\providecommand\ordinarycolon{:}
15854
15855defineMacro("\\ordinarycolon", ":"); //\def\vcentcolon{\mathrel{\mathop\ordinarycolon}}
15856//TODO(edemaine): Not yet centered. Fix via \raisebox or #726
15857
15858defineMacro("\\vcentcolon", "\\mathrel{\\mathop\\ordinarycolon}"); // \providecommand*\dblcolon{\vcentcolon\mathrel{\mkern-.9mu}\vcentcolon}
15859
15860defineMacro("\\dblcolon", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}" + "{\\mathop{\\char\"2237}}"); // \providecommand*\coloneqq{\vcentcolon\mathrel{\mkern-1.2mu}=}
15861
15862defineMacro("\\coloneqq", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}" + "{\\mathop{\\char\"2254}}"); // ≔
15863// \providecommand*\Coloneqq{\dblcolon\mathrel{\mkern-1.2mu}=}
15864
15865defineMacro("\\Coloneqq", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}" + "{\\mathop{\\char\"2237\\char\"3d}}"); // \providecommand*\coloneq{\vcentcolon\mathrel{\mkern-1.2mu}\mathrel{-}}
15866
15867defineMacro("\\coloneq", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}" + "{\\mathop{\\char\"3a\\char\"2212}}"); // \providecommand*\Coloneq{\dblcolon\mathrel{\mkern-1.2mu}\mathrel{-}}
15868
15869defineMacro("\\Coloneq", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}" + "{\\mathop{\\char\"2237\\char\"2212}}"); // \providecommand*\eqqcolon{=\mathrel{\mkern-1.2mu}\vcentcolon}
15870
15871defineMacro("\\eqqcolon", "\\html@mathml{" + "\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}" + "{\\mathop{\\char\"2255}}"); // ≕
15872// \providecommand*\Eqqcolon{=\mathrel{\mkern-1.2mu}\dblcolon}
15873
15874defineMacro("\\Eqqcolon", "\\html@mathml{" + "\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}" + "{\\mathop{\\char\"3d\\char\"2237}}"); // \providecommand*\eqcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\vcentcolon}
15875
15876defineMacro("\\eqcolon", "\\html@mathml{" + "\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}" + "{\\mathop{\\char\"2239}}"); // \providecommand*\Eqcolon{\mathrel{-}\mathrel{\mkern-1.2mu}\dblcolon}
15877
15878defineMacro("\\Eqcolon", "\\html@mathml{" + "\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}" + "{\\mathop{\\char\"2212\\char\"2237}}"); // \providecommand*\colonapprox{\vcentcolon\mathrel{\mkern-1.2mu}\approx}
15879
15880defineMacro("\\colonapprox", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}" + "{\\mathop{\\char\"3a\\char\"2248}}"); // \providecommand*\Colonapprox{\dblcolon\mathrel{\mkern-1.2mu}\approx}
15881
15882defineMacro("\\Colonapprox", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}" + "{\\mathop{\\char\"2237\\char\"2248}}"); // \providecommand*\colonsim{\vcentcolon\mathrel{\mkern-1.2mu}\sim}
15883
15884defineMacro("\\colonsim", "\\html@mathml{" + "\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}" + "{\\mathop{\\char\"3a\\char\"223c}}"); // \providecommand*\Colonsim{\dblcolon\mathrel{\mkern-1.2mu}\sim}
15885
15886defineMacro("\\Colonsim", "\\html@mathml{" + "\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}" + "{\\mathop{\\char\"2237\\char\"223c}}"); // Some Unicode characters are implemented with macros to mathtools functions.
15887
15888defineMacro("\u2237", "\\dblcolon"); // ::
15889
15890defineMacro("\u2239", "\\eqcolon"); // -:
15891
15892defineMacro("\u2254", "\\coloneqq"); // :=
15893
15894defineMacro("\u2255", "\\eqqcolon"); // =:
15895
15896defineMacro("\u2A74", "\\Coloneqq"); // ::=
15897//////////////////////////////////////////////////////////////////////
15898// colonequals.sty
15899// Alternate names for mathtools's macros:
15900
15901defineMacro("\\ratio", "\\vcentcolon");
15902defineMacro("\\coloncolon", "\\dblcolon");
15903defineMacro("\\colonequals", "\\coloneqq");
15904defineMacro("\\coloncolonequals", "\\Coloneqq");
15905defineMacro("\\equalscolon", "\\eqqcolon");
15906defineMacro("\\equalscoloncolon", "\\Eqqcolon");
15907defineMacro("\\colonminus", "\\coloneq");
15908defineMacro("\\coloncolonminus", "\\Coloneq");
15909defineMacro("\\minuscolon", "\\eqcolon");
15910defineMacro("\\minuscoloncolon", "\\Eqcolon"); // \colonapprox name is same in mathtools and colonequals.
15911
15912defineMacro("\\coloncolonapprox", "\\Colonapprox"); // \colonsim name is same in mathtools and colonequals.
15913
15914defineMacro("\\coloncolonsim", "\\Colonsim"); // Additional macros, implemented by analogy with mathtools definitions:
15915
15916defineMacro("\\simcolon", "\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}");
15917defineMacro("\\simcoloncolon", "\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}");
15918defineMacro("\\approxcolon", "\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}");
15919defineMacro("\\approxcoloncolon", "\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"); // Present in newtxmath, pxfonts and txfonts
15920
15921defineMacro("\\notni", "\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220C}}");
15922defineMacro("\\limsup", "\\DOTSB\\operatorname*{lim\\,sup}");
15923defineMacro("\\liminf", "\\DOTSB\\operatorname*{lim\\,inf}"); //////////////////////////////////////////////////////////////////////
15924// From amsopn.sty
15925
15926defineMacro("\\injlim", "\\DOTSB\\operatorname*{inj\\,lim}");
15927defineMacro("\\projlim", "\\DOTSB\\operatorname*{proj\\,lim}");
15928defineMacro("\\varlimsup", "\\DOTSB\\operatorname*{\\overline{lim}}");
15929defineMacro("\\varliminf", "\\DOTSB\\operatorname*{\\underline{lim}}");
15930defineMacro("\\varinjlim", "\\DOTSB\\operatorname*{\\underrightarrow{lim}}");
15931defineMacro("\\varprojlim", "\\DOTSB\\operatorname*{\\underleftarrow{lim}}"); //////////////////////////////////////////////////////////////////////
15932// MathML alternates for KaTeX glyphs in the Unicode private area
15933
15934defineMacro("\\gvertneqq", "\\html@mathml{\\@gvertneqq}{\u2269}");
15935defineMacro("\\lvertneqq", "\\html@mathml{\\@lvertneqq}{\u2268}");
15936defineMacro("\\ngeqq", "\\html@mathml{\\@ngeqq}{\u2271}");
15937defineMacro("\\ngeqslant", "\\html@mathml{\\@ngeqslant}{\u2271}");
15938defineMacro("\\nleqq", "\\html@mathml{\\@nleqq}{\u2270}");
15939defineMacro("\\nleqslant", "\\html@mathml{\\@nleqslant}{\u2270}");
15940defineMacro("\\nshortmid", "\\html@mathml{\\@nshortmid}{∤}");
15941defineMacro("\\nshortparallel", "\\html@mathml{\\@nshortparallel}{∦}");
15942defineMacro("\\nsubseteqq", "\\html@mathml{\\@nsubseteqq}{\u2288}");
15943defineMacro("\\nsupseteqq", "\\html@mathml{\\@nsupseteqq}{\u2289}");
15944defineMacro("\\varsubsetneq", "\\html@mathml{\\@varsubsetneq}{⊊}");
15945defineMacro("\\varsubsetneqq", "\\html@mathml{\\@varsubsetneqq}{⫋}");
15946defineMacro("\\varsupsetneq", "\\html@mathml{\\@varsupsetneq}{⊋}");
15947defineMacro("\\varsupsetneqq", "\\html@mathml{\\@varsupsetneqq}{⫌}");
15948defineMacro("\\imath", "\\html@mathml{\\@imath}{\u0131}");
15949defineMacro("\\jmath", "\\html@mathml{\\@jmath}{\u0237}"); //////////////////////////////////////////////////////////////////////
15950// stmaryrd and semantic
15951// The stmaryrd and semantic packages render the next four items by calling a
15952// glyph. Those glyphs do not exist in the KaTeX fonts. Hence the macros.
15953
15954defineMacro("\\llbracket", "\\html@mathml{" + "\\mathopen{[\\mkern-3.2mu[}}" + "{\\mathopen{\\char`\u27e6}}");
15955defineMacro("\\rrbracket", "\\html@mathml{" + "\\mathclose{]\\mkern-3.2mu]}}" + "{\\mathclose{\\char`\u27e7}}");
15956defineMacro("\u27e6", "\\llbracket"); // blackboard bold [
15957
15958defineMacro("\u27e7", "\\rrbracket"); // blackboard bold ]
15959
15960defineMacro("\\lBrace", "\\html@mathml{" + "\\mathopen{\\{\\mkern-3.2mu[}}" + "{\\mathopen{\\char`\u2983}}");
15961defineMacro("\\rBrace", "\\html@mathml{" + "\\mathclose{]\\mkern-3.2mu\\}}}" + "{\\mathclose{\\char`\u2984}}");
15962defineMacro("\u2983", "\\lBrace"); // blackboard bold {
15963
15964defineMacro("\u2984", "\\rBrace"); // blackboard bold }
15965// TODO: Create variable sized versions of the last two items. I believe that
15966// will require new font glyphs.
15967// The stmaryrd function `\minuso` provides a "Plimsoll" symbol that
15968// superimposes the characters \circ and \mathminus. Used in chemistry.
15969
15970defineMacro("\\minuso", "\\mathbin{\\html@mathml{" + "{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}" + "{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}" + "{\\char`⦵}}");
15971defineMacro("⦵", "\\minuso"); //////////////////////////////////////////////////////////////////////
15972// texvc.sty
15973// The texvc package contains macros available in mediawiki pages.
15974// We omit the functions deprecated at
15975// https://en.wikipedia.org/wiki/Help:Displaying_a_formula#Deprecated_syntax
15976// We also omit texvc's \O, which conflicts with \text{\O}
15977
15978defineMacro("\\darr", "\\downarrow");
15979defineMacro("\\dArr", "\\Downarrow");
15980defineMacro("\\Darr", "\\Downarrow");
15981defineMacro("\\lang", "\\langle");
15982defineMacro("\\rang", "\\rangle");
15983defineMacro("\\uarr", "\\uparrow");
15984defineMacro("\\uArr", "\\Uparrow");
15985defineMacro("\\Uarr", "\\Uparrow");
15986defineMacro("\\N", "\\mathbb{N}");
15987defineMacro("\\R", "\\mathbb{R}");
15988defineMacro("\\Z", "\\mathbb{Z}");
15989defineMacro("\\alef", "\\aleph");
15990defineMacro("\\alefsym", "\\aleph");
15991defineMacro("\\Alpha", "\\mathrm{A}");
15992defineMacro("\\Beta", "\\mathrm{B}");
15993defineMacro("\\bull", "\\bullet");
15994defineMacro("\\Chi", "\\mathrm{X}");
15995defineMacro("\\clubs", "\\clubsuit");
15996defineMacro("\\cnums", "\\mathbb{C}");
15997defineMacro("\\Complex", "\\mathbb{C}");
15998defineMacro("\\Dagger", "\\ddagger");
15999defineMacro("\\diamonds", "\\diamondsuit");
16000defineMacro("\\empty", "\\emptyset");
16001defineMacro("\\Epsilon", "\\mathrm{E}");
16002defineMacro("\\Eta", "\\mathrm{H}");
16003defineMacro("\\exist", "\\exists");
16004defineMacro("\\harr", "\\leftrightarrow");
16005defineMacro("\\hArr", "\\Leftrightarrow");
16006defineMacro("\\Harr", "\\Leftrightarrow");
16007defineMacro("\\hearts", "\\heartsuit");
16008defineMacro("\\image", "\\Im");
16009defineMacro("\\infin", "\\infty");
16010defineMacro("\\Iota", "\\mathrm{I}");
16011defineMacro("\\isin", "\\in");
16012defineMacro("\\Kappa", "\\mathrm{K}");
16013defineMacro("\\larr", "\\leftarrow");
16014defineMacro("\\lArr", "\\Leftarrow");
16015defineMacro("\\Larr", "\\Leftarrow");
16016defineMacro("\\lrarr", "\\leftrightarrow");
16017defineMacro("\\lrArr", "\\Leftrightarrow");
16018defineMacro("\\Lrarr", "\\Leftrightarrow");
16019defineMacro("\\Mu", "\\mathrm{M}");
16020defineMacro("\\natnums", "\\mathbb{N}");
16021defineMacro("\\Nu", "\\mathrm{N}");
16022defineMacro("\\Omicron", "\\mathrm{O}");
16023defineMacro("\\plusmn", "\\pm");
16024defineMacro("\\rarr", "\\rightarrow");
16025defineMacro("\\rArr", "\\Rightarrow");
16026defineMacro("\\Rarr", "\\Rightarrow");
16027defineMacro("\\real", "\\Re");
16028defineMacro("\\reals", "\\mathbb{R}");
16029defineMacro("\\Reals", "\\mathbb{R}");
16030defineMacro("\\Rho", "\\mathrm{P}");
16031defineMacro("\\sdot", "\\cdot");
16032defineMacro("\\sect", "\\S");
16033defineMacro("\\spades", "\\spadesuit");
16034defineMacro("\\sub", "\\subset");
16035defineMacro("\\sube", "\\subseteq");
16036defineMacro("\\supe", "\\supseteq");
16037defineMacro("\\Tau", "\\mathrm{T}");
16038defineMacro("\\thetasym", "\\vartheta"); // TODO: defineMacro("\\varcoppa", "\\\mbox{\\coppa}");
16039
16040defineMacro("\\weierp", "\\wp");
16041defineMacro("\\Zeta", "\\mathrm{Z}"); //////////////////////////////////////////////////////////////////////
16042// statmath.sty
16043// https://ctan.math.illinois.edu/macros/latex/contrib/statmath/statmath.pdf
16044
16045defineMacro("\\argmin", "\\DOTSB\\operatorname*{arg\\,min}");
16046defineMacro("\\argmax", "\\DOTSB\\operatorname*{arg\\,max}");
16047defineMacro("\\plim", "\\DOTSB\\mathop{\\operatorname{plim}}\\limits"); //////////////////////////////////////////////////////////////////////
16048// braket.sty
16049// http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/braket/braket.pdf
16050
16051defineMacro("\\bra", "\\mathinner{\\langle{#1}|}");
16052defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}");
16053defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}");
16054defineMacro("\\Bra", "\\left\\langle#1\\right|");
16055defineMacro("\\Ket", "\\left|#1\\right\\rangle");
16056
16057var braketHelper = one => context => {
16058  var left = context.consumeArg().tokens;
16059  var middle = context.consumeArg().tokens;
16060  var middleDouble = context.consumeArg().tokens;
16061  var right = context.consumeArg().tokens;
16062  var oldMiddle = context.macros.get("|");
16063  var oldMiddleDouble = context.macros.get("\\|");
16064  context.macros.beginGroup();
16065
16066  var midMacro = double => context => {
16067    if (one) {
16068      // Only modify the first instance of | or \|
16069      context.macros.set("|", oldMiddle);
16070
16071      if (middleDouble.length) {
16072        context.macros.set("\\|", oldMiddleDouble);
16073      }
16074    }
16075
16076    var doubled = double;
16077
16078    if (!double && middleDouble.length) {
vendor: 8,266 bytes, lines 16079-16360
16079      // Mimic \@ifnextchar
16080      var nextToken = context.future();
16081
16082      if (nextToken.text === "|") {
16083        context.popToken();
16084        doubled = true;
16085      }
16086    }
16087
16088    return {
16089      tokens: doubled ? middleDouble : middle,
16090      numArgs: 0
16091    };
16092  };
16093
16094  context.macros.set("|", midMacro(false));
16095
16096  if (middleDouble.length) {
16097    context.macros.set("\\|", midMacro(true));
16098  }
16099
16100  var arg = context.consumeArg().tokens;
16101  var expanded = context.expandTokens([...right, ...arg, ...left // reversed
16102  ]);
16103  context.macros.endGroup();
16104  return {
16105    tokens: expanded.reverse(),
16106    numArgs: 0
16107  };
16108};
16109
16110defineMacro("\\bra@ket", braketHelper(false));
16111defineMacro("\\bra@set", braketHelper(true));
16112defineMacro("\\Braket", "\\bra@ket{\\left\\langle}" + "{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");
16113defineMacro("\\Set", "\\bra@set{\\left\\{\\:}" + "{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");
16114defineMacro("\\set", "\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"); // has no support for special || or \|
16115//////////////////////////////////////////////////////////////////////
16116// actuarialangle.dtx
16117
16118defineMacro("\\angln", "{\\angl n}"); // Custom Khan Academy colors, should be moved to an optional package
16119
16120defineMacro("\\blue", "\\textcolor{##6495ed}{#1}");
16121defineMacro("\\orange", "\\textcolor{##ffa500}{#1}");
16122defineMacro("\\pink", "\\textcolor{##ff00af}{#1}");
16123defineMacro("\\red", "\\textcolor{##df0030}{#1}");
16124defineMacro("\\green", "\\textcolor{##28ae7b}{#1}");
16125defineMacro("\\gray", "\\textcolor{gray}{#1}");
16126defineMacro("\\purple", "\\textcolor{##9d38bd}{#1}");
16127defineMacro("\\blueA", "\\textcolor{##ccfaff}{#1}");
16128defineMacro("\\blueB", "\\textcolor{##80f6ff}{#1}");
16129defineMacro("\\blueC", "\\textcolor{##63d9ea}{#1}");
16130defineMacro("\\blueD", "\\textcolor{##11accd}{#1}");
16131defineMacro("\\blueE", "\\textcolor{##0c7f99}{#1}");
16132defineMacro("\\tealA", "\\textcolor{##94fff5}{#1}");
16133defineMacro("\\tealB", "\\textcolor{##26edd5}{#1}");
16134defineMacro("\\tealC", "\\textcolor{##01d1c1}{#1}");
16135defineMacro("\\tealD", "\\textcolor{##01a995}{#1}");
16136defineMacro("\\tealE", "\\textcolor{##208170}{#1}");
16137defineMacro("\\greenA", "\\textcolor{##b6ffb0}{#1}");
16138defineMacro("\\greenB", "\\textcolor{##8af281}{#1}");
16139defineMacro("\\greenC", "\\textcolor{##74cf70}{#1}");
16140defineMacro("\\greenD", "\\textcolor{##1fab54}{#1}");
16141defineMacro("\\greenE", "\\textcolor{##0d923f}{#1}");
16142defineMacro("\\goldA", "\\textcolor{##ffd0a9}{#1}");
16143defineMacro("\\goldB", "\\textcolor{##ffbb71}{#1}");
16144defineMacro("\\goldC", "\\textcolor{##ff9c39}{#1}");
16145defineMacro("\\goldD", "\\textcolor{##e07d10}{#1}");
16146defineMacro("\\goldE", "\\textcolor{##a75a05}{#1}");
16147defineMacro("\\redA", "\\textcolor{##fca9a9}{#1}");
16148defineMacro("\\redB", "\\textcolor{##ff8482}{#1}");
16149defineMacro("\\redC", "\\textcolor{##f9685d}{#1}");
16150defineMacro("\\redD", "\\textcolor{##e84d39}{#1}");
16151defineMacro("\\redE", "\\textcolor{##bc2612}{#1}");
16152defineMacro("\\maroonA", "\\textcolor{##ffbde0}{#1}");
16153defineMacro("\\maroonB", "\\textcolor{##ff92c6}{#1}");
16154defineMacro("\\maroonC", "\\textcolor{##ed5fa6}{#1}");
16155defineMacro("\\maroonD", "\\textcolor{##ca337c}{#1}");
16156defineMacro("\\maroonE", "\\textcolor{##9e034e}{#1}");
16157defineMacro("\\purpleA", "\\textcolor{##ddd7ff}{#1}");
16158defineMacro("\\purpleB", "\\textcolor{##c6b9fc}{#1}");
16159defineMacro("\\purpleC", "\\textcolor{##aa87ff}{#1}");
16160defineMacro("\\purpleD", "\\textcolor{##7854ab}{#1}");
16161defineMacro("\\purpleE", "\\textcolor{##543b78}{#1}");
16162defineMacro("\\mintA", "\\textcolor{##f5f9e8}{#1}");
16163defineMacro("\\mintB", "\\textcolor{##edf2df}{#1}");
16164defineMacro("\\mintC", "\\textcolor{##e0e5cc}{#1}");
16165defineMacro("\\grayA", "\\textcolor{##f6f7f7}{#1}");
16166defineMacro("\\grayB", "\\textcolor{##f0f1f2}{#1}");
16167defineMacro("\\grayC", "\\textcolor{##e3e5e6}{#1}");
16168defineMacro("\\grayD", "\\textcolor{##d6d8da}{#1}");
16169defineMacro("\\grayE", "\\textcolor{##babec2}{#1}");
16170defineMacro("\\grayF", "\\textcolor{##888d93}{#1}");
16171defineMacro("\\grayG", "\\textcolor{##626569}{#1}");
16172defineMacro("\\grayH", "\\textcolor{##3b3e40}{#1}");
16173defineMacro("\\grayI", "\\textcolor{##21242c}{#1}");
16174defineMacro("\\kaBlue", "\\textcolor{##314453}{#1}");
16175defineMacro("\\kaGreen", "\\textcolor{##71B307}{#1}");
16176
16177/**
16178 * This file contains the “gullet” where macros are expanded
16179 * until only non-macro tokens remain.
16180 */
16181// List of commands that act like macros but aren't defined as a macro,
16182// function, or symbol.  Used in `isDefined`.
16183var implicitCommands = {
16184  "^": true,
16185  // Parser.js
16186  "_": true,
16187  // Parser.js
16188  "\\limits": true,
16189  // Parser.js
16190  "\\nolimits": true // Parser.js
16191
16192};
16193class MacroExpander {
16194  constructor(input, settings, mode) {
16195    this.settings = void 0;
16196    this.expansionCount = void 0;
16197    this.lexer = void 0;
16198    this.macros = void 0;
16199    this.stack = void 0;
16200    this.mode = void 0;
16201    this.settings = settings;
16202    this.expansionCount = 0;
16203    this.feed(input); // Make new global namespace
16204
16205    this.macros = new Namespace(macros, settings.macros);
16206    this.mode = mode;
16207    this.stack = []; // contains tokens in REVERSE order
16208  }
16209  /**
16210   * Feed a new input string to the same MacroExpander
16211   * (with existing macros etc.).
16212   */
16213
16214
16215  feed(input) {
16216    this.lexer = new Lexer(input, this.settings);
16217  }
16218  /**
16219   * Switches between "text" and "math" modes.
16220   */
16221
16222
16223  switchMode(newMode) {
16224    this.mode = newMode;
16225  }
16226  /**
16227   * Start a new group nesting within all namespaces.
16228   */
16229
16230
16231  beginGroup() {
16232    this.macros.beginGroup();
16233  }
16234  /**
16235   * End current group nesting within all namespaces.
16236   */
16237
16238
16239  endGroup() {
16240    this.macros.endGroup();
16241  }
16242  /**
16243   * Ends all currently nested groups (if any), restoring values before the
16244   * groups began.  Useful in case of an error in the middle of parsing.
16245   */
16246
16247
16248  endGroups() {
16249    this.macros.endGroups();
16250  }
16251  /**
16252   * Returns the topmost token on the stack, without expanding it.
16253   * Similar in behavior to TeX's `\futurelet`.
16254   */
16255
16256
16257  future() {
16258    if (this.stack.length === 0) {
16259      this.pushToken(this.lexer.lex());
16260    }
16261
16262    return this.stack[this.stack.length - 1];
16263  }
16264  /**
16265   * Remove and return the next unexpanded token.
16266   */
16267
16268
16269  popToken() {
16270    this.future(); // ensure non-empty stack
16271
16272    return this.stack.pop();
16273  }
16274  /**
16275   * Add a given token to the token stack.  In particular, this get be used
16276   * to put back a token returned from one of the other methods.
16277   */
16278
16279
16280  pushToken(token) {
16281    this.stack.push(token);
16282  }
16283  /**
16284   * Append an array of tokens to the token stack.
16285   */
16286
16287
16288  pushTokens(tokens) {
16289    this.stack.push(...tokens);
16290  }
16291  /**
16292   * Find an macro argument without expanding tokens and append the array of
16293   * tokens to the token stack. Uses Token as a container for the result.
16294   */
16295
16296
16297  scanArgument(isOptional) {
16298    var start;
16299    var end;
16300    var tokens;
16301
16302    if (isOptional) {
16303      this.consumeSpaces(); // \@ifnextchar gobbles any space following it
16304
16305      if (this.future().text !== "[") {
16306        return null;
16307      }
16308
16309      start = this.popToken(); // don't include [ in tokens
16310
16311      ({
16312        tokens,
16313        end
16314      } = this.consumeArg(["]"]));
16315    } else {
16316      ({
16317        tokens,
16318        start,
16319        end
16320      } = this.consumeArg());
16321    } // indicate the end of an argument
16322
16323
16324    this.pushToken(new Token("EOF", end.loc));
16325    this.pushTokens(tokens);
16326    return start.range(end, "");
16327  }
16328  /**
16329   * Consume all following space tokens, without expansion.
16330   */
16331
16332
16333  consumeSpaces() {
16334    for (;;) {
16335      var token = this.future();
16336
16337      if (token.text === " ") {
16338        this.stack.pop();
16339      } else {
16340        break;
16341      }
16342    }
16343  }
16344  /**
16345   * Consume an argument from the token stream, and return the resulting array
16346   * of tokens and start/end token.
16347   */
16348
16349
16350  consumeArg(delims) {
16351    // The argument for a delimited parameter is the shortest (possibly
16352    // empty) sequence of tokens with properly nested {...} groups that is
16353    // followed ... by this particular list of non-parameter tokens.
16354    // The argument for an undelimited parameter is the next nonblank
16355    // token, unless that token is ‘{’, when the argument will be the
16356    // entire {...} group that follows.
16357    var tokens = [];
16358    var isDelimited = delims && delims.length > 0;
16359
16360    if (!isDelimited) {
vendor: 5,152 bytes, lines 16361-16534
16361      // Ignore spaces between arguments.  As the TeXbook says:
16362      // "After you have said ‘\def\row#1#2{...}’, you are allowed to
16363      //  put spaces between the arguments (e.g., ‘\row x n’), because
16364      //  TeX doesn’t use single spaces as undelimited arguments."
16365      this.consumeSpaces();
16366    }
16367
16368    var start = this.future();
16369    var tok;
16370    var depth = 0;
16371    var match = 0;
16372
16373    do {
16374      tok = this.popToken();
16375      tokens.push(tok);
16376
16377      if (tok.text === "{") {
16378        ++depth;
16379      } else if (tok.text === "}") {
16380        --depth;
16381
16382        if (depth === -1) {
16383          throw new ParseError("Extra }", tok);
16384        }
16385      } else if (tok.text === "EOF") {
16386        throw new ParseError("Unexpected end of input in a macro argument" + ", expected '" + (delims && isDelimited ? delims[match] : "}") + "'", tok);
16387      }
16388
16389      if (delims && isDelimited) {
16390        if ((depth === 0 || depth === 1 && delims[match] === "{") && tok.text === delims[match]) {
16391          ++match;
16392
16393          if (match === delims.length) {
16394            // don't include delims in tokens
16395            tokens.splice(-match, match);
16396            break;
16397          }
16398        } else {
16399          match = 0;
16400        }
16401      }
16402    } while (depth !== 0 || isDelimited); // If the argument found ... has the form ‘{<nested tokens>}’,
16403    // ... the outermost braces enclosing the argument are removed
16404
16405
16406    if (start.text === "{" && tokens[tokens.length - 1].text === "}") {
16407      tokens.pop();
16408      tokens.shift();
16409    }
16410
16411    tokens.reverse(); // to fit in with stack order
16412
16413    return {
16414      tokens,
16415      start,
16416      end: tok
16417    };
16418  }
16419  /**
16420   * Consume the specified number of (delimited) arguments from the token
16421   * stream and return the resulting array of arguments.
16422   */
16423
16424
16425  consumeArgs(numArgs, delimiters) {
16426    if (delimiters) {
16427      if (delimiters.length !== numArgs + 1) {
16428        throw new ParseError("The length of delimiters doesn't match the number of args!");
16429      }
16430
16431      var delims = delimiters[0];
16432
16433      for (var i = 0; i < delims.length; i++) {
16434        var tok = this.popToken();
16435
16436        if (delims[i] !== tok.text) {
16437          throw new ParseError("Use of the macro doesn't match its definition", tok);
16438        }
16439      }
16440    }
16441
16442    var args = [];
16443
16444    for (var _i = 0; _i < numArgs; _i++) {
16445      args.push(this.consumeArg(delimiters && delimiters[_i + 1]).tokens);
16446    }
16447
16448    return args;
16449  }
16450  /**
16451   * Increment `expansionCount` by the specified amount.
16452   * Throw an error if it exceeds `maxExpand`.
16453   */
16454
16455
16456  countExpansion(amount) {
16457    this.expansionCount += amount;
16458
16459    if (this.expansionCount > this.settings.maxExpand) {
16460      throw new ParseError("Too many expansions: infinite loop or " + "need to increase maxExpand setting");
16461    }
16462  }
16463  /**
16464   * Expand the next token only once if possible.
16465   *
16466   * If the token is expanded, the resulting tokens will be pushed onto
16467   * the stack in reverse order, and the number of such tokens will be
16468   * returned.  This number might be zero or positive.
16469   *
16470   * If not, the return value is `false`, and the next token remains at the
16471   * top of the stack.
16472   *
16473   * In either case, the next token will be on the top of the stack,
16474   * or the stack will be empty (in case of empty expansion
16475   * and no other tokens).
16476   *
16477   * Used to implement `expandAfterFuture` and `expandNextToken`.
16478   *
16479   * If expandableOnly, only expandable tokens are expanded and
16480   * an undefined control sequence results in an error.
16481   */
16482
16483
16484  expandOnce(expandableOnly) {
16485    var topToken = this.popToken();
16486    var name = topToken.text;
16487    var expansion = !topToken.noexpand ? this._getExpansion(name) : null;
16488
16489    if (expansion == null || expandableOnly && expansion.unexpandable) {
16490      if (expandableOnly && expansion == null && name[0] === "\\" && !this.isDefined(name)) {
16491        throw new ParseError("Undefined control sequence: " + name);
16492      }
16493
16494      this.pushToken(topToken);
16495      return false;
16496    }
16497
16498    this.countExpansion(1);
16499    var tokens = expansion.tokens;
16500    var args = this.consumeArgs(expansion.numArgs, expansion.delimiters);
16501
16502    if (expansion.numArgs) {
16503      // paste arguments in place of the placeholders
16504      tokens = tokens.slice(); // make a shallow copy
16505
16506      for (var i = tokens.length - 1; i >= 0; --i) {
16507        var tok = tokens[i];
16508
16509        if (tok.text === "#") {
16510          if (i === 0) {
16511            throw new ParseError("Incomplete placeholder at end of macro body", tok);
16512          }
16513
16514          tok = tokens[--i]; // next token on stack
16515
16516          if (tok.text === "#") {
16517            // ## → #
16518            tokens.splice(i + 1, 1); // drop first #
16519          } else if (/^[1-9]$/.test(tok.text)) {
16520            // replace the placeholder with the indicated argument
16521            tokens.splice(i, 2, ...args[+tok.text - 1]);
16522          } else {
16523            throw new ParseError("Not a valid argument number", tok);
16524          }
16525        }
16526      }
16527    } // Concatenate expansion onto top of stack.
16528
16529
16530    this.pushTokens(tokens);
16531    return tokens.length;
16532  }
16533  /**
16534   * Expand the next token only once (if possible), and return the resulting
vendor: 8,681 bytes, lines 16535-16961
16535   * top token on the stack (without removing anything from the stack).
16536   * Similar in behavior to TeX's `\expandafter\futurelet`.
16537   * Equivalent to expandOnce() followed by future().
16538   */
16539
16540
16541  expandAfterFuture() {
16542    this.expandOnce();
16543    return this.future();
16544  }
16545  /**
16546   * Recursively expand first token, then return first non-expandable token.
16547   */
16548
16549
16550  expandNextToken() {
16551    for (;;) {
16552      if (this.expandOnce() === false) {
16553        // fully expanded
16554        var token = this.stack.pop(); // the token after \noexpand is interpreted as if its meaning
16555        // were ‘\relax’
16556
16557        if (token.treatAsRelax) {
16558          token.text = "\\relax";
16559        }
16560
16561        return token;
16562      }
16563    } // Flow unable to figure out that this pathway is impossible.
16564    // https://github.com/facebook/flow/issues/4808
16565
16566
16567    throw new Error(); // eslint-disable-line no-unreachable
16568  }
16569  /**
16570   * Fully expand the given macro name and return the resulting list of
16571   * tokens, or return `undefined` if no such macro is defined.
16572   */
16573
16574
16575  expandMacro(name) {
16576    return this.macros.has(name) ? this.expandTokens([new Token(name)]) : undefined;
16577  }
16578  /**
16579   * Fully expand the given token stream and return the resulting list of
16580   * tokens.  Note that the input tokens are in reverse order, but the
16581   * output tokens are in forward order.
16582   */
16583
16584
16585  expandTokens(tokens) {
16586    var output = [];
16587    var oldStackLength = this.stack.length;
16588    this.pushTokens(tokens);
16589
16590    while (this.stack.length > oldStackLength) {
16591      // Expand only expandable tokens
16592      if (this.expandOnce(true) === false) {
16593        // fully expanded
16594        var token = this.stack.pop();
16595
16596        if (token.treatAsRelax) {
16597          // the expansion of \noexpand is the token itself
16598          token.noexpand = false;
16599          token.treatAsRelax = false;
16600        }
16601
16602        output.push(token);
16603      }
16604    } // Count all of these tokens as additional expansions, to prevent
16605    // exponential blowup from linearly many \edef's.
16606
16607
16608    this.countExpansion(output.length);
16609    return output;
16610  }
16611  /**
16612   * Fully expand the given macro name and return the result as a string,
16613   * or return `undefined` if no such macro is defined.
16614   */
16615
16616
16617  expandMacroAsText(name) {
16618    var tokens = this.expandMacro(name);
16619
16620    if (tokens) {
16621      return tokens.map(token => token.text).join("");
16622    } else {
16623      return tokens;
16624    }
16625  }
16626  /**
16627   * Returns the expanded macro as a reversed array of tokens and a macro
16628   * argument count.  Or returns `null` if no such macro.
16629   */
16630
16631
16632  _getExpansion(name) {
16633    var definition = this.macros.get(name);
16634
16635    if (definition == null) {
16636      // mainly checking for undefined here
16637      return definition;
16638    } // If a single character has an associated catcode other than 13
16639    // (active character), then don't expand it.
16640
16641
16642    if (name.length === 1) {
16643      var catcode = this.lexer.catcodes[name];
16644
16645      if (catcode != null && catcode !== 13) {
16646        return;
16647      }
16648    }
16649
16650    var expansion = typeof definition === "function" ? definition(this) : definition;
16651
16652    if (typeof expansion === "string") {
16653      var numArgs = 0;
16654
16655      if (expansion.indexOf("#") !== -1) {
16656        var stripped = expansion.replace(/##/g, "");
16657
16658        while (stripped.indexOf("#" + (numArgs + 1)) !== -1) {
16659          ++numArgs;
16660        }
16661      }
16662
16663      var bodyLexer = new Lexer(expansion, this.settings);
16664      var tokens = [];
16665      var tok = bodyLexer.lex();
16666
16667      while (tok.text !== "EOF") {
16668        tokens.push(tok);
16669        tok = bodyLexer.lex();
16670      }
16671
16672      tokens.reverse(); // to fit in with stack using push and pop
16673
16674      var expanded = {
16675        tokens,
16676        numArgs
16677      };
16678      return expanded;
16679    }
16680
16681    return expansion;
16682  }
16683  /**
16684   * Determine whether a command is currently "defined" (has some
16685   * functionality), meaning that it's a macro (in the current group),
16686   * a function, a symbol, or one of the special commands listed in
16687   * `implicitCommands`.
16688   */
16689
16690
16691  isDefined(name) {
16692    return this.macros.has(name) || functions.hasOwnProperty(name) || symbols.math.hasOwnProperty(name) || symbols.text.hasOwnProperty(name) || implicitCommands.hasOwnProperty(name);
16693  }
16694  /**
16695   * Determine whether a command is expandable.
16696   */
16697
16698
16699  isExpandable(name) {
16700    var macro = this.macros.get(name);
16701    return macro != null ? typeof macro === "string" || typeof macro === "function" || !macro.unexpandable : functions.hasOwnProperty(name) && !functions[name].primitive;
16702  }
16703
16704}
16705
16706// Helpers for Parser.js handling of Unicode (sub|super)script characters.
16707var unicodeSubRegEx = /^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/;
16708var uSubsAndSups = Object.freeze({
16709  '₊': '+',
16710  '₋': '-',
16711  '₌': '=',
16712  '₍': '(',
16713  '₎': ')',
16714  '₀': '0',
16715  '₁': '1',
16716  '₂': '2',
16717  '₃': '3',
16718  '₄': '4',
16719  '₅': '5',
16720  '₆': '6',
16721  '₇': '7',
16722  '₈': '8',
16723  '₉': '9',
16724  '\u2090': 'a',
16725  '\u2091': 'e',
16726  '\u2095': 'h',
16727  '\u1D62': 'i',
16728  '\u2C7C': 'j',
16729  '\u2096': 'k',
16730  '\u2097': 'l',
16731  '\u2098': 'm',
16732  '\u2099': 'n',
16733  '\u2092': 'o',
16734  '\u209A': 'p',
16735  '\u1D63': 'r',
16736  '\u209B': 's',
16737  '\u209C': 't',
16738  '\u1D64': 'u',
16739  '\u1D65': 'v',
16740  '\u2093': 'x',
16741  '\u1D66': 'β',
16742  '\u1D67': 'γ',
16743  '\u1D68': 'ρ',
16744  '\u1D69': '\u03d5',
16745  '\u1D6A': 'χ',
16746  '⁺': '+',
16747  '⁻': '-',
16748  '⁼': '=',
16749  '⁽': '(',
16750  '⁾': ')',
16751  '⁰': '0',
16752  '¹': '1',
16753  '²': '2',
16754  '³': '3',
16755  '⁴': '4',
16756  '⁵': '5',
16757  '⁶': '6',
16758  '⁷': '7',
16759  '⁸': '8',
16760  '⁹': '9',
16761  '\u1D2C': 'A',
16762  '\u1D2E': 'B',
16763  '\u1D30': 'D',
16764  '\u1D31': 'E',
16765  '\u1D33': 'G',
16766  '\u1D34': 'H',
16767  '\u1D35': 'I',
16768  '\u1D36': 'J',
16769  '\u1D37': 'K',
16770  '\u1D38': 'L',
16771  '\u1D39': 'M',
16772  '\u1D3A': 'N',
16773  '\u1D3C': 'O',
16774  '\u1D3E': 'P',
16775  '\u1D3F': 'R',
16776  '\u1D40': 'T',
16777  '\u1D41': 'U',
16778  '\u2C7D': 'V',
16779  '\u1D42': 'W',
16780  '\u1D43': 'a',
16781  '\u1D47': 'b',
16782  '\u1D9C': 'c',
16783  '\u1D48': 'd',
16784  '\u1D49': 'e',
16785  '\u1DA0': 'f',
16786  '\u1D4D': 'g',
16787  '\u02B0': 'h',
16788  '\u2071': 'i',
16789  '\u02B2': 'j',
16790  '\u1D4F': 'k',
16791  '\u02E1': 'l',
16792  '\u1D50': 'm',
16793  '\u207F': 'n',
16794  '\u1D52': 'o',
16795  '\u1D56': 'p',
16796  '\u02B3': 'r',
16797  '\u02E2': 's',
16798  '\u1D57': 't',
16799  '\u1D58': 'u',
16800  '\u1D5B': 'v',
16801  '\u02B7': 'w',
16802  '\u02E3': 'x',
16803  '\u02B8': 'y',
16804  '\u1DBB': 'z',
16805  '\u1D5D': 'β',
16806  '\u1D5E': 'γ',
16807  '\u1D5F': 'δ',
16808  '\u1D60': '\u03d5',
16809  '\u1D61': 'χ',
16810  '\u1DBF': 'θ'
16811});
16812
16813/* eslint no-constant-condition:0 */
16814
16815var unicodeAccents = {
16816  "́": {
16817    "text": "\\'",
16818    "math": "\\acute"
16819  },
16820  "̀": {
16821    "text": "\\`",
16822    "math": "\\grave"
16823  },
16824  "̈": {
16825    "text": "\\\"",
16826    "math": "\\ddot"
16827  },
16828  "̃": {
16829    "text": "\\~",
16830    "math": "\\tilde"
16831  },
16832  "̄": {
16833    "text": "\\=",
16834    "math": "\\bar"
16835  },
16836  "̆": {
16837    "text": "\\u",
16838    "math": "\\breve"
16839  },
16840  "̌": {
16841    "text": "\\v",
16842    "math": "\\check"
16843  },
16844  "̂": {
16845    "text": "\\^",
16846    "math": "\\hat"
16847  },
16848  "̇": {
16849    "text": "\\.",
16850    "math": "\\dot"
16851  },
16852  "̊": {
16853    "text": "\\r",
16854    "math": "\\mathring"
16855  },
16856  "̋": {
16857    "text": "\\H"
16858  },
16859  "̧": {
16860    "text": "\\c"
16861  }
16862};
16863var unicodeSymbols = {
16864  "á": "á",
16865  "à": "à",
16866  "ä": "ä",
16867  "ǟ": "ǟ",
16868  "ã": "ã",
16869  "ā": "ā",
16870  "ă": "ă",
16871  "ắ": "ắ",
16872  "ằ": "ằ",
16873  "ẵ": "ẵ",
16874  "ǎ": "ǎ",
16875  "â": "â",
16876  "ấ": "ấ",
16877  "ầ": "ầ",
16878  "ẫ": "ẫ",
16879  "ȧ": "ȧ",
16880  "ǡ": "ǡ",
16881  "å": "å",
16882  "ǻ": "ǻ",
16883  "ḃ": "ḃ",
16884  "ć": "ć",
16885  "ḉ": "ḉ",
16886  "č": "č",
16887  "ĉ": "ĉ",
16888  "ċ": "ċ",
16889  "ç": "ç",
16890  "ď": "ď",
16891  "ḋ": "ḋ",
16892  "ḑ": "ḑ",
16893  "é": "é",
16894  "è": "è",
16895  "ë": "ë",
16896  "ẽ": "ẽ",
16897  "ē": "ē",
16898  "ḗ": "ḗ",
16899  "ḕ": "ḕ",
16900  "ĕ": "ĕ",
16901  "ḝ": "ḝ",
16902  "ě": "ě",
16903  "ê": "ê",
16904  "ế": "ế",
16905  "ề": "ề",
16906  "ễ": "ễ",
16907  "ė": "ė",
16908  "ȩ": "ȩ",
16909  "ḟ": "ḟ",
16910  "ǵ": "ǵ",
16911  "ḡ": "ḡ",
16912  "ğ": "ğ",
16913  "ǧ": "ǧ",
16914  "ĝ": "ĝ",
16915  "ġ": "ġ",
16916  "ģ": "ģ",
16917  "ḧ": "ḧ",
16918  "ȟ": "ȟ",
16919  "ĥ": "ĥ",
16920  "ḣ": "ḣ",
16921  "ḩ": "ḩ",
16922  "í": "í",
16923  "ì": "ì",
16924  "ï": "ï",
16925  "ḯ": "ḯ",
16926  "ĩ": "ĩ",
16927  "ī": "ī",
16928  "ĭ": "ĭ",
16929  "ǐ": "ǐ",
16930  "î": "î",
16931  "ǰ": "ǰ",
16932  "ĵ": "ĵ",
16933  "ḱ": "ḱ",
16934  "ǩ": "ǩ",
16935  "ķ": "ķ",
16936  "ĺ": "ĺ",
16937  "ľ": "ľ",
16938  "ļ": "ļ",
16939  "ḿ": "ḿ",
16940  "ṁ": "ṁ",
16941  "ń": "ń",
16942  "ǹ": "ǹ",
16943  "ñ": "ñ",
16944  "ň": "ň",
16945  "ṅ": "ṅ",
16946  "ņ": "ņ",
16947  "ó": "ó",
16948  "ò": "ò",
16949  "ö": "ö",
16950  "ȫ": "ȫ",
16951  "õ": "õ",
16952  "ṍ": "ṍ",
16953  "ṏ": "ṏ",
16954  "ȭ": "ȭ",
16955  "ō": "ō",
16956  "ṓ": "ṓ",
16957  "ṑ": "ṑ",
16958  "ŏ": "ŏ",
16959  "ǒ": "ǒ",
16960  "ô": "ô",
16961  "ố": "ố",
16962  "ồ": "ồ",
16963  "ỗ": "ỗ",
16964  "ȯ": "ȯ",
16965  "ȱ": "ȱ",
16966  "ő": "ő",
16967  "ṕ": "ṕ",
16968  "ṗ": "ṗ",
16969  "ŕ": "ŕ",
16970  "ř": "ř",
16971  "ṙ": "ṙ",
16972  "ŗ": "ŗ",
16973  "ś": "ś",
16974  "ṥ": "ṥ",
16975  "š": "š",
16976  "ṧ": "ṧ",
16977  "ŝ": "ŝ",
16978  "ṡ": "ṡ",
16979  "ş": "ş",
16980  "ẗ": "ẗ",
16981  "ť": "ť",
16982  "ṫ": "ṫ",
16983  "ţ": "ţ",
16984  "ú": "ú",
16985  "ù": "ù",
16986  "ü": "ü",
16987  "ǘ": "ǘ",
16988  "ǜ": "ǜ",
16989  "ǖ": "ǖ",
16990  "ǚ": "ǚ",
16991  "ũ": "ũ",
16992  "ṹ": "ṹ",
16993  "ū": "ū",
16994  "ṻ": "ṻ",
16995  "ŭ": "ŭ",
16996  "ǔ": "ǔ",
16997  "û": "û",
16998  "ů": "ů",
16999  "ű": "ű",
17000  "ṽ": "ṽ",
17001  "ẃ": "ẃ",
17002  "ẁ": "ẁ",
17003  "ẅ": "ẅ",
17004  "ŵ": "ŵ",
17005  "ẇ": "ẇ",
17006  "ẘ": "ẘ",
17007  "ẍ": "ẍ",
17008  "ẋ": "ẋ",
17009  "ý": "ý",
17010  "ỳ": "ỳ",
17011  "ÿ": "ÿ",
17012  "ỹ": "ỹ",
17013  "ȳ": "ȳ",
17014  "ŷ": "ŷ",
17015  "ẏ": "ẏ",
17016  "ẙ": "ẙ",
17017  "ź": "ź",
17018  "ž": "ž",
17019  "ẑ": "ẑ",
17020  "ż": "ż",
17021  "Á": "Á",
17022  "À": "À",
17023  "Ä": "Ä",
17024  "Ǟ": "Ǟ",
17025  "Ã": "Ã",
17026  "Ā": "Ā",
17027  "Ă": "Ă",
17028  "Ắ": "Ắ",
17029  "Ằ": "Ằ",
17030  "Ẵ": "Ẵ",
17031  "Ǎ": "Ǎ",
17032  "Â": "Â",
17033  "Ấ": "Ấ",
17034  "Ầ": "Ầ",
17035  "Ẫ": "Ẫ",
17036  "Ȧ": "Ȧ",
17037  "Ǡ": "Ǡ",
17038  "Å": "Å",
17039  "Ǻ": "Ǻ",
17040  "Ḃ": "Ḃ",
17041  "Ć": "Ć",
17042  "Ḉ": "Ḉ",
17043  "Č": "Č",
17044  "Ĉ": "Ĉ",
17045  "Ċ": "Ċ",
17046  "Ç": "Ç",
17047  "Ď": "Ď",
17048  "Ḋ": "Ḋ",
17049  "Ḑ": "Ḑ",
17050  "É": "É",
17051  "È": "È",
17052  "Ë": "Ë",
17053  "Ẽ": "Ẽ",
17054  "Ē": "Ē",
17055  "Ḗ": "Ḗ",
17056  "Ḕ": "Ḕ",
17057  "Ĕ": "Ĕ",
17058  "Ḝ": "Ḝ",
17059  "Ě": "Ě",
17060  "Ê": "Ê",
17061  "Ế": "Ế",
17062  "Ề": "Ề",
17063  "Ễ": "Ễ",
17064  "Ė": "Ė",
17065  "Ȩ": "Ȩ",
17066  "Ḟ": "Ḟ",
17067  "Ǵ": "Ǵ",
17068  "Ḡ": "Ḡ",
17069  "Ğ": "Ğ",
17070  "Ǧ": "Ǧ",
17071  "Ĝ": "Ĝ",
17072  "Ġ": "Ġ",
17073  "Ģ": "Ģ",
17074  "Ḧ": "Ḧ",
17075  "Ȟ": "Ȟ",
17076  "Ĥ": "Ĥ",
17077  "Ḣ": "Ḣ",
17078  "Ḩ": "Ḩ",
17079  "Í": "Í",
17080  "Ì": "Ì",
17081  "Ï": "Ï",
17082  "Ḯ": "Ḯ",
17083  "Ĩ": "Ĩ",
17084  "Ī": "Ī",
17085  "Ĭ": "Ĭ",
17086  "Ǐ": "Ǐ",
17087  "Î": "Î",
17088  "İ": "İ",
17089  "Ĵ": "Ĵ",
17090  "Ḱ": "Ḱ",
17091  "Ǩ": "Ǩ",
17092  "Ķ": "Ķ",
17093  "Ĺ": "Ĺ",
17094  "Ľ": "Ľ",
17095  "Ļ": "Ļ",
17096  "Ḿ": "Ḿ",
17097  "Ṁ": "Ṁ",
17098  "Ń": "Ń",
17099  "Ǹ": "Ǹ",
17100  "Ñ": "Ñ",
17101  "Ň": "Ň",
17102  "Ṅ": "Ṅ",
17103  "Ņ": "Ņ",
17104  "Ó": "Ó",
17105  "Ò": "Ò",
17106  "Ö": "Ö",
17107  "Ȫ": "Ȫ",
17108  "Õ": "Õ",
17109  "Ṍ": "Ṍ",
17110  "Ṏ": "Ṏ",
17111  "Ȭ": "Ȭ",
17112  "Ō": "Ō",
17113  "Ṓ": "Ṓ",
17114  "Ṑ": "Ṑ",
17115  "Ŏ": "Ŏ",
17116  "Ǒ": "Ǒ",
17117  "Ô": "Ô",
17118  "Ố": "Ố",
17119  "Ồ": "Ồ",
17120  "Ỗ": "Ỗ",
17121  "Ȯ": "Ȯ",
17122  "Ȱ": "Ȱ",
17123  "Ő": "Ő",
17124  "Ṕ": "Ṕ",
17125  "Ṗ": "Ṗ",
17126  "Ŕ": "Ŕ",
17127  "Ř": "Ř",
17128  "Ṙ": "Ṙ",
17129  "Ŗ": "Ŗ",
17130  "Ś": "Ś",
17131  "Ṥ": "Ṥ",
17132  "Š": "Š",
17133  "Ṧ": "Ṧ",
17134  "Ŝ": "Ŝ",
17135  "Ṡ": "Ṡ",
17136  "Ş": "Ş",
17137  "Ť": "Ť",
17138  "Ṫ": "Ṫ",
17139  "Ţ": "Ţ",
17140  "Ú": "Ú",
17141  "Ù": "Ù",
17142  "Ü": "Ü",
17143  "Ǘ": "Ǘ",
17144  "Ǜ": "Ǜ",
17145  "Ǖ": "Ǖ",
17146  "Ǚ": "Ǚ",
17147  "Ũ": "Ũ",
17148  "Ṹ": "Ṹ",
17149  "Ū": "Ū",
17150  "Ṻ": "Ṻ",
17151  "Ŭ": "Ŭ",
17152  "Ǔ": "Ǔ",
17153  "Û": "Û",
17154  "Ů": "Ů",
17155  "Ű": "Ű",
17156  "Ṽ": "Ṽ",
17157  "Ẃ": "Ẃ",
17158  "Ẁ": "Ẁ",
17159  "Ẅ": "Ẅ",
17160  "Ŵ": "Ŵ",
17161  "Ẇ": "Ẇ",
17162  "Ẍ": "Ẍ",
17163  "Ẋ": "Ẋ",
17164  "Ý": "Ý",
17165  "Ỳ": "Ỳ",
17166  "Ÿ": "Ÿ",
17167  "Ỹ": "Ỹ",
17168  "Ȳ": "Ȳ",
17169  "Ŷ": "Ŷ",
17170  "Ẏ": "Ẏ",
17171  "Ź": "Ź",
17172  "Ž": "Ž",
17173  "Ẑ": "Ẑ",
17174  "Ż": "Ż",
17175  "ά": "ά",
17176  "ὰ": "ὰ",
17177  "ᾱ": "ᾱ",
17178  "ᾰ": "ᾰ",
17179  "έ": "έ",
17180  "ὲ": "ὲ",
17181  "ή": "ή",
17182  "ὴ": "ὴ",
17183  "ί": "ί",
17184  "ὶ": "ὶ",
17185  "ϊ": "ϊ",
17186  "ΐ": "ΐ",
17187  "ῒ": "ῒ",
17188  "ῑ": "ῑ",
17189  "ῐ": "ῐ",
17190  "ό": "ό",
17191  "ὸ": "ὸ",
17192  "ύ": "ύ",
17193  "ὺ": "ὺ",
17194  "ϋ": "ϋ",
17195  "ΰ": "ΰ",
17196  "ῢ": "ῢ",
17197  "ῡ": "ῡ",
17198  "ῠ": "ῠ",
17199  "ώ": "ώ",
17200  "ὼ": "ὼ",
17201  "Ύ": "Ύ",
17202  "Ὺ": "Ὺ",
17203  "Ϋ": "Ϋ",
17204  "Ῡ": "Ῡ",
17205  "Ῠ": "Ῠ",
17206  "Ώ": "Ώ",
17207  "Ὼ": "Ὼ"
17208};
17209
17210/**
17211 * This file contains the parser used to parse out a TeX expression from the
17212 * input. Since TeX isn't context-free, standard parsers don't work particularly
17213 * well.
17214 *
17215 * The strategy of this parser is as such:
17216 *
17217 * The main functions (the `.parse...` ones) take a position in the current
17218 * parse string to parse tokens from. The lexer (found in Lexer.js, stored at
17219 * this.gullet.lexer) also supports pulling out tokens at arbitrary places. When
17220 * individual tokens are needed at a position, the lexer is called to pull out a
17221 * token, which is then used.
17222 *
17223 * The parser has a property called "mode" indicating the mode that
17224 * the parser is currently in. Currently it has to be one of "math" or
17225 * "text", which denotes whether the current environment is a math-y
17226 * one or a text-y one (e.g. inside \text). Currently, this serves to
17227 * limit the functions which can be used in text mode.
17228 *
17229 * The main functions then return an object which contains the useful data that
17230 * was parsed at its given point, and a new position at the end of the parsed
17231 * data. The main functions can call each other and continue the parsing by
17232 * using the returned position as a new starting point.
17233 *
17234 * There are also extra `.handle...` functions, which pull out some reused
17235 * functionality into self-contained functions.
17236 *
17237 * The functions return ParseNodes.
17238 */
17239class Parser {
17240  constructor(input, settings) {
17241    this.mode = void 0;
17242    this.gullet = void 0;
17243    this.settings = void 0;
17244    this.leftrightDepth = void 0;
17245    this.nextToken = void 0;
17246    // Start in math mode
17247    this.mode = "math"; // Create a new macro expander (gullet) and (indirectly via that) also a
17248    // new lexer (mouth) for this parser (stomach, in the language of TeX)
17249
17250    this.gullet = new MacroExpander(input, settings, this.mode); // Store the settings for use in parsing
17251
17252    this.settings = settings; // Count leftright depth (for \middle errors)
17253
17254    this.leftrightDepth = 0;
17255  }
17256  /**
17257   * Checks a result to make sure it has the right type, and throws an
17258   * appropriate error otherwise.
17259   */
17260
17261
17262  expect(text, consume) {
17263    if (consume === void 0) {
17264      consume = true;
17265    }
17266
17267    if (this.fetch().text !== text) {
vendor: 4,486 bytes, lines 17268-17438
17268      throw new ParseError("Expected '" + text + "', got '" + this.fetch().text + "'", this.fetch());
17269    }
17270
17271    if (consume) {
17272      this.consume();
17273    }
17274  }
17275  /**
17276   * Discards the current lookahead token, considering it consumed.
17277   */
17278
17279
17280  consume() {
17281    this.nextToken = null;
17282  }
17283  /**
17284   * Return the current lookahead token, or if there isn't one (at the
17285   * beginning, or if the previous lookahead token was consume()d),
17286   * fetch the next token as the new lookahead token and return it.
17287   */
17288
17289
17290  fetch() {
17291    if (this.nextToken == null) {
17292      this.nextToken = this.gullet.expandNextToken();
17293    }
17294
17295    return this.nextToken;
17296  }
17297  /**
17298   * Switches between "text" and "math" modes.
17299   */
17300
17301
17302  switchMode(newMode) {
17303    this.mode = newMode;
17304    this.gullet.switchMode(newMode);
17305  }
17306  /**
17307   * Main parsing function, which parses an entire input.
17308   */
17309
17310
17311  parse() {
17312    if (!this.settings.globalGroup) {
17313      // Create a group namespace for the math expression.
17314      // (LaTeX creates a new group for every $...$, $$...$$, \[...\].)
17315      this.gullet.beginGroup();
17316    } // Use old \color behavior (same as LaTeX's \textcolor) if requested.
17317    // We do this within the group for the math expression, so it doesn't
17318    // pollute settings.macros.
17319
17320
17321    if (this.settings.colorIsTextColor) {
17322      this.gullet.macros.set("\\color", "\\textcolor");
17323    }
17324
17325    try {
17326      // Try to parse the input
17327      var parse = this.parseExpression(false); // If we succeeded, make sure there's an EOF at the end
17328
17329      this.expect("EOF"); // End the group namespace for the expression
17330
17331      if (!this.settings.globalGroup) {
17332        this.gullet.endGroup();
17333      }
17334
17335      return parse; // Close any leftover groups in case of a parse error.
17336    } finally {
17337      this.gullet.endGroups();
17338    }
17339  }
17340  /**
17341   * Fully parse a separate sequence of tokens as a separate job.
17342   * Tokens should be specified in reverse order, as in a MacroDefinition.
17343   */
17344
17345
17346  subparse(tokens) {
17347    // Save the next token from the current job.
17348    var oldToken = this.nextToken;
17349    this.consume(); // Run the new job, terminating it with an excess '}'
17350
17351    this.gullet.pushToken(new Token("}"));
17352    this.gullet.pushTokens(tokens);
17353    var parse = this.parseExpression(false);
17354    this.expect("}"); // Restore the next token from the current job.
17355
17356    this.nextToken = oldToken;
17357    return parse;
17358  }
17359
17360  /**
17361   * Parses an "expression", which is a list of atoms.
17362   *
17363   * `breakOnInfix`: Should the parsing stop when we hit infix nodes? This
17364   *                 happens when functions have higher precedence han infix
17365   *                 nodes in implicit parses.
17366   *
17367   * `breakOnTokenText`: The text of the token that the expression should end
17368   *                     with, or `null` if something else should end the
17369   *                     expression.
17370   */
17371  parseExpression(breakOnInfix, breakOnTokenText) {
17372    var body = []; // Keep adding atoms to the body until we can't parse any more atoms (either
17373    // we reached the end, a }, or a \right)
17374
17375    while (true) {
17376      // Ignore spaces in math mode
17377      if (this.mode === "math") {
17378        this.consumeSpaces();
17379      }
17380
17381      var lex = this.fetch();
17382
17383      if (Parser.endOfExpression.indexOf(lex.text) !== -1) {
17384        break;
17385      }
17386
17387      if (breakOnTokenText && lex.text === breakOnTokenText) {
17388        break;
17389      }
17390
17391      if (breakOnInfix && functions[lex.text] && functions[lex.text].infix) {
17392        break;
17393      }
17394
17395      var atom = this.parseAtom(breakOnTokenText);
17396
17397      if (!atom) {
17398        break;
17399      } else if (atom.type === "internal") {
17400        continue;
17401      }
17402
17403      body.push(atom);
17404    }
17405
17406    if (this.mode === "text") {
17407      this.formLigatures(body);
17408    }
17409
17410    return this.handleInfixNodes(body);
17411  }
17412  /**
17413   * Rewrites infix operators such as \over with corresponding commands such
17414   * as \frac.
17415   *
17416   * There can only be one infix operator per group.  If there's more than one
17417   * then the expression is ambiguous.  This can be resolved by adding {}.
17418   */
17419
17420
17421  handleInfixNodes(body) {
17422    var overIndex = -1;
17423    var funcName;
17424
17425    for (var i = 0; i < body.length; i++) {
17426      if (body[i].type === "infix") {
17427        if (overIndex !== -1) {
17428          throw new ParseError("only one infix operator per group", body[i].token);
17429        }
17430
17431        overIndex = i;
17432        funcName = body[i].replaceWith;
17433      }
17434    }
17435
17436    if (overIndex !== -1 && funcName) {
17437      var numerNode;
17438      var denomNode;
vendor: 14,111 bytes, lines 17439-17976
17439      var numerBody = body.slice(0, overIndex);
17440      var denomBody = body.slice(overIndex + 1);
17441
17442      if (numerBody.length === 1 && numerBody[0].type === "ordgroup") {
17443        numerNode = numerBody[0];
17444      } else {
17445        numerNode = {
17446          type: "ordgroup",
17447          mode: this.mode,
17448          body: numerBody
17449        };
17450      }
17451
17452      if (denomBody.length === 1 && denomBody[0].type === "ordgroup") {
17453        denomNode = denomBody[0];
17454      } else {
17455        denomNode = {
17456          type: "ordgroup",
17457          mode: this.mode,
17458          body: denomBody
17459        };
17460      }
17461
17462      var node;
17463
17464      if (funcName === "\\\\abovefrac") {
17465        node = this.callFunction(funcName, [numerNode, body[overIndex], denomNode], []);
17466      } else {
17467        node = this.callFunction(funcName, [numerNode, denomNode], []);
17468      }
17469
17470      return [node];
17471    } else {
17472      return body;
17473    }
17474  }
17475  /**
17476   * Handle a subscript or superscript with nice errors.
17477   */
17478
17479
17480  handleSupSubscript(name // For error reporting.
17481  ) {
17482    var symbolToken = this.fetch();
17483    var symbol = symbolToken.text;
17484    this.consume();
17485    this.consumeSpaces(); // ignore spaces before sup/subscript argument
17486
17487    var group = this.parseGroup(name);
17488
17489    if (!group) {
17490      throw new ParseError("Expected group after '" + symbol + "'", symbolToken);
17491    }
17492
17493    return group;
17494  }
17495  /**
17496   * Converts the textual input of an unsupported command into a text node
17497   * contained within a color node whose color is determined by errorColor
17498   */
17499
17500
17501  formatUnsupportedCmd(text) {
17502    var textordArray = [];
17503
17504    for (var i = 0; i < text.length; i++) {
17505      textordArray.push({
17506        type: "textord",
17507        mode: "text",
17508        text: text[i]
17509      });
17510    }
17511
17512    var textNode = {
17513      type: "text",
17514      mode: this.mode,
17515      body: textordArray
17516    };
17517    var colorNode = {
17518      type: "color",
17519      mode: this.mode,
17520      color: this.settings.errorColor,
17521      body: [textNode]
17522    };
17523    return colorNode;
17524  }
17525  /**
17526   * Parses a group with optional super/subscripts.
17527   */
17528
17529
17530  parseAtom(breakOnTokenText) {
17531    // The body of an atom is an implicit group, so that things like
17532    // \left(x\right)^2 work correctly.
17533    var base = this.parseGroup("atom", breakOnTokenText); // In text mode, we don't have superscripts or subscripts
17534
17535    if (this.mode === "text") {
17536      return base;
17537    } // Note that base may be empty (i.e. null) at this point.
17538
17539
17540    var superscript;
17541    var subscript;
17542
17543    while (true) {
17544      // Guaranteed in math mode, so eat any spaces first.
17545      this.consumeSpaces(); // Lex the first token
17546
17547      var lex = this.fetch();
17548
17549      if (lex.text === "\\limits" || lex.text === "\\nolimits") {
17550        // We got a limit control
17551        if (base && base.type === "op") {
17552          var limits = lex.text === "\\limits";
17553          base.limits = limits;
17554          base.alwaysHandleSupSub = true;
17555        } else if (base && base.type === "operatorname") {
17556          if (base.alwaysHandleSupSub) {
17557            base.limits = lex.text === "\\limits";
17558          }
17559        } else {
17560          throw new ParseError("Limit controls must follow a math operator", lex);
17561        }
17562
17563        this.consume();
17564      } else if (lex.text === "^") {
17565        // We got a superscript start
17566        if (superscript) {
17567          throw new ParseError("Double superscript", lex);
17568        }
17569
17570        superscript = this.handleSupSubscript("superscript");
17571      } else if (lex.text === "_") {
17572        // We got a subscript start
17573        if (subscript) {
17574          throw new ParseError("Double subscript", lex);
17575        }
17576
17577        subscript = this.handleSupSubscript("subscript");
17578      } else if (lex.text === "'") {
17579        // We got a prime
17580        if (superscript) {
17581          throw new ParseError("Double superscript", lex);
17582        }
17583
17584        var prime = {
17585          type: "textord",
17586          mode: this.mode,
17587          text: "\\prime"
17588        }; // Many primes can be grouped together, so we handle this here
17589
17590        var primes = [prime];
17591        this.consume(); // Keep lexing tokens until we get something that's not a prime
17592
17593        while (this.fetch().text === "'") {
17594          // For each one, add another prime to the list
17595          primes.push(prime);
17596          this.consume();
17597        } // If there's a superscript following the primes, combine that
17598        // superscript in with the primes.
17599
17600
17601        if (this.fetch().text === "^") {
17602          primes.push(this.handleSupSubscript("superscript"));
17603        } // Put everything into an ordgroup as the superscript
17604
17605
17606        superscript = {
17607          type: "ordgroup",
17608          mode: this.mode,
17609          body: primes
17610        };
17611      } else if (uSubsAndSups[lex.text]) {
17612        // A Unicode subscript or superscript character.
17613        // We treat these similarly to the unicode-math package.
17614        // So we render a string of Unicode (sub|super)scripts the
17615        // same as a (sub|super)script of regular characters.
17616        var isSub = unicodeSubRegEx.test(lex.text);
17617        var subsupTokens = [];
17618        subsupTokens.push(new Token(uSubsAndSups[lex.text]));
17619        this.consume(); // Continue fetching tokens to fill out the string.
17620
17621        while (true) {
17622          var token = this.fetch().text;
17623
17624          if (!uSubsAndSups[token]) {
17625            break;
17626          }
17627
17628          if (unicodeSubRegEx.test(token) !== isSub) {
17629            break;
17630          }
17631
17632          subsupTokens.unshift(new Token(uSubsAndSups[token]));
17633          this.consume();
17634        } // Now create a (sub|super)script.
17635
17636
17637        var body = this.subparse(subsupTokens);
17638
17639        if (isSub) {
17640          subscript = {
17641            type: "ordgroup",
17642            mode: "math",
17643            body
17644          };
17645        } else {
17646          superscript = {
17647            type: "ordgroup",
17648            mode: "math",
17649            body
17650          };
17651        }
17652      } else {
17653        // If it wasn't ^, _, or ', stop parsing super/subscripts
17654        break;
17655      }
17656    } // Base must be set if superscript or subscript are set per logic above,
17657    // but need to check here for type check to pass.
17658
17659
17660    if (superscript || subscript) {
17661      // If we got either a superscript or subscript, create a supsub
17662      return {
17663        type: "supsub",
17664        mode: this.mode,
17665        base: base,
17666        sup: superscript,
17667        sub: subscript
17668      };
17669    } else {
17670      // Otherwise return the original body
17671      return base;
17672    }
17673  }
17674  /**
17675   * Parses an entire function, including its base and all of its arguments.
17676   */
17677
17678
17679  parseFunction(breakOnTokenText, name // For determining its context
17680  ) {
17681    var token = this.fetch();
17682    var func = token.text;
17683    var funcData = functions[func];
17684
17685    if (!funcData) {
17686      return null;
17687    }
17688
17689    this.consume(); // consume command token
17690
17691    if (name && name !== "atom" && !funcData.allowedInArgument) {
17692      throw new ParseError("Got function '" + func + "' with no arguments" + (name ? " as " + name : ""), token);
17693    } else if (this.mode === "text" && !funcData.allowedInText) {
17694      throw new ParseError("Can't use function '" + func + "' in text mode", token);
17695    } else if (this.mode === "math" && funcData.allowedInMath === false) {
17696      throw new ParseError("Can't use function '" + func + "' in math mode", token);
17697    }
17698
17699    var {
17700      args,
17701      optArgs
17702    } = this.parseArguments(func, funcData);
17703    return this.callFunction(func, args, optArgs, token, breakOnTokenText);
17704  }
17705  /**
17706   * Call a function handler with a suitable context and arguments.
17707   */
17708
17709
17710  callFunction(name, args, optArgs, token, breakOnTokenText) {
17711    var context = {
17712      funcName: name,
17713      parser: this,
17714      token,
17715      breakOnTokenText
17716    };
17717    var func = functions[name];
17718
17719    if (func && func.handler) {
17720      return func.handler(context, args, optArgs);
17721    } else {
17722      throw new ParseError("No function handler for " + name);
17723    }
17724  }
17725  /**
17726   * Parses the arguments of a function or environment
17727   */
17728
17729
17730  parseArguments(func, // Should look like "\name" or "\begin{name}".
17731  funcData) {
17732    var totalArgs = funcData.numArgs + funcData.numOptionalArgs;
17733
17734    if (totalArgs === 0) {
17735      return {
17736        args: [],
17737        optArgs: []
17738      };
17739    }
17740
17741    var args = [];
17742    var optArgs = [];
17743
17744    for (var i = 0; i < totalArgs; i++) {
17745      var argType = funcData.argTypes && funcData.argTypes[i];
17746      var isOptional = i < funcData.numOptionalArgs;
17747
17748      if (funcData.primitive && argType == null || // \sqrt expands into primitive if optional argument doesn't exist
17749      funcData.type === "sqrt" && i === 1 && optArgs[0] == null) {
17750        argType = "primitive";
17751      }
17752
17753      var arg = this.parseGroupOfType("argument to '" + func + "'", argType, isOptional);
17754
17755      if (isOptional) {
17756        optArgs.push(arg);
17757      } else if (arg != null) {
17758        args.push(arg);
17759      } else {
17760        // should be unreachable
17761        throw new ParseError("Null argument, please report this as a bug");
17762      }
17763    }
17764
17765    return {
17766      args,
17767      optArgs
17768    };
17769  }
17770  /**
17771   * Parses a group when the mode is changing.
17772   */
17773
17774
17775  parseGroupOfType(name, type, optional) {
17776    switch (type) {
17777      case "color":
17778        return this.parseColorGroup(optional);
17779
17780      case "size":
17781        return this.parseSizeGroup(optional);
17782
17783      case "url":
17784        return this.parseUrlGroup(optional);
17785
17786      case "math":
17787      case "text":
17788        return this.parseArgumentGroup(optional, type);
17789
17790      case "hbox":
17791        {
17792          // hbox argument type wraps the argument in the equivalent of
17793          // \hbox, which is like \text but switching to \textstyle size.
17794          var group = this.parseArgumentGroup(optional, "text");
17795          return group != null ? {
17796            type: "styling",
17797            mode: group.mode,
17798            body: [group],
17799            style: "text" // simulate \textstyle
17800
17801          } : null;
17802        }
17803
17804      case "raw":
17805        {
17806          var token = this.parseStringGroup("raw", optional);
17807          return token != null ? {
17808            type: "raw",
17809            mode: "text",
17810            string: token.text
17811          } : null;
17812        }
17813
17814      case "primitive":
17815        {
17816          if (optional) {
17817            throw new ParseError("A primitive argument cannot be optional");
17818          }
17819
17820          var _group = this.parseGroup(name);
17821
17822          if (_group == null) {
17823            throw new ParseError("Expected group as " + name, this.fetch());
17824          }
17825
17826          return _group;
17827        }
17828
17829      case "original":
17830      case null:
17831      case undefined:
17832        return this.parseArgumentGroup(optional);
17833
17834      default:
17835        throw new ParseError("Unknown group type as " + name, this.fetch());
17836    }
17837  }
17838  /**
17839   * Discard any space tokens, fetching the next non-space token.
17840   */
17841
17842
17843  consumeSpaces() {
17844    while (this.fetch().text === " ") {
17845      this.consume();
17846    }
17847  }
17848  /**
17849   * Parses a group, essentially returning the string formed by the
17850   * brace-enclosed tokens plus some position information.
17851   */
17852
17853
17854  parseStringGroup(modeName, // Used to describe the mode in error messages.
17855  optional) {
17856    var argToken = this.gullet.scanArgument(optional);
17857
17858    if (argToken == null) {
17859      return null;
17860    }
17861
17862    var str = "";
17863    var nextToken;
17864
17865    while ((nextToken = this.fetch()).text !== "EOF") {
17866      str += nextToken.text;
17867      this.consume();
17868    }
17869
17870    this.consume(); // consume the end of the argument
17871
17872    argToken.text = str;
17873    return argToken;
17874  }
17875  /**
17876   * Parses a regex-delimited group: the largest sequence of tokens
17877   * whose concatenated strings match `regex`. Returns the string
17878   * formed by the tokens plus some position information.
17879   */
17880
17881
17882  parseRegexGroup(regex, modeName // Used to describe the mode in error messages.
17883  ) {
17884    var firstToken = this.fetch();
17885    var lastToken = firstToken;
17886    var str = "";
17887    var nextToken;
17888
17889    while ((nextToken = this.fetch()).text !== "EOF" && regex.test(str + nextToken.text)) {
17890      lastToken = nextToken;
17891      str += lastToken.text;
17892      this.consume();
17893    }
17894
17895    if (str === "") {
17896      throw new ParseError("Invalid " + modeName + ": '" + firstToken.text + "'", firstToken);
17897    }
17898
17899    return firstToken.range(lastToken, str);
17900  }
17901  /**
17902   * Parses a color description.
17903   */
17904
17905
17906  parseColorGroup(optional) {
17907    var res = this.parseStringGroup("color", optional);
17908
17909    if (res == null) {
17910      return null;
17911    }
17912
17913    var match = /^(#[a-f0-9]{3}|#?[a-f0-9]{6}|[a-z]+)$/i.exec(res.text);
17914
17915    if (!match) {
17916      throw new ParseError("Invalid color: '" + res.text + "'", res);
17917    }
17918
17919    var color = match[0];
17920
17921    if (/^[0-9a-f]{6}$/i.test(color)) {
17922      // We allow a 6-digit HTML color spec without a leading "#".
17923      // This follows the xcolor package's HTML color model.
17924      // Predefined color names are all missed by this RegEx pattern.
17925      color = "#" + color;
17926    }
17927
17928    return {
17929      type: "color-token",
17930      mode: this.mode,
17931      color
17932    };
17933  }
17934  /**
17935   * Parses a size specification, consisting of magnitude and unit.
17936   */
17937
17938
17939  parseSizeGroup(optional) {
17940    var res;
17941    var isBlank = false; // don't expand before parseStringGroup
17942
17943    this.gullet.consumeSpaces();
17944
17945    if (!optional && this.gullet.future().text !== "{") {
17946      res = this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/, "size");
17947    } else {
17948      res = this.parseStringGroup("size", optional);
17949    }
17950
17951    if (!res) {
17952      return null;
17953    }
17954
17955    if (!optional && res.text.length === 0) {
17956      // Because we've tested for what is !optional, this block won't
17957      // affect \kern, \hspace, etc. It will capture the mandatory arguments
17958      // to \genfrac and \above.
17959      res.text = "0pt"; // Enable \above{}
17960
17961      isBlank = true; // This is here specifically for \genfrac
17962    }
17963
17964    var match = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(res.text);
17965
17966    if (!match) {
17967      throw new ParseError("Invalid size: '" + res.text + "'", res);
17968    }
17969
17970    var data = {
17971      number: +(match[1] + match[2]),
17972      // sign + magnitude, cast to number
17973      unit: match[3]
17974    };
17975
17976    if (!validUnit(data)) {
vendor: 11,167 bytes, lines 17977-18353
17977      throw new ParseError("Invalid unit: '" + data.unit + "'", res);
17978    }
17979
17980    return {
17981      type: "size",
17982      mode: this.mode,
17983      value: data,
17984      isBlank
17985    };
17986  }
17987  /**
17988   * Parses an URL, checking escaped letters and allowed protocols,
17989   * and setting the catcode of % as an active character (as in \hyperref).
17990   */
17991
17992
17993  parseUrlGroup(optional) {
17994    this.gullet.lexer.setCatcode("%", 13); // active character
17995
17996    this.gullet.lexer.setCatcode("~", 12); // other character
17997
17998    var res = this.parseStringGroup("url", optional);
17999    this.gullet.lexer.setCatcode("%", 14); // comment character
18000
18001    this.gullet.lexer.setCatcode("~", 13); // active character
18002
18003    if (res == null) {
18004      return null;
18005    } // hyperref package allows backslashes alone in href, but doesn't
18006    // generate valid links in such cases; we interpret this as
18007    // "undefined" behaviour, and keep them as-is. Some browser will
18008    // replace backslashes with forward slashes.
18009
18010
18011    var url = res.text.replace(/\\([#$%&~_^{}])/g, '$1');
18012    return {
18013      type: "url",
18014      mode: this.mode,
18015      url
18016    };
18017  }
18018  /**
18019   * Parses an argument with the mode specified.
18020   */
18021
18022
18023  parseArgumentGroup(optional, mode) {
18024    var argToken = this.gullet.scanArgument(optional);
18025
18026    if (argToken == null) {
18027      return null;
18028    }
18029
18030    var outerMode = this.mode;
18031
18032    if (mode) {
18033      // Switch to specified mode
18034      this.switchMode(mode);
18035    }
18036
18037    this.gullet.beginGroup();
18038    var expression = this.parseExpression(false, "EOF"); // TODO: find an alternative way to denote the end
18039
18040    this.expect("EOF"); // expect the end of the argument
18041
18042    this.gullet.endGroup();
18043    var result = {
18044      type: "ordgroup",
18045      mode: this.mode,
18046      loc: argToken.loc,
18047      body: expression
18048    };
18049
18050    if (mode) {
18051      // Switch mode back
18052      this.switchMode(outerMode);
18053    }
18054
18055    return result;
18056  }
18057  /**
18058   * Parses an ordinary group, which is either a single nucleus (like "x")
18059   * or an expression in braces (like "{x+y}") or an implicit group, a group
18060   * that starts at the current position, and ends right before a higher explicit
18061   * group ends, or at EOF.
18062   */
18063
18064
18065  parseGroup(name, // For error reporting.
18066  breakOnTokenText) {
18067    var firstToken = this.fetch();
18068    var text = firstToken.text;
18069    var result; // Try to parse an open brace or \begingroup
18070
18071    if (text === "{" || text === "\\begingroup") {
18072      this.consume();
18073      var groupEnd = text === "{" ? "}" : "\\endgroup";
18074      this.gullet.beginGroup(); // If we get a brace, parse an expression
18075
18076      var expression = this.parseExpression(false, groupEnd);
18077      var lastToken = this.fetch();
18078      this.expect(groupEnd); // Check that we got a matching closing brace
18079
18080      this.gullet.endGroup();
18081      result = {
18082        type: "ordgroup",
18083        mode: this.mode,
18084        loc: SourceLocation.range(firstToken, lastToken),
18085        body: expression,
18086        // A group formed by \begingroup...\endgroup is a semi-simple group
18087        // which doesn't affect spacing in math mode, i.e., is transparent.
18088        // https://tex.stackexchange.com/questions/1930/when-should-one-
18089        // use-begingroup-instead-of-bgroup
18090        semisimple: text === "\\begingroup" || undefined
18091      };
18092    } else {
18093      // If there exists a function with this name, parse the function.
18094      // Otherwise, just return a nucleus
18095      result = this.parseFunction(breakOnTokenText, name) || this.parseSymbol();
18096
18097      if (result == null && text[0] === "\\" && !implicitCommands.hasOwnProperty(text)) {
18098        if (this.settings.throwOnError) {
18099          throw new ParseError("Undefined control sequence: " + text, firstToken);
18100        }
18101
18102        result = this.formatUnsupportedCmd(text);
18103        this.consume();
18104      }
18105    }
18106
18107    return result;
18108  }
18109  /**
18110   * Form ligature-like combinations of characters for text mode.
18111   * This includes inputs like "--", "---", "``" and "''".
18112   * The result will simply replace multiple textord nodes with a single
18113   * character in each value by a single textord node having multiple
18114   * characters in its value.  The representation is still ASCII source.
18115   * The group will be modified in place.
18116   */
18117
18118
18119  formLigatures(group) {
18120    var n = group.length - 1;
18121
18122    for (var i = 0; i < n; ++i) {
18123      var a = group[i]; // $FlowFixMe: Not every node type has a `text` property.
18124
18125      var v = a.text;
18126
18127      if (v === "-" && group[i + 1].text === "-") {
18128        if (i + 1 < n && group[i + 2].text === "-") {
18129          group.splice(i, 3, {
18130            type: "textord",
18131            mode: "text",
18132            loc: SourceLocation.range(a, group[i + 2]),
18133            text: "---"
18134          });
18135          n -= 2;
18136        } else {
18137          group.splice(i, 2, {
18138            type: "textord",
18139            mode: "text",
18140            loc: SourceLocation.range(a, group[i + 1]),
18141            text: "--"
18142          });
18143          n -= 1;
18144        }
18145      }
18146
18147      if ((v === "'" || v === "`") && group[i + 1].text === v) {
18148        group.splice(i, 2, {
18149          type: "textord",
18150          mode: "text",
18151          loc: SourceLocation.range(a, group[i + 1]),
18152          text: v + v
18153        });
18154        n -= 1;
18155      }
18156    }
18157  }
18158  /**
18159   * Parse a single symbol out of the string. Here, we handle single character
18160   * symbols and special functions like \verb.
18161   */
18162
18163
18164  parseSymbol() {
18165    var nucleus = this.fetch();
18166    var text = nucleus.text;
18167
18168    if (/^\\verb[^a-zA-Z]/.test(text)) {
18169      this.consume();
18170      var arg = text.slice(5);
18171      var star = arg.charAt(0) === "*";
18172
18173      if (star) {
18174        arg = arg.slice(1);
18175      } // Lexer's tokenRegex is constructed to always have matching
18176      // first/last characters.
18177
18178
18179      if (arg.length < 2 || arg.charAt(0) !== arg.slice(-1)) {
18180        throw new ParseError("\\verb assertion failed --\n                    please report what input caused this bug");
18181      }
18182
18183      arg = arg.slice(1, -1); // remove first and last char
18184
18185      return {
18186        type: "verb",
18187        mode: "text",
18188        body: arg,
18189        star
18190      };
18191    } // At this point, we should have a symbol, possibly with accents.
18192    // First expand any accented base symbol according to unicodeSymbols.
18193
18194
18195    if (unicodeSymbols.hasOwnProperty(text[0]) && !symbols[this.mode][text[0]]) {
18196      // This behavior is not strict (XeTeX-compatible) in math mode.
18197      if (this.settings.strict && this.mode === "math") {
18198        this.settings.reportNonstrict("unicodeTextInMathMode", "Accented Unicode text character \"" + text[0] + "\" used in " + "math mode", nucleus);
18199      }
18200
18201      text = unicodeSymbols[text[0]] + text.slice(1);
18202    } // Strip off any combining characters
18203
18204
18205    var match = combiningDiacriticalMarksEndRegex.exec(text);
18206
18207    if (match) {
18208      text = text.substring(0, match.index);
18209
18210      if (text === 'i') {
18211        text = '\u0131'; // dotless i, in math and text mode
18212      } else if (text === 'j') {
18213        text = '\u0237'; // dotless j, in math and text mode
18214      }
18215    } // Recognize base symbol
18216
18217
18218    var symbol;
18219
18220    if (symbols[this.mode][text]) {
18221      if (this.settings.strict && this.mode === 'math' && extraLatin.indexOf(text) >= 0) {
18222        this.settings.reportNonstrict("unicodeTextInMathMode", "Latin-1/Unicode text character \"" + text[0] + "\" used in " + "math mode", nucleus);
18223      }
18224
18225      var group = symbols[this.mode][text].group;
18226      var loc = SourceLocation.range(nucleus);
18227      var s;
18228
18229      if (ATOMS.hasOwnProperty(group)) {
18230        // $FlowFixMe
18231        var family = group;
18232        s = {
18233          type: "atom",
18234          mode: this.mode,
18235          family,
18236          loc,
18237          text
18238        };
18239      } else {
18240        // $FlowFixMe
18241        s = {
18242          type: group,
18243          mode: this.mode,
18244          loc,
18245          text
18246        };
18247      } // $FlowFixMe
18248
18249
18250      symbol = s;
18251    } else if (text.charCodeAt(0) >= 0x80) {
18252      // no symbol for e.g. ^
18253      if (this.settings.strict) {
18254        if (!supportedCodepoint(text.charCodeAt(0))) {
18255          this.settings.reportNonstrict("unknownSymbol", "Unrecognized Unicode character \"" + text[0] + "\"" + (" (" + text.charCodeAt(0) + ")"), nucleus);
18256        } else if (this.mode === "math") {
18257          this.settings.reportNonstrict("unicodeTextInMathMode", "Unicode text character \"" + text[0] + "\" used in math mode", nucleus);
18258        }
18259      } // All nonmathematical Unicode characters are rendered as if they
18260      // are in text mode (wrapped in \text) because that's what it
18261      // takes to render them in LaTeX.  Setting `mode: this.mode` is
18262      // another natural choice (the user requested math mode), but
18263      // this makes it more difficult for getCharacterMetrics() to
18264      // distinguish Unicode characters without metrics and those for
18265      // which we want to simulate the letter M.
18266
18267
18268      symbol = {
18269        type: "textord",
18270        mode: "text",
18271        loc: SourceLocation.range(nucleus),
18272        text
18273      };
18274    } else {
18275      return null; // EOF, ^, _, {, }, etc.
18276    }
18277
18278    this.consume(); // Transform combining characters into accents
18279
18280    if (match) {
18281      for (var i = 0; i < match[0].length; i++) {
18282        var accent = match[0][i];
18283
18284        if (!unicodeAccents[accent]) {
18285          throw new ParseError("Unknown accent ' " + accent + "'", nucleus);
18286        }
18287
18288        var command = unicodeAccents[accent][this.mode] || unicodeAccents[accent].text;
18289
18290        if (!command) {
18291          throw new ParseError("Accent " + accent + " unsupported in " + this.mode + " mode", nucleus);
18292        }
18293
18294        symbol = {
18295          type: "accent",
18296          mode: this.mode,
18297          loc: SourceLocation.range(nucleus),
18298          label: command,
18299          isStretchy: false,
18300          isShifty: true,
18301          // $FlowFixMe
18302          base: symbol
18303        };
18304      }
18305    } // $FlowFixMe
18306
18307
18308    return symbol;
18309  }
18310
18311}
18312Parser.endOfExpression = ["}", "\\endgroup", "\\end", "\\right", "&"];
18313
18314/**
18315 * Provides a single function for parsing an expression using a Parser
18316 * TODO(emily): Remove this
18317 */
18318
18319/**
18320 * Parses an expression using a Parser, then returns the parsed result.
18321 */
18322var parseTree = function parseTree(toParse, settings) {
18323  if (!(typeof toParse === 'string' || toParse instanceof String)) {
18324    throw new TypeError('KaTeX can only parse string typed expression');
18325  }
18326
18327  var parser = new Parser(toParse, settings); // Blank out any \df@tag to avoid spurious "Duplicate \tag" errors
18328
18329  delete parser.gullet.macros.current["\\df@tag"];
18330  var tree = parser.parse(); // Prevent a color definition from persisting between calls to katex.render().
18331
18332  delete parser.gullet.macros.current["\\current@color"];
18333  delete parser.gullet.macros.current["\\color"]; // If the input used \tag, it will set the \df@tag macro to the tag.
18334  // In this case, we separately parse the tag and wrap the tree.
18335
18336  if (parser.gullet.macros.get("\\df@tag")) {
18337    if (!settings.displayMode) {
18338      throw new ParseError("\\tag works only in display equations");
18339    }
18340
18341    tree = [{
18342      type: "tag",
18343      mode: "text",
18344      body: tree,
18345      tag: parser.subparse([new Token("\\df@tag")])
18346    }];
18347  }
18348
18349  return tree;
18350};
18351
18352/* eslint no-console:0 */
18353
vendor: 4,558 bytes, lines 18354-18519
18354/**
18355 * Parse and build an expression, and place that expression in the DOM node
18356 * given.
18357 */
18358var render = function render(expression, baseNode, options) {
18359  baseNode.textContent = "";
18360  var node = renderToDomTree(expression, options).toNode();
18361  baseNode.appendChild(node);
18362}; // KaTeX's styles don't work properly in quirks mode. Print out an error, and
18363// disable rendering.
18364
18365
18366if (typeof document !== "undefined") {
18367  if (document.compatMode !== "CSS1Compat") {
18368    typeof console !== "undefined" && console.warn("Warning: KaTeX doesn't work in quirks mode. Make sure your " + "website has a suitable doctype.");
18369
18370    render = function render() {
18371      throw new ParseError("KaTeX doesn't work in quirks mode.");
18372    };
18373  }
18374}
18375/**
18376 * Parse and build an expression, and return the markup for that.
18377 */
18378
18379
18380var renderToString = function renderToString(expression, options) {
18381  var markup = renderToDomTree(expression, options).toMarkup();
18382  return markup;
18383};
18384/**
18385 * Parse an expression and return the parse tree.
18386 */
18387
18388
18389var generateParseTree = function generateParseTree(expression, options) {
18390  var settings = new Settings(options);
18391  return parseTree(expression, settings);
18392};
18393/**
18394 * If the given error is a KaTeX ParseError and options.throwOnError is false,
18395 * renders the invalid LaTeX as a span with hover title giving the KaTeX
18396 * error message.  Otherwise, simply throws the error.
18397 */
18398
18399
18400var renderError = function renderError(error, expression, options) {
18401  if (options.throwOnError || !(error instanceof ParseError)) {
18402    throw error;
18403  }
18404
18405  var node = buildCommon.makeSpan(["katex-error"], [new SymbolNode(expression)]);
18406  node.setAttribute("title", error.toString());
18407  node.setAttribute("style", "color:" + options.errorColor);
18408  return node;
18409};
18410/**
18411 * Generates and returns the katex build tree. This is used for advanced
18412 * use cases (like rendering to custom output).
18413 */
18414
18415
18416var renderToDomTree = function renderToDomTree(expression, options) {
18417  var settings = new Settings(options);
18418
18419  try {
18420    var tree = parseTree(expression, settings);
18421    return buildTree(tree, expression, settings);
18422  } catch (error) {
18423    return renderError(error, expression, settings);
18424  }
18425};
18426/**
18427 * Generates and returns the katex build tree, with just HTML (no MathML).
18428 * This is used for advanced use cases (like rendering to custom output).
18429 */
18430
18431
18432var renderToHTMLTree = function renderToHTMLTree(expression, options) {
18433  var settings = new Settings(options);
18434
18435  try {
18436    var tree = parseTree(expression, settings);
18437    return buildHTMLTree(tree, expression, settings);
18438  } catch (error) {
18439    return renderError(error, expression, settings);
18440  }
18441};
18442
18443var version = "0.16.21";
18444var __domTree = {
18445  Span,
18446  Anchor,
18447  SymbolNode,
18448  SvgNode,
18449  PathNode,
18450  LineNode
18451}; // ESM exports
18452
18453var katex = {
18454  /**
18455   * Current KaTeX version
18456   */
18457  version,
18458
18459  /**
18460   * Renders the given LaTeX into an HTML+MathML combination, and adds
18461   * it as a child to the specified DOM node.
18462   */
18463  render,
18464
18465  /**
18466   * Renders the given LaTeX into an HTML+MathML combination string,
18467   * for sending to the client.
18468   */
18469  renderToString,
18470
18471  /**
18472   * KaTeX error, usually during parsing.
18473   */
18474  ParseError,
18475
18476  /**
18477   * The schema of Settings
18478   */
18479  SETTINGS_SCHEMA,
18480
18481  /**
18482   * Parses the given LaTeX into KaTeX's internal parse tree structure,
18483   * without rendering to HTML or MathML.
18484   *
18485   * NOTE: This method is not currently recommended for public use.
18486   * The internal tree representation is unstable and is very likely
18487   * to change. Use at your own risk.
18488   */
18489  __parse: generateParseTree,
18490
18491  /**
18492   * Renders the given LaTeX into an HTML+MathML internal DOM tree
18493   * representation, without flattening that representation to a string.
18494   *
18495   * NOTE: This method is not currently recommended for public use.
18496   * The internal tree representation is unstable and is very likely
18497   * to change. Use at your own risk.
18498   */
18499  __renderToDomTree: renderToDomTree,
18500
18501  /**
18502   * Renders the given LaTeX into an HTML internal DOM tree representation,
18503   * without MathML and without flattening that representation to a string.
18504   *
18505   * NOTE: This method is not currently recommended for public use.
18506   * The internal tree representation is unstable and is very likely
18507   * to change. Use at your own risk.
18508   */
18509  __renderToHTMLTree: renderToHTMLTree,
18510
18511  /**
18512   * extends internal font metrics object with a new object
18513   * each key in the new object represents a font name
18514  */
18515  __setFontMetrics: setFontMetrics,
18516
18517  /**
18518   * adds a new symbol to builtin symbols table
18519   */
18520  __defineSymbol: defineSymbol,
18521
18522  /**
18523   * adds a new function to builtin function list,
18524   * which directly produce parse tree elements
18525   * and have their own html/mathml builders
18526   */
18527  __defineFunction: defineFunction,
18528
18529  /**
18530   * adds a new macro to builtin macro list
18531   */
18532  __defineMacro: defineMacro,
18533
18534  /**
18535   * Expose the dom tree node types, which can be useful for type checking nodes.
18536   *
18537   * NOTE: These methods are not currently recommended for public use.
18538   * The internal tree representation is unstable and is very likely
18539   * to change. Use at your own risk.
18540   */
18541  __domTree
18542};
18543
18544
18545
18546
18547/***/ })
18548
18549}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.