for all equations?
51 | linebreaks: false, // do linebreaking?
52 | equationNumbers: "none", // or "AMS" or "all"
53 | cjkCharWidth: 13, // width of CJK character
54 |
55 | math: "", // the math to typeset
56 | format: "TeX", // the input format (TeX, inline-TeX, AsciiMath, or MathML)
57 | xmlns: "mml", // the namespace to use for MathML
58 |
59 | html: false, // return HTML output?
60 | htmlNode: false, // DOM element for HTML output?
61 | css: false, // return CSS for HTML output?
62 | mml: false, // return mml output?
63 | mmlNode: false, // DOM element for MML output?
64 | svg: false, // return svg output?
65 | svgNode: false, // DOM element for SVG output?
66 | speakText: true, // add spoken annotations
67 | timeout: 10 * 1000, // 10 second timeout before restarting MathJax
68 | };
69 |
70 | //
71 | // The MathJax server states
72 | //
73 | var STATE = {
74 | STOPPED: 1, // no DOM or MathJax available
75 | STARTED: 2, // DOM loaded, MathJax starting up
76 | READY: 3, // MathJax initialized and ready to process math
77 | BUSY: 4, // MathJax currently processing math
78 | RESTART: 5, // start() called while MathJax is starting up
79 | };
80 |
81 | //
82 | // The MathJaxPath is normaized against file:/// so that Windows paths are correct
83 | //
84 | var MathJaxPath = url.resolve("file:///","file:"+require.resolve('mathjax'));
85 | var MathJaxConfig; // configuration for when starting MathJax
86 | var MathJax; // filled in once MathJax is loaded
87 | var serverState = STATE.STOPPED; // nothing loaded yet
88 | var timer; // used to reset MathJax if it runs too long
89 |
90 | var document, window, content, html; // the DOM elements
91 |
92 | var queue = []; // queue of typesetting requests of the form [data,callback]
93 | var data, callback, originalData; // the current queue item
94 | var errors = []; // errors collected durring the typesetting
95 | var sErrors = []; // errors collected durring MathJax startup
96 | var ID = 0; // id for this SVG element
97 |
98 | //
99 | // The delimiters used for each of the input formats
100 | //
101 | var TYPES = {
102 | TeX: "tex; mode=display",
103 | "inline-TeX": "tex",
104 | AsciiMath: "asciimath",
105 | MathML: "mml"
106 | };
107 |
108 | var CHTMLSTYLES; // filled in when CommonHTML is loaded
109 |
110 | /********************************************************************/
111 |
112 | //
113 | // Create the DOM window and set up the console wtihin it
114 | // Add an error handler to trap unexpected errors (requires
115 | // modifying jsdom)
116 | // Add a where we can put the math to be typeset
117 | // and typeset math in the three formats we use (to force
118 | // the jax to be loaded completely)
119 | //
120 | function GetWindow() {
121 | var virtualConsole = new jsdom.VirtualConsole();
122 | virtualConsole.sendTo(console);
123 | window = new JSDOM('',{
124 | virtualConsole: virtualConsole,
125 | userAgent: "Node.js",
126 | runScripts: "dangerously",
127 | resources: "usable"
128 | }).window;
129 | document = window.document;
130 | html = document.firstChild;
131 | window.addEventListener("error",function (event) {AddError("Error: "+event.error.stack)});
132 | content = document.body.appendChild(document.createElement("div"));
133 | content.id = "MathJax_Content";
134 | content.innerHTML = '' +
135 | '' +
136 | '';
137 | }
138 |
139 | //
140 | // Set up a Mathjax configuration within the window
141 | //
142 | function ConfigureMathJax() {
143 | window.MathJax = {
144 | //
145 | // Load all input jax and preprocessors
146 | // Load AMS extensions and the autoload extension for TeX
147 | // Create stand-alone SVG elements with font caches by default
148 | // (users can override that)
149 | //
150 | jax: ["input/TeX", "input/MathML", "input/AsciiMath", "output/SVG", "output/CommonHTML"],
151 | extensions: ["toMathML.js"],
152 | TeX: {extensions: window.Array("AMSmath.js","AMSsymbols.js","autoload-all.js")},
153 | SVG: {useFontCache: true, useGlobalCache: false, EqnChunk: 1000000, EqnDelay: 0},
154 | CommonHTML: {EqnChunk: 1000000, EqnDelay: 0, undefinedFamily:"monospace"},
155 |
156 | //
157 | // This gets run before MathJax queues any actions
158 | //
159 | AuthorInit: function () {
160 | MathJax = window.MathJax;
161 |
162 | // Add custom paths to configuration
163 | for (let key in paths) {
164 | MathJax.Ajax.config.path[key] = paths[key];
165 | }
166 |
167 | delete MathJax.Hub.config.styles; // don't need any styles
168 | MathJax.Hub.Startup.MenuZoom = function () {}; // don't load menu or zoom code
169 | MathJax.Extension.MathEvents = {
170 | Event:{}, Touch:{}, Hover:{} // fake structure to avid errors
171 | };
172 | MathJax.Ajax.loaded[MathJax.Ajax.fileURL("[MathJax]/extensions/MathEvents.js")] = true;
173 |
174 | //
175 | // When creating stylesheets, no need to wait for them
176 | // to become active, so just do the callback
177 | //
178 | MathJax.Ajax.timer.create = function (callback,node) {
179 | callback = MathJax.Callback(callback);
180 | callback(this.STATUS.OK);
181 | return callback;
182 | };
183 |
184 | //
185 | // Use the console for messages, if we are requesting them
186 | //
187 | MathJax.Message.Set = function (text,n,delay) {
188 | if (displayMessages && n !== 0) {
189 | if (text instanceof window.Array)
190 | {text = MathJax.Localization._.apply(MathJax.Localization,text)}
191 | console.error(text);
192 | }
193 | };
194 | MathJax.Message.Clear = function () {};
195 | MathJax.Message.Remove = function () {};
196 | MathJax.Message.Init = function () {};
197 |
198 | //
199 | // Trap Math Processing Errors
200 | //
201 | MathJax.Hub.Register.MessageHook("Math Processing Error",function (message) {
202 | AddError("Math Processing Error: "+message[2].message);
203 | });
204 | MathJax.Hub.Register.MessageHook("SVG Jax - unknown char",function (message) {
205 | AddError("SVG - Unknown character: U+"+message[1].toString(16).toUpperCase()+
206 | " in "+(message[2].fonts||["unknown"]).join(","),!undefinedChar);
207 | });
208 | MathJax.Hub.Register.MessageHook("CommonHTML Jax - unknown char",function (message) {
209 | AddError("CHTML - Unknown character: U+"+message[1].toString(16).toUpperCase()+
210 | " in "+(message[2].fonts||["unknown"]).join(","),!undefinedChar);
211 | });
212 | MathJax.Hub.Register.MessageHook("MathML Jax - unknown node type",function (message) {
213 | AddError("MathML - Unknown node type: "+message[1]);
214 | });
215 | MathJax.Hub.Register.MessageHook("MathML Jax - parse error",function (message) {
216 | AddError("MathML - "+message[1]);
217 | });
218 | MathJax.Hub.Register.MessageHook("AsciiMath Jax - parse error",function (message) {
219 | AddError("AsciiMath parse error: "+message[1]);
220 | });
221 | MathJax.Hub.Register.MessageHook("TeX Jax - parse error",function (message) {
222 | AddError("TeX parse error: "+message[1]);
223 | });
224 | MathJax.Hub.Register.MessageHook("file load error",function (message) {
225 | AddError("File load error: "+message[1]);
226 | });
227 |
228 | //
229 | // Set the delays to 0 (we don't need to update the screen)
230 | //
231 | MathJax.Hub.processSectionDelay = 0;
232 | MathJax.Hub.processUpdateTime = 10000000; // don't interrupt processing of output
233 | MathJax.Hub.processUpdateDelay = 0;
234 |
235 | //
236 | // Adjust the SVG output jax
237 | //
238 | MathJax.Hub.Register.StartupHook("SVG Jax Config",function () {
239 | var SVG = MathJax.OutputJax.SVG, HTML = MathJax.HTML;
240 |
241 | //
242 | // Don't need the styles
243 | //
244 | delete SVG.config.styles
245 |
246 | SVG.Augment({
247 | //
248 | // Set up the default ex-size and width
249 | //
250 | InitializeSVG: function () {
251 | this.pxPerInch = 96;
252 | this.defaultEx = 6;
253 | this.defaultWidth = 100;
254 | },
255 | //
256 | // Adjust preTranslate() to not try to find the ex-size or
257 | // the container widths.
258 | //
259 | preTranslate: function (state) {
260 | var scripts = state.jax[this.id], i, m = scripts.length,
261 | script, prev, span, div, jax, ex, em,
262 | maxwidth = 100000, relwidth = false, cwidth,
263 | linebreak = this.config.linebreaks.automatic,
264 | width = this.config.linebreaks.width;
265 | //
266 | // Loop through the scripts
267 | //
268 | for (i = 0; i < m; i++) {
269 | script = scripts[i]; if (!script.parentNode) continue;
270 | //
271 | // Remove any existing output
272 | //
273 | prev = script.previousSibling;
274 | if (prev && String(prev.className).match(/^MathJax(_SVG)?(_Display)?( MathJax(_SVG)?_Processing)?$/))
275 | {prev.parentNode.removeChild(prev)}
276 | //
277 | // Add the span, and a div if in display mode,
278 | // then mark it as being processed
279 | //
280 | jax = script.MathJax.elementJax; if (!jax) continue;
281 | jax.SVG = {display: (jax.root.Get("display") === "block")}
282 | span = div = HTML.Element("span",{
283 | style: {"font-size": this.config.scale+"%", display:"inline-block"},
284 | className:"MathJax_SVG", id:jax.inputID+"-Frame", isMathJax:true, jaxID:this.id
285 | });
286 | if (jax.SVG.display) {
287 | div = HTML.Element("div",{className:"MathJax_SVG_Display"});
288 | div.appendChild(span);
289 | }
290 | div.className += " MathJax_SVG_Processing";
291 | script.parentNode.insertBefore(div,script);
292 | //
293 | // Set SVG data for jax
294 | //
295 | jax.SVG.ex = ex = (data||defaults).ex;
296 | jax.SVG.em = em = ex / SVG.TeX.x_height * 1000; // scale ex to x_height
297 | jax.SVG.cwidth = width / em * 1000;
298 | jax.SVG.lineWidth = (linebreak ? width / em * 1000 : SVG.BIGDIMEN);
299 | }
300 | //
301 | // Set state variables used for displaying equations in chunks
302 | //
303 | state.SVGeqn = state.SVGlast = 0; state.SVGi = -1;
304 | state.SVGchunk = this.config.EqnChunk;
305 | state.SVGdelay = false;
306 | }
307 | });
308 |
309 | //
310 | // TEXT boxes use getBBox, which isn't implemented, so
311 | // use a monspace font and fake the size. Since these
312 | // are used only for error messages and undefined characters,
313 | // this should be good enough for now.
314 | //
315 | SVG.BBOX.TEXT.Augment({
316 | Init: function (scale,text,def) {
317 | if (!def) {def = {}}; def.stroke = "none";
318 | if (def["font-style"] === "") delete def["font-style"];
319 | if (def["font-weight"] === "") delete def["font-weight"];
320 | this.SUPER(arguments).Init.call(this,def);
321 | SVG.addText(this.element,text);
322 | // tweaking font fallback behavior: https://github.com/mathjax/MathJax-node/issues/299
323 | var textWidth = text.split('')
324 | .map(function(c) { return isFullwidthCodePoint(c.codePointAt()) ? data.cjkCharWidth : 8.5 })
325 | .reduce(function(a, b) { return a + b }, 0);
326 | var bbox = {width: textWidth, height: 18, y: -12};
327 | scale *= 1000/SVG.em;
328 | this.element.setAttribute("font-family","monospace");
329 | this.element.setAttribute("transform","scale("+scale+") matrix(1 0 0 -1 0 0)");
330 | this.w = this.r = bbox.width*scale; this.l = 0;
331 | this.h = this.H = -bbox.y*scale;
332 | this.d = this.D = (bbox.height + bbox.y)*scale;
333 | }
334 | });
335 |
336 | //
337 | // Don't have mglyph load images
338 | //
339 | MathJax.Hub.Register.StartupHook("SVG mglyph Ready",function () {
340 | var MML = MathJax.ElementJax.mml;
341 | var MGLYPH = MML.mglyph;
342 | var TOSVG = MGLYPH.prototype.toSVG;
343 | MGLYPH.Augment({
344 | toSVG: function (variant,scale) {
345 | var values = this.getValues("src","width","height");
346 | if (values.src !== "" && !MGLYPH.GLYPH[values.src]) {
347 | if (!values.width || !values.height) {
348 | AddError("mglyphs must have explicit width and height in mathjax-node");
349 | }
350 | MGLYPH.GLYPH[values.src] = {
351 | img: {SRC: values.src, width: 0, height: 0},
352 | status: "OK"
353 | };
354 | }
355 | return TOSVG.apply(this,arguments);
356 | }
357 | });
358 | });
359 |
360 | });
361 |
362 | //
363 | // Adjust the CommonHTML output jax
364 | //
365 | MathJax.Hub.Register.StartupHook("CommonHTML Jax Config",function () {
366 | var CHTML = MathJax.OutputJax.CommonHTML, HTML = MathJax.HTML;
367 |
368 | //
369 | // Don't need these styles
370 | //
371 | var STYLES = CHTML.config.styles;
372 | delete STYLES["#MathJax_CHTML_Tooltip"];
373 | delete STYLES[".MJXc-processing"];
374 | delete STYLES[".MJXc-processed"];
375 | delete STYLES[".mjx-chartest"];
376 | delete STYLES[".mjx-chartest .mjx-char"];
377 | delete STYLES[".mjx-chartest .mjx-box"];
378 | delete STYLES[".mjx-test"];
379 | delete STYLES[".mjx-ex-boxtest"];
380 | // fontURL to current MathJax version
381 | if (!fontURL){
382 | fontURL = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/' + MathJax.version + '/fonts/HTML-CSS';
383 | }
384 | CHTML.Augment({
385 | webfontDir: fontURL,
386 | //
387 | // Set up the default ex-size and width
388 | //
389 | getDefaultExEm: function () {
390 | var styles = document.head.getElementsByTagName("style");
391 | CHTMLSTYLES = styles[styles.length-1].innerHTML;
392 | this.pxPerInch = 96;
393 | this.defaultEx = 6;
394 | this.defaultEm = 6 / CHTML.TEX.x_height * 1000;
395 | this.defaultWidth = 100;
396 | },
397 | //
398 | // Adjust preTranslate() to not try to find the ex-size or
399 | // the container widths.
400 | //
401 | preTranslate: function (state) {
402 | var scripts = state.jax[this.id], i, m = scripts.length,
403 | script, prev, node, jax, ex, em,
404 | maxwidth = 100000, relwidth = false, cwidth = 0,
405 | linebreak = this.config.linebreaks.automatic,
406 | width = this.config.linebreaks.width;
407 | //
408 | // Loop through the scripts
409 | //
410 | for (i = 0; i < m; i++) {
411 | script = scripts[i]; if (!script.parentNode) continue;
412 | //
413 | // Remove any existing output
414 | //
415 | prev = script.previousSibling;
416 | if (prev && prev.className && String(prev.className).substr(0,9) === "mjx-chtml")
417 | prev.parentNode.removeChild(prev);
418 | //
419 | // Add the node for the math and mark it as being processed
420 | //
421 | jax = script.MathJax.elementJax; if (!jax) continue;
422 | jax.CHTML = {display: (jax.root.Get("display") === "block")}
423 | node = CHTML.Element("mjx-chtml",{
424 | id:jax.inputID+"-Frame", isMathJax:true, jaxID:this.id
425 | });
426 | if (jax.CHTML.display) {
427 | //
428 | // Zoom box requires an outer container to get the positioning right.
429 | //
430 | var NODE = CHTML.Element("mjx-chtml",{className:"MJXc-display",isMathJax:false});
431 | NODE.appendChild(node); node = NODE;
432 | }
433 |
434 | node.className += " MJXc-processing";
435 | script.parentNode.insertBefore(node,script);
436 | //
437 | // Set CHTML data for jax
438 | //
439 | jax.CHTML.ex = ex = (data||defaults).ex;
440 | jax.CHTML.em = jax.CHTML.outerEm = em = ex / CHTML.TEX.x_height; // scale ex to x_height
441 | jax.CHTML.cwidth = width / em;
442 | jax.CHTML.lineWidth = (linebreak ? width / em : 1000000);
443 | jax.CHTML.scale = 1; jax.CHTML.fontsize = "100%";
444 | }
445 | //
446 | // Set state variables used for displaying equations in chunks
447 | //
448 | state.CHTMLeqn = state.CHTMLlast = 0; state.CHTMLi = -1;
449 | state.CHTMLchunk = this.config.EqnChunk;
450 | state.CHTMLdelay = false;
451 | },
452 |
453 | //
454 | // We are using a monospaced font, so fake the size
455 | //
456 | getHDW: function (c,name,styles) {
457 | return {h:.8, d:.2, w:c.length*.5};
458 | }
459 |
460 | });
461 |
462 | //
463 | // Don't have mglyph load images
464 | //
465 | MathJax.Hub.Register.StartupHook("CommonHTML mglyph Ready",function () {
466 | var MML = MathJax.ElementJax.mml;
467 | var MGLYPH = MML.mglyph;
468 | var TOCHTML = MGLYPH.prototype.toCommonHTML;
469 | MGLYPH.Augment({
470 | toCommonHTML: function (node,options) {
471 | var values = this.getValues("src","width","height");
472 | if (values.src !== "" && !MGLYPH.GLYPH[values.src]) {
473 | if (!values.width || !values.height) {
474 | AddError("mglyphs must have explicit width and height in mathjax-node");
475 | }
476 | MGLYPH.GLYPH[values.src] = {
477 | img: {SRC: values.src, width: 0, height: 0},
478 | status: "OK"
479 | };
480 | }
481 | return TOCHTML.apply(this,arguments);
482 | }
483 | });
484 | });
485 |
486 | });
487 |
488 | //
489 | // Set up None output jax (for when only MathML output is needed)
490 | //
491 | MathJax.Hub.Register.StartupHook("End Jax", function () {
492 | MathJax.OutputJax.None = MathJax.OutputJax({
493 | id: "None",
494 | preTranslate: function () {},
495 | Translate: function () {},
496 | postTranslate: function () {}
497 | });
498 | MathJax.OutputJax.None.loadComplete("jax.js");
499 | MathJax.OutputJax.None.Register("jax/mml");
500 | });
501 |
502 | //
503 | // Reset the color extension after `autoload-all`
504 | //
505 | if (MathJax.AuthorConfig.extensions.indexOf("TeX/color.js") == -1 && MathJax.AuthorConfig.extensions.indexOf("TeX/autoload-all.js") == -1) {
506 | MathJax.Hub.Register.StartupHook("TeX autoload-all Ready",function () {
507 | var macros = MathJax.InputJax.TeX.Definitions.macros;
508 | macros.color = "Color";
509 | delete macros.textcolor;
510 | delete macros.colorbox;
511 | delete macros.fcolorbox;
512 | delete macros.definecolor;
513 | });
514 | }
515 |
516 | //
517 | // Start the typesetting queue when MathJax is ready
518 | // (reseting the counters so that the initial math doesn't affect them)
519 | //
520 | MathJax.Hub.Register.StartupHook("End",function () {
521 | if (MathJax.OutputJax.SVG.resetGlyphs) MathJax.OutputJax.SVG.resetGlyphs(true);
522 | MathJax.ElementJax.mml.ID = 0;
523 | if (serverState === STATE.RESTART) {
524 | setTimeout(RestartMathJax, 100);
525 | } else {
526 | serverState = STATE.READY;
527 | MathJax.Hub.Queue(
528 | function () {sErrors = errors},
529 | StartQueue
530 | );
531 | }
532 | });
533 | }
534 | };
535 |
536 | if (extensions) {
537 | //
538 | // Parse added extensions list and add to standard ones
539 | //
540 | var extensionList = extensions.split(/\s*,\s*/);
541 | for (var i = 0; i < extensionList.length; i++) {
542 | var matches = extensionList[i].match(/^(.*?)(\.js)?$/);
543 | window.MathJax.extensions.push(matches[1] + '.js');
544 | }
545 | }
546 |
547 | //
548 | // Turn arrays into jsdom window arrays
549 | // (so "instanceof Array" will identify them properly)
550 | //
551 | var adjustArrays = function (obj) {
552 | for (var id in obj) {if (obj.hasOwnProperty(id)) {
553 | if (obj[id] instanceof Array) {
554 | var A = window.Array();
555 | obj[id] = A.concat.apply(A,obj[id]);
556 | } else if (typeof obj[id] === "object") {
557 | adjustArrays(obj[id]);
558 | }
559 | }}
560 | }
561 | if (MathJaxConfig) {
562 | adjustArrays(MathJaxConfig);
563 | // merge the defaults into the user configuration (to sanitize)
564 | window.MathJax = Insert(Insert({},MathJaxConfig),window.MathJax);
565 | if (MathJaxConfig.extensions) {
566 | window.MathJax.extensions = window.MathJax.extensions.concat(MathJaxConfig.extensions);
567 | }
568 | }
569 | }
570 |
571 | //
572 | // Insert one objects into another
573 | //
574 | function Insert(dst,src) {
575 | for (var id in src) {if (src.hasOwnProperty(id)) {
576 | // allow for concatenation of arrays?
577 | if (typeof src[id] === 'object' && !(src[id] instanceof Array) &&
578 | (typeof dst[id] === 'object' || typeof dst[id] === 'function'))
579 | {Insert(dst[id],src[id])} else {dst[id] = src[id]}
580 | }}
581 | return dst;
582 | }
583 |
584 | //
585 | // Load MathJax into the DOM
586 | //
587 | function StartMathJax() {
588 | serverState = STATE.STARTED;
589 | var script = document.createElement("script");
590 | script.src = MathJaxPath;
591 | script.onerror = function () {AddError("Can't load MathJax.js from "+MathJaxPath)};
592 | document.head.appendChild(script);
593 | }
594 |
595 | /********************************************************************/
596 |
597 | //
598 | // Return an error value (and report it to console)
599 | //
600 | function ReportError(message,currentCallback) {
601 | AddError(message);
602 | (currentCallback||callback)({errors: errors});
603 | }
604 |
605 | //
606 | // Add an error to the error list and display it on the console
607 | //
608 | function AddError(message,nopush) {
609 | if (displayErrors) console.error(message);
610 | if (!nopush) errors.push(message);
611 | }
612 |
613 |
614 | /********************************************************************/
615 |
616 | //
617 | // Creates the MathML output (taking MathJax resets
618 | // into account)
619 | //
620 | function GetMML(result) {
621 | if (!data.mml && !data.mmlNode) return;
622 | var jax = MathJax.Hub.getAllJax()[0];
623 | if (data.speakText && !jax.root.alttext) {
624 | jax.root.alttext = result.speakText;
625 | var attrNames = jax.root.attrNames;
626 | if (attrNames && attrNames.indexOf("alttext") === -1) {
627 | attrNames.push("alttext");
628 | }
629 | }
630 | try {
631 | var mml = jax.root.toMathML('',jax);
632 | } catch(err) {
633 | if (!err.restart) {throw err;} // an actual error
634 | return MathJax.Callback.After(window.Array(GetMML,result),err.restart);
635 | }
636 | if (data.mml) result.mml = mml;
637 | if (data.mmlNode) result.mmlNode = JSDOM.fragment(mml).firstChild;
638 | }
639 |
640 | //
641 | // Creates speech string and updates the MathML to include it, if needed
642 | //
643 | function GetSpeech(result) {
644 | if (!data.speakText) return;
645 | result.speakText = "Equation";
646 | if (data.format !== "MathML") result.speakText = data.math;
647 | else {
648 | var jax = MathJax.Hub.getAllJax()[0];
649 | if (jax.root.alttext) result.speakText = jax.root.alttext;
650 | }
651 | }
652 |
653 | //
654 | // Create HTML and CSS output, if requested
655 | //
656 | function GetHTML(result) {
657 | if (data.css) result.css = CHTMLSTYLES;
658 | if (!data.html && !data.htmlNode) return;
659 | var jax = MathJax.Hub.getAllJax()[0]; if (!jax) return;
660 | var script = jax.SourceElement(), html = script.previousSibling;
661 |
662 | // add speech text if there isn't one
663 | if (data.speakText){
664 | var labelTarget = html.querySelector('.mjx-math');
665 | for (child of labelTarget.childNodes) child.setAttribute("aria-hidden",true);
666 | if (!labelTarget.getAttribute("aria-label")){
667 | labelTarget.setAttribute("aria-label",result.speakText);
668 | }
669 | }
670 | // remove automatically generated IDs
671 | var ids = html.querySelectorAll('[id^="MJXc-Node-"]');
672 | for (var i = 0; i < ids.length; i++){
673 | ids[i].removeAttribute("id");
674 | }
675 | // remove extreneous frame element
676 | var frame = html.querySelector('[id^="MathJax-Element-"]');
677 | if (frame){
678 | // in display-mode, the frame is inside the display-style wrapper
679 | html.insertBefore(frame.firstChild, frame);
680 | html.removeChild(frame);
681 | }
682 | else{
683 | // otherwise (inline-mode) the frame is the root element
684 | html.removeAttribute("id");
685 | }
686 | if (data.html) result.html = html.outerHTML;
687 | if (data.htmlNode) result.htmlNode = html;
688 | }
689 |
690 | //
691 | // Create SVG output, if requested
692 | //
693 | function GetSVG(result) {
694 | if (!data.svg && !data.svgNode) return;
695 | var jax = MathJax.Hub.getAllJax()[0]; if (!jax) return;
696 | var script = jax.SourceElement(),
697 | svg = script.previousSibling.getElementsByTagName("svg")[0];
698 | svg.setAttribute("xmlns","http://www.w3.org/2000/svg");
699 |
700 | //
701 | // Add the speech text and mark the SVG appropriately
702 | //
703 | if (data.speakText){
704 | for (var i=0, m=svg.childNodes.length; i < m; i++)
705 | svg.childNodes[i].setAttribute("aria-hidden",true);
706 | // Note: if aria-label exists, getSpeech preserved it in speakText
707 | // remove aria-label since labelled-by title is preferred
708 | svg.removeAttribute("aria-label");
709 | ID++; var id = "MathJax-SVG-"+ID+"-Title";
710 | svg.setAttribute("aria-labelledby",id);
711 | var node = MathJax.HTML.Element("title",{id:id},[result.speakText]);
712 | svg.insertBefore(node,svg.firstChild);
713 | }
714 |
715 | if (data.svg){
716 | //
717 | // SVG data is modified to add linebreaks for readability,
718 | // and to put back the xlink namespace that is removed in HTML5
719 | //
720 | var svgdata = svg.outerHTML.replace(/><([^/])/g,">\n<$1")
721 | .replace(/(<\/[a-z]*>)(?=<\/)/g,"$1\n")
722 | .replace(/(<(?:use|image) [^>]*)(href=)/g,' $1xlink:$2');
723 |
724 | //
725 | // Add the requested data to the results
726 | //
727 | result.svg = svgdata;
728 | }
729 | if (data.svgNode) result.svgNode = svg;
730 | result.width = svg.getAttribute("width");
731 | result.height = svg.getAttribute("height");
732 | result.style = svg.style.cssText;
733 | }
734 |
735 | /********************************************************************/
736 |
737 | //
738 | // Start typesetting the queued expressions
739 | //
740 | function StartQueue() {
741 | data = callback = originalData = null; // clear existing equation, if any
742 | errors = sErrors; sErrors = []; // clear any errors
743 | if (!queue.length) return; // return if nothing to do
744 |
745 | serverState = STATE.BUSY;
746 | var result = {}, $$ = window.Array;
747 |
748 | //
749 | // Get the math data and callback
750 | // and set the content with the proper script type
751 | //
752 | var item = queue.shift();
753 | data = item[0]; callback = item[1]; originalData = item[2];
754 | content.innerHTML = "";
755 | MathJax.HTML.addElement(content,"script",{type: "math/"+TYPES[data.format]},[data.math]);
756 | html.setAttribute("xmlns:"+data.xmlns,"http://www.w3.org/1998/Math/MathML");
757 |
758 | //
759 | // Set the SVG and TeX parameters
760 | // according to the requested data
761 | //
762 | var CHTML = MathJax.OutputJax.CommonHTML,
763 | SVG = MathJax.OutputJax.SVG,
764 | TEX = MathJax.InputJax.TeX,
765 | HUB = MathJax.Hub;
766 |
767 | SVG.defaultEx = CHTML.defaultEx = data.ex;
768 | SVG.defaultWidth = CHTMLdefaultWidth = data.width * data.ex;
769 | SVG.config.linebreaks.automatic = CHTML.config.linebreaks.automatic = data.linebreaks;
770 | SVG.config.linebreaks.width = CHTML.config.linebreaks.width = data.width * data.ex;
771 | SVG.config.useFontCache = data.useFontCache;
772 | SVG.config.useGlobalCache = data.useGlobalCache;
773 | TEX.config.equationNumbers.autoNumber = data.equationNumbers;
774 |
775 | //
776 | // Set the state from data.state or clear it
777 | //
778 | GetState(data.state);
779 |
780 | //
781 | // Get the renderer to use
782 | //
783 | var renderer = (
784 | (data.html || data.htmlNode || data.css) ? "CommonHTML" :
785 | (data.svg || data.svgNode) ? "SVG" : "None"
786 | );
787 |
788 | //
789 | // Set up a timeout timer to restart MathJax if it runs too long,
790 | // Then push the Typeset call, the MathML, speech, and SVG calls,
791 | // and our TypesetDone routine
792 | //
793 | timer = setTimeout(RestartMathJax,data.timeout);
794 | HUB.Queue(
795 | $$(SetRenderer,renderer),
796 | $$("Process",HUB),
797 | $$(TypesetDone,result),
798 | $$(GetSpeech,result),
799 | $$(GetMML,result),
800 | $$(GetHTML,result),
801 | $$(RerenderSVG,result),
802 | $$(GetSVG,result),
803 | $$(ReturnResult,result)
804 | );
805 | }
806 |
807 | //
808 | // Update the MathJax values from the state,
809 | // or clear them if there is no state.
810 | //
811 | function GetState(state) {
812 | var SVG = MathJax.OutputJax.SVG,
813 | TEX = MathJax.InputJax.TeX,
814 | MML = MathJax.ElementJax.mml,
815 | AMS = MathJax.Extension["TeX/AMSmath"],
816 | HUB = MathJax.Hub, HTML = MathJax.HTML,
817 | GLYPH = (SVG.BBOX||{}).GLYPH;
818 |
819 | if (state && state.AMS) {
820 | AMS.startNumber = state.AMS.startNumber;
821 | AMS.labels = state.AMS.labels;
822 | AMS.IDs = state.AMS.IDs;
823 | MML.SUPER.ID = state.mmlID;
824 | GLYPH.glyphs = state.glyphs;
825 | GLYPH.defs = state.defs;
826 | GLYPH.n = state.n;
827 | ID = state.ID;
828 | } else {
829 | if (state) {state.AMS = {}}
830 | if (SVG.resetGlyphs) SVG.resetGlyphs(true);
831 | if (data.useGlobalCache) {
832 | state.glyphs = {};
833 | state.defs = HTML.Element("defs");
834 | state.n = 0;
835 | }
836 | if (TEX.resetEquationNumbers) TEX.resetEquationNumbers();
837 | MML.SUPER.ID = ID = 0;
838 | MathJax.OutputJax.CommonHTML.ID = 0;
839 | }
840 | }
841 |
842 | //
843 | // When the expression is typeset,
844 | // clear the timeout timer, if any,
845 | // and update the MathJax state,
846 | //
847 | function TypesetDone(result) {
848 | if (timer) {clearTimeout(timer); timer = null}
849 | html.removeAttribute("xmlns:"+data.xmlns);
850 | }
851 |
852 | //
853 | // Return the result object, and
854 | // do the next queued expression
855 | //
856 | function ReturnResult(result) {
857 | if (errors.length) {
858 | result.errors = errors;
859 | }
860 | var state = data.state;
861 | if (state) {
862 | var AMS = MathJax.Extension["TeX/AMSmath"];
863 | var GLYPH = (MathJax.OutputJax.SVG||{}).BBOX.GLYPH;
864 | state.AMS.startNumber = AMS.startNumber;
865 | state.AMS.labels = AMS.labels;
866 | state.AMS.IDs = AMS.IDs;
867 | state.mmlID = MathJax.ElementJax.mml.SUPER.ID;
868 | state.glyphs = GLYPH.glyphs;
869 | state.defs = GLYPH.defs;
870 | state.n = GLYPH.n;
871 | state.ID = ID;
872 | }
873 | serverState = STATE.READY;
874 | callback(result, originalData);
875 | if (serverState === STATE.READY) StartQueue();
876 | }
877 |
878 | //
879 | // Set the MathJax renderer
880 | //
881 | function SetRenderer(renderer) {
882 | return MathJax.Hub.setRenderer(renderer);
883 | }
884 |
885 | function RerenderSVG(result) {
886 | if ((data.html || data.htmlNode || data.css) && (data.svg || data.svgNode)) {
887 | timer = setTimeout(RestartMathJax,data.timeout);
888 | var queue = MathJax.Callback.Queue(), $$ = window.Array;
889 | return queue.Push(
890 | $$(SetRenderer,"SVG"),
891 | $$("Rerender",MathJax.Hub),
892 | $$(TypesetDone,result)
893 | );
894 | }
895 | }
896 |
897 |
898 | /********************************************************************/
899 |
900 | //
901 | // If MathJax times out, discard the DOM
902 | // and load a new one (get a fresh MathJax)
903 | //
904 | function RestartMathJax() {
905 | if (timer) {
906 | MathJax.Hub.queue.queue = []; // clear MathJax queue, so pending operations won't fire
907 | MathJax = timer = window = document = html = content = null;
908 | ReportError("Timeout waiting for MathJax: restarting");
909 | }
910 | serverState = STATE.STOPPED;
911 | GetWindow();
912 | ConfigureMathJax();
913 | StartMathJax();
914 | }
915 |
916 | /********************************************************************/
917 |
918 | //
919 | // The API call to typeset an equation
920 | //
921 | // %%% cache results?
922 | // %%% check types and values of parameters
923 | //
924 |
925 | // callback API for compatibility with MathJax
926 | var cbTypeset = function (data, callback) {
927 | if (!callback || typeof(callback) !== "function") {
928 | if (displayErrors) console.error("Missing callback");
929 | return;
930 | }
931 | var options = {};
932 | for (var id in defaults) {if (defaults.hasOwnProperty(id)) {
933 | options[id] = (data.hasOwnProperty(id) ? data[id]: defaults[id]);
934 | }}
935 | if (data.state) {options.state = data.state}
936 | if (!TYPES[options.format]) {ReportError("Unknown format: "+options.format,callback); return}
937 | queue.push([options,callback,Object.assign({},data)]);
938 | if (serverState == STATE.STOPPED) {RestartMathJax()}
939 | if (serverState == STATE.READY) StartQueue();
940 | }
941 |
942 | // main API, callback and promise compatible
943 | exports.typeset = function (data, callback) {
944 | if (callback) cbTypeset(data, callback);
945 | else return new Promise(function (resolve, reject) {
946 | cbTypeset(data, function (output, input) {
947 | if (output.errors) reject(output.errors);
948 | else resolve(output, input);
949 | });
950 | });
951 | };
952 |
953 | //
954 | // Manually start MathJax (this is done automatically
955 | // when the first typeset() call is made), but delay
956 | // restart if we are already starting up (prevents
957 | // multiple calls to start() from causing confusion).
958 | //
959 | exports.start = function () {
960 | if (serverState === STATE.STARTED) {
961 | serverState = STATE.RESTART;
962 | } else if (serverState !== STATE.ABORT) {
963 | RestartMathJax();
964 | }
965 | }
966 |
967 | //
968 | // Configure MathJax and the API
969 | // You can pass additional configuration options to MathJax using the
970 | // MathJax property, and can set displayErrors and displayMessages
971 | // that control the display of error messages, and extensions to add
972 | // additional MathJax extensions to the base or to sub-categories.
973 | //
974 | // E.g.
975 | // mjAPI.config({
976 | // MathJax: {SVG: {font: "STIX-Web"}},
977 | // displayErrors: false,
978 | // extensions: 'Safe,TeX/noUndefined'
979 | // });
980 | //
981 | exports.config = function (config) {
982 | if (config.displayMessages != null) {displayMessages = config.displayMessages}
983 | if (config.displayErrors != null) {displayErrors = config.displayErrors}
984 | if (config.undefinedCharError != null) {undefinedChar = config.undefinedCharError}
985 | if (config.extensions != null) {extensions = config.extensions}
986 | if (config.paths != null) {paths = config.paths}
987 | if (config.fontURL != null) {fontURL = config.fontURL}
988 | if (config.MathJax) {
989 | // strip MathJax config blocks to avoid errors
990 | if (config.MathJax.config) delete config.MathJax.config
991 | MathJaxConfig = config.MathJax
992 | }
993 | }
994 |
--------------------------------------------------------------------------------
/lib/patch/jsdom.js:
--------------------------------------------------------------------------------
1 | //
2 | // We need to load cssstyle's parsers.js, but its location differs
3 | // between node 4 and node 5, so check which one we have.
4 | //
5 |
6 | var PARSERS = 'cssstyle/lib/parsers.js';
7 |
8 | //
9 | // Patch for CSSStyleDeclaration lengthRegEx so that it includes ex units
10 | // (plus a number of other units that are left out)
11 | //
12 | var FixValueType = function () {
13 | var parsers = require(PARSERS);
14 |
15 | var integerRegEx = /^[\-+]?[0-9]+$/;
16 | var numberRegEx = /^[\-+]?[0-9]*\.[0-9]+$/;
17 | var lengthRegEx = /^(0|[\-+]?[0-9]*\.?[0-9]+(in|cm|mm|pt|pc|px|em|ex|ch|rem|vh|vw|vmin|vmax))$/;
18 | var percentRegEx = /^[\-+]?[0-9]*\.?[0-9]+%$/;
19 | var urlRegEx = /^url\(\s*([^\)]*)\s*\)$/;
20 | var stringRegEx = /^(\"[^\"]*\"|\'[^\']*\')$/;
21 | var colorRegEx1 = /^#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])?$/;
22 | var colorRegEx2 = /^rgb\(([^\)]*)\)$/;
23 | var colorRegEx3 = /^rgba\(([^\)]*)\)$/;
24 | var angleRegEx = /^([\-+]?[0-9]*\.?[0-9]+)(deg|grad|rad)$/;
25 |
26 | parsers.valueType = function valueType(val) {
27 | var TYPES = parsers.TYPES;
28 | if (val === '' || val === null) return TYPES.NULL_OR_EMPTY_STR;
29 | if (typeof val === 'number') val = val.toString();
30 | if (typeof val !== 'string') return undefined;
31 |
32 | if (integerRegEx.test(val)) return TYPES.INTEGER;
33 | if (numberRegEx.test(val)) return TYPES.NUMBER;
34 | if (lengthRegEx.test(val)) return TYPES.LENGTH;
35 | if (percentRegEx.test(val)) return TYPES.PERCENT;
36 | if (urlRegEx.test(val)) return TYPES.URL;
37 | if (stringRegEx.test(val)) return TYPES.STRING;
38 | if (angleRegEx.test(val)) return TYPES.ANGLE;
39 | if (colorRegEx1.test(val)) return TYPES.COLOR;
40 | var res = colorRegEx2.exec(val);
41 | var parts;
42 | if (res !== null) {
43 | parts = res[1].split(/\s*,\s*/);
44 | if (parts.length !== 3) return undefined;
45 | if (parts.every(percentRegEx.test.bind(percentRegEx)) ||
46 | parts.every(integerRegEx.test.bind(integerRegEx))) return TYPES.COLOR;
47 | return undefined;
48 | }
49 | res = colorRegEx3.exec(val);
50 | if (res !== null) {
51 | parts = res[1].split(/\s*,\s*/);
52 | if (parts.length !== 4) return undefined;
53 | if (parts.slice(0, 3).every(percentRegEx.test.bind(percentRegEx)) ||
54 | parts.every(integerRegEx.test.bind(integerRegEx))) {
55 | if (numberRegEx.test(parts[3])) return TYPES.COLOR;
56 | }
57 | return undefined;
58 | }
59 | val = val.toLowerCase();
60 | switch (val) {
61 | case 'maroon':
62 | case 'red':
63 | case 'orange':
64 | case 'yellow':
65 | case 'olive':
66 | case 'purple':
67 | case 'fuchsia':
68 | case 'white':
69 | case 'lime':
70 | case 'green':
71 | case 'navy':
72 | case 'blue':
73 | case 'aqua':
74 | case 'teal':
75 | case 'black':
76 | case 'silver':
77 | case 'gray':
78 | // the following are deprecated in CSS3
79 | case 'activeborder':
80 | case 'activecaption':
81 | case 'appworkspace':
82 | case 'background':
83 | case 'buttonface':
84 | case 'buttonhighlight':
85 | case 'buttonshadow':
86 | case 'buttontext':
87 | case 'captiontext':
88 | case 'graytext':
89 | case 'highlight':
90 | case 'highlighttext':
91 | case 'inactiveborder':
92 | case 'inactivecaption':
93 | case 'inactivecaptiontext':
94 | case 'infobackground':
95 | case 'infotext':
96 | case 'menu':
97 | case 'menutext':
98 | case 'scrollbar':
99 | case 'threeddarkshadow':
100 | case 'threedface':
101 | case 'threedhighlight':
102 | case 'threedlightshadow':
103 | case 'threedshadow':
104 | case 'window':
105 | case 'windowframe':
106 | case 'windowtext':
107 | return TYPES.COLOR;
108 | default:
109 | return TYPES.KEYWORD;
110 | }
111 | };
112 | }
113 |
114 |
115 | //
116 | // Patch jsdom functions
117 | //
118 | exports.patch = function (JSDOM) {
119 | var window = new JSDOM('').window;
120 | var document = window.document;
121 |
122 | var div = document.createElement("div");
123 |
124 | //
125 | // Check if units of ex are allowed
126 | //
127 | div.style.marginTop = "3ex";
128 | if (div.style.marginTop !== "3ex") FixValueType();
129 | }
130 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mathjax-node",
3 | "version": "2.1.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "abab": {
8 | "version": "2.0.0",
9 | "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz",
10 | "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w=="
11 | },
12 | "acorn": {
13 | "version": "5.7.4",
14 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
15 | "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg=="
16 | },
17 | "acorn-globals": {
18 | "version": "4.3.0",
19 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz",
20 | "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==",
21 | "requires": {
22 | "acorn": "^6.0.1",
23 | "acorn-walk": "^6.0.1"
24 | },
25 | "dependencies": {
26 | "acorn": {
27 | "version": "6.4.1",
28 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
29 | "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA=="
30 | }
31 | }
32 | },
33 | "acorn-walk": {
34 | "version": "6.1.1",
35 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz",
36 | "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw=="
37 | },
38 | "ajv": {
39 | "version": "6.12.6",
40 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
41 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
42 | "requires": {
43 | "fast-deep-equal": "^3.1.1",
44 | "fast-json-stable-stringify": "^2.0.0",
45 | "json-schema-traverse": "^0.4.1",
46 | "uri-js": "^4.2.2"
47 | },
48 | "dependencies": {
49 | "fast-deep-equal": {
50 | "version": "3.1.3",
51 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
52 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
53 | }
54 | }
55 | },
56 | "array-equal": {
57 | "version": "1.0.0",
58 | "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
59 | "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM="
60 | },
61 | "asn1": {
62 | "version": "0.2.4",
63 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
64 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
65 | "requires": {
66 | "safer-buffer": "~2.1.0"
67 | }
68 | },
69 | "assert-plus": {
70 | "version": "1.0.0",
71 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
72 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
73 | },
74 | "async-limiter": {
75 | "version": "1.0.0",
76 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
77 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
78 | },
79 | "asynckit": {
80 | "version": "0.4.0",
81 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
82 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
83 | },
84 | "aws-sign2": {
85 | "version": "0.7.0",
86 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
87 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
88 | },
89 | "aws4": {
90 | "version": "1.8.0",
91 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
92 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
93 | },
94 | "balanced-match": {
95 | "version": "1.0.0",
96 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
97 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
98 | "dev": true
99 | },
100 | "bcrypt-pbkdf": {
101 | "version": "1.0.2",
102 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
103 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
104 | "requires": {
105 | "tweetnacl": "^0.14.3"
106 | }
107 | },
108 | "brace-expansion": {
109 | "version": "1.1.11",
110 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
111 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
112 | "dev": true,
113 | "requires": {
114 | "balanced-match": "^1.0.0",
115 | "concat-map": "0.0.1"
116 | }
117 | },
118 | "browser-process-hrtime": {
119 | "version": "0.1.3",
120 | "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz",
121 | "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw=="
122 | },
123 | "caseless": {
124 | "version": "0.12.0",
125 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
126 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
127 | },
128 | "combined-stream": {
129 | "version": "1.0.7",
130 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
131 | "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
132 | "requires": {
133 | "delayed-stream": "~1.0.0"
134 | }
135 | },
136 | "concat-map": {
137 | "version": "0.0.1",
138 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
139 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
140 | "dev": true
141 | },
142 | "core-util-is": {
143 | "version": "1.0.2",
144 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
145 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
146 | },
147 | "cssom": {
148 | "version": "0.3.6",
149 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz",
150 | "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A=="
151 | },
152 | "cssstyle": {
153 | "version": "1.2.1",
154 | "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.1.tgz",
155 | "integrity": "sha512-7DYm8qe+gPx/h77QlCyFmX80+fGaE/6A/Ekl0zaszYOubvySO2saYFdQ78P29D0UsULxFKCetDGNaNRUdSF+2A==",
156 | "requires": {
157 | "cssom": "0.3.x"
158 | }
159 | },
160 | "dashdash": {
161 | "version": "1.14.1",
162 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
163 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
164 | "requires": {
165 | "assert-plus": "^1.0.0"
166 | }
167 | },
168 | "data-urls": {
169 | "version": "1.1.0",
170 | "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
171 | "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
172 | "requires": {
173 | "abab": "^2.0.0",
174 | "whatwg-mimetype": "^2.2.0",
175 | "whatwg-url": "^7.0.0"
176 | },
177 | "dependencies": {
178 | "whatwg-url": {
179 | "version": "7.0.0",
180 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz",
181 | "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==",
182 | "requires": {
183 | "lodash.sortby": "^4.7.0",
184 | "tr46": "^1.0.1",
185 | "webidl-conversions": "^4.0.2"
186 | }
187 | }
188 | }
189 | },
190 | "deep-equal": {
191 | "version": "1.0.1",
192 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
193 | "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
194 | "dev": true
195 | },
196 | "deep-is": {
197 | "version": "0.1.3",
198 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
199 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
200 | },
201 | "define-properties": {
202 | "version": "1.1.3",
203 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
204 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
205 | "dev": true,
206 | "requires": {
207 | "object-keys": "^1.0.12"
208 | }
209 | },
210 | "defined": {
211 | "version": "1.0.0",
212 | "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
213 | "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
214 | "dev": true
215 | },
216 | "delayed-stream": {
217 | "version": "1.0.0",
218 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
219 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
220 | },
221 | "domexception": {
222 | "version": "1.0.1",
223 | "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
224 | "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
225 | "requires": {
226 | "webidl-conversions": "^4.0.2"
227 | }
228 | },
229 | "ecc-jsbn": {
230 | "version": "0.1.2",
231 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
232 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
233 | "requires": {
234 | "jsbn": "~0.1.0",
235 | "safer-buffer": "^2.1.0"
236 | }
237 | },
238 | "es-abstract": {
239 | "version": "1.13.0",
240 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
241 | "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
242 | "dev": true,
243 | "requires": {
244 | "es-to-primitive": "^1.2.0",
245 | "function-bind": "^1.1.1",
246 | "has": "^1.0.3",
247 | "is-callable": "^1.1.4",
248 | "is-regex": "^1.0.4",
249 | "object-keys": "^1.0.12"
250 | }
251 | },
252 | "es-to-primitive": {
253 | "version": "1.2.0",
254 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
255 | "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
256 | "dev": true,
257 | "requires": {
258 | "is-callable": "^1.1.4",
259 | "is-date-object": "^1.0.1",
260 | "is-symbol": "^1.0.2"
261 | }
262 | },
263 | "escodegen": {
264 | "version": "1.11.1",
265 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz",
266 | "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==",
267 | "requires": {
268 | "esprima": "^3.1.3",
269 | "estraverse": "^4.2.0",
270 | "esutils": "^2.0.2",
271 | "optionator": "^0.8.1",
272 | "source-map": "~0.6.1"
273 | }
274 | },
275 | "esprima": {
276 | "version": "3.1.3",
277 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
278 | "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
279 | },
280 | "estraverse": {
281 | "version": "4.2.0",
282 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
283 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
284 | },
285 | "esutils": {
286 | "version": "2.0.2",
287 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
288 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
289 | },
290 | "extend": {
291 | "version": "3.0.2",
292 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
293 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
294 | },
295 | "extsprintf": {
296 | "version": "1.3.0",
297 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
298 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
299 | },
300 | "fast-json-stable-stringify": {
301 | "version": "2.0.0",
302 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
303 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
304 | },
305 | "fast-levenshtein": {
306 | "version": "2.0.6",
307 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
308 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
309 | },
310 | "for-each": {
311 | "version": "0.3.3",
312 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
313 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
314 | "dev": true,
315 | "requires": {
316 | "is-callable": "^1.1.3"
317 | }
318 | },
319 | "forever-agent": {
320 | "version": "0.6.1",
321 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
322 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
323 | },
324 | "form-data": {
325 | "version": "2.3.3",
326 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
327 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
328 | "requires": {
329 | "asynckit": "^0.4.0",
330 | "combined-stream": "^1.0.6",
331 | "mime-types": "^2.1.12"
332 | }
333 | },
334 | "fs.realpath": {
335 | "version": "1.0.0",
336 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
337 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
338 | "dev": true
339 | },
340 | "function-bind": {
341 | "version": "1.1.1",
342 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
343 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
344 | "dev": true
345 | },
346 | "getpass": {
347 | "version": "0.1.7",
348 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
349 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
350 | "requires": {
351 | "assert-plus": "^1.0.0"
352 | }
353 | },
354 | "glob": {
355 | "version": "7.1.3",
356 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
357 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
358 | "dev": true,
359 | "requires": {
360 | "fs.realpath": "^1.0.0",
361 | "inflight": "^1.0.4",
362 | "inherits": "2",
363 | "minimatch": "^3.0.4",
364 | "once": "^1.3.0",
365 | "path-is-absolute": "^1.0.0"
366 | }
367 | },
368 | "har-schema": {
369 | "version": "2.0.0",
370 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
371 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
372 | },
373 | "har-validator": {
374 | "version": "5.1.3",
375 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
376 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
377 | "requires": {
378 | "ajv": "^6.5.5",
379 | "har-schema": "^2.0.0"
380 | }
381 | },
382 | "has": {
383 | "version": "1.0.3",
384 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
385 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
386 | "dev": true,
387 | "requires": {
388 | "function-bind": "^1.1.1"
389 | }
390 | },
391 | "has-symbols": {
392 | "version": "1.0.0",
393 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
394 | "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
395 | "dev": true
396 | },
397 | "html-encoding-sniffer": {
398 | "version": "1.0.2",
399 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
400 | "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
401 | "requires": {
402 | "whatwg-encoding": "^1.0.1"
403 | }
404 | },
405 | "http-signature": {
406 | "version": "1.2.0",
407 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
408 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
409 | "requires": {
410 | "assert-plus": "^1.0.0",
411 | "jsprim": "^1.2.2",
412 | "sshpk": "^1.7.0"
413 | }
414 | },
415 | "iconv-lite": {
416 | "version": "0.4.24",
417 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
418 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
419 | "requires": {
420 | "safer-buffer": ">= 2.1.2 < 3"
421 | }
422 | },
423 | "inflight": {
424 | "version": "1.0.6",
425 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
426 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
427 | "dev": true,
428 | "requires": {
429 | "once": "^1.3.0",
430 | "wrappy": "1"
431 | }
432 | },
433 | "inherits": {
434 | "version": "2.0.3",
435 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
436 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
437 | "dev": true
438 | },
439 | "is-callable": {
440 | "version": "1.1.4",
441 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
442 | "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
443 | "dev": true
444 | },
445 | "is-date-object": {
446 | "version": "1.0.1",
447 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
448 | "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
449 | "dev": true
450 | },
451 | "is-fullwidth-code-point": {
452 | "version": "2.0.0",
453 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
454 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
455 | },
456 | "is-regex": {
457 | "version": "1.0.4",
458 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
459 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
460 | "dev": true,
461 | "requires": {
462 | "has": "^1.0.1"
463 | }
464 | },
465 | "is-symbol": {
466 | "version": "1.0.2",
467 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
468 | "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
469 | "dev": true,
470 | "requires": {
471 | "has-symbols": "^1.0.0"
472 | }
473 | },
474 | "is-typedarray": {
475 | "version": "1.0.0",
476 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
477 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
478 | },
479 | "isstream": {
480 | "version": "0.1.2",
481 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
482 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
483 | },
484 | "jsbn": {
485 | "version": "0.1.1",
486 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
487 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
488 | },
489 | "jsdom": {
490 | "version": "11.12.0",
491 | "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz",
492 | "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==",
493 | "requires": {
494 | "abab": "^2.0.0",
495 | "acorn": "^5.5.3",
496 | "acorn-globals": "^4.1.0",
497 | "array-equal": "^1.0.0",
498 | "cssom": ">= 0.3.2 < 0.4.0",
499 | "cssstyle": "^1.0.0",
500 | "data-urls": "^1.0.0",
501 | "domexception": "^1.0.1",
502 | "escodegen": "^1.9.1",
503 | "html-encoding-sniffer": "^1.0.2",
504 | "left-pad": "^1.3.0",
505 | "nwsapi": "^2.0.7",
506 | "parse5": "4.0.0",
507 | "pn": "^1.1.0",
508 | "request": "^2.87.0",
509 | "request-promise-native": "^1.0.5",
510 | "sax": "^1.2.4",
511 | "symbol-tree": "^3.2.2",
512 | "tough-cookie": "^2.3.4",
513 | "w3c-hr-time": "^1.0.1",
514 | "webidl-conversions": "^4.0.2",
515 | "whatwg-encoding": "^1.0.3",
516 | "whatwg-mimetype": "^2.1.0",
517 | "whatwg-url": "^6.4.1",
518 | "ws": "^5.2.0",
519 | "xml-name-validator": "^3.0.0"
520 | }
521 | },
522 | "json-schema": {
523 | "version": "0.2.3",
524 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
525 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
526 | },
527 | "json-schema-traverse": {
528 | "version": "0.4.1",
529 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
530 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
531 | },
532 | "json-stringify-safe": {
533 | "version": "5.0.1",
534 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
535 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
536 | },
537 | "jsprim": {
538 | "version": "1.4.1",
539 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
540 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
541 | "requires": {
542 | "assert-plus": "1.0.0",
543 | "extsprintf": "1.3.0",
544 | "json-schema": "0.2.3",
545 | "verror": "1.10.0"
546 | }
547 | },
548 | "left-pad": {
549 | "version": "1.3.0",
550 | "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
551 | "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA=="
552 | },
553 | "levn": {
554 | "version": "0.3.0",
555 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
556 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
557 | "requires": {
558 | "prelude-ls": "~1.1.2",
559 | "type-check": "~0.3.2"
560 | }
561 | },
562 | "lodash": {
563 | "version": "4.17.21",
564 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
565 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
566 | },
567 | "lodash.sortby": {
568 | "version": "4.7.0",
569 | "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
570 | "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
571 | },
572 | "mathjax": {
573 | "version": "2.7.5",
574 | "resolved": "https://registry.npmjs.org/mathjax/-/mathjax-2.7.5.tgz",
575 | "integrity": "sha512-OzsJNitEHAJB3y4IIlPCAvS0yoXwYjlo2Y4kmm9KQzyIBZt2d8yKRalby3uTRNN4fZQiGL2iMXjpdP1u2Rq2DQ=="
576 | },
577 | "mime-db": {
578 | "version": "1.38.0",
579 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
580 | "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg=="
581 | },
582 | "mime-types": {
583 | "version": "2.1.22",
584 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
585 | "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
586 | "requires": {
587 | "mime-db": "~1.38.0"
588 | }
589 | },
590 | "minimatch": {
591 | "version": "3.0.4",
592 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
593 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
594 | "dev": true,
595 | "requires": {
596 | "brace-expansion": "^1.1.7"
597 | }
598 | },
599 | "minimist": {
600 | "version": "1.2.6",
601 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
602 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
603 | "dev": true
604 | },
605 | "nwsapi": {
606 | "version": "2.1.1",
607 | "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.1.tgz",
608 | "integrity": "sha512-T5GaA1J/d34AC8mkrFD2O0DR17kwJ702ZOtJOsS8RpbsQZVOC2/xYFb1i/cw+xdM54JIlMuojjDOYct8GIWtwg=="
609 | },
610 | "oauth-sign": {
611 | "version": "0.9.0",
612 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
613 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
614 | },
615 | "object-inspect": {
616 | "version": "1.6.0",
617 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
618 | "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==",
619 | "dev": true
620 | },
621 | "object-keys": {
622 | "version": "1.1.0",
623 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz",
624 | "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==",
625 | "dev": true
626 | },
627 | "once": {
628 | "version": "1.4.0",
629 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
630 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
631 | "dev": true,
632 | "requires": {
633 | "wrappy": "1"
634 | }
635 | },
636 | "optionator": {
637 | "version": "0.8.2",
638 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
639 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
640 | "requires": {
641 | "deep-is": "~0.1.3",
642 | "fast-levenshtein": "~2.0.4",
643 | "levn": "~0.3.0",
644 | "prelude-ls": "~1.1.2",
645 | "type-check": "~0.3.2",
646 | "wordwrap": "~1.0.0"
647 | }
648 | },
649 | "parse5": {
650 | "version": "4.0.0",
651 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
652 | "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA=="
653 | },
654 | "path-is-absolute": {
655 | "version": "1.0.1",
656 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
657 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
658 | "dev": true
659 | },
660 | "path-parse": {
661 | "version": "1.0.7",
662 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
663 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
664 | "dev": true
665 | },
666 | "performance-now": {
667 | "version": "2.1.0",
668 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
669 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
670 | },
671 | "pn": {
672 | "version": "1.1.0",
673 | "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
674 | "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
675 | },
676 | "prelude-ls": {
677 | "version": "1.1.2",
678 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
679 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
680 | },
681 | "psl": {
682 | "version": "1.1.31",
683 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
684 | "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw=="
685 | },
686 | "punycode": {
687 | "version": "2.1.1",
688 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
689 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
690 | },
691 | "qs": {
692 | "version": "6.5.2",
693 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
694 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
695 | },
696 | "request": {
697 | "version": "2.88.0",
698 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
699 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
700 | "requires": {
701 | "aws-sign2": "~0.7.0",
702 | "aws4": "^1.8.0",
703 | "caseless": "~0.12.0",
704 | "combined-stream": "~1.0.6",
705 | "extend": "~3.0.2",
706 | "forever-agent": "~0.6.1",
707 | "form-data": "~2.3.2",
708 | "har-validator": "~5.1.0",
709 | "http-signature": "~1.2.0",
710 | "is-typedarray": "~1.0.0",
711 | "isstream": "~0.1.2",
712 | "json-stringify-safe": "~5.0.1",
713 | "mime-types": "~2.1.19",
714 | "oauth-sign": "~0.9.0",
715 | "performance-now": "^2.1.0",
716 | "qs": "~6.5.2",
717 | "safe-buffer": "^5.1.2",
718 | "tough-cookie": "~2.4.3",
719 | "tunnel-agent": "^0.6.0",
720 | "uuid": "^3.3.2"
721 | },
722 | "dependencies": {
723 | "punycode": {
724 | "version": "1.4.1",
725 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
726 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
727 | },
728 | "tough-cookie": {
729 | "version": "2.4.3",
730 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
731 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
732 | "requires": {
733 | "psl": "^1.1.24",
734 | "punycode": "^1.4.1"
735 | }
736 | }
737 | }
738 | },
739 | "request-promise-core": {
740 | "version": "1.1.2",
741 | "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
742 | "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
743 | "requires": {
744 | "lodash": "^4.17.11"
745 | }
746 | },
747 | "request-promise-native": {
748 | "version": "1.0.7",
749 | "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz",
750 | "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==",
751 | "requires": {
752 | "request-promise-core": "1.1.2",
753 | "stealthy-require": "^1.1.1",
754 | "tough-cookie": "^2.3.3"
755 | }
756 | },
757 | "resolve": {
758 | "version": "1.10.0",
759 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
760 | "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
761 | "dev": true,
762 | "requires": {
763 | "path-parse": "^1.0.6"
764 | }
765 | },
766 | "resumer": {
767 | "version": "0.0.0",
768 | "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz",
769 | "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
770 | "dev": true,
771 | "requires": {
772 | "through": "~2.3.4"
773 | }
774 | },
775 | "safe-buffer": {
776 | "version": "5.1.2",
777 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
778 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
779 | },
780 | "safer-buffer": {
781 | "version": "2.1.2",
782 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
783 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
784 | },
785 | "sax": {
786 | "version": "1.2.4",
787 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
788 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
789 | },
790 | "source-map": {
791 | "version": "0.6.1",
792 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
793 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
794 | "optional": true
795 | },
796 | "sshpk": {
797 | "version": "1.16.1",
798 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
799 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
800 | "requires": {
801 | "asn1": "~0.2.3",
802 | "assert-plus": "^1.0.0",
803 | "bcrypt-pbkdf": "^1.0.0",
804 | "dashdash": "^1.12.0",
805 | "ecc-jsbn": "~0.1.1",
806 | "getpass": "^0.1.1",
807 | "jsbn": "~0.1.0",
808 | "safer-buffer": "^2.0.2",
809 | "tweetnacl": "~0.14.0"
810 | }
811 | },
812 | "stealthy-require": {
813 | "version": "1.1.1",
814 | "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
815 | "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
816 | },
817 | "string.prototype.trim": {
818 | "version": "1.1.2",
819 | "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
820 | "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=",
821 | "dev": true,
822 | "requires": {
823 | "define-properties": "^1.1.2",
824 | "es-abstract": "^1.5.0",
825 | "function-bind": "^1.0.2"
826 | }
827 | },
828 | "symbol-tree": {
829 | "version": "3.2.2",
830 | "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
831 | "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY="
832 | },
833 | "tape": {
834 | "version": "4.10.1",
835 | "resolved": "https://registry.npmjs.org/tape/-/tape-4.10.1.tgz",
836 | "integrity": "sha512-G0DywYV1jQeY3axeYnXUOt6ktnxS9OPJh97FGR3nrua8lhWi1zPflLxcAHavZ7Jf3qUfY7cxcVIVFa4mY2IY1w==",
837 | "dev": true,
838 | "requires": {
839 | "deep-equal": "~1.0.1",
840 | "defined": "~1.0.0",
841 | "for-each": "~0.3.3",
842 | "function-bind": "~1.1.1",
843 | "glob": "~7.1.3",
844 | "has": "~1.0.3",
845 | "inherits": "~2.0.3",
846 | "minimist": "~1.2.0",
847 | "object-inspect": "~1.6.0",
848 | "resolve": "~1.10.0",
849 | "resumer": "~0.0.0",
850 | "string.prototype.trim": "~1.1.2",
851 | "through": "~2.3.8"
852 | }
853 | },
854 | "through": {
855 | "version": "2.3.8",
856 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
857 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
858 | "dev": true
859 | },
860 | "tough-cookie": {
861 | "version": "2.5.0",
862 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
863 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
864 | "requires": {
865 | "psl": "^1.1.28",
866 | "punycode": "^2.1.1"
867 | }
868 | },
869 | "tr46": {
870 | "version": "1.0.1",
871 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
872 | "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
873 | "requires": {
874 | "punycode": "^2.1.0"
875 | }
876 | },
877 | "tunnel-agent": {
878 | "version": "0.6.0",
879 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
880 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
881 | "requires": {
882 | "safe-buffer": "^5.0.1"
883 | }
884 | },
885 | "tweetnacl": {
886 | "version": "0.14.5",
887 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
888 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
889 | },
890 | "type-check": {
891 | "version": "0.3.2",
892 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
893 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
894 | "requires": {
895 | "prelude-ls": "~1.1.2"
896 | }
897 | },
898 | "uri-js": {
899 | "version": "4.2.2",
900 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
901 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
902 | "requires": {
903 | "punycode": "^2.1.0"
904 | }
905 | },
906 | "uuid": {
907 | "version": "3.3.2",
908 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
909 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
910 | },
911 | "verror": {
912 | "version": "1.10.0",
913 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
914 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
915 | "requires": {
916 | "assert-plus": "^1.0.0",
917 | "core-util-is": "1.0.2",
918 | "extsprintf": "^1.2.0"
919 | }
920 | },
921 | "w3c-hr-time": {
922 | "version": "1.0.1",
923 | "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
924 | "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
925 | "requires": {
926 | "browser-process-hrtime": "^0.1.2"
927 | }
928 | },
929 | "webidl-conversions": {
930 | "version": "4.0.2",
931 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
932 | "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
933 | },
934 | "whatwg-encoding": {
935 | "version": "1.0.5",
936 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
937 | "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
938 | "requires": {
939 | "iconv-lite": "0.4.24"
940 | }
941 | },
942 | "whatwg-mimetype": {
943 | "version": "2.3.0",
944 | "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
945 | "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g=="
946 | },
947 | "whatwg-url": {
948 | "version": "6.5.0",
949 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
950 | "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
951 | "requires": {
952 | "lodash.sortby": "^4.7.0",
953 | "tr46": "^1.0.1",
954 | "webidl-conversions": "^4.0.2"
955 | }
956 | },
957 | "wordwrap": {
958 | "version": "1.0.0",
959 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
960 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
961 | },
962 | "wrappy": {
963 | "version": "1.0.2",
964 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
965 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
966 | "dev": true
967 | },
968 | "ws": {
969 | "version": "5.2.3",
970 | "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz",
971 | "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==",
972 | "requires": {
973 | "async-limiter": "~1.0.0"
974 | }
975 | },
976 | "xml-name-validator": {
977 | "version": "3.0.0",
978 | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
979 | "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
980 | }
981 | }
982 | }
983 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mathjax-node",
3 | "version": "2.1.1",
4 | "description": "API's for calling MathJax from node.js",
5 | "keywords": [
6 | "MathJax",
7 | "math",
8 | "svg",
9 | "HTML",
10 | "MathML",
11 | "TeX",
12 | "AsciiMath"
13 | ],
14 | "maintainers": [
15 | "MathJax Consortium (http://www.mathjax.org)"
16 | ],
17 | "bugs": {
18 | "url": "http://github.com/mathjax/MathJax-node/issues"
19 | },
20 | "license": "Apache-2.0",
21 | "repository": {
22 | "type": "git",
23 | "url": "git://github.com/mathjax/MathJax-node.git"
24 | },
25 | "dependencies": {
26 | "is-fullwidth-code-point": "^2.0.0",
27 | "jsdom": "^11.0.0",
28 | "lodash": "^4.17.20",
29 | "mathjax": "^2.7.2"
30 | },
31 | "engines": {
32 | "node": ">=6.0.0"
33 | },
34 | "scripts": {
35 | "test": "tape test/*.js"
36 | },
37 | "main": "./lib/main.js",
38 | "devDependencies": {
39 | "tape": "^4.0.3"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/test/assets/test.js:
--------------------------------------------------------------------------------
1 | MathJax.Hub.Register.StartupHook("TeX Jax Ready", function () {
2 | MathJax.InputJax.TeX.Definitions.Add({
3 | macros: {
4 | test: ["Macro", "\text{This is a Test}"]
5 | }
6 | });
7 | });
8 |
9 | MathJax.Ajax.loadComplete("[test]/test.js");
10 |
--------------------------------------------------------------------------------
/test/base-config-extensions.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require('../lib/main.js');
3 |
4 | tape('Options "extension": multiple extensions', function(t) {
5 | t.plan(1);
6 | mjAPI.config({
7 | extensions: 'TeX/autoload-all.js, TeX/color.js'
8 | });
9 | mjAPI.typeset(
10 | {
11 | math: 'E = mc^2',
12 | format: 'TeX',
13 | mml: true
14 | },
15 | function(data) {
16 | t.notOk(
17 | data.errors,
18 | 'Config block with multiple extensions throws no error'
19 | );
20 | }
21 | );
22 | });
23 |
--------------------------------------------------------------------------------
/test/base-config-fonturl.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var mjVersion = require('../package-lock.json').dependencies['mathjax'].version
4 |
5 | tape('basic configuration: check fontURL', function (t) {
6 | t.plan(2);
7 |
8 | var tex = 'a';
9 |
10 | mjAPI.typeset({
11 | math: tex,
12 | format: "TeX",
13 | css: true,
14 | htmlNode: true
15 | }, function (result, data) {
16 | var mjVersion = result.htmlNode.ownerDocument.defaultView.MathJax.version;
17 | var URL = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/' + mjVersion + '/fonts/HTML-CSS';
18 | t.ok(result.css.indexOf(URL) > -1, 'Default fontURL');
19 |
20 | //
21 | // reconfigure
22 | //
23 | mjAPI.config({
24 | fontURL: 'https://example.com'
25 | });
26 | mjAPI.start();
27 |
28 | //
29 | // Next test
30 | //
31 |
32 | mjAPI.typeset({
33 | math: 'a',
34 | format: "TeX",
35 | css: true,
36 | }, function (result, data) {
37 | t.ok(result.css.indexOf('https://example.com') > -1, 'Configuring fontURL');
38 | //
39 | // reconfigure
40 | //
41 | mjAPI.config({fontURL: ''});
42 | mjAPI.start();
43 | });
44 |
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/test/base-errors-startup.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require('../lib/main.js');
3 |
4 | tape('Catch errors during startup phase', function(t) {
5 | t.plan(1);
6 | mjAPI.config({
7 | extensions: 'blargh'
8 | });
9 | mjAPI.start();
10 | mjAPI.typeset(
11 | {
12 | math: 'x',
13 | format: 'TeX',
14 | mml: true
15 | },
16 | function(data) {
17 | t.ok(
18 | data.errors,
19 | 'Error (loading non-existent extension) is caught in output'
20 | );
21 | // reset configuration
22 | mjAPI.config({
23 | extensions: ''
24 | });
25 | mjAPI.start();
26 | }
27 | );
28 | });
29 |
--------------------------------------------------------------------------------
/test/base-mathjax.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('basic test: check MathJax core', function(t) {
5 | t.plan(2);
6 |
7 | var tex = '';
8 |
9 | mjAPI.typeset({
10 | math: tex,
11 | format: "TeX",
12 | mml: true
13 | }, function(result,data) {
14 | t.ok(result.mml, 'MathJax core seems ok');
15 | t.ok(data.format, 'MathJax input preserved');
16 | });
17 |
18 | });
19 |
--------------------------------------------------------------------------------
/test/base-typeset-promise.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('basic test: check typeset promise API', function (t) {
5 | t.plan(2);
6 |
7 | mjAPI.config({displayErrors: false});
8 |
9 | var tex = '';
10 |
11 | //
12 | // promise resolved
13 | //
14 | mjAPI.typeset({
15 | math: tex,
16 | format: "TeX",
17 | mml: true
18 | }).then((result) => t.ok(result.mml, 'Typset promise resolved on success'));
19 |
20 | //
21 | // promise frejected
22 | //
23 | mjAPI.typeset({
24 | math: tex,
25 | format: "MathML",
26 | mml: true
27 | }).catch((error) => t.ok(error, 'Typeset promise rejected on error'));
28 |
29 | //
30 | // reset configuration
31 | //
32 | mjAPI.typeset({math: '', format: 'TeX', mml: true}, () => {
33 | mjAPI.config({displayErrors: true});
34 | });
35 |
36 | });
37 |
--------------------------------------------------------------------------------
/test/base-warnings.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | mjAPI.config({undefinedCharError: true});
4 |
5 | tape('basic test: check warnings', function (t) {
6 | t.plan(2);
7 |
8 | mjAPI.config({displayErrors: false});
9 |
10 | mjAPI.typeset({math:'\u5475', html:true})
11 | .catch(errors => t.ok(errors, 'CommonHTML output reports error'));
12 | mjAPI.typeset({math:'\u5475', svg:true})
13 | .catch(errors => t.ok(errors, 'SVG output reports error'));
14 |
15 | //
16 | // reset configuration
17 | //
18 | mjAPI.typeset({math: '', format: 'TeX', mml: true}, () => {
19 | mjAPI.config({displayErrors: true});
20 | });
21 |
22 | });
23 |
--------------------------------------------------------------------------------
/test/config-third-party-extensions.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | const path = require('path');
4 |
5 | tape('Configuring third party extensions', function(t) {
6 | t.plan(1);
7 |
8 | mjAPI.config( {
9 | extensions: '[test]/test.js',
10 | paths: {
11 | 'test': path.join(__dirname,'assets/')
12 | }
13 | });
14 | mjAPI.start();
15 |
16 | var tex = '\\test';
17 |
18 | mjAPI.typeset({
19 | math: tex,
20 | format: "TeX",
21 | mmlNode: true
22 | }, function(data) {
23 | t.notOk(data.errors, 'No error loading the extension');
24 | //
25 | // reset configuration
26 | //
27 | mjAPI.config({extensions: '', paths: {}});
28 | mjAPI.start();
29 | });
30 |
31 | });
32 |
--------------------------------------------------------------------------------
/test/css.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('CSS output', function(t) {
5 | t.plan(3);
6 |
7 | mjAPI.typeset({
8 | math: tex,
9 | format: "TeX",
10 | css: true
11 | }, function(data) {
12 | t.ok(data.css, 'css output while no other output');
13 | });
14 |
15 | var tex = 'x';
16 |
17 | mjAPI.typeset({
18 | math: tex,
19 | format: "TeX",
20 | css: true,
21 | svg: true
22 | }, function(data) {
23 | t.ok(data.css, 'css output created alongside SVG output');
24 | t.ok(data.svg, 'svg output is created');
25 | });
26 |
27 | });
28 |
--------------------------------------------------------------------------------
/test/issue104.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var JSDOM = require('jsdom').JSDOM;
4 |
5 | tape('the SVG width should match the default', function(t) {
6 | t.plan(1);
7 |
8 | var tex = 'a \\\\ b';
9 | var expected = '100ex';
10 |
11 | mjAPI.typeset({
12 | math: tex,
13 | format: "TeX",
14 | svg: true
15 | }, function(data) {
16 | var window = new JSDOM(data.svg).window;
17 | var document = window.document;
18 | var element = window.document.getElementsByTagName("svg")[0];
19 | var width = element.getAttribute('width');
20 | t.equal(width, expected);
21 | });
22 |
23 | });
24 |
--------------------------------------------------------------------------------
/test/issue175.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var JSDOM = require('jsdom').JSDOM;
4 |
5 | tape('color extension should be reset', function(t) {
6 | t.plan(3);
7 |
8 | mjAPI.config({displayErrors: false});
9 |
10 | var tex = '\\colorbox{green}{x}';
11 | var tex2 = '\\color{red}{x}x';
12 |
13 | mjAPI.typeset({
14 | math: tex,
15 | format: "TeX",
16 | mml: true
17 | }, function(data) {
18 | t.ok(data.errors, 'Color extension disabled');
19 | });
20 |
21 | mjAPI.typeset({
22 | math: tex2,
23 | format: "TeX",
24 | mml: true
25 | }, function(data) {
26 | var document = new JSDOM(data.mml).window.document;
27 | var mstyle = document.querySelector('mstyle');
28 | t.ok(document.querySelectorAll('mi')[0].parentNode === mstyle, 'Color macro behaves correctly (1 of 2)');
29 | t.notOk(document.querySelectorAll('mi')[1].parentNode === mstyle, 'Color macro behaves correctly (2 of 2)');
30 | mjAPI.config({displayErrors: true}); // reset configuration
31 | });
32 |
33 | });
34 |
--------------------------------------------------------------------------------
/test/issue207.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var JSDOM = require('jsdom').JSDOM;
4 |
5 | tape('Generate dummy speechText', function(t) {
6 | t.plan(9);
7 |
8 | var input1 = 'source';
9 | var input2 = '';
10 | var input3 = '';
11 | var expected1 = 'source';
12 | var expected2 = 'alttext';
13 | var expected3 = 'Equation';
14 | var desc1 = 'source';
15 | var desc2 = 'original MathML alttext';
16 | var desc3 = 'default dummy value';
17 |
18 | mjSpeechTest = function(data, expected, desc) {
19 | var document = new JSDOM(data.html).window.document;
20 | var element = document.querySelector('.mjx-math');
21 | var actual = element.getAttribute('aria-label');
22 | t.equal(actual, expected, 'HTML output contains speechText from ' + desc);
23 | document = new JSDOM(data.mml).window.document;
24 | element = document.querySelector('math');
25 | actual = element.getAttribute('alttext');
26 | t.equal(actual, expected, 'MathML output contains speechText from ' + desc);
27 | document = new JSDOM(data.svg).window.document;
28 | var svgTitle = document.querySelector('title');
29 | actual = svgTitle.innerHTML;
30 | t.equal(actual, expected, 'SVG output contains speechText from ' + desc);
31 | };
32 |
33 | //
34 | // TeX source
35 | //
36 | mjAPI.typeset({
37 | math: input1,
38 | format: "TeX",
39 | html: true,
40 | svg: true,
41 | mml: true
42 | }, function(data) {mjSpeechTest(data, expected1, desc1)});
43 |
44 | //
45 | // MathML alttext
46 | //
47 | mjAPI.typeset({
48 | math: input2,
49 | format: "MathML",
50 | html: true,
51 | svg: true,
52 | mml: true
53 | }, function(data) {mjSpeechTest(data, expected2, desc2)});
54 |
55 | //
56 | // MathML without alttext
57 | //
58 | mjAPI.typeset({
59 | math: input3,
60 | format: "MathML",
61 | html: true,
62 | svg: true,
63 | mml: true
64 | }, function(data) {mjSpeechTest(data, expected3, desc3)});
65 |
66 | });
67 |
--------------------------------------------------------------------------------
/test/issue215.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var JSDOM = require('jsdom').JSDOM;
4 |
5 | tape('HTML output should remove automatically generated IDs', function(t) {
6 | t.plan(2);
7 |
8 | var tex = 'a \\\\ b';
9 | var expected = '100ex';
10 |
11 | mjAPI.typeset({
12 | math: tex,
13 | format: "TeX",
14 | html: true
15 | }, function(data) {
16 | var document = new JSDOM(data.html).window.document;
17 | var id = document.querySelector('[id^="MJXc-Node-"]');
18 | var frame = document.querySelector('[id^="MathJax-Element-"]');
19 | t.notOk(id, 'automatic ids successfully removed');
20 | t.notOk(frame, 'MathJax-Element-[n]-frame id successfully removed');
21 | });
22 |
23 | });
24 |
--------------------------------------------------------------------------------
/test/issue219.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var JSDOM = require('jsdom').JSDOM;
4 |
5 | tape('Basic Check: pass jsdom object to output', function(t) {
6 | t.plan(3);
7 |
8 | var tex = 'x';
9 |
10 | mjAPI.typeset({
11 | math: tex,
12 | format: "TeX",
13 | html: true,
14 | htmlNode: true,
15 | svg: true,
16 | svgNode: true,
17 | mml: true,
18 | mmlNode: true
19 | }, function(data) {
20 | var window = new JSDOM().window;
21 | t.ok(data.htmlNode instanceof window.HTMLElement, 'htmlNode is an HTMLElement');
22 | t.ok(data.svgNode instanceof window.SVGElement, 'svgNode is an SVGElement');
23 | t.ok(data.mmlNode instanceof window.Element, 'mmlNode is an Element');
24 | });
25 |
26 | });
27 |
--------------------------------------------------------------------------------
/test/issue220.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var JSDOM = require('jsdom').JSDOM;
4 |
5 | tape('displayAlign:left in HTML output', function(t) {
6 | t.plan(1);
7 |
8 | mjAPI.config({MathJax: {"displayAlign": "left"}});
9 | mjAPI.start();
10 |
11 | var tex = 'x';
12 | var expected = "text-align: left;";
13 |
14 | mjAPI.typeset({
15 | math: tex,
16 | format: "TeX",
17 | html: true
18 | }, function(data) {
19 | var document = new JSDOM(data.html).window.document;
20 | var element = document.getElementsByClassName("MJXc-display")[0];
21 | var result = element.getAttribute('style');
22 | t.equal(result, expected);
23 | //
24 | // reset configuration
25 | //
26 | mjAPI.config({MathJax: {}});
27 | mjAPI.start();
28 | });
29 |
30 | });
31 |
--------------------------------------------------------------------------------
/test/issue223.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var JSDOM = require('jsdom').JSDOM;
4 |
5 | tape('displayIndent:left in HTML output', function(t) {
6 | t.plan(2);
7 |
8 | mjAPI.config({MathJax: {displayIndent: '10em'}});
9 | mjAPI.start();
10 |
11 | var first = 'x';
12 | var second = 'x \\tag{1}'
13 | expected = "10em";
14 |
15 | //
16 | // basic text
17 | //
18 | mjAPI.typeset({
19 | math: first,
20 | format: "TeX",
21 | html: true
22 | }, function(data) {
23 | var document = new JSDOM(data.html).window.document;
24 | var element = document.getElementsByClassName('MJXc-display')[0];
25 | var result = element.style.marginLeft;
26 | t.ok((result === expected), 'style includes a margin');
27 | });
28 |
29 | //
30 | // test for mlabeledtr
31 | //
32 | mjAPI.typeset({
33 | math: second,
34 | format: "TeX",
35 | html: true
36 | }, function(data) {
37 | var document = new JSDOM(data.html).window.document;
38 | var element = document.getElementsByClassName('mjx-table')[0];
39 | var result = element.style.marginLeft;
40 | t.ok((result === expected), 'style includes a margin');
41 | //
42 | // reset configuration
43 | //
44 | mjAPI.config({MathJax: {}});
45 | mjAPI.start();
46 | });
47 |
48 | });
49 |
--------------------------------------------------------------------------------
/test/issue241.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('SVG output: add xlink to href in ', function(t) {
5 | t.plan(1);
6 |
7 | var mml = '';
8 | var expected = /xlink:href/;
9 |
10 | mjAPI.typeset({
11 | math: mml,
12 | format: "MathML",
13 | svg: true
14 | }, function(data) {
15 | t.ok(data.svg.match(expected));
16 | });
17 |
18 | });
19 |
--------------------------------------------------------------------------------
/test/issue260.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require('../lib/main.js');
3 |
4 | tape('getSVG should increment state.ID', function(t) {
5 | t.plan(1);
6 |
7 | var mml = '';
8 | var state = {};
9 |
10 | mjAPI.typeset({
11 | math: mml,
12 | format: 'MathML',
13 | speakText: true,
14 | svg: true,
15 | state: state}, function(data) {});
16 | mjAPI.typeset({
17 | math: mml,
18 | format: 'MathML',
19 | speakText: true,
20 | svg: true,
21 | state: state
22 | }, function(data) {
23 | t.equal(state.ID, 2, 'state.ID incremented')
24 | });
25 |
26 | });
27 |
--------------------------------------------------------------------------------
/test/issue276.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var JSDOM = require('jsdom').JSDOM;
4 |
5 | tape('SVG output: physical units', function(t) {
6 | t.plan(1);
7 |
8 | var mml = '';
9 |
10 | mjAPI.typeset({
11 | math: mml,
12 | format: "MathML",
13 | svg: true
14 | }, function(data) {
15 | var document = new JSDOM(data.svg).window.document;
16 | var width = document.querySelector('svg').getAttribute('width');
17 | t.notEqual(width, '0', '');
18 | });
19 |
20 | });
21 |
--------------------------------------------------------------------------------
/test/issue277.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('mmlNode should not produce mml', function(t) {
5 | t.plan(1);
6 |
7 | var tex = 'x';
8 |
9 | mjAPI.typeset({
10 | math: tex,
11 | format: "TeX",
12 | mmlNode: true
13 | }, function(data) {
14 | t.ok(data.mml === undefined, 'mml not generated');
15 | });
16 |
17 | });
18 |
--------------------------------------------------------------------------------
/test/issue288.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('HTML output when requesting both SVG and HTML', function(t) {
5 | t.plan(2);
6 |
7 | var tex = 'x';
8 |
9 | mjAPI.typeset({
10 | math: tex,
11 | format: "TeX",
12 | htmlNode: true,
13 | svgNode: true
14 | }, function(data) {
15 | t.equal(data.htmlNode.className, 'mjx-chtml MJXc-display', 'htmlNode output is correct');
16 | });
17 |
18 | mjAPI.typeset({
19 | math: tex,
20 | format: "TeX",
21 | html: true,
22 | svgNode: true
23 | }, function(data) {
24 | t.ok(data.html, 'html output is present')
25 | });
26 |
27 | });
28 |
--------------------------------------------------------------------------------
/test/issue289.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('HTML output: add aria-label to correct childnode', function(t) {
5 | t.plan(1);
6 |
7 | var mml = '';
8 |
9 | mjAPI.typeset({
10 | math: mml,
11 | format: "MathML",
12 | htmlNode: true,
13 | html: true
14 | }, function(data) {
15 | t.equal(data.htmlNode.parentNode.querySelectorAll('[aria-label]').length, 1, 'Aria-label is unique');
16 | });
17 |
18 | });
19 |
--------------------------------------------------------------------------------
/test/mathjax-config-combined.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('MathJax configuration: strip config block', function (t) {
5 | t.plan(1);
6 |
7 | mjAPI.config({
8 | MathJax: {
9 | config: ["TeX-AMS_SVG.js"]
10 | }
11 | });
12 | mjAPI.start();
13 |
14 | mjAPI.typeset({
15 | math: 'E = mc^2',
16 | format: "TeX",
17 | mml: true,
18 | }, function (data) {
19 | t.ok(data, 'Config block did not cause errors');
20 | //
21 | // reset configuration
22 | //
23 | mjAPI.config({MathJax: {}});
24 | mjAPI.start();
25 | });
26 |
27 | });
28 |
--------------------------------------------------------------------------------
/test/output-html-linebreaks-manual.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('Output, HTML: linebreaks, manual', function(t) {
5 | t.plan(1);
6 |
7 | var tex = 'A \\\\ B';
8 | var expected = 'AB'
9 |
10 | mjAPI.typeset({
11 | math: tex,
12 | format: "TeX",
13 | html: true
14 | }, function(data) {
15 | t.equal(data.html, expected, 'HTML output as expected');
16 | });
17 |
18 | });
19 |
--------------------------------------------------------------------------------
/test/pass_data.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('Passing data along', function(t) {
5 | t.plan(1);
6 |
7 | var tex = 'x';
8 |
9 | mjAPI.typeset({
10 | math: tex,
11 | format: "TeX",
12 | css: true,
13 | something: 'expected',
14 | }, function(data, input) {
15 | t.equal(input.something, 'expected', 'Data was passed along to output');
16 | });
17 |
18 | });
19 |
--------------------------------------------------------------------------------
/test/svg-full-width-chars.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('the SVG output should renders full-width characters correctly', function(t) {
5 | t.plan(1);
6 |
7 | mjAPI.config({displayErrors: false});
8 |
9 | var tex = '\\text{\u62FE\u96F6}^i';
10 |
11 | mjAPI.typeset({
12 | math: tex,
13 | format: "TeX",
14 | svg: true
15 | }, function(data) {
16 | t.ok(data.width, '5.133ex', 'Width is correct');
17 | mjAPI.config({displayErrors: true}); // reset configuration
18 | });
19 |
20 | });
21 |
--------------------------------------------------------------------------------
/test/svg-metadata.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 | var jsdom = require('jsdom').jsdom;
4 |
5 | tape('the SVG output should add dimensions and styles', function(t) {
6 | t.plan(3);
7 |
8 | var tex = 'a + b';
9 |
10 | mjAPI.typeset({
11 | math: tex,
12 | format: "TeX",
13 | svg: true
14 | }, function(data) {
15 | t.ok(data.width, 'Width is present');
16 | t.ok(data.height, 'Height is present');
17 | t.ok(data.style, 'Style is present');
18 | });
19 |
20 | });
21 |
--------------------------------------------------------------------------------
/test/useFontCache.js:
--------------------------------------------------------------------------------
1 | var tape = require('tape');
2 | var mjAPI = require("../lib/main.js");
3 |
4 | tape('basic configuration: useFontCache', function (t) {
5 | t.plan(2);
6 |
7 | var tex = 'a';
8 |
9 | mjAPI.typeset({
10 | math: tex,
11 | format: "TeX",
12 | svg: true,
13 | useFontCache: false
14 | }, function (result, data) {
15 | t.ok(result.svg.indexOf('