www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

mhchem.js (79514B)


      1 (function webpackUniversalModuleDefinition(root, factory) {
      2 	if(typeof exports === 'object' && typeof module === 'object')
      3 		module.exports = factory(require("katex"));
      4 	else if(typeof define === 'function' && define.amd)
      5 		define(["katex"], factory);
      6 	else {
      7 		var a = typeof exports === 'object' ? factory(require("katex")) : factory(root["katex"]);
      8 		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
      9 	}
     10 })((typeof self !== 'undefined' ? self : this), function(__WEBPACK_EXTERNAL_MODULE__974__) {
     11 return /******/ (function() { // webpackBootstrap
     12 /******/ 	"use strict";
     13 /******/ 	var __webpack_modules__ = ({
     14 
     15 /***/ 974:
     16 /***/ (function(module) {
     17 
     18 module.exports = __WEBPACK_EXTERNAL_MODULE__974__;
     19 
     20 /***/ })
     21 
     22 /******/ 	});
     23 /************************************************************************/
     24 /******/ 	// The module cache
     25 /******/ 	var __webpack_module_cache__ = {};
     26 /******/ 	
     27 /******/ 	// The require function
     28 /******/ 	function __webpack_require__(moduleId) {
     29 /******/ 		// Check if module is in cache
     30 /******/ 		if(__webpack_module_cache__[moduleId]) {
     31 /******/ 			return __webpack_module_cache__[moduleId].exports;
     32 /******/ 		}
     33 /******/ 		// Create a new module (and put it into the cache)
     34 /******/ 		var module = __webpack_module_cache__[moduleId] = {
     35 /******/ 			// no module.id needed
     36 /******/ 			// no module.loaded needed
     37 /******/ 			exports: {}
     38 /******/ 		};
     39 /******/ 	
     40 /******/ 		// Execute the module function
     41 /******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
     42 /******/ 	
     43 /******/ 		// Return the exports of the module
     44 /******/ 		return module.exports;
     45 /******/ 	}
     46 /******/ 	
     47 /************************************************************************/
     48 /******/ 	/* webpack/runtime/compat get default export */
     49 /******/ 	!function() {
     50 /******/ 		// getDefaultExport function for compatibility with non-harmony modules
     51 /******/ 		__webpack_require__.n = function(module) {
     52 /******/ 			var getter = module && module.__esModule ?
     53 /******/ 				function() { return module['default']; } :
     54 /******/ 				function() { return module; };
     55 /******/ 			__webpack_require__.d(getter, { a: getter });
     56 /******/ 			return getter;
     57 /******/ 		};
     58 /******/ 	}();
     59 /******/ 	
     60 /******/ 	/* webpack/runtime/define property getters */
     61 /******/ 	!function() {
     62 /******/ 		// define getter functions for harmony exports
     63 /******/ 		__webpack_require__.d = function(exports, definition) {
     64 /******/ 			for(var key in definition) {
     65 /******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
     66 /******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
     67 /******/ 				}
     68 /******/ 			}
     69 /******/ 		};
     70 /******/ 	}();
     71 /******/ 	
     72 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
     73 /******/ 	!function() {
     74 /******/ 		__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
     75 /******/ 	}();
     76 /******/ 	
     77 /************************************************************************/
     78 var __webpack_exports__ = {};
     79 // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
     80 !function() {
     81 /* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(974);
     82 /* harmony import */ var katex__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(katex__WEBPACK_IMPORTED_MODULE_0__);
     83 /* eslint-disable */
     84 
     85 /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
     86 
     87 /* vim: set ts=2 et sw=2 tw=80: */
     88 
     89 /*************************************************************
     90  *
     91  *  KaTeX mhchem.js
     92  *
     93  *  This file implements a KaTeX version of mhchem version 3.3.0.
     94  *  It is adapted from MathJax/extensions/TeX/mhchem.js
     95  *  It differs from the MathJax version as follows:
     96  *    1. The interface is changed so that it can be called from KaTeX, not MathJax.
     97  *    2. \rlap and \llap are replaced with \mathrlap and \mathllap.
     98  *    3. Four lines of code are edited in order to use \raisebox instead of \raise.
     99  *    4. The reaction arrow code is simplified. All reaction arrows are rendered
    100  *       using KaTeX extensible arrows instead of building non-extensible arrows.
    101  *    5. \tripledash vertical alignment is slightly adjusted.
    102  *
    103  *    This code, as other KaTeX code, is released under the MIT license.
    104  * 
    105  * /*************************************************************
    106  *
    107  *  MathJax/extensions/TeX/mhchem.js
    108  *
    109  *  Implements the \ce command for handling chemical formulas
    110  *  from the mhchem LaTeX package.
    111  *
    112  *  ---------------------------------------------------------------------
    113  *
    114  *  Copyright (c) 2011-2015 The MathJax Consortium
    115  *  Copyright (c) 2015-2018 Martin Hensel
    116  *
    117  *  Licensed under the Apache License, Version 2.0 (the "License");
    118  *  you may not use this file except in compliance with the License.
    119  *  You may obtain a copy of the License at
    120  *
    121  *      http://www.apache.org/licenses/LICENSE-2.0
    122  *
    123  *  Unless required by applicable law or agreed to in writing, software
    124  *  distributed under the License is distributed on an "AS IS" BASIS,
    125  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    126  *  See the License for the specific language governing permissions and
    127  *  limitations under the License.
    128  */
    129 //
    130 // Coding Style
    131 //   - use '' for identifiers that can by minified/uglified
    132 //   - use "" for strings that need to stay untouched
    133 // version: "3.3.0" for MathJax and KaTeX
    134 // Add \ce, \pu, and \tripledash to the KaTeX macros.
    135 katex__WEBPACK_IMPORTED_MODULE_0___default().__defineMacro("\\ce", function (context) {
    136   return chemParse(context.consumeArgs(1)[0], "ce");
    137 });
    138 
    139 katex__WEBPACK_IMPORTED_MODULE_0___default().__defineMacro("\\pu", function (context) {
    140   return chemParse(context.consumeArgs(1)[0], "pu");
    141 }); //  Needed for \bond for the ~ forms
    142 //  Raise by 2.56mu, not 2mu. We're raising a hyphen-minus, U+002D, not 
    143 //  a mathematical minus, U+2212. So we need that extra 0.56.
    144 
    145 
    146 katex__WEBPACK_IMPORTED_MODULE_0___default().__defineMacro("\\tripledash", "{\\vphantom{-}\\raisebox{2.56mu}{$\\mkern2mu" + "\\tiny\\text{-}\\mkern1mu\\text{-}\\mkern1mu\\text{-}\\mkern2mu$}}");
    147 
    148  //
    149 //  This is the main function for handing the \ce and \pu commands.
    150 //  It takes the argument to \ce or \pu and returns the corresponding TeX string.
    151 //
    152 
    153 var chemParse = function chemParse(tokens, stateMachine) {
    154   // Recreate the argument string from KaTeX's array of tokens.
    155   var str = "";
    156   var expectedLoc = tokens[tokens.length - 1].loc.start;
    157 
    158   for (var i = tokens.length - 1; i >= 0; i--) {
    159     if (tokens[i].loc.start > expectedLoc) {
    160       // context.consumeArgs has eaten a space.
    161       str += " ";
    162       expectedLoc = tokens[i].loc.start;
    163     }
    164 
    165     str += tokens[i].text;
    166     expectedLoc += tokens[i].text.length;
    167   }
    168 
    169   var tex = texify.go(mhchemParser.go(str, stateMachine));
    170   return tex;
    171 }; //
    172 // Core parser for mhchem syntax  (recursive)
    173 //
    174 
    175 /** @type {MhchemParser} */
    176 
    177 
    178 var mhchemParser = {
    179   //
    180   // Parses mchem \ce syntax
    181   //
    182   // Call like
    183   //   go("H2O");
    184   //
    185   go: function go(input, stateMachine) {
    186     if (!input) {
    187       return [];
    188     }
    189 
    190     if (stateMachine === undefined) {
    191       stateMachine = 'ce';
    192     }
    193 
    194     var state = '0'; //
    195     // String buffers for parsing:
    196     //
    197     // buffer.a == amount
    198     // buffer.o == element
    199     // buffer.b == left-side superscript
    200     // buffer.p == left-side subscript
    201     // buffer.q == right-side subscript
    202     // buffer.d == right-side superscript
    203     //
    204     // buffer.r == arrow
    205     // buffer.rdt == arrow, script above, type
    206     // buffer.rd == arrow, script above, content
    207     // buffer.rqt == arrow, script below, type
    208     // buffer.rq == arrow, script below, content
    209     //
    210     // buffer.text_
    211     // buffer.rm
    212     // etc.
    213     //
    214     // buffer.parenthesisLevel == int, starting at 0
    215     // buffer.sb == bool, space before
    216     // buffer.beginsWithBond == bool
    217     //
    218     // These letters are also used as state names.
    219     //
    220     // Other states:
    221     // 0 == begin of main part (arrow/operator unlikely)
    222     // 1 == next entity
    223     // 2 == next entity (arrow/operator unlikely)
    224     // 3 == next atom
    225     // c == macro
    226     //
    227 
    228     /** @type {Buffer} */
    229 
    230     var buffer = {};
    231     buffer['parenthesisLevel'] = 0;
    232     input = input.replace(/\n/g, " ");
    233     input = input.replace(/[\u2212\u2013\u2014\u2010]/g, "-");
    234     input = input.replace(/[\u2026]/g, "..."); //
    235     // Looks through mhchemParser.transitions, to execute a matching action
    236     // (recursive)
    237     //
    238 
    239     var lastInput;
    240     var watchdog = 10;
    241     /** @type {ParserOutput[]} */
    242 
    243     var output = [];
    244 
    245     while (true) {
    246       if (lastInput !== input) {
    247         watchdog = 10;
    248         lastInput = input;
    249       } else {
    250         watchdog--;
    251       } //
    252       // Find actions in transition table
    253       //
    254 
    255 
    256       var machine = mhchemParser.stateMachines[stateMachine];
    257       var t = machine.transitions[state] || machine.transitions['*'];
    258 
    259       iterateTransitions: for (var i = 0; i < t.length; i++) {
    260         var matches = mhchemParser.patterns.match_(t[i].pattern, input);
    261 
    262         if (matches) {
    263           //
    264           // Execute actions
    265           //
    266           var task = t[i].task;
    267 
    268           for (var iA = 0; iA < task.action_.length; iA++) {
    269             var o; //
    270             // Find and execute action
    271             //
    272 
    273             if (machine.actions[task.action_[iA].type_]) {
    274               o = machine.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option);
    275             } else if (mhchemParser.actions[task.action_[iA].type_]) {
    276               o = mhchemParser.actions[task.action_[iA].type_](buffer, matches.match_, task.action_[iA].option);
    277             } else {
    278               throw ["MhchemBugA", "mhchem bug A. Please report. (" + task.action_[iA].type_ + ")"]; // Trying to use non-existing action
    279             } //
    280             // Add output
    281             //
    282 
    283 
    284             mhchemParser.concatArray(output, o);
    285           } //
    286           // Set next state,
    287           // Shorten input,
    288           // Continue with next character
    289           //   (= apply only one transition per position)
    290           //
    291 
    292 
    293           state = task.nextState || state;
    294 
    295           if (input.length > 0) {
    296             if (!task.revisit) {
    297               input = matches.remainder;
    298             }
    299 
    300             if (!task.toContinue) {
    301               break iterateTransitions;
    302             }
    303           } else {
    304             return output;
    305           }
    306         }
    307       } //
    308       // Prevent infinite loop
    309       //
    310 
    311 
    312       if (watchdog <= 0) {
    313         throw ["MhchemBugU", "mhchem bug U. Please report."]; // Unexpected character
    314       }
    315     }
    316   },
    317   concatArray: function concatArray(a, b) {
    318     if (b) {
    319       if (Array.isArray(b)) {
    320         for (var iB = 0; iB < b.length; iB++) {
    321           a.push(b[iB]);
    322         }
    323       } else {
    324         a.push(b);
    325       }
    326     }
    327   },
    328   patterns: {
    329     //
    330     // Matching patterns
    331     // either regexps or function that return null or {match_:"a", remainder:"bc"}
    332     //
    333     patterns: {
    334       // property names must not look like integers ("2") for correct property traversal order, later on
    335       'empty': /^$/,
    336       'else': /^./,
    337       'else2': /^./,
    338       'space': /^\s/,
    339       'space A': /^\s(?=[A-Z\\$])/,
    340       'space$': /^\s$/,
    341       'a-z': /^[a-z]/,
    342       'x': /^x/,
    343       'x$': /^x$/,
    344       'i$': /^i$/,
    345       'letters': /^(?:[a-zA-Z\u03B1-\u03C9\u0391-\u03A9?@]|(?:\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))))+/,
    346       '\\greek': /^\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Xi|Pi|Sigma|Upsilon|Phi|Psi|Omega)(?:\s+|\{\}|(?![a-zA-Z]))/,
    347       'one lowercase latin letter $': /^(?:([a-z])(?:$|[^a-zA-Z]))$/,
    348       '$one lowercase latin letter$ $': /^\$(?:([a-z])(?:$|[^a-zA-Z]))\$$/,
    349       'one lowercase greek letter $': /^(?:\$?[\u03B1-\u03C9]\$?|\$?\\(?:alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|psi|omega)\s*\$?)(?:\s+|\{\}|(?![a-zA-Z]))$/,
    350       'digits': /^[0-9]+/,
    351       '-9.,9': /^[+\-]?(?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))/,
    352       '-9.,9 no missing 0': /^[+\-]?[0-9]+(?:[.,][0-9]+)?/,
    353       '(-)(9.,9)(e)(99)': function e99(input) {
    354         var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))?(\((?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+))\))?(?:([eE]|\s*(\*|x|\\times|\u00D7)\s*10\^)([+\-]?[0-9]+|\{[+\-]?[0-9]+\}))?/);
    355 
    356         if (m && m[0]) {
    357           return {
    358             match_: m.splice(1),
    359             remainder: input.substr(m[0].length)
    360           };
    361         }
    362 
    363         return null;
    364       },
    365       '(-)(9)^(-9)': function _(input) {
    366         var m = input.match(/^(\+\-|\+\/\-|\+|\-|\\pm\s?)?([0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\.[0-9]+)?)\^([+\-]?[0-9]+|\{[+\-]?[0-9]+\})/);
    367 
    368         if (m && m[0]) {
    369           return {
    370             match_: m.splice(1),
    371             remainder: input.substr(m[0].length)
    372           };
    373         }
    374 
    375         return null;
    376       },
    377       'state of aggregation $': function stateOfAggregation$(input) {
    378         // ... or crystal system
    379         var a = mhchemParser.patterns.findObserveGroups(input, "", /^\([a-z]{1,3}(?=[\),])/, ")", ""); // (aq), (aq,$\infty$), (aq, sat)
    380 
    381         if (a && a.remainder.match(/^($|[\s,;\)\]\}])/)) {
    382           return a;
    383         } //  AND end of 'phrase'
    384 
    385 
    386         var m = input.match(/^(?:\((?:\\ca\s?)?\$[amothc]\$\))/); // OR crystal system ($o$) (\ca$c$)
    387 
    388         if (m) {
    389           return {
    390             match_: m[0],
    391             remainder: input.substr(m[0].length)
    392           };
    393         }
    394 
    395         return null;
    396       },
    397       '_{(state of aggregation)}$': /^_\{(\([a-z]{1,3}\))\}/,
    398       '{[(': /^(?:\\\{|\[|\()/,
    399       ')]}': /^(?:\)|\]|\\\})/,
    400       ', ': /^[,;]\s*/,
    401       ',': /^[,;]/,
    402       '.': /^[.]/,
    403       '. ': /^([.\u22C5\u00B7\u2022])\s*/,
    404       '...': /^\.\.\.(?=$|[^.])/,
    405       '* ': /^([*])\s*/,
    406       '^{(...)}': function _(input) {
    407         return mhchemParser.patterns.findObserveGroups(input, "^{", "", "", "}");
    408       },
    409       '^($...$)': function $$(input) {
    410         return mhchemParser.patterns.findObserveGroups(input, "^", "$", "$", "");
    411       },
    412       '^a': /^\^([0-9]+|[^\\_])/,
    413       '^\\x{}{}': function x(input) {
    414         return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true);
    415       },
    416       '^\\x{}': function x(input) {
    417         return mhchemParser.patterns.findObserveGroups(input, "^", /^\\[a-zA-Z]+\{/, "}", "");
    418       },
    419       '^\\x': /^\^(\\[a-zA-Z]+)\s*/,
    420       '^(-1)': /^\^(-?\d+)/,
    421       '\'': /^'/,
    422       '_{(...)}': function _(input) {
    423         return mhchemParser.patterns.findObserveGroups(input, "_{", "", "", "}");
    424       },
    425       '_($...$)': function _$$(input) {
    426         return mhchemParser.patterns.findObserveGroups(input, "_", "$", "$", "");
    427       },
    428       '_9': /^_([+\-]?[0-9]+|[^\\])/,
    429       '_\\x{}{}': function _X(input) {
    430         return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true);
    431       },
    432       '_\\x{}': function _X(input) {
    433         return mhchemParser.patterns.findObserveGroups(input, "_", /^\\[a-zA-Z]+\{/, "}", "");
    434       },
    435       '_\\x': /^_(\\[a-zA-Z]+)\s*/,
    436       '^_': /^(?:\^(?=_)|\_(?=\^)|[\^_]$)/,
    437       '{}': /^\{\}/,
    438       '{...}': function _(input) {
    439         return mhchemParser.patterns.findObserveGroups(input, "", "{", "}", "");
    440       },
    441       '{(...)}': function _(input) {
    442         return mhchemParser.patterns.findObserveGroups(input, "{", "", "", "}");
    443       },
    444       '$...$': function $$(input) {
    445         return mhchemParser.patterns.findObserveGroups(input, "", "$", "$", "");
    446       },
    447       '${(...)}$': function $$(input) {
    448         return mhchemParser.patterns.findObserveGroups(input, "${", "", "", "}$");
    449       },
    450       '$(...)$': function $$(input) {
    451         return mhchemParser.patterns.findObserveGroups(input, "$", "", "", "$");
    452       },
    453       '=<>': /^[=<>]/,
    454       '#': /^[#\u2261]/,
    455       '+': /^\+/,
    456       '-$': /^-(?=[\s_},;\]/]|$|\([a-z]+\))/,
    457       // -space -, -; -] -/ -$ -state-of-aggregation
    458       '-9': /^-(?=[0-9])/,
    459       '- orbital overlap': /^-(?=(?:[spd]|sp)(?:$|[\s,;\)\]\}]))/,
    460       '-': /^-/,
    461       'pm-operator': /^(?:\\pm|\$\\pm\$|\+-|\+\/-)/,
    462       'operator': /^(?:\+|(?:[\-=<>]|<<|>>|\\approx|\$\\approx\$)(?=\s|$|-?[0-9]))/,
    463       'arrowUpDown': /^(?:v|\(v\)|\^|\(\^\))(?=$|[\s,;\)\]\}])/,
    464       '\\bond{(...)}': function bond(input) {
    465         return mhchemParser.patterns.findObserveGroups(input, "\\bond{", "", "", "}");
    466       },
    467       '->': /^(?:<->|<-->|->|<-|<=>>|<<=>|<=>|[\u2192\u27F6\u21CC])/,
    468       'CMT': /^[CMT](?=\[)/,
    469       '[(...)]': function _(input) {
    470         return mhchemParser.patterns.findObserveGroups(input, "[", "", "", "]");
    471       },
    472       '1st-level escape': /^(&|\\\\|\\hline)\s*/,
    473       '\\,': /^(?:\\[,\ ;:])/,
    474       // \\x - but output no space before
    475       '\\x{}{}': function x(input) {
    476         return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", "", "", "{", "}", "", true);
    477       },
    478       '\\x{}': function x(input) {
    479         return mhchemParser.patterns.findObserveGroups(input, "", /^\\[a-zA-Z]+\{/, "}", "");
    480       },
    481       '\\ca': /^\\ca(?:\s+|(?![a-zA-Z]))/,
    482       '\\x': /^(?:\\[a-zA-Z]+\s*|\\[_&{}%])/,
    483       'orbital': /^(?:[0-9]{1,2}[spdfgh]|[0-9]{0,2}sp)(?=$|[^a-zA-Z])/,
    484       // only those with numbers in front, because the others will be formatted correctly anyway
    485       'others': /^[\/~|]/,
    486       '\\frac{(...)}': function frac(input) {
    487         return mhchemParser.patterns.findObserveGroups(input, "\\frac{", "", "", "}", "{", "", "", "}");
    488       },
    489       '\\overset{(...)}': function overset(input) {
    490         return mhchemParser.patterns.findObserveGroups(input, "\\overset{", "", "", "}", "{", "", "", "}");
    491       },
    492       "\\underset{(...)}": function underset(input) {
    493         return mhchemParser.patterns.findObserveGroups(input, "\\underset{", "", "", "}", "{", "", "", "}");
    494       },
    495       "\\underbrace{(...)}": function underbrace(input) {
    496         return mhchemParser.patterns.findObserveGroups(input, "\\underbrace{", "", "", "}_", "{", "", "", "}");
    497       },
    498       '\\color{(...)}0': function color0(input) {
    499         return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}");
    500       },
    501       '\\color{(...)}{(...)}1': function color1(input) {
    502         return mhchemParser.patterns.findObserveGroups(input, "\\color{", "", "", "}", "{", "", "", "}");
    503       },
    504       '\\color(...){(...)}2': function color2(input) {
    505         return mhchemParser.patterns.findObserveGroups(input, "\\color", "\\", "", /^(?=\{)/, "{", "", "", "}");
    506       },
    507       '\\ce{(...)}': function ce(input) {
    508         return mhchemParser.patterns.findObserveGroups(input, "\\ce{", "", "", "}");
    509       },
    510       'oxidation$': /^(?:[+-][IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/,
    511       'd-oxidation$': /^(?:[+-]?\s?[IVX]+|\\pm\s*0|\$\\pm\$\s*0)$/,
    512       // 0 could be oxidation or charge
    513       'roman numeral': /^[IVX]+/,
    514       '1/2$': /^[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+(?:\$[a-z]\$|[a-z])?$/,
    515       'amount': function amount(input) {
    516         var match; // e.g. 2, 0.5, 1/2, -2, n/2, +;  $a$ could be added later in parsing
    517 
    518         match = input.match(/^(?:(?:(?:\([+\-]?[0-9]+\/[0-9]+\)|[+\-]?(?:[0-9]+|\$[a-z]\$|[a-z])\/[0-9]+|[+\-]?[0-9]+[.,][0-9]+|[+\-]?\.[0-9]+|[+\-]?[0-9]+)(?:[a-z](?=\s*[A-Z]))?)|[+\-]?[a-z](?=\s*[A-Z])|\+(?!\s))/);
    519 
    520         if (match) {
    521           return {
    522             match_: match[0],
    523             remainder: input.substr(match[0].length)
    524           };
    525         }
    526 
    527         var a = mhchemParser.patterns.findObserveGroups(input, "", "$", "$", "");
    528 
    529         if (a) {
    530           // e.g. $2n-1$, $-$
    531           match = a.match_.match(/^\$(?:\(?[+\-]?(?:[0-9]*[a-z]?[+\-])?[0-9]*[a-z](?:[+\-][0-9]*[a-z]?)?\)?|\+|-)\$$/);
    532 
    533           if (match) {
    534             return {
    535               match_: match[0],
    536               remainder: input.substr(match[0].length)
    537             };
    538           }
    539         }
    540 
    541         return null;
    542       },
    543       'amount2': function amount2(input) {
    544         return this['amount'](input);
    545       },
    546       '(KV letters),': /^(?:[A-Z][a-z]{0,2}|i)(?=,)/,
    547       'formula$': function formula$(input) {
    548         if (input.match(/^\([a-z]+\)$/)) {
    549           return null;
    550         } // state of aggregation = no formula
    551 
    552 
    553         var match = input.match(/^(?:[a-z]|(?:[0-9\ \+\-\,\.\(\)]+[a-z])+[0-9\ \+\-\,\.\(\)]*|(?:[a-z][0-9\ \+\-\,\.\(\)]+)+[a-z]?)$/);
    554 
    555         if (match) {
    556           return {
    557             match_: match[0],
    558             remainder: input.substr(match[0].length)
    559           };
    560         }
    561 
    562         return null;
    563       },
    564       'uprightEntities': /^(?:pH|pOH|pC|pK|iPr|iBu)(?=$|[^a-zA-Z])/,
    565       '/': /^\s*(\/)\s*/,
    566       '//': /^\s*(\/\/)\s*/,
    567       '*': /^\s*[*.]\s*/
    568     },
    569     findObserveGroups: function findObserveGroups(input, begExcl, begIncl, endIncl, endExcl, beg2Excl, beg2Incl, end2Incl, end2Excl, combine) {
    570       /** @type {{(input: string, pattern: string | RegExp): string | string[] | null;}} */
    571       var _match = function _match(input, pattern) {
    572         if (typeof pattern === "string") {
    573           if (input.indexOf(pattern) !== 0) {
    574             return null;
    575           }
    576 
    577           return pattern;
    578         } else {
    579           var match = input.match(pattern);
    580 
    581           if (!match) {
    582             return null;
    583           }
    584 
    585           return match[0];
    586         }
    587       };
    588       /** @type {{(input: string, i: number, endChars: string | RegExp): {endMatchBegin: number, endMatchEnd: number} | null;}} */
    589 
    590 
    591       var _findObserveGroups = function _findObserveGroups(input, i, endChars) {
    592         var braces = 0;
    593 
    594         while (i < input.length) {
    595           var a = input.charAt(i);
    596 
    597           var match = _match(input.substr(i), endChars);
    598 
    599           if (match !== null && braces === 0) {
    600             return {
    601               endMatchBegin: i,
    602               endMatchEnd: i + match.length
    603             };
    604           } else if (a === "{") {
    605             braces++;
    606           } else if (a === "}") {
    607             if (braces === 0) {
    608               throw ["ExtraCloseMissingOpen", "Extra close brace or missing open brace"];
    609             } else {
    610               braces--;
    611             }
    612           }
    613 
    614           i++;
    615         }
    616 
    617         if (braces > 0) {
    618           return null;
    619         }
    620 
    621         return null;
    622       };
    623 
    624       var match = _match(input, begExcl);
    625 
    626       if (match === null) {
    627         return null;
    628       }
    629 
    630       input = input.substr(match.length);
    631       match = _match(input, begIncl);
    632 
    633       if (match === null) {
    634         return null;
    635       }
    636 
    637       var e = _findObserveGroups(input, match.length, endIncl || endExcl);
    638 
    639       if (e === null) {
    640         return null;
    641       }
    642 
    643       var match1 = input.substring(0, endIncl ? e.endMatchEnd : e.endMatchBegin);
    644 
    645       if (!(beg2Excl || beg2Incl)) {
    646         return {
    647           match_: match1,
    648           remainder: input.substr(e.endMatchEnd)
    649         };
    650       } else {
    651         var group2 = this.findObserveGroups(input.substr(e.endMatchEnd), beg2Excl, beg2Incl, end2Incl, end2Excl);
    652 
    653         if (group2 === null) {
    654           return null;
    655         }
    656         /** @type {string[]} */
    657 
    658 
    659         var matchRet = [match1, group2.match_];
    660         return {
    661           match_: combine ? matchRet.join("") : matchRet,
    662           remainder: group2.remainder
    663         };
    664       }
    665     },
    666     //
    667     // Matching function
    668     // e.g. match("a", input) will look for the regexp called "a" and see if it matches
    669     // returns null or {match_:"a", remainder:"bc"}
    670     //
    671     match_: function match_(m, input) {
    672       var pattern = mhchemParser.patterns.patterns[m];
    673 
    674       if (pattern === undefined) {
    675         throw ["MhchemBugP", "mhchem bug P. Please report. (" + m + ")"]; // Trying to use non-existing pattern
    676       } else if (typeof pattern === "function") {
    677         return mhchemParser.patterns.patterns[m](input); // cannot use cached var pattern here, because some pattern functions need this===mhchemParser
    678       } else {
    679         // RegExp
    680         var match = input.match(pattern);
    681 
    682         if (match) {
    683           var mm;
    684 
    685           if (match[2]) {
    686             mm = [match[1], match[2]];
    687           } else if (match[1]) {
    688             mm = match[1];
    689           } else {
    690             mm = match[0];
    691           }
    692 
    693           return {
    694             match_: mm,
    695             remainder: input.substr(match[0].length)
    696           };
    697         }
    698 
    699         return null;
    700       }
    701     }
    702   },
    703   //
    704   // Generic state machine actions
    705   //
    706   actions: {
    707     'a=': function a(buffer, m) {
    708       buffer.a = (buffer.a || "") + m;
    709     },
    710     'b=': function b(buffer, m) {
    711       buffer.b = (buffer.b || "") + m;
    712     },
    713     'p=': function p(buffer, m) {
    714       buffer.p = (buffer.p || "") + m;
    715     },
    716     'o=': function o(buffer, m) {
    717       buffer.o = (buffer.o || "") + m;
    718     },
    719     'q=': function q(buffer, m) {
    720       buffer.q = (buffer.q || "") + m;
    721     },
    722     'd=': function d(buffer, m) {
    723       buffer.d = (buffer.d || "") + m;
    724     },
    725     'rm=': function rm(buffer, m) {
    726       buffer.rm = (buffer.rm || "") + m;
    727     },
    728     'text=': function text(buffer, m) {
    729       buffer.text_ = (buffer.text_ || "") + m;
    730     },
    731     'insert': function insert(buffer, m, a) {
    732       return {
    733         type_: a
    734       };
    735     },
    736     'insert+p1': function insertP1(buffer, m, a) {
    737       return {
    738         type_: a,
    739         p1: m
    740       };
    741     },
    742     'insert+p1+p2': function insertP1P2(buffer, m, a) {
    743       return {
    744         type_: a,
    745         p1: m[0],
    746         p2: m[1]
    747       };
    748     },
    749     'copy': function copy(buffer, m) {
    750       return m;
    751     },
    752     'rm': function rm(buffer, m) {
    753       return {
    754         type_: 'rm',
    755         p1: m || ""
    756       };
    757     },
    758     'text': function text(buffer, m) {
    759       return mhchemParser.go(m, 'text');
    760     },
    761     '{text}': function text(buffer, m) {
    762       var ret = ["{"];
    763       mhchemParser.concatArray(ret, mhchemParser.go(m, 'text'));
    764       ret.push("}");
    765       return ret;
    766     },
    767     'tex-math': function texMath(buffer, m) {
    768       return mhchemParser.go(m, 'tex-math');
    769     },
    770     'tex-math tight': function texMathTight(buffer, m) {
    771       return mhchemParser.go(m, 'tex-math tight');
    772     },
    773     'bond': function bond(buffer, m, k) {
    774       return {
    775         type_: 'bond',
    776         kind_: k || m
    777       };
    778     },
    779     'color0-output': function color0Output(buffer, m) {
    780       return {
    781         type_: 'color0',
    782         color: m[0]
    783       };
    784     },
    785     'ce': function ce(buffer, m) {
    786       return mhchemParser.go(m);
    787     },
    788     '1/2': function _(buffer, m) {
    789       /** @type {ParserOutput[]} */
    790       var ret = [];
    791 
    792       if (m.match(/^[+\-]/)) {
    793         ret.push(m.substr(0, 1));
    794         m = m.substr(1);
    795       }
    796 
    797       var n = m.match(/^([0-9]+|\$[a-z]\$|[a-z])\/([0-9]+)(\$[a-z]\$|[a-z])?$/);
    798       n[1] = n[1].replace(/\$/g, "");
    799       ret.push({
    800         type_: 'frac',
    801         p1: n[1],
    802         p2: n[2]
    803       });
    804 
    805       if (n[3]) {
    806         n[3] = n[3].replace(/\$/g, "");
    807         ret.push({
    808           type_: 'tex-math',
    809           p1: n[3]
    810         });
    811       }
    812 
    813       return ret;
    814     },
    815     '9,9': function _(buffer, m) {
    816       return mhchemParser.go(m, '9,9');
    817     }
    818   },
    819   //
    820   // createTransitions
    821   // convert  { 'letter': { 'state': { action_: 'output' } } }  to  { 'state' => [ { pattern: 'letter', task: { action_: [{type_: 'output'}] } } ] }
    822   // with expansion of 'a|b' to 'a' and 'b' (at 2 places)
    823   //
    824   createTransitions: function createTransitions(o) {
    825     var pattern, state;
    826     /** @type {string[]} */
    827 
    828     var stateArray;
    829     var i; //
    830     // 1. Collect all states
    831     //
    832 
    833     /** @type {Transitions} */
    834 
    835     var transitions = {};
    836 
    837     for (pattern in o) {
    838       for (state in o[pattern]) {
    839         stateArray = state.split("|");
    840         o[pattern][state].stateArray = stateArray;
    841 
    842         for (i = 0; i < stateArray.length; i++) {
    843           transitions[stateArray[i]] = [];
    844         }
    845       }
    846     } //
    847     // 2. Fill states
    848     //
    849 
    850 
    851     for (pattern in o) {
    852       for (state in o[pattern]) {
    853         stateArray = o[pattern][state].stateArray || [];
    854 
    855         for (i = 0; i < stateArray.length; i++) {
    856           //
    857           // 2a. Normalize actions into array:  'text=' ==> [{type_:'text='}]
    858           // (Note to myself: Resolving the function here would be problematic. It would need .bind (for *this*) and currying (for *option*).)
    859           //
    860 
    861           /** @type {any} */
    862           var p = o[pattern][state];
    863 
    864           if (p.action_) {
    865             p.action_ = [].concat(p.action_);
    866 
    867             for (var k = 0; k < p.action_.length; k++) {
    868               if (typeof p.action_[k] === "string") {
    869                 p.action_[k] = {
    870                   type_: p.action_[k]
    871                 };
    872               }
    873             }
    874           } else {
    875             p.action_ = [];
    876           } //
    877           // 2.b Multi-insert
    878           //
    879 
    880 
    881           var patternArray = pattern.split("|");
    882 
    883           for (var j = 0; j < patternArray.length; j++) {
    884             if (stateArray[i] === '*') {
    885               // insert into all
    886               for (var t in transitions) {
    887                 transitions[t].push({
    888                   pattern: patternArray[j],
    889                   task: p
    890                 });
    891               }
    892             } else {
    893               transitions[stateArray[i]].push({
    894                 pattern: patternArray[j],
    895                 task: p
    896               });
    897             }
    898           }
    899         }
    900       }
    901     }
    902 
    903     return transitions;
    904   },
    905   stateMachines: {}
    906 }; //
    907 // Definition of state machines
    908 //
    909 
    910 mhchemParser.stateMachines = {
    911   //
    912   // \ce state machines
    913   //
    914   //#region ce
    915   'ce': {
    916     // main parser
    917     transitions: mhchemParser.createTransitions({
    918       'empty': {
    919         '*': {
    920           action_: 'output'
    921         }
    922       },
    923       'else': {
    924         '0|1|2': {
    925           action_: 'beginsWithBond=false',
    926           revisit: true,
    927           toContinue: true
    928         }
    929       },
    930       'oxidation$': {
    931         '0': {
    932           action_: 'oxidation-output'
    933         }
    934       },
    935       'CMT': {
    936         'r': {
    937           action_: 'rdt=',
    938           nextState: 'rt'
    939         },
    940         'rd': {
    941           action_: 'rqt=',
    942           nextState: 'rdt'
    943         }
    944       },
    945       'arrowUpDown': {
    946         '0|1|2|as': {
    947           action_: ['sb=false', 'output', 'operator'],
    948           nextState: '1'
    949         }
    950       },
    951       'uprightEntities': {
    952         '0|1|2': {
    953           action_: ['o=', 'output'],
    954           nextState: '1'
    955         }
    956       },
    957       'orbital': {
    958         '0|1|2|3': {
    959           action_: 'o=',
    960           nextState: 'o'
    961         }
    962       },
    963       '->': {
    964         '0|1|2|3': {
    965           action_: 'r=',
    966           nextState: 'r'
    967         },
    968         'a|as': {
    969           action_: ['output', 'r='],
    970           nextState: 'r'
    971         },
    972         '*': {
    973           action_: ['output', 'r='],
    974           nextState: 'r'
    975         }
    976       },
    977       '+': {
    978         'o': {
    979           action_: 'd= kv',
    980           nextState: 'd'
    981         },
    982         'd|D': {
    983           action_: 'd=',
    984           nextState: 'd'
    985         },
    986         'q': {
    987           action_: 'd=',
    988           nextState: 'qd'
    989         },
    990         'qd|qD': {
    991           action_: 'd=',
    992           nextState: 'qd'
    993         },
    994         'dq': {
    995           action_: ['output', 'd='],
    996           nextState: 'd'
    997         },
    998         '3': {
    999           action_: ['sb=false', 'output', 'operator'],
   1000           nextState: '0'
   1001         }
   1002       },
   1003       'amount': {
   1004         '0|2': {
   1005           action_: 'a=',
   1006           nextState: 'a'
   1007         }
   1008       },
   1009       'pm-operator': {
   1010         '0|1|2|a|as': {
   1011           action_: ['sb=false', 'output', {
   1012             type_: 'operator',
   1013             option: '\\pm'
   1014           }],
   1015           nextState: '0'
   1016         }
   1017       },
   1018       'operator': {
   1019         '0|1|2|a|as': {
   1020           action_: ['sb=false', 'output', 'operator'],
   1021           nextState: '0'
   1022         }
   1023       },
   1024       '-$': {
   1025         'o|q': {
   1026           action_: ['charge or bond', 'output'],
   1027           nextState: 'qd'
   1028         },
   1029         'd': {
   1030           action_: 'd=',
   1031           nextState: 'd'
   1032         },
   1033         'D': {
   1034           action_: ['output', {
   1035             type_: 'bond',
   1036             option: "-"
   1037           }],
   1038           nextState: '3'
   1039         },
   1040         'q': {
   1041           action_: 'd=',
   1042           nextState: 'qd'
   1043         },
   1044         'qd': {
   1045           action_: 'd=',
   1046           nextState: 'qd'
   1047         },
   1048         'qD|dq': {
   1049           action_: ['output', {
   1050             type_: 'bond',
   1051             option: "-"
   1052           }],
   1053           nextState: '3'
   1054         }
   1055       },
   1056       '-9': {
   1057         '3|o': {
   1058           action_: ['output', {
   1059             type_: 'insert',
   1060             option: 'hyphen'
   1061           }],
   1062           nextState: '3'
   1063         }
   1064       },
   1065       '- orbital overlap': {
   1066         'o': {
   1067           action_: ['output', {
   1068             type_: 'insert',
   1069             option: 'hyphen'
   1070           }],
   1071           nextState: '2'
   1072         },
   1073         'd': {
   1074           action_: ['output', {
   1075             type_: 'insert',
   1076             option: 'hyphen'
   1077           }],
   1078           nextState: '2'
   1079         }
   1080       },
   1081       '-': {
   1082         '0|1|2': {
   1083           action_: [{
   1084             type_: 'output',
   1085             option: 1
   1086           }, 'beginsWithBond=true', {
   1087             type_: 'bond',
   1088             option: "-"
   1089           }],
   1090           nextState: '3'
   1091         },
   1092         '3': {
   1093           action_: {
   1094             type_: 'bond',
   1095             option: "-"
   1096           }
   1097         },
   1098         'a': {
   1099           action_: ['output', {
   1100             type_: 'insert',
   1101             option: 'hyphen'
   1102           }],
   1103           nextState: '2'
   1104         },
   1105         'as': {
   1106           action_: [{
   1107             type_: 'output',
   1108             option: 2
   1109           }, {
   1110             type_: 'bond',
   1111             option: "-"
   1112           }],
   1113           nextState: '3'
   1114         },
   1115         'b': {
   1116           action_: 'b='
   1117         },
   1118         'o': {
   1119           action_: {
   1120             type_: '- after o/d',
   1121             option: false
   1122           },
   1123           nextState: '2'
   1124         },
   1125         'q': {
   1126           action_: {
   1127             type_: '- after o/d',
   1128             option: false
   1129           },
   1130           nextState: '2'
   1131         },
   1132         'd|qd|dq': {
   1133           action_: {
   1134             type_: '- after o/d',
   1135             option: true
   1136           },
   1137           nextState: '2'
   1138         },
   1139         'D|qD|p': {
   1140           action_: ['output', {
   1141             type_: 'bond',
   1142             option: "-"
   1143           }],
   1144           nextState: '3'
   1145         }
   1146       },
   1147       'amount2': {
   1148         '1|3': {
   1149           action_: 'a=',
   1150           nextState: 'a'
   1151         }
   1152       },
   1153       'letters': {
   1154         '0|1|2|3|a|as|b|p|bp|o': {
   1155           action_: 'o=',
   1156           nextState: 'o'
   1157         },
   1158         'q|dq': {
   1159           action_: ['output', 'o='],
   1160           nextState: 'o'
   1161         },
   1162         'd|D|qd|qD': {
   1163           action_: 'o after d',
   1164           nextState: 'o'
   1165         }
   1166       },
   1167       'digits': {
   1168         'o': {
   1169           action_: 'q=',
   1170           nextState: 'q'
   1171         },
   1172         'd|D': {
   1173           action_: 'q=',
   1174           nextState: 'dq'
   1175         },
   1176         'q': {
   1177           action_: ['output', 'o='],
   1178           nextState: 'o'
   1179         },
   1180         'a': {
   1181           action_: 'o=',
   1182           nextState: 'o'
   1183         }
   1184       },
   1185       'space A': {
   1186         'b|p|bp': {}
   1187       },
   1188       'space': {
   1189         'a': {
   1190           nextState: 'as'
   1191         },
   1192         '0': {
   1193           action_: 'sb=false'
   1194         },
   1195         '1|2': {
   1196           action_: 'sb=true'
   1197         },
   1198         'r|rt|rd|rdt|rdq': {
   1199           action_: 'output',
   1200           nextState: '0'
   1201         },
   1202         '*': {
   1203           action_: ['output', 'sb=true'],
   1204           nextState: '1'
   1205         }
   1206       },
   1207       '1st-level escape': {
   1208         '1|2': {
   1209           action_: ['output', {
   1210             type_: 'insert+p1',
   1211             option: '1st-level escape'
   1212           }]
   1213         },
   1214         '*': {
   1215           action_: ['output', {
   1216             type_: 'insert+p1',
   1217             option: '1st-level escape'
   1218           }],
   1219           nextState: '0'
   1220         }
   1221       },
   1222       '[(...)]': {
   1223         'r|rt': {
   1224           action_: 'rd=',
   1225           nextState: 'rd'
   1226         },
   1227         'rd|rdt': {
   1228           action_: 'rq=',
   1229           nextState: 'rdq'
   1230         }
   1231       },
   1232       '...': {
   1233         'o|d|D|dq|qd|qD': {
   1234           action_: ['output', {
   1235             type_: 'bond',
   1236             option: "..."
   1237           }],
   1238           nextState: '3'
   1239         },
   1240         '*': {
   1241           action_: [{
   1242             type_: 'output',
   1243             option: 1
   1244           }, {
   1245             type_: 'insert',
   1246             option: 'ellipsis'
   1247           }],
   1248           nextState: '1'
   1249         }
   1250       },
   1251       '. |* ': {
   1252         '*': {
   1253           action_: ['output', {
   1254             type_: 'insert',
   1255             option: 'addition compound'
   1256           }],
   1257           nextState: '1'
   1258         }
   1259       },
   1260       'state of aggregation $': {
   1261         '*': {
   1262           action_: ['output', 'state of aggregation'],
   1263           nextState: '1'
   1264         }
   1265       },
   1266       '{[(': {
   1267         'a|as|o': {
   1268           action_: ['o=', 'output', 'parenthesisLevel++'],
   1269           nextState: '2'
   1270         },
   1271         '0|1|2|3': {
   1272           action_: ['o=', 'output', 'parenthesisLevel++'],
   1273           nextState: '2'
   1274         },
   1275         '*': {
   1276           action_: ['output', 'o=', 'output', 'parenthesisLevel++'],
   1277           nextState: '2'
   1278         }
   1279       },
   1280       ')]}': {
   1281         '0|1|2|3|b|p|bp|o': {
   1282           action_: ['o=', 'parenthesisLevel--'],
   1283           nextState: 'o'
   1284         },
   1285         'a|as|d|D|q|qd|qD|dq': {
   1286           action_: ['output', 'o=', 'parenthesisLevel--'],
   1287           nextState: 'o'
   1288         }
   1289       },
   1290       ', ': {
   1291         '*': {
   1292           action_: ['output', 'comma'],
   1293           nextState: '0'
   1294         }
   1295       },
   1296       '^_': {
   1297         // ^ and _ without a sensible argument
   1298         '*': {}
   1299       },
   1300       '^{(...)}|^($...$)': {
   1301         '0|1|2|as': {
   1302           action_: 'b=',
   1303           nextState: 'b'
   1304         },
   1305         'p': {
   1306           action_: 'b=',
   1307           nextState: 'bp'
   1308         },
   1309         '3|o': {
   1310           action_: 'd= kv',
   1311           nextState: 'D'
   1312         },
   1313         'q': {
   1314           action_: 'd=',
   1315           nextState: 'qD'
   1316         },
   1317         'd|D|qd|qD|dq': {
   1318           action_: ['output', 'd='],
   1319           nextState: 'D'
   1320         }
   1321       },
   1322       '^a|^\\x{}{}|^\\x{}|^\\x|\'': {
   1323         '0|1|2|as': {
   1324           action_: 'b=',
   1325           nextState: 'b'
   1326         },
   1327         'p': {
   1328           action_: 'b=',
   1329           nextState: 'bp'
   1330         },
   1331         '3|o': {
   1332           action_: 'd= kv',
   1333           nextState: 'd'
   1334         },
   1335         'q': {
   1336           action_: 'd=',
   1337           nextState: 'qd'
   1338         },
   1339         'd|qd|D|qD': {
   1340           action_: 'd='
   1341         },
   1342         'dq': {
   1343           action_: ['output', 'd='],
   1344           nextState: 'd'
   1345         }
   1346       },
   1347       '_{(state of aggregation)}$': {
   1348         'd|D|q|qd|qD|dq': {
   1349           action_: ['output', 'q='],
   1350           nextState: 'q'
   1351         }
   1352       },
   1353       '_{(...)}|_($...$)|_9|_\\x{}{}|_\\x{}|_\\x': {
   1354         '0|1|2|as': {
   1355           action_: 'p=',
   1356           nextState: 'p'
   1357         },
   1358         'b': {
   1359           action_: 'p=',
   1360           nextState: 'bp'
   1361         },
   1362         '3|o': {
   1363           action_: 'q=',
   1364           nextState: 'q'
   1365         },
   1366         'd|D': {
   1367           action_: 'q=',
   1368           nextState: 'dq'
   1369         },
   1370         'q|qd|qD|dq': {
   1371           action_: ['output', 'q='],
   1372           nextState: 'q'
   1373         }
   1374       },
   1375       '=<>': {
   1376         '0|1|2|3|a|as|o|q|d|D|qd|qD|dq': {
   1377           action_: [{
   1378             type_: 'output',
   1379             option: 2
   1380           }, 'bond'],
   1381           nextState: '3'
   1382         }
   1383       },
   1384       '#': {
   1385         '0|1|2|3|a|as|o': {
   1386           action_: [{
   1387             type_: 'output',
   1388             option: 2
   1389           }, {
   1390             type_: 'bond',
   1391             option: "#"
   1392           }],
   1393           nextState: '3'
   1394         }
   1395       },
   1396       '{}': {
   1397         '*': {
   1398           action_: {
   1399             type_: 'output',
   1400             option: 1
   1401           },
   1402           nextState: '1'
   1403         }
   1404       },
   1405       '{...}': {
   1406         '0|1|2|3|a|as|b|p|bp': {
   1407           action_: 'o=',
   1408           nextState: 'o'
   1409         },
   1410         'o|d|D|q|qd|qD|dq': {
   1411           action_: ['output', 'o='],
   1412           nextState: 'o'
   1413         }
   1414       },
   1415       '$...$': {
   1416         'a': {
   1417           action_: 'a='
   1418         },
   1419         // 2$n$
   1420         '0|1|2|3|as|b|p|bp|o': {
   1421           action_: 'o=',
   1422           nextState: 'o'
   1423         },
   1424         // not 'amount'
   1425         'as|o': {
   1426           action_: 'o='
   1427         },
   1428         'q|d|D|qd|qD|dq': {
   1429           action_: ['output', 'o='],
   1430           nextState: 'o'
   1431         }
   1432       },
   1433       '\\bond{(...)}': {
   1434         '*': {
   1435           action_: [{
   1436             type_: 'output',
   1437             option: 2
   1438           }, 'bond'],
   1439           nextState: "3"
   1440         }
   1441       },
   1442       '\\frac{(...)}': {
   1443         '*': {
   1444           action_: [{
   1445             type_: 'output',
   1446             option: 1
   1447           }, 'frac-output'],
   1448           nextState: '3'
   1449         }
   1450       },
   1451       '\\overset{(...)}': {
   1452         '*': {
   1453           action_: [{
   1454             type_: 'output',
   1455             option: 2
   1456           }, 'overset-output'],
   1457           nextState: '3'
   1458         }
   1459       },
   1460       "\\underset{(...)}": {
   1461         '*': {
   1462           action_: [{
   1463             type_: 'output',
   1464             option: 2
   1465           }, 'underset-output'],
   1466           nextState: '3'
   1467         }
   1468       },
   1469       "\\underbrace{(...)}": {
   1470         '*': {
   1471           action_: [{
   1472             type_: 'output',
   1473             option: 2
   1474           }, 'underbrace-output'],
   1475           nextState: '3'
   1476         }
   1477       },
   1478       '\\color{(...)}{(...)}1|\\color(...){(...)}2': {
   1479         '*': {
   1480           action_: [{
   1481             type_: 'output',
   1482             option: 2
   1483           }, 'color-output'],
   1484           nextState: '3'
   1485         }
   1486       },
   1487       '\\color{(...)}0': {
   1488         '*': {
   1489           action_: [{
   1490             type_: 'output',
   1491             option: 2
   1492           }, 'color0-output']
   1493         }
   1494       },
   1495       '\\ce{(...)}': {
   1496         '*': {
   1497           action_: [{
   1498             type_: 'output',
   1499             option: 2
   1500           }, 'ce'],
   1501           nextState: '3'
   1502         }
   1503       },
   1504       '\\,': {
   1505         '*': {
   1506           action_: [{
   1507             type_: 'output',
   1508             option: 1
   1509           }, 'copy'],
   1510           nextState: '1'
   1511         }
   1512       },
   1513       '\\x{}{}|\\x{}|\\x': {
   1514         '0|1|2|3|a|as|b|p|bp|o|c0': {
   1515           action_: ['o=', 'output'],
   1516           nextState: '3'
   1517         },
   1518         '*': {
   1519           action_: ['output', 'o=', 'output'],
   1520           nextState: '3'
   1521         }
   1522       },
   1523       'others': {
   1524         '*': {
   1525           action_: [{
   1526             type_: 'output',
   1527             option: 1
   1528           }, 'copy'],
   1529           nextState: '3'
   1530         }
   1531       },
   1532       'else2': {
   1533         'a': {
   1534           action_: 'a to o',
   1535           nextState: 'o',
   1536           revisit: true
   1537         },
   1538         'as': {
   1539           action_: ['output', 'sb=true'],
   1540           nextState: '1',
   1541           revisit: true
   1542         },
   1543         'r|rt|rd|rdt|rdq': {
   1544           action_: ['output'],
   1545           nextState: '0',
   1546           revisit: true
   1547         },
   1548         '*': {
   1549           action_: ['output', 'copy'],
   1550           nextState: '3'
   1551         }
   1552       }
   1553     }),
   1554     actions: {
   1555       'o after d': function oAfterD(buffer, m) {
   1556         var ret;
   1557 
   1558         if ((buffer.d || "").match(/^[0-9]+$/)) {
   1559           var tmp = buffer.d;
   1560           buffer.d = undefined;
   1561           ret = this['output'](buffer);
   1562           buffer.b = tmp;
   1563         } else {
   1564           ret = this['output'](buffer);
   1565         }
   1566 
   1567         mhchemParser.actions['o='](buffer, m);
   1568         return ret;
   1569       },
   1570       'd= kv': function dKv(buffer, m) {
   1571         buffer.d = m;
   1572         buffer.dType = 'kv';
   1573       },
   1574       'charge or bond': function chargeOrBond(buffer, m) {
   1575         if (buffer['beginsWithBond']) {
   1576           /** @type {ParserOutput[]} */
   1577           var ret = [];
   1578           mhchemParser.concatArray(ret, this['output'](buffer));
   1579           mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-"));
   1580           return ret;
   1581         } else {
   1582           buffer.d = m;
   1583         }
   1584       },
   1585       '- after o/d': function afterOD(buffer, m, isAfterD) {
   1586         var c1 = mhchemParser.patterns.match_('orbital', buffer.o || "");
   1587         var c2 = mhchemParser.patterns.match_('one lowercase greek letter $', buffer.o || "");
   1588         var c3 = mhchemParser.patterns.match_('one lowercase latin letter $', buffer.o || "");
   1589         var c4 = mhchemParser.patterns.match_('$one lowercase latin letter$ $', buffer.o || "");
   1590         var hyphenFollows = m === "-" && (c1 && c1.remainder === "" || c2 || c3 || c4);
   1591 
   1592         if (hyphenFollows && !buffer.a && !buffer.b && !buffer.p && !buffer.d && !buffer.q && !c1 && c3) {
   1593           buffer.o = '$' + buffer.o + '$';
   1594         }
   1595         /** @type {ParserOutput[]} */
   1596 
   1597 
   1598         var ret = [];
   1599 
   1600         if (hyphenFollows) {
   1601           mhchemParser.concatArray(ret, this['output'](buffer));
   1602           ret.push({
   1603             type_: 'hyphen'
   1604           });
   1605         } else {
   1606           c1 = mhchemParser.patterns.match_('digits', buffer.d || "");
   1607 
   1608           if (isAfterD && c1 && c1.remainder === '') {
   1609             mhchemParser.concatArray(ret, mhchemParser.actions['d='](buffer, m));
   1610             mhchemParser.concatArray(ret, this['output'](buffer));
   1611           } else {
   1612             mhchemParser.concatArray(ret, this['output'](buffer));
   1613             mhchemParser.concatArray(ret, mhchemParser.actions['bond'](buffer, m, "-"));
   1614           }
   1615         }
   1616 
   1617         return ret;
   1618       },
   1619       'a to o': function aToO(buffer) {
   1620         buffer.o = buffer.a;
   1621         buffer.a = undefined;
   1622       },
   1623       'sb=true': function sbTrue(buffer) {
   1624         buffer.sb = true;
   1625       },
   1626       'sb=false': function sbFalse(buffer) {
   1627         buffer.sb = false;
   1628       },
   1629       'beginsWithBond=true': function beginsWithBondTrue(buffer) {
   1630         buffer['beginsWithBond'] = true;
   1631       },
   1632       'beginsWithBond=false': function beginsWithBondFalse(buffer) {
   1633         buffer['beginsWithBond'] = false;
   1634       },
   1635       'parenthesisLevel++': function parenthesisLevel(buffer) {
   1636         buffer['parenthesisLevel']++;
   1637       },
   1638       'parenthesisLevel--': function parenthesisLevel(buffer) {
   1639         buffer['parenthesisLevel']--;
   1640       },
   1641       'state of aggregation': function stateOfAggregation(buffer, m) {
   1642         return {
   1643           type_: 'state of aggregation',
   1644           p1: mhchemParser.go(m, 'o')
   1645         };
   1646       },
   1647       'comma': function comma(buffer, m) {
   1648         var a = m.replace(/\s*$/, '');
   1649         var withSpace = a !== m;
   1650 
   1651         if (withSpace && buffer['parenthesisLevel'] === 0) {
   1652           return {
   1653             type_: 'comma enumeration L',
   1654             p1: a
   1655           };
   1656         } else {
   1657           return {
   1658             type_: 'comma enumeration M',
   1659             p1: a
   1660           };
   1661         }
   1662       },
   1663       'output': function output(buffer, m, entityFollows) {
   1664         // entityFollows:
   1665         //   undefined = if we have nothing else to output, also ignore the just read space (buffer.sb)
   1666         //   1 = an entity follows, never omit the space if there was one just read before (can only apply to state 1)
   1667         //   2 = 1 + the entity can have an amount, so output a\, instead of converting it to o (can only apply to states a|as)
   1668 
   1669         /** @type {ParserOutput | ParserOutput[]} */
   1670         var ret;
   1671 
   1672         if (!buffer.r) {
   1673           ret = [];
   1674 
   1675           if (!buffer.a && !buffer.b && !buffer.p && !buffer.o && !buffer.q && !buffer.d && !entityFollows) {//ret = [];
   1676           } else {
   1677             if (buffer.sb) {
   1678               ret.push({
   1679                 type_: 'entitySkip'
   1680               });
   1681             }
   1682 
   1683             if (!buffer.o && !buffer.q && !buffer.d && !buffer.b && !buffer.p && entityFollows !== 2) {
   1684               buffer.o = buffer.a;
   1685               buffer.a = undefined;
   1686             } else if (!buffer.o && !buffer.q && !buffer.d && (buffer.b || buffer.p)) {
   1687               buffer.o = buffer.a;
   1688               buffer.d = buffer.b;
   1689               buffer.q = buffer.p;
   1690               buffer.a = buffer.b = buffer.p = undefined;
   1691             } else {
   1692               if (buffer.o && buffer.dType === 'kv' && mhchemParser.patterns.match_('d-oxidation$', buffer.d || "")) {
   1693                 buffer.dType = 'oxidation';
   1694               } else if (buffer.o && buffer.dType === 'kv' && !buffer.q) {
   1695                 buffer.dType = undefined;
   1696               }
   1697             }
   1698 
   1699             ret.push({
   1700               type_: 'chemfive',
   1701               a: mhchemParser.go(buffer.a, 'a'),
   1702               b: mhchemParser.go(buffer.b, 'bd'),
   1703               p: mhchemParser.go(buffer.p, 'pq'),
   1704               o: mhchemParser.go(buffer.o, 'o'),
   1705               q: mhchemParser.go(buffer.q, 'pq'),
   1706               d: mhchemParser.go(buffer.d, buffer.dType === 'oxidation' ? 'oxidation' : 'bd'),
   1707               dType: buffer.dType
   1708             });
   1709           }
   1710         } else {
   1711           // r
   1712 
   1713           /** @type {ParserOutput[]} */
   1714           var rd;
   1715 
   1716           if (buffer.rdt === 'M') {
   1717             rd = mhchemParser.go(buffer.rd, 'tex-math');
   1718           } else if (buffer.rdt === 'T') {
   1719             rd = [{
   1720               type_: 'text',
   1721               p1: buffer.rd || ""
   1722             }];
   1723           } else {
   1724             rd = mhchemParser.go(buffer.rd);
   1725           }
   1726           /** @type {ParserOutput[]} */
   1727 
   1728 
   1729           var rq;
   1730 
   1731           if (buffer.rqt === 'M') {
   1732             rq = mhchemParser.go(buffer.rq, 'tex-math');
   1733           } else if (buffer.rqt === 'T') {
   1734             rq = [{
   1735               type_: 'text',
   1736               p1: buffer.rq || ""
   1737             }];
   1738           } else {
   1739             rq = mhchemParser.go(buffer.rq);
   1740           }
   1741 
   1742           ret = {
   1743             type_: 'arrow',
   1744             r: buffer.r,
   1745             rd: rd,
   1746             rq: rq
   1747           };
   1748         }
   1749 
   1750         for (var p in buffer) {
   1751           if (p !== 'parenthesisLevel' && p !== 'beginsWithBond') {
   1752             delete buffer[p];
   1753           }
   1754         }
   1755 
   1756         return ret;
   1757       },
   1758       'oxidation-output': function oxidationOutput(buffer, m) {
   1759         var ret = ["{"];
   1760         mhchemParser.concatArray(ret, mhchemParser.go(m, 'oxidation'));
   1761         ret.push("}");
   1762         return ret;
   1763       },
   1764       'frac-output': function fracOutput(buffer, m) {
   1765         return {
   1766           type_: 'frac-ce',
   1767           p1: mhchemParser.go(m[0]),
   1768           p2: mhchemParser.go(m[1])
   1769         };
   1770       },
   1771       'overset-output': function oversetOutput(buffer, m) {
   1772         return {
   1773           type_: 'overset',
   1774           p1: mhchemParser.go(m[0]),
   1775           p2: mhchemParser.go(m[1])
   1776         };
   1777       },
   1778       'underset-output': function undersetOutput(buffer, m) {
   1779         return {
   1780           type_: 'underset',
   1781           p1: mhchemParser.go(m[0]),
   1782           p2: mhchemParser.go(m[1])
   1783         };
   1784       },
   1785       'underbrace-output': function underbraceOutput(buffer, m) {
   1786         return {
   1787           type_: 'underbrace',
   1788           p1: mhchemParser.go(m[0]),
   1789           p2: mhchemParser.go(m[1])
   1790         };
   1791       },
   1792       'color-output': function colorOutput(buffer, m) {
   1793         return {
   1794           type_: 'color',
   1795           color1: m[0],
   1796           color2: mhchemParser.go(m[1])
   1797         };
   1798       },
   1799       'r=': function r(buffer, m) {
   1800         buffer.r = m;
   1801       },
   1802       'rdt=': function rdt(buffer, m) {
   1803         buffer.rdt = m;
   1804       },
   1805       'rd=': function rd(buffer, m) {
   1806         buffer.rd = m;
   1807       },
   1808       'rqt=': function rqt(buffer, m) {
   1809         buffer.rqt = m;
   1810       },
   1811       'rq=': function rq(buffer, m) {
   1812         buffer.rq = m;
   1813       },
   1814       'operator': function operator(buffer, m, p1) {
   1815         return {
   1816           type_: 'operator',
   1817           kind_: p1 || m
   1818         };
   1819       }
   1820     }
   1821   },
   1822   'a': {
   1823     transitions: mhchemParser.createTransitions({
   1824       'empty': {
   1825         '*': {}
   1826       },
   1827       '1/2$': {
   1828         '0': {
   1829           action_: '1/2'
   1830         }
   1831       },
   1832       'else': {
   1833         '0': {
   1834           nextState: '1',
   1835           revisit: true
   1836         }
   1837       },
   1838       '$(...)$': {
   1839         '*': {
   1840           action_: 'tex-math tight',
   1841           nextState: '1'
   1842         }
   1843       },
   1844       ',': {
   1845         '*': {
   1846           action_: {
   1847             type_: 'insert',
   1848             option: 'commaDecimal'
   1849           }
   1850         }
   1851       },
   1852       'else2': {
   1853         '*': {
   1854           action_: 'copy'
   1855         }
   1856       }
   1857     }),
   1858     actions: {}
   1859   },
   1860   'o': {
   1861     transitions: mhchemParser.createTransitions({
   1862       'empty': {
   1863         '*': {}
   1864       },
   1865       '1/2$': {
   1866         '0': {
   1867           action_: '1/2'
   1868         }
   1869       },
   1870       'else': {
   1871         '0': {
   1872           nextState: '1',
   1873           revisit: true
   1874         }
   1875       },
   1876       'letters': {
   1877         '*': {
   1878           action_: 'rm'
   1879         }
   1880       },
   1881       '\\ca': {
   1882         '*': {
   1883           action_: {
   1884             type_: 'insert',
   1885             option: 'circa'
   1886           }
   1887         }
   1888       },
   1889       '\\x{}{}|\\x{}|\\x': {
   1890         '*': {
   1891           action_: 'copy'
   1892         }
   1893       },
   1894       '${(...)}$|$(...)$': {
   1895         '*': {
   1896           action_: 'tex-math'
   1897         }
   1898       },
   1899       '{(...)}': {
   1900         '*': {
   1901           action_: '{text}'
   1902         }
   1903       },
   1904       'else2': {
   1905         '*': {
   1906           action_: 'copy'
   1907         }
   1908       }
   1909     }),
   1910     actions: {}
   1911   },
   1912   'text': {
   1913     transitions: mhchemParser.createTransitions({
   1914       'empty': {
   1915         '*': {
   1916           action_: 'output'
   1917         }
   1918       },
   1919       '{...}': {
   1920         '*': {
   1921           action_: 'text='
   1922         }
   1923       },
   1924       '${(...)}$|$(...)$': {
   1925         '*': {
   1926           action_: 'tex-math'
   1927         }
   1928       },
   1929       '\\greek': {
   1930         '*': {
   1931           action_: ['output', 'rm']
   1932         }
   1933       },
   1934       '\\,|\\x{}{}|\\x{}|\\x': {
   1935         '*': {
   1936           action_: ['output', 'copy']
   1937         }
   1938       },
   1939       'else': {
   1940         '*': {
   1941           action_: 'text='
   1942         }
   1943       }
   1944     }),
   1945     actions: {
   1946       'output': function output(buffer) {
   1947         if (buffer.text_) {
   1948           /** @type {ParserOutput} */
   1949           var ret = {
   1950             type_: 'text',
   1951             p1: buffer.text_
   1952           };
   1953 
   1954           for (var p in buffer) {
   1955             delete buffer[p];
   1956           }
   1957 
   1958           return ret;
   1959         }
   1960       }
   1961     }
   1962   },
   1963   'pq': {
   1964     transitions: mhchemParser.createTransitions({
   1965       'empty': {
   1966         '*': {}
   1967       },
   1968       'state of aggregation $': {
   1969         '*': {
   1970           action_: 'state of aggregation'
   1971         }
   1972       },
   1973       'i$': {
   1974         '0': {
   1975           nextState: '!f',
   1976           revisit: true
   1977         }
   1978       },
   1979       '(KV letters),': {
   1980         '0': {
   1981           action_: 'rm',
   1982           nextState: '0'
   1983         }
   1984       },
   1985       'formula$': {
   1986         '0': {
   1987           nextState: 'f',
   1988           revisit: true
   1989         }
   1990       },
   1991       '1/2$': {
   1992         '0': {
   1993           action_: '1/2'
   1994         }
   1995       },
   1996       'else': {
   1997         '0': {
   1998           nextState: '!f',
   1999           revisit: true
   2000         }
   2001       },
   2002       '${(...)}$|$(...)$': {
   2003         '*': {
   2004           action_: 'tex-math'
   2005         }
   2006       },
   2007       '{(...)}': {
   2008         '*': {
   2009           action_: 'text'
   2010         }
   2011       },
   2012       'a-z': {
   2013         'f': {
   2014           action_: 'tex-math'
   2015         }
   2016       },
   2017       'letters': {
   2018         '*': {
   2019           action_: 'rm'
   2020         }
   2021       },
   2022       '-9.,9': {
   2023         '*': {
   2024           action_: '9,9'
   2025         }
   2026       },
   2027       ',': {
   2028         '*': {
   2029           action_: {
   2030             type_: 'insert+p1',
   2031             option: 'comma enumeration S'
   2032           }
   2033         }
   2034       },
   2035       '\\color{(...)}{(...)}1|\\color(...){(...)}2': {
   2036         '*': {
   2037           action_: 'color-output'
   2038         }
   2039       },
   2040       '\\color{(...)}0': {
   2041         '*': {
   2042           action_: 'color0-output'
   2043         }
   2044       },
   2045       '\\ce{(...)}': {
   2046         '*': {
   2047           action_: 'ce'
   2048         }
   2049       },
   2050       '\\,|\\x{}{}|\\x{}|\\x': {
   2051         '*': {
   2052           action_: 'copy'
   2053         }
   2054       },
   2055       'else2': {
   2056         '*': {
   2057           action_: 'copy'
   2058         }
   2059       }
   2060     }),
   2061     actions: {
   2062       'state of aggregation': function stateOfAggregation(buffer, m) {
   2063         return {
   2064           type_: 'state of aggregation subscript',
   2065           p1: mhchemParser.go(m, 'o')
   2066         };
   2067       },
   2068       'color-output': function colorOutput(buffer, m) {
   2069         return {
   2070           type_: 'color',
   2071           color1: m[0],
   2072           color2: mhchemParser.go(m[1], 'pq')
   2073         };
   2074       }
   2075     }
   2076   },
   2077   'bd': {
   2078     transitions: mhchemParser.createTransitions({
   2079       'empty': {
   2080         '*': {}
   2081       },
   2082       'x$': {
   2083         '0': {
   2084           nextState: '!f',
   2085           revisit: true
   2086         }
   2087       },
   2088       'formula$': {
   2089         '0': {
   2090           nextState: 'f',
   2091           revisit: true
   2092         }
   2093       },
   2094       'else': {
   2095         '0': {
   2096           nextState: '!f',
   2097           revisit: true
   2098         }
   2099       },
   2100       '-9.,9 no missing 0': {
   2101         '*': {
   2102           action_: '9,9'
   2103         }
   2104       },
   2105       '.': {
   2106         '*': {
   2107           action_: {
   2108             type_: 'insert',
   2109             option: 'electron dot'
   2110           }
   2111         }
   2112       },
   2113       'a-z': {
   2114         'f': {
   2115           action_: 'tex-math'
   2116         }
   2117       },
   2118       'x': {
   2119         '*': {
   2120           action_: {
   2121             type_: 'insert',
   2122             option: 'KV x'
   2123           }
   2124         }
   2125       },
   2126       'letters': {
   2127         '*': {
   2128           action_: 'rm'
   2129         }
   2130       },
   2131       '\'': {
   2132         '*': {
   2133           action_: {
   2134             type_: 'insert',
   2135             option: 'prime'
   2136           }
   2137         }
   2138       },
   2139       '${(...)}$|$(...)$': {
   2140         '*': {
   2141           action_: 'tex-math'
   2142         }
   2143       },
   2144       '{(...)}': {
   2145         '*': {
   2146           action_: 'text'
   2147         }
   2148       },
   2149       '\\color{(...)}{(...)}1|\\color(...){(...)}2': {
   2150         '*': {
   2151           action_: 'color-output'
   2152         }
   2153       },
   2154       '\\color{(...)}0': {
   2155         '*': {
   2156           action_: 'color0-output'
   2157         }
   2158       },
   2159       '\\ce{(...)}': {
   2160         '*': {
   2161           action_: 'ce'
   2162         }
   2163       },
   2164       '\\,|\\x{}{}|\\x{}|\\x': {
   2165         '*': {
   2166           action_: 'copy'
   2167         }
   2168       },
   2169       'else2': {
   2170         '*': {
   2171           action_: 'copy'
   2172         }
   2173       }
   2174     }),
   2175     actions: {
   2176       'color-output': function colorOutput(buffer, m) {
   2177         return {
   2178           type_: 'color',
   2179           color1: m[0],
   2180           color2: mhchemParser.go(m[1], 'bd')
   2181         };
   2182       }
   2183     }
   2184   },
   2185   'oxidation': {
   2186     transitions: mhchemParser.createTransitions({
   2187       'empty': {
   2188         '*': {}
   2189       },
   2190       'roman numeral': {
   2191         '*': {
   2192           action_: 'roman-numeral'
   2193         }
   2194       },
   2195       '${(...)}$|$(...)$': {
   2196         '*': {
   2197           action_: 'tex-math'
   2198         }
   2199       },
   2200       'else': {
   2201         '*': {
   2202           action_: 'copy'
   2203         }
   2204       }
   2205     }),
   2206     actions: {
   2207       'roman-numeral': function romanNumeral(buffer, m) {
   2208         return {
   2209           type_: 'roman numeral',
   2210           p1: m || ""
   2211         };
   2212       }
   2213     }
   2214   },
   2215   'tex-math': {
   2216     transitions: mhchemParser.createTransitions({
   2217       'empty': {
   2218         '*': {
   2219           action_: 'output'
   2220         }
   2221       },
   2222       '\\ce{(...)}': {
   2223         '*': {
   2224           action_: ['output', 'ce']
   2225         }
   2226       },
   2227       '{...}|\\,|\\x{}{}|\\x{}|\\x': {
   2228         '*': {
   2229           action_: 'o='
   2230         }
   2231       },
   2232       'else': {
   2233         '*': {
   2234           action_: 'o='
   2235         }
   2236       }
   2237     }),
   2238     actions: {
   2239       'output': function output(buffer) {
   2240         if (buffer.o) {
   2241           /** @type {ParserOutput} */
   2242           var ret = {
   2243             type_: 'tex-math',
   2244             p1: buffer.o
   2245           };
   2246 
   2247           for (var p in buffer) {
   2248             delete buffer[p];
   2249           }
   2250 
   2251           return ret;
   2252         }
   2253       }
   2254     }
   2255   },
   2256   'tex-math tight': {
   2257     transitions: mhchemParser.createTransitions({
   2258       'empty': {
   2259         '*': {
   2260           action_: 'output'
   2261         }
   2262       },
   2263       '\\ce{(...)}': {
   2264         '*': {
   2265           action_: ['output', 'ce']
   2266         }
   2267       },
   2268       '{...}|\\,|\\x{}{}|\\x{}|\\x': {
   2269         '*': {
   2270           action_: 'o='
   2271         }
   2272       },
   2273       '-|+': {
   2274         '*': {
   2275           action_: 'tight operator'
   2276         }
   2277       },
   2278       'else': {
   2279         '*': {
   2280           action_: 'o='
   2281         }
   2282       }
   2283     }),
   2284     actions: {
   2285       'tight operator': function tightOperator(buffer, m) {
   2286         buffer.o = (buffer.o || "") + "{" + m + "}";
   2287       },
   2288       'output': function output(buffer) {
   2289         if (buffer.o) {
   2290           /** @type {ParserOutput} */
   2291           var ret = {
   2292             type_: 'tex-math',
   2293             p1: buffer.o
   2294           };
   2295 
   2296           for (var p in buffer) {
   2297             delete buffer[p];
   2298           }
   2299 
   2300           return ret;
   2301         }
   2302       }
   2303     }
   2304   },
   2305   '9,9': {
   2306     transitions: mhchemParser.createTransitions({
   2307       'empty': {
   2308         '*': {}
   2309       },
   2310       ',': {
   2311         '*': {
   2312           action_: 'comma'
   2313         }
   2314       },
   2315       'else': {
   2316         '*': {
   2317           action_: 'copy'
   2318         }
   2319       }
   2320     }),
   2321     actions: {
   2322       'comma': function comma() {
   2323         return {
   2324           type_: 'commaDecimal'
   2325         };
   2326       }
   2327     }
   2328   },
   2329   //#endregion
   2330   //
   2331   // \pu state machines
   2332   //
   2333   //#region pu
   2334   'pu': {
   2335     transitions: mhchemParser.createTransitions({
   2336       'empty': {
   2337         '*': {
   2338           action_: 'output'
   2339         }
   2340       },
   2341       'space$': {
   2342         '*': {
   2343           action_: ['output', 'space']
   2344         }
   2345       },
   2346       '{[(|)]}': {
   2347         '0|a': {
   2348           action_: 'copy'
   2349         }
   2350       },
   2351       '(-)(9)^(-9)': {
   2352         '0': {
   2353           action_: 'number^',
   2354           nextState: 'a'
   2355         }
   2356       },
   2357       '(-)(9.,9)(e)(99)': {
   2358         '0': {
   2359           action_: 'enumber',
   2360           nextState: 'a'
   2361         }
   2362       },
   2363       'space': {
   2364         '0|a': {}
   2365       },
   2366       'pm-operator': {
   2367         '0|a': {
   2368           action_: {
   2369             type_: 'operator',
   2370             option: '\\pm'
   2371           },
   2372           nextState: '0'
   2373         }
   2374       },
   2375       'operator': {
   2376         '0|a': {
   2377           action_: 'copy',
   2378           nextState: '0'
   2379         }
   2380       },
   2381       '//': {
   2382         'd': {
   2383           action_: 'o=',
   2384           nextState: '/'
   2385         }
   2386       },
   2387       '/': {
   2388         'd': {
   2389           action_: 'o=',
   2390           nextState: '/'
   2391         }
   2392       },
   2393       '{...}|else': {
   2394         '0|d': {
   2395           action_: 'd=',
   2396           nextState: 'd'
   2397         },
   2398         'a': {
   2399           action_: ['space', 'd='],
   2400           nextState: 'd'
   2401         },
   2402         '/|q': {
   2403           action_: 'q=',
   2404           nextState: 'q'
   2405         }
   2406       }
   2407     }),
   2408     actions: {
   2409       'enumber': function enumber(buffer, m) {
   2410         /** @type {ParserOutput[]} */
   2411         var ret = [];
   2412 
   2413         if (m[0] === "+-" || m[0] === "+/-") {
   2414           ret.push("\\pm ");
   2415         } else if (m[0]) {
   2416           ret.push(m[0]);
   2417         }
   2418 
   2419         if (m[1]) {
   2420           mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9'));
   2421 
   2422           if (m[2]) {
   2423             if (m[2].match(/[,.]/)) {
   2424               mhchemParser.concatArray(ret, mhchemParser.go(m[2], 'pu-9,9'));
   2425             } else {
   2426               ret.push(m[2]);
   2427             }
   2428           }
   2429 
   2430           m[3] = m[4] || m[3];
   2431 
   2432           if (m[3]) {
   2433             m[3] = m[3].trim();
   2434 
   2435             if (m[3] === "e" || m[3].substr(0, 1) === "*") {
   2436               ret.push({
   2437                 type_: 'cdot'
   2438               });
   2439             } else {
   2440               ret.push({
   2441                 type_: 'times'
   2442               });
   2443             }
   2444           }
   2445         }
   2446 
   2447         if (m[3]) {
   2448           ret.push("10^{" + m[5] + "}");
   2449         }
   2450 
   2451         return ret;
   2452       },
   2453       'number^': function number(buffer, m) {
   2454         /** @type {ParserOutput[]} */
   2455         var ret = [];
   2456 
   2457         if (m[0] === "+-" || m[0] === "+/-") {
   2458           ret.push("\\pm ");
   2459         } else if (m[0]) {
   2460           ret.push(m[0]);
   2461         }
   2462 
   2463         mhchemParser.concatArray(ret, mhchemParser.go(m[1], 'pu-9,9'));
   2464         ret.push("^{" + m[2] + "}");
   2465         return ret;
   2466       },
   2467       'operator': function operator(buffer, m, p1) {
   2468         return {
   2469           type_: 'operator',
   2470           kind_: p1 || m
   2471         };
   2472       },
   2473       'space': function space() {
   2474         return {
   2475           type_: 'pu-space-1'
   2476         };
   2477       },
   2478       'output': function output(buffer) {
   2479         /** @type {ParserOutput | ParserOutput[]} */
   2480         var ret;
   2481         var md = mhchemParser.patterns.match_('{(...)}', buffer.d || "");
   2482 
   2483         if (md && md.remainder === '') {
   2484           buffer.d = md.match_;
   2485         }
   2486 
   2487         var mq = mhchemParser.patterns.match_('{(...)}', buffer.q || "");
   2488 
   2489         if (mq && mq.remainder === '') {
   2490           buffer.q = mq.match_;
   2491         }
   2492 
   2493         if (buffer.d) {
   2494           buffer.d = buffer.d.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C");
   2495           buffer.d = buffer.d.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F");
   2496         }
   2497 
   2498         if (buffer.q) {
   2499           // fraction
   2500           buffer.q = buffer.q.replace(/\u00B0C|\^oC|\^{o}C/g, "{}^{\\circ}C");
   2501           buffer.q = buffer.q.replace(/\u00B0F|\^oF|\^{o}F/g, "{}^{\\circ}F");
   2502           var b5 = {
   2503             d: mhchemParser.go(buffer.d, 'pu'),
   2504             q: mhchemParser.go(buffer.q, 'pu')
   2505           };
   2506 
   2507           if (buffer.o === '//') {
   2508             ret = {
   2509               type_: 'pu-frac',
   2510               p1: b5.d,
   2511               p2: b5.q
   2512             };
   2513           } else {
   2514             ret = b5.d;
   2515 
   2516             if (b5.d.length > 1 || b5.q.length > 1) {
   2517               ret.push({
   2518                 type_: ' / '
   2519               });
   2520             } else {
   2521               ret.push({
   2522                 type_: '/'
   2523               });
   2524             }
   2525 
   2526             mhchemParser.concatArray(ret, b5.q);
   2527           }
   2528         } else {
   2529           // no fraction
   2530           ret = mhchemParser.go(buffer.d, 'pu-2');
   2531         }
   2532 
   2533         for (var p in buffer) {
   2534           delete buffer[p];
   2535         }
   2536 
   2537         return ret;
   2538       }
   2539     }
   2540   },
   2541   'pu-2': {
   2542     transitions: mhchemParser.createTransitions({
   2543       'empty': {
   2544         '*': {
   2545           action_: 'output'
   2546         }
   2547       },
   2548       '*': {
   2549         '*': {
   2550           action_: ['output', 'cdot'],
   2551           nextState: '0'
   2552         }
   2553       },
   2554       '\\x': {
   2555         '*': {
   2556           action_: 'rm='
   2557         }
   2558       },
   2559       'space': {
   2560         '*': {
   2561           action_: ['output', 'space'],
   2562           nextState: '0'
   2563         }
   2564       },
   2565       '^{(...)}|^(-1)': {
   2566         '1': {
   2567           action_: '^(-1)'
   2568         }
   2569       },
   2570       '-9.,9': {
   2571         '0': {
   2572           action_: 'rm=',
   2573           nextState: '0'
   2574         },
   2575         '1': {
   2576           action_: '^(-1)',
   2577           nextState: '0'
   2578         }
   2579       },
   2580       '{...}|else': {
   2581         '*': {
   2582           action_: 'rm=',
   2583           nextState: '1'
   2584         }
   2585       }
   2586     }),
   2587     actions: {
   2588       'cdot': function cdot() {
   2589         return {
   2590           type_: 'tight cdot'
   2591         };
   2592       },
   2593       '^(-1)': function _(buffer, m) {
   2594         buffer.rm += "^{" + m + "}";
   2595       },
   2596       'space': function space() {
   2597         return {
   2598           type_: 'pu-space-2'
   2599         };
   2600       },
   2601       'output': function output(buffer) {
   2602         /** @type {ParserOutput | ParserOutput[]} */
   2603         var ret = [];
   2604 
   2605         if (buffer.rm) {
   2606           var mrm = mhchemParser.patterns.match_('{(...)}', buffer.rm || "");
   2607 
   2608           if (mrm && mrm.remainder === '') {
   2609             ret = mhchemParser.go(mrm.match_, 'pu');
   2610           } else {
   2611             ret = {
   2612               type_: 'rm',
   2613               p1: buffer.rm
   2614             };
   2615           }
   2616         }
   2617 
   2618         for (var p in buffer) {
   2619           delete buffer[p];
   2620         }
   2621 
   2622         return ret;
   2623       }
   2624     }
   2625   },
   2626   'pu-9,9': {
   2627     transitions: mhchemParser.createTransitions({
   2628       'empty': {
   2629         '0': {
   2630           action_: 'output-0'
   2631         },
   2632         'o': {
   2633           action_: 'output-o'
   2634         }
   2635       },
   2636       ',': {
   2637         '0': {
   2638           action_: ['output-0', 'comma'],
   2639           nextState: 'o'
   2640         }
   2641       },
   2642       '.': {
   2643         '0': {
   2644           action_: ['output-0', 'copy'],
   2645           nextState: 'o'
   2646         }
   2647       },
   2648       'else': {
   2649         '*': {
   2650           action_: 'text='
   2651         }
   2652       }
   2653     }),
   2654     actions: {
   2655       'comma': function comma() {
   2656         return {
   2657           type_: 'commaDecimal'
   2658         };
   2659       },
   2660       'output-0': function output0(buffer) {
   2661         /** @type {ParserOutput[]} */
   2662         var ret = [];
   2663         buffer.text_ = buffer.text_ || "";
   2664 
   2665         if (buffer.text_.length > 4) {
   2666           var a = buffer.text_.length % 3;
   2667 
   2668           if (a === 0) {
   2669             a = 3;
   2670           }
   2671 
   2672           for (var i = buffer.text_.length - 3; i > 0; i -= 3) {
   2673             ret.push(buffer.text_.substr(i, 3));
   2674             ret.push({
   2675               type_: '1000 separator'
   2676             });
   2677           }
   2678 
   2679           ret.push(buffer.text_.substr(0, a));
   2680           ret.reverse();
   2681         } else {
   2682           ret.push(buffer.text_);
   2683         }
   2684 
   2685         for (var p in buffer) {
   2686           delete buffer[p];
   2687         }
   2688 
   2689         return ret;
   2690       },
   2691       'output-o': function outputO(buffer) {
   2692         /** @type {ParserOutput[]} */
   2693         var ret = [];
   2694         buffer.text_ = buffer.text_ || "";
   2695 
   2696         if (buffer.text_.length > 4) {
   2697           var a = buffer.text_.length - 3;
   2698 
   2699           for (var i = 0; i < a; i += 3) {
   2700             ret.push(buffer.text_.substr(i, 3));
   2701             ret.push({
   2702               type_: '1000 separator'
   2703             });
   2704           }
   2705 
   2706           ret.push(buffer.text_.substr(i));
   2707         } else {
   2708           ret.push(buffer.text_);
   2709         }
   2710 
   2711         for (var p in buffer) {
   2712           delete buffer[p];
   2713         }
   2714 
   2715         return ret;
   2716       }
   2717     }
   2718   } //#endregion
   2719 
   2720 }; //
   2721 // texify: Take MhchemParser output and convert it to TeX
   2722 //
   2723 
   2724 /** @type {Texify} */
   2725 
   2726 var texify = {
   2727   go: function go(input, isInner) {
   2728     // (recursive, max 4 levels)
   2729     if (!input) {
   2730       return "";
   2731     }
   2732 
   2733     var res = "";
   2734     var cee = false;
   2735 
   2736     for (var i = 0; i < input.length; i++) {
   2737       var inputi = input[i];
   2738 
   2739       if (typeof inputi === "string") {
   2740         res += inputi;
   2741       } else {
   2742         res += texify._go2(inputi);
   2743 
   2744         if (inputi.type_ === '1st-level escape') {
   2745           cee = true;
   2746         }
   2747       }
   2748     }
   2749 
   2750     if (!isInner && !cee && res) {
   2751       res = "{" + res + "}";
   2752     }
   2753 
   2754     return res;
   2755   },
   2756   _goInner: function _goInner(input) {
   2757     if (!input) {
   2758       return input;
   2759     }
   2760 
   2761     return texify.go(input, true);
   2762   },
   2763   _go2: function _go2(buf) {
   2764     /** @type {undefined | string} */
   2765     var res;
   2766 
   2767     switch (buf.type_) {
   2768       case 'chemfive':
   2769         res = "";
   2770         var b5 = {
   2771           a: texify._goInner(buf.a),
   2772           b: texify._goInner(buf.b),
   2773           p: texify._goInner(buf.p),
   2774           o: texify._goInner(buf.o),
   2775           q: texify._goInner(buf.q),
   2776           d: texify._goInner(buf.d)
   2777         }; //
   2778         // a
   2779         //
   2780 
   2781         if (b5.a) {
   2782           if (b5.a.match(/^[+\-]/)) {
   2783             b5.a = "{" + b5.a + "}";
   2784           }
   2785 
   2786           res += b5.a + "\\,";
   2787         } //
   2788         // b and p
   2789         //
   2790 
   2791 
   2792         if (b5.b || b5.p) {
   2793           res += "{\\vphantom{X}}";
   2794           res += "^{\\hphantom{" + (b5.b || "") + "}}_{\\hphantom{" + (b5.p || "") + "}}";
   2795           res += "{\\vphantom{X}}";
   2796           res += "^{\\smash[t]{\\vphantom{2}}\\mathllap{" + (b5.b || "") + "}}";
   2797           res += "_{\\vphantom{2}\\mathllap{\\smash[t]{" + (b5.p || "") + "}}}";
   2798         } //
   2799         // o
   2800         //
   2801 
   2802 
   2803         if (b5.o) {
   2804           if (b5.o.match(/^[+\-]/)) {
   2805             b5.o = "{" + b5.o + "}";
   2806           }
   2807 
   2808           res += b5.o;
   2809         } //
   2810         // q and d
   2811         //
   2812 
   2813 
   2814         if (buf.dType === 'kv') {
   2815           if (b5.d || b5.q) {
   2816             res += "{\\vphantom{X}}";
   2817           }
   2818 
   2819           if (b5.d) {
   2820             res += "^{" + b5.d + "}";
   2821           }
   2822 
   2823           if (b5.q) {
   2824             res += "_{\\smash[t]{" + b5.q + "}}";
   2825           }
   2826         } else if (buf.dType === 'oxidation') {
   2827           if (b5.d) {
   2828             res += "{\\vphantom{X}}";
   2829             res += "^{" + b5.d + "}";
   2830           }
   2831 
   2832           if (b5.q) {
   2833             res += "{\\vphantom{X}}";
   2834             res += "_{\\smash[t]{" + b5.q + "}}";
   2835           }
   2836         } else {
   2837           if (b5.q) {
   2838             res += "{\\vphantom{X}}";
   2839             res += "_{\\smash[t]{" + b5.q + "}}";
   2840           }
   2841 
   2842           if (b5.d) {
   2843             res += "{\\vphantom{X}}";
   2844             res += "^{" + b5.d + "}";
   2845           }
   2846         }
   2847 
   2848         break;
   2849 
   2850       case 'rm':
   2851         res = "\\mathrm{" + buf.p1 + "}";
   2852         break;
   2853 
   2854       case 'text':
   2855         if (buf.p1.match(/[\^_]/)) {
   2856           buf.p1 = buf.p1.replace(" ", "~").replace("-", "\\text{-}");
   2857           res = "\\mathrm{" + buf.p1 + "}";
   2858         } else {
   2859           res = "\\text{" + buf.p1 + "}";
   2860         }
   2861 
   2862         break;
   2863 
   2864       case 'roman numeral':
   2865         res = "\\mathrm{" + buf.p1 + "}";
   2866         break;
   2867 
   2868       case 'state of aggregation':
   2869         res = "\\mskip2mu " + texify._goInner(buf.p1);
   2870         break;
   2871 
   2872       case 'state of aggregation subscript':
   2873         res = "\\mskip1mu " + texify._goInner(buf.p1);
   2874         break;
   2875 
   2876       case 'bond':
   2877         res = texify._getBond(buf.kind_);
   2878 
   2879         if (!res) {
   2880           throw ["MhchemErrorBond", "mhchem Error. Unknown bond type (" + buf.kind_ + ")"];
   2881         }
   2882 
   2883         break;
   2884 
   2885       case 'frac':
   2886         var c = "\\frac{" + buf.p1 + "}{" + buf.p2 + "}";
   2887         res = "\\mathchoice{\\textstyle" + c + "}{" + c + "}{" + c + "}{" + c + "}";
   2888         break;
   2889 
   2890       case 'pu-frac':
   2891         var d = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
   2892         res = "\\mathchoice{\\textstyle" + d + "}{" + d + "}{" + d + "}{" + d + "}";
   2893         break;
   2894 
   2895       case 'tex-math':
   2896         res = buf.p1 + " ";
   2897         break;
   2898 
   2899       case 'frac-ce':
   2900         res = "\\frac{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
   2901         break;
   2902 
   2903       case 'overset':
   2904         res = "\\overset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
   2905         break;
   2906 
   2907       case 'underset':
   2908         res = "\\underset{" + texify._goInner(buf.p1) + "}{" + texify._goInner(buf.p2) + "}";
   2909         break;
   2910 
   2911       case 'underbrace':
   2912         res = "\\underbrace{" + texify._goInner(buf.p1) + "}_{" + texify._goInner(buf.p2) + "}";
   2913         break;
   2914 
   2915       case 'color':
   2916         res = "{\\color{" + buf.color1 + "}{" + texify._goInner(buf.color2) + "}}";
   2917         break;
   2918 
   2919       case 'color0':
   2920         res = "\\color{" + buf.color + "}";
   2921         break;
   2922 
   2923       case 'arrow':
   2924         var b6 = {
   2925           rd: texify._goInner(buf.rd),
   2926           rq: texify._goInner(buf.rq)
   2927         };
   2928 
   2929         var arrow = "\\x" + texify._getArrow(buf.r);
   2930 
   2931         if (b6.rq) {
   2932           arrow += "[{" + b6.rq + "}]";
   2933         }
   2934 
   2935         if (b6.rd) {
   2936           arrow += "{" + b6.rd + "}";
   2937         } else {
   2938           arrow += "{}";
   2939         }
   2940 
   2941         res = arrow;
   2942         break;
   2943 
   2944       case 'operator':
   2945         res = texify._getOperator(buf.kind_);
   2946         break;
   2947 
   2948       case '1st-level escape':
   2949         res = buf.p1 + " "; // &, \\\\, \\hlin
   2950 
   2951         break;
   2952 
   2953       case 'space':
   2954         res = " ";
   2955         break;
   2956 
   2957       case 'entitySkip':
   2958         res = "~";
   2959         break;
   2960 
   2961       case 'pu-space-1':
   2962         res = "~";
   2963         break;
   2964 
   2965       case 'pu-space-2':
   2966         res = "\\mkern3mu ";
   2967         break;
   2968 
   2969       case '1000 separator':
   2970         res = "\\mkern2mu ";
   2971         break;
   2972 
   2973       case 'commaDecimal':
   2974         res = "{,}";
   2975         break;
   2976 
   2977       case 'comma enumeration L':
   2978         res = "{" + buf.p1 + "}\\mkern6mu ";
   2979         break;
   2980 
   2981       case 'comma enumeration M':
   2982         res = "{" + buf.p1 + "}\\mkern3mu ";
   2983         break;
   2984 
   2985       case 'comma enumeration S':
   2986         res = "{" + buf.p1 + "}\\mkern1mu ";
   2987         break;
   2988 
   2989       case 'hyphen':
   2990         res = "\\text{-}";
   2991         break;
   2992 
   2993       case 'addition compound':
   2994         res = "\\,{\\cdot}\\,";
   2995         break;
   2996 
   2997       case 'electron dot':
   2998         res = "\\mkern1mu \\bullet\\mkern1mu ";
   2999         break;
   3000 
   3001       case 'KV x':
   3002         res = "{\\times}";
   3003         break;
   3004 
   3005       case 'prime':
   3006         res = "\\prime ";
   3007         break;
   3008 
   3009       case 'cdot':
   3010         res = "\\cdot ";
   3011         break;
   3012 
   3013       case 'tight cdot':
   3014         res = "\\mkern1mu{\\cdot}\\mkern1mu ";
   3015         break;
   3016 
   3017       case 'times':
   3018         res = "\\times ";
   3019         break;
   3020 
   3021       case 'circa':
   3022         res = "{\\sim}";
   3023         break;
   3024 
   3025       case '^':
   3026         res = "uparrow";
   3027         break;
   3028 
   3029       case 'v':
   3030         res = "downarrow";
   3031         break;
   3032 
   3033       case 'ellipsis':
   3034         res = "\\ldots ";
   3035         break;
   3036 
   3037       case '/':
   3038         res = "/";
   3039         break;
   3040 
   3041       case ' / ':
   3042         res = "\\,/\\,";
   3043         break;
   3044 
   3045       default:
   3046         assertNever(buf);
   3047         throw ["MhchemBugT", "mhchem bug T. Please report."];
   3048       // Missing texify rule or unknown MhchemParser output
   3049     }
   3050 
   3051     assertString(res);
   3052     return res;
   3053   },
   3054   _getArrow: function _getArrow(a) {
   3055     switch (a) {
   3056       case "->":
   3057         return "rightarrow";
   3058 
   3059       case "\u2192":
   3060         return "rightarrow";
   3061 
   3062       case "\u27F6":
   3063         return "rightarrow";
   3064 
   3065       case "<-":
   3066         return "leftarrow";
   3067 
   3068       case "<->":
   3069         return "leftrightarrow";
   3070 
   3071       case "<-->":
   3072         return "rightleftarrows";
   3073 
   3074       case "<=>":
   3075         return "rightleftharpoons";
   3076 
   3077       case "\u21CC":
   3078         return "rightleftharpoons";
   3079 
   3080       case "<=>>":
   3081         return "rightequilibrium";
   3082 
   3083       case "<<=>":
   3084         return "leftequilibrium";
   3085 
   3086       default:
   3087         assertNever(a);
   3088         throw ["MhchemBugT", "mhchem bug T. Please report."];
   3089     }
   3090   },
   3091   _getBond: function _getBond(a) {
   3092     switch (a) {
   3093       case "-":
   3094         return "{-}";
   3095 
   3096       case "1":
   3097         return "{-}";
   3098 
   3099       case "=":
   3100         return "{=}";
   3101 
   3102       case "2":
   3103         return "{=}";
   3104 
   3105       case "#":
   3106         return "{\\equiv}";
   3107 
   3108       case "3":
   3109         return "{\\equiv}";
   3110 
   3111       case "~":
   3112         return "{\\tripledash}";
   3113 
   3114       case "~-":
   3115         return "{\\mathrlap{\\raisebox{-.1em}{$-$}}\\raisebox{.1em}{$\\tripledash$}}";
   3116 
   3117       case "~=":
   3118         return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$\\tripledash$}}-}";
   3119 
   3120       case "~--":
   3121         return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$\\tripledash$}}-}";
   3122 
   3123       case "-~-":
   3124         return "{\\mathrlap{\\raisebox{-.2em}{$-$}}\\mathrlap{\\raisebox{.2em}{$-$}}\\tripledash}";
   3125 
   3126       case "...":
   3127         return "{{\\cdot}{\\cdot}{\\cdot}}";
   3128 
   3129       case "....":
   3130         return "{{\\cdot}{\\cdot}{\\cdot}{\\cdot}}";
   3131 
   3132       case "->":
   3133         return "{\\rightarrow}";
   3134 
   3135       case "<-":
   3136         return "{\\leftarrow}";
   3137 
   3138       case "<":
   3139         return "{<}";
   3140 
   3141       case ">":
   3142         return "{>}";
   3143 
   3144       default:
   3145         assertNever(a);
   3146         throw ["MhchemBugT", "mhchem bug T. Please report."];
   3147     }
   3148   },
   3149   _getOperator: function _getOperator(a) {
   3150     switch (a) {
   3151       case "+":
   3152         return " {}+{} ";
   3153 
   3154       case "-":
   3155         return " {}-{} ";
   3156 
   3157       case "=":
   3158         return " {}={} ";
   3159 
   3160       case "<":
   3161         return " {}<{} ";
   3162 
   3163       case ">":
   3164         return " {}>{} ";
   3165 
   3166       case "<<":
   3167         return " {}\\ll{} ";
   3168 
   3169       case ">>":
   3170         return " {}\\gg{} ";
   3171 
   3172       case "\\pm":
   3173         return " {}\\pm{} ";
   3174 
   3175       case "\\approx":
   3176         return " {}\\approx{} ";
   3177 
   3178       case "$\\approx$":
   3179         return " {}\\approx{} ";
   3180 
   3181       case "v":
   3182         return " \\downarrow{} ";
   3183 
   3184       case "(v)":
   3185         return " \\downarrow{} ";
   3186 
   3187       case "^":
   3188         return " \\uparrow{} ";
   3189 
   3190       case "(^)":
   3191         return " \\uparrow{} ";
   3192 
   3193       default:
   3194         assertNever(a);
   3195         throw ["MhchemBugT", "mhchem bug T. Please report."];
   3196     }
   3197   }
   3198 }; //
   3199 // Helpers for code anaylsis
   3200 // Will show type error at calling position
   3201 //
   3202 
   3203 /** @param {number} a */
   3204 
   3205 function assertNever(a) {}
   3206 /** @param {string} a */
   3207 
   3208 
   3209 function assertString(a) {}
   3210 }();
   3211 __webpack_exports__ = __webpack_exports__.default;
   3212 /******/ 	return __webpack_exports__;
   3213 /******/ })()
   3214 ;
   3215 });