1 /*
  2  JessieCode Interpreter and Compiler
  3 
  4     Copyright 2011-2026
  5         Michael Gerhaeuser,
  6         Alfred Wassermann
  7 
  8     JessieCode is free software dual licensed under the GNU LGPL or MIT License.
  9 
 10     You can redistribute it and/or modify it under the terms of the
 11 
 12       * GNU Lesser General Public License as published by
 13         the Free Software Foundation, either version 3 of the License, or
 14         (at your option) any later version
 15       OR
 16       * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
 17 
 18     JessieCode is distributed in the hope that it will be useful,
 19     but WITHOUT ANY WARRANTY; without even the implied warranty of
 20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 21     GNU Lesser General Public License for more details.
 22 
 23     You should have received a copy of the GNU Lesser General Public License and
 24     the MIT License along with JessieCode. If not, see <https://www.gnu.org/licenses/>
 25     and <https://opensource.org/licenses/MIT/>.
 26  */
 27 
 28 /*global JXG: true, define: true, window: true, console: true, self: true, document: true, parser: true*/
 29 /*jslint nomen: true, plusplus: true*/
 30 
 31 /**
 32  * @fileoverview JessieCode is a scripting language designed to provide a
 33  * simple scripting language to build constructions
 34  * with JSXGraph. It is similar to JavaScript, but prevents access to the DOM.
 35  * Hence, it can be used in community driven math portals which want to use
 36  * JSXGraph to display interactive math graphics.
 37  */
 38 
 39 import JXG from "../jxg.js";
 40 import Const from "../base/constants.js";
 41 import Text from "../base/text.js";
 42 import Mat from "../math/math.js";
 43 import Interval from "../math/ia.js";
 44 import Geometry from "../math/geometry.js";
 45 import Statistics from "../math/statistics.js";
 46 import Type from "../utils/type.js";
 47 import Env from "../utils/env.js";
 48 
 49 // IE 6-8 compatibility
 50 if (!Object.create) {
 51     Object.create = function (o, properties) {
 52         if (typeof o !== 'object' && typeof o !== 'function') throw new TypeError('Object prototype may only be an Object: ' + o);
 53         else if (o === null) throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
 54 
 55         if (typeof properties != 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
 56 
 57         function F() { }
 58 
 59         F.prototype = o;
 60 
 61         return new F();
 62     };
 63 }
 64 
 65 var priv = {
 66     modules: {
 67         'math': Mat,
 68         'math/geometry': Geometry,
 69         'math/statistics': Statistics,
 70         'math/numerics': Mat.Numerics
 71     }
 72 };
 73 
 74 /**
 75  * A JessieCode object provides an interface to the parser and stores all variables and objects used within a JessieCode script.
 76  * The optional argument <tt>code</tt> is interpreted after initializing. To evaluate more code after initializing a JessieCode instance
 77  * please use {@link JXG.JessieCode#parse}. For code snippets like single expressions use {@link JXG.JessieCode#snippet}.
 78  * @constructor
 79  * @param {String} [code] Code to parse.
 80  * @param {Boolean} [geonext=false] Geonext compatibility mode.
 81  */
 82 JXG.JessieCode = function (code, geonext) {
 83     // Control structures
 84 
 85     /**
 86      * The global scope.
 87      * @type Object
 88      */
 89     this.scope = {
 90         id: 0,
 91         hasChild: true,
 92         args: [],
 93         locals: {},
 94         context: null,
 95         previous: null
 96     };
 97 
 98     /**
 99      * Keeps track of all possible scopes every required.
100      * @type Array
101      */
102     this.scopes = [];
103     this.scopes.push(this.scope);
104 
105     /**
106      * A stack to store debug information (like line and column where it was defined) of a parameter
107      * @type Array
108      * @private
109      */
110     this.dpstack = [[]];
111 
112     /**
113      * Determines the parameter stack scope.
114      * @type Number
115      * @private
116      */
117     this.pscope = 0;
118 
119     /**
120      * Used to store the property-value definition while parsing an object literal.
121      * @type Array
122      * @private
123      */
124     this.propstack = [{}];
125 
126     /**
127      * The current scope of the object literal stack {@link JXG.JessieCode#propstack}.
128      * @type Number
129      * @private
130      */
131     this.propscope = 0;
132 
133     /**
134      * Store the left hand side of an assignment. If an element is constructed and no attributes are given, this is
135      * used as the element's name.
136      * @type Array
137      * @private
138      */
139     this.lhs = [];
140 
141     /**
142      * lhs flag, used by JXG.JessieCode#replaceNames
143      * @type Boolean
144      * @default false
145      */
146     this.isLHS = false;
147 
148     /**
149      * The id of an HTML node in which innerText all warnings are stored (if no <tt>console</tt> object is available).
150      * @type String
151      * @default 'jcwarn'
152      */
153     this.warnLog = 'jcwarn';
154 
155     /**
156      * Store $log messages in case there's no console.
157      * @type Array
158      */
159     this.$log = [];
160 
161     /**
162      * Built-in functions and constants
163      * @type Object
164      */
165     this.builtIn = this.defineBuiltIn();
166 
167     /**
168      * List of all possible operands in JessieCode (except of JSXGraph objects).
169      * @type Object
170      */
171     this.operands = this.getPossibleOperands();
172 
173     /**
174      * The board which currently is used to create and look up elements.
175      * @type JXG.Board
176      */
177     this.board = null;
178 
179     /**
180      * Force slider names to return value instead of node
181      * @type Boolean
182      */
183     this.forceValueCall = false;
184 
185     /**
186      * Keep track of which element is created in which line.
187      * @type Object
188      */
189     this.lineToElement = {};
190 
191     this.parCurLine = 1;
192     this.parCurColumn = 0;
193     this.line = 1;
194     this.col = 1;
195 
196     if (JXG.CA) {
197         // Old simplifier
198         this.CA = new JXG.CA(this.node, this.createNode, this);
199     }
200     if (JXG.CAS) {
201         // New simplifier
202         this.CAS = new JXG.CAS(this.node, this.createNode, this);
203     }
204 
205     this.code = '';
206 
207     if (typeof code === 'string') {
208         this.parse(code, geonext);
209     }
210 };
211 
212 JXG.extend(JXG.JessieCode.prototype, /** @lends JXG.JessieCode.prototype */ {
213     /**
214      * Create a new parse tree node.
215      * @param {String} type Type of node, e.g. node_op, node_var, or node_const
216      * @param value The nodes value, e.g. a variables value or a functions body.
217      * @param {Array} children Arbitrary number of child nodes.
218      */
219     node: function (type, value, children) {
220         return {
221             type: type,
222             value: value,
223             children: children
224         };
225     },
226 
227     /**
228      * Create a new parse tree node. Basically the same as node(), but this builds
229      * the children part out of an arbitrary number of parameters, instead of one
230      * array parameter.
231      * @param {String} type Type of node, e.g. node_op, node_var, or node_const
232      * @param value The nodes value, e.g. a variables value or a functions body.
233      * @param children Arbitrary number of parameters; define the child nodes.
234      */
235     createNode: function (type, value, children) {
236         var n = this.node(type, value, []),
237             i;
238 
239         for (i = 2; i < arguments.length; i++) {
240             n.children.push(arguments[i]);
241         }
242 
243         if (n.type === 'node_const' && Type.isNumber(n.value)) {
244             n.isMath = true;
245         }
246 
247         n.line = this.parCurLine;
248         n.col = this.parCurColumn;
249 
250         return n;
251     },
252 
253     /**
254      * Create a new scope.
255      * @param {Array} args
256      * @returns {Object}
257      */
258     pushScope: function (args) {
259         var scope = {
260             args: args,
261             locals: {},
262             context: null,
263             previous: this.scope
264         };
265 
266         this.scope.hasChild = true;
267         this.scope = scope;
268         scope.id = this.scopes.push(scope) - 1;
269 
270         return scope;
271     },
272 
273     /**
274      * Remove the current scope and reinstate the previous scope
275      * @returns {Object}
276      */
277     popScope: function () {
278         var s = this.scope.previous;
279 
280         // make sure the global scope is not lost
281         this.scope = (s !== null) ? s : this.scope;
282 
283         return this.scope;
284     },
285 
286     /**
287      * Looks up an {@link JXG.GeometryElement} by its id.
288      * @param {String} id
289      * @returns {JXG.GeometryElement}
290      */
291     getElementById: function (id) {
292         return this.board.objects[id];
293     },
294 
295     log: function () {
296         this.$log.push(arguments);
297 
298         if (typeof console === 'object' && console.log) {
299             console.log.apply(console, arguments);
300         }
301     },
302 
303     /**
304      * Returns a element creator function which takes two parameters: the parents array and the attributes object.
305      * @param {String} vname The element type, e.g. 'point', 'line', 'midpoint'
306      * @returns {function}
307      */
308     creator: (function () {
309         // stores the already defined creators
310         var _ccache = {}, r;
311 
312         r = function (vname) {
313             var f;
314 
315             // _ccache is global, i.e. it is the same for ALL JessieCode instances.
316             // That's why we need the board id here
317             if (typeof _ccache[this.board.id + vname] === 'function') {
318                 f = _ccache[this.board.id + vname];
319             } else {
320                 f = (function (that) {
321                     return function (parameters, attributes) {
322                         var attr;
323 
324                         if (Type.exists(attributes)) {
325                             attr = attributes;
326                         } else {
327                             attr = {};
328                         }
329                         if (attr.name === undefined && attr.id === undefined) {
330                             attr.name = ((that.lhs[that.scope.id] !== 0) ? that.lhs[that.scope.id] : '');
331                         }
332                         return that.board.create(vname, parameters, attr);
333                     };
334                 }(this));
335 
336                 f.creator = true;
337                 _ccache[this.board.id + vname] = f;
338             }
339 
340             return f;
341         };
342 
343         r.clearCache = function () {
344             _ccache = {};
345         };
346 
347         return r;
348     }()),
349 
350     /**
351      * Assigns a value to a variable in the current scope.
352      * @param {String} vname Variable name
353      * @param value Anything
354      * @see JXG.JessieCode#sstack
355      * @see JXG.JessieCode#scope
356      */
357     letvar: function (vname, value) {
358         if (this.builtIn[vname]) {
359             this._warn('"' + vname + '" is a predefined value.');
360         }
361 
362         this.scope.locals[vname] = value;
363     },
364 
365     /**
366      * Checks if the given variable name can be found in the current scope chain.
367      * @param {String} vname
368      * @returns {Object} A reference to the scope object the variable can be found in or null if it can't be found.
369      */
370     isLocalVariable: function (vname) {
371         var s = this.scope;
372 
373         while (s !== null) {
374             if (Type.exists(s.locals[vname])) {
375                 return s;
376             }
377 
378             s = s.previous;
379         }
380 
381         return null;
382     },
383 
384     /**
385      * Checks if the given variable name is a parameter in any scope from the current to the global scope.
386      * @param {String} vname
387      * @returns {Object} A reference to the scope object that contains the variable in its arg list.
388      */
389     isParameter: function (vname) {
390         var s = this.scope;
391 
392         while (s !== null) {
393             if (Type.indexOf(s.args, vname) > -1) {
394                 return s;
395             }
396 
397             s = s.previous;
398         }
399 
400         return null;
401     },
402 
403     /**
404      * Checks if the given variable name is a valid creator method.
405      * @param {String} vname
406      * @returns {Boolean}
407      */
408     isCreator: function (vname) {
409         // check for an element with this name
410         return !!JXG.elements[vname];
411     },
412 
413     /**
414      * Checks if the given variable identifier is a valid member of the JavaScript Math Object.
415      * @param {String} vname
416      * @returns {Boolean}
417      */
418     isMathMethod: function (vname) {
419         return vname !== 'E' && !!Math[vname];
420     },
421 
422     /**
423      * Returns true if the given identifier is a builtIn variable/function.
424      * @param {String} vname
425      * @returns {Boolean}
426      */
427     isBuiltIn: function (vname) {
428         return !!this.builtIn[vname];
429     },
430 
431     /**
432      * Looks up the value of the given variable. We use a simple type inspection.
433      *
434      * @param {String} vname Name of the variable
435      * @param {Boolean} [local=false] Only look up the internal symbol table and don't look for
436      * the <tt>vname</tt> in Math or the element list.
437      * @param {Boolean} [isFunctionName=false] Lookup function of type builtIn, Math.*, creator.
438      *
439      * @see JXG.JessieCode#resolveType
440      */
441     getvar: function (vname, local, isFunctionName) {
442         var s;
443 
444         local = Type.def(local, false);
445 
446         // Local scope has always precedence
447         s = this.isLocalVariable(vname);
448 
449         if (s !== null) {
450             return s.locals[vname];
451         }
452 
453         // Handle the - so far only - few constants by hard coding them.
454         if (vname === '$board' || vname === 'EULER' || vname === 'PI') {
455             return this.builtIn[vname];
456         }
457 
458         if (isFunctionName) {
459             if (this.isBuiltIn(vname)) {
460                 return this.builtIn[vname];
461             }
462 
463             if (this.isMathMethod(vname)) {
464                 return Math[vname];
465             }
466 
467             // check for an element with this name
468             if (this.isCreator(vname)) {
469                 return this.creator(vname);
470             }
471         }
472 
473         if (!local) {
474             s = this.board.select(vname);
475             if (s !== vname) {
476                 return s;
477             }
478         }
479     },
480 
481     /**
482      * Look up the value of a local variable.
483      * @param {string} vname
484      * @returns {*}
485      */
486     resolve: function (vname) {
487         var s = this.scope;
488 
489         while (s !== null) {
490             if (Type.exists(s.locals[vname])) {
491                 return s.locals[vname];
492             }
493 
494             s = s.previous;
495         }
496     },
497 
498     /**
499      * TODO this needs to be called from JS and should not generate JS code
500      * Looks up a variable identifier in various tables and generates JavaScript code that could be eval'd to get the value.
501      * @param {String} vname Identifier
502      * @param {Boolean} [local=false] Don't resolve ids and names of elements
503      * @param {Boolean} [withProps=false]
504      */
505     getvarJS: function (vname, local, withProps) {
506         var s, r = '', re;
507 
508         local = Type.def(local, false);
509         withProps = Type.def(withProps, false);
510 
511         s = this.isParameter(vname);
512         if (s !== null) {
513             return vname;
514         }
515 
516         s = this.isLocalVariable(vname);
517         if (s !== null && !withProps) {
518             return '$jc$.resolve(\'' + vname + '\')';
519         }
520 
521         // check for an element with this name
522         if (this.isCreator(vname)) {
523             return '(function () { var a = Array.prototype.slice.call(arguments, 0), props = ' + (withProps ? 'a.pop()' : '{}') + '; return $jc$.board.create.apply($jc$.board, [\'' + vname + '\'].concat([a, props])); })';
524         }
525 
526         if (withProps) {
527             this._error('Syntax error (attribute values are allowed with element creators only)');
528         }
529 
530         if (this.isBuiltIn(vname)) {
531             // If src does not exist, it is a number. In that case, just return the value.
532             r = this.builtIn[vname].src || this.builtIn[vname];
533 
534             // Get the "real" name of the function
535             if (Type.isNumber(r)) {
536                 return r;
537             }
538             // Search a JSXGraph object in board
539             if (r.match(/board\.select/)) {
540                 return r;
541             }
542 
543             /* eslint-disable no-useless-escape */
544             vname = r.split('.').pop();
545             if (Type.exists(this.board.mathLib)) {
546                 // Handle builtin case: ln(x) -> Math.log
547                 re = new RegExp('^Math\.' + vname);
548                 if (re.exec(r) !== null) {
549                     return r.replace(re, '$jc$.board.mathLib.' + vname);
550                 }
551             }
552             if (Type.exists(this.board.mathLibJXG)) {
553                 // Handle builtin case: factorial(x) -> JXG.Math.factorial
554                 re = new RegExp('^JXG\.Math\.');
555                 if (re.exec(r) !== null) {
556                     return r.replace(re, '$jc$.board.mathLibJXG.');
557                 }
558                 return r;
559             }
560             /* eslint-enable no-useless-escape */
561             return r;
562 
563             // return this.builtIn[vname].src || this.builtIn[vname];
564         }
565 
566         if (this.isMathMethod(vname)) {
567             return '$jc$.board.mathLib.' + vname;
568             //                return 'Math.' + vname;
569         }
570 
571         // if (!local) {
572         //     if (Type.isId(this.board, vname)) {
573         //         r = '$jc$.board.objects[\'' + vname + '\']';
574         //     } else if (Type.isName(this.board, vname)) {
575         //         r = '$jc$.board.elementsByName[\'' + vname + '\']';
576         //     } else if (Type.isGroup(this.board, vname)) {
577         //         r = '$jc$.board.groups[\'' + vname + '\']';
578         //     }
579 
580         //     return r;
581         // }
582         if (!local) {
583             if (Type.isId(this.board, vname)) {
584                 r = '$jc$.board.objects[\'' + vname + '\']';
585                 if (this.board.objects[vname].elType === 'slider') {
586                     r += '.Value()';
587                 }
588             } else if (Type.isName(this.board, vname)) {
589                 r = '$jc$.board.elementsByName[\'' + vname + '\']';
590                 if (this.board.elementsByName[vname].elType === 'slider') {
591                     r += '.Value()';
592                 }
593             } else if (Type.isGroup(this.board, vname)) {
594                 r = '$jc$.board.groups[\'' + vname + '\']';
595             }
596 
597             return r;
598         }
599 
600         return '';
601     },
602 
603     /**
604      * Adds the property <tt>isMap</tt> to a function and sets it to true.
605      * @param {function} f
606      * @returns {function}
607      */
608     makeMap: function (f) {
609         f.isMap = true;
610 
611         return f;
612     },
613 
614     functionCodeJS: function (node) {
615         var p = node.children[0].join(', '),
616             bo = '',
617             bc = '';
618 
619         if (node.value === 'op_map') {
620             bo = '{ return  ';
621             bc = ' }';
622         }
623 
624         return 'function (' + p + ') {\n' +
625             'var $oldscope$ = $jc$.scope;\n' +
626             '$jc$.scope = $jc$.scopes[' + this.scope.id + '];\n' +
627             'var r = (function () ' + bo + this.compile(node.children[1], true) + bc + ')();\n' +
628             '$jc$.scope = $oldscope$;\n' +
629             'return r;\n' +
630             '}';
631     },
632 
633     /**
634      * Converts a node type <tt>node_op</tt> and value <tt>op_map</tt> or <tt>op_function</tt> into a executable
635      * function. Does a simple type inspection.
636      * @param {Object} node
637      * @returns {function}
638      * @see JXG.JessieCode#resolveType
639      */
640     defineFunction: function (node) {
641         var fun, i, that = this,
642             list = node.children[0],
643             scope = this.pushScope(list);
644 
645         if (this.board.options.jc.compile) {
646             this.isLHS = false;
647 
648             // we currently need to put the parameters into the local scope
649             // until the compiled JS variable lookup code is fixed
650             for (i = 0; i < list.length; i++) {
651                 scope.locals[list[i]] = list[i];
652             }
653 
654             this.replaceNames(node.children[1]);
655 
656             /** @ignore */
657             fun = (function (jc) {
658                 var fun,
659                     // str = 'var f = ' + $jc$.functionCodeJS(node) + '; f;';
660                     str = 'var f = function($jc$) { return ' +
661                         jc.functionCodeJS(node) +
662                         '}; f;';
663 
664                 try {
665                     // yeah, eval is evil, but we don't have much choice here.
666                     // the str is well defined and there is no user input in it that we didn't check before
667 
668                     /*jslint evil:true*/
669                     // fun = eval(str);
670                     fun = eval(str)(jc);
671                     /*jslint evil:false*/
672 
673                     scope.argtypes = [];
674                     for (i = 0; i < list.length; i++) {
675                         scope.argtypes.push(that.resolveType(list[i], node));
676                     }
677 
678                     return fun;
679                 } catch (e) {
680                     // $jc$._warn('error compiling function\n\n' + str + '\n\n' + e.toString());
681                     jc._warn("error compiling function\n\n" + str + "\n\n" + e.toString());
682                     return function () { };
683                 }
684             }(this));
685 
686             // clean up scope
687             this.popScope();
688         } else {
689             /** @ignore */
690             fun = (function (_pstack, that, id) {
691                 return function () {
692                     var r, oldscope;
693 
694                     oldscope = that.scope;
695                     that.scope = that.scopes[id];
696 
697                     for (r = 0; r < _pstack.length; r++) {
698                         that.scope.locals[_pstack[r]] = arguments[r];
699                     }
700 
701                     r = that.execute(node.children[1]);
702                     that.scope = oldscope;
703 
704                     return r;
705                 };
706             }(list, this, scope.id));
707         }
708 
709         fun.node = node;
710         fun.scope = scope;
711         fun.toJS = fun.toString;
712         fun.toString = (function (_that) {
713             return function () {
714                 return _that.compile(_that.replaceIDs(Type.deepCopy(node)));
715             };
716         }(this));
717 
718         fun.deps = {};
719         this.collectDependencies(node.children[1], node.children[0], fun.deps);
720 
721         return fun;
722     },
723 
724     /**
725      * Merge all attribute values given with an element creator into one object.
726      * @param {Object} o An arbitrary number of objects
727      * @returns {Object} All given objects merged into one. If properties appear in more (case sensitive) than one
728      * object the last value is taken.
729      */
730     mergeAttributes: function (o) {
731         var i, attr = {};
732 
733         for (i = 0; i < arguments.length; i++) {
734             attr = Type.deepCopy(attr, arguments[i], true);
735         }
736 
737         return attr;
738     },
739 
740     /**
741      * Sets the property <tt>what</tt> of <tt>o</tt> to <tt>value</tt>
742      * @param {JXG.Point|JXG.Text} o
743      * @param {String} what
744      * @param value
745      */
746     setProp: function (o, what, value) {
747         var par = {}, x, y;
748 
749         if (o.elementClass === Const.OBJECT_CLASS_POINT && (what === 'X' || what === 'Y')) {
750             // set coords
751 
752             what = what.toLowerCase();
753 
754             // we have to deal with three cases here:
755             // o.isDraggable && typeof value === number:
756             //   stay draggable, just set the new coords (e.g. via moveTo)
757             // o.isDraggable && typeof value === function:
758             //   convert to !o.isDraggable, set the new coords via o.addConstraint()
759             // !o.isDraggable:
760             //   stay !o.isDraggable, update the given coord by overwriting X/YEval
761 
762             if (o.isDraggable && typeof value === 'number') {
763                 x = (what === 'x') ? value : o.X();
764                 y = (what === 'y') ? value : o.Y();
765 
766                 o.setPosition(Const.COORDS_BY_USER, [x, y]);
767             } else if (o.isDraggable && (typeof value === 'function' || typeof value === 'string')) {
768                 x = (what === 'x') ? value : o.coords.usrCoords[1];
769                 y = (what === 'y') ? value : o.coords.usrCoords[2];
770 
771                 o.addConstraint([x, y]);
772             } else if (!o.isDraggable) {
773                 x = (what === 'x') ? value : o.XEval.origin;
774                 y = (what === 'y') ? value : o.YEval.origin;
775 
776                 o.addConstraint([x, y]);
777             }
778 
779             this.board.update();
780         } else if (o.elementClass === Const.OBJECT_CLASS_TEXT && (what === 'X' || what === 'Y')) {
781             if (typeof value === 'number') {
782                 o[what] = function () { return value; };
783             } else if (typeof value === 'function') {
784                 o.isDraggable = false;
785                 o[what] = value;
786             } else if (typeof value === 'string') {
787                 o.isDraggable = false;
788                 o[what] = Type.createFunction(value, this.board);
789                 o[what + 'jc'] = value;
790             }
791 
792             o[what].origin = value;
793 
794             this.board.update();
795         } else if (o.type && o.elementClass && o.visProp) {
796             if (Type.exists(o[o.methodMap[what]]) && typeof o[o.methodMap[what]] !== 'function') {
797                 o[o.methodMap[what]] = value;
798             } else {
799                 par[what] = value;
800                 o.setAttribute(par);
801             }
802         } else {
803             o[what] = value;
804         }
805     },
806 
807     /**
808      * Generic method to parse JessieCode.
809      * This consists of generating an AST with parser.parse,
810      * apply simplifying rules from CA and
811      * manipulate the AST according to the second parameter "cmd".
812      * @param  {String} code      JessieCode code to be parsed
813      * @param  {String} cmd       Type of manipulation to be done with AST
814      * @param {Object} [options]  Object with attributes <ul>
815      *     <li>{Boolean} [geonext=false]     Geonext compatibility mode.</li>
816      *     <li>{Boolean} [dontstore=false]   If false, the code string is stored in this.code, i.e. in the JessieCode object, e.g. in board.jc.</li>
817      *     </ul>
818      * @return {Object} Returns result of computation as directed in cmd.
819      */
820     _genericParse: function (code, cmd, options) {
821         var i, setTextBackup, ast, result,
822             ccode = code.replace(/\r\n/g, '\n').split('\n'),
823             cleaned = [];
824 
825         if (!Type.exists(options)) {
826             options = {};
827         }
828 
829         if (!options.dontstore) {
830             this.code += code + '\n';
831         }
832 
833         if (Text) {
834             setTextBackup = Text.prototype.setText;
835             Text.prototype.setText = Text.prototype.setTextJessieCode;
836         }
837 
838         try {
839             for (i = 0; i < ccode.length; i++) {
840                 if (!!options.geonext) {
841                     ccode[i] = JXG.GeonextParser.geonext2JS(ccode[i], this.board);
842                 }
843                 cleaned.push(ccode[i]);
844             }
845 
846             code = cleaned.join('\n');
847             ast = parser.parse(code);
848             if (this.CA) {
849                 ast = this.CA.expandDerivatives(ast, null, ast);
850                 ast = this.CA.removeTrivialNodes(ast);
851             }
852             if (this.CAS) {
853                 // Search for expression of form `D(f, x)` and determine the
854                 // the derivative symbolically.
855                 ast = this.CAS.expandDerivatives(ast, null, ast);
856 
857                 // options.method = options.method || "strong";
858                 // options.form = options.form || "fractions";
859                 // options.steps = options.steps || [];
860                 // options.iterations = options.iterations || 1000;
861                 // ast = this.CAS._simplify_aux(ast, options);
862             }
863             switch (cmd) {
864                 case 'parse':
865                     result = this.execute(ast);
866                     break;
867                 case 'manipulate':
868                     result = this.compile(ast);
869                     break;
870                 case 'simplify':
871                     if (Type.exists(this.CAS)) {
872                         options.method = options.method || "strong";
873                         options.form = options.form || "fractions";
874                         options.steps = options.steps || [];
875                         options.iterations = options.iterations || 1000;
876                         ast = this.CAS.simplify(ast, options);
877                         result = this.CAS.compile(ast);
878                     } else {
879                         result = this.compile(ast);
880                     }
881                     break;
882                 case 'format':
883                     result = this.compile(ast, false, options);
884                     break;
885                 case 'getAst':
886                     result = ast;
887                     break;
888                 default:
889                     result = false;
890             }
891         } catch (e) {  // catch is mandatory in old IEs
892             // console.log(e);
893             // We throw the error again,
894             // so the user can catch it.
895             throw e;
896         } finally {
897             // make sure the original text method is back in place
898             if (Text) {
899                 Text.prototype.setText = setTextBackup;
900             }
901         }
902 
903         return result;
904     },
905 
906     /**
907      * Parses JessieCode.
908      * This consists of generating an AST with parser.parse, apply simplifying rules
909      * from CA and executing the ast by calling this.execute(ast).
910      *
911      * @param {String} code             JessieCode code to be parsed
912      * @param {Boolean} [geonext=false] Geonext compatibility mode.
913      * @param {Boolean} [dontstore=false] If false, the code string is stored in this.code.
914      * @return {Object}                 Parse JessieCode code and execute it.
915      */
916     parse: function (code, geonext, dontstore) {
917         return this._genericParse(code, 'parse', {geonext: geonext, dontstore: dontstore});
918     },
919 
920     /**
921      * Manipulate JessieCode.
922      * This consists of generating an AST with parser.parse,
923      * apply simplifying rules from CA
924      * and compile the AST back to JessieCode.
925      *
926      * @param {String} code             JessieCode code to be parsed
927      * @param {Boolean} [geonext=false] Geonext compatibility mode.
928      * @param {Boolean} [dontstore=false] If false, the code string is stored in this.code.
929      * @return {String}                 Simplified JessieCode code
930      */
931     manipulate: function (code, geonext, dontstore) {
932         return this._genericParse(code, 'manipulate', {geonext: geonext, dontstore: dontstore});
933     },
934 
935     /**
936      * Manipulate JessieCode.
937      * This consists of generating an AST with parser.parse,
938      * apply simplifying rules from CAS
939      * and compile the AST back to JessieCode with minimal number of parentheses.
940      *
941      * @param {String} code             JessieCode code to be parsed
942      * @return {String}                 Simplified JessieCode code
943      */
944     simplify: function (code) {
945         return this._genericParse(code, 'simplify');
946     },
947 
948     /**
949      * Format JessieCode.
950      * This consists of generating an AST with parser.parse,
951      * and compile the AST back to JessieCode with options.
952      *
953      * @param {String} code      JessieCode code to be parsed.
954      * @param {Object} options   For possible options see param "format" in {@link JXG.JessieCode#compile}.
955      * @return {String}          Manipulated JessieCode string. This is no necessarily a parsable JessieCode code!
956      */
957     format: function (code, options) {
958         return this._genericParse(code, 'format', options);
959     },
960 
961     /**
962      * Get abstract syntax tree (AST) from JessieCode code.
963      * This consists of generating an AST with parser.parse.
964      *
965      * @param {String} code
966      * @param {Boolean} [geonext=false] Geonext compatibility mode.
967      * @param {Boolean} [dontstore=false] If false, the code string is stored in this.code.
968      * @return {Node}  AST
969      */
970     getAST: function (code, geonext, dontstore) {
971         return this._genericParse(code, 'getAst', {geonext: geonext, dontstore: dontstore});
972     },
973 
974     /**
975      * Parses a JessieCode snippet, e.g. "3+4", and wraps it into a function, if desired.
976      * @param {String} code A small snippet of JessieCode. Must not be an assignment.
977      * @param {Boolean} [funwrap=true] If true, the code is wrapped in a function.
978      * @param {String} [varname=''] Name of the parameter(s)
979      * @param {Boolean} [geonext=false] Geonext compatibility mode.
980      * @param {Boolean} [forceValueCall=true] Force evaluation of value method of sliders.
981      */
982     snippet: function (code, funwrap, varname, geonext, forceValueCall) {
983         var c;
984 
985         funwrap = Type.def(funwrap, true);
986         varname = Type.def(varname, '');
987         geonext = Type.def(geonext, false);
988         this.forceValueCall = Type.def(forceValueCall, true);
989 
990         c = (funwrap ? ' function (' + varname + ') { return ' : '') +
991                 code +
992             (funwrap ? '; }' : '') + ';';
993 
994         return this.parse(c, geonext, true);
995     },
996 
997     /**
998      * Traverses through the given subtree and changes all values of nodes with the replaced flag set by
999      * {@link JXG.JessieCode#replaceNames} to the name of the element (if not empty).
1000      * @param {Object} node
1001      */
1002     replaceIDs: function (node) {
1003         var i, v;
1004 
1005         if (node.replaced) {
1006             // These children exist, if node.replaced is set.
1007             v = this.board.objects[node.children[1][0].value];
1008 
1009             if (Type.exists(v) && v.name !== "") {
1010                 node.type = 'node_var';
1011                 node.value = v.name;
1012 
1013                 // Maybe it's not necessary, but just to be sure that everything is cleaned up we better delete all
1014                 // children and the replaced flag
1015                 node.children.length = 0;
1016                 delete node.replaced;
1017             }
1018         }
1019 
1020         if (Type.isArray(node)) {
1021             for (i = 0; i < node.length; i++) {
1022                 node[i] = this.replaceIDs(node[i]);
1023             }
1024         }
1025 
1026         if (node.children) {
1027             // assignments are first evaluated on the right hand side
1028             for (i = node.children.length; i > 0; i--) {
1029                 if (Type.exists(node.children[i - 1])) {
1030                     node.children[i - 1] = this.replaceIDs(node.children[i - 1]);
1031                 }
1032 
1033             }
1034         }
1035 
1036         return node;
1037     },
1038 
1039     /**
1040      * Traverses through the given subtree and changes all elements referenced by names through referencing them by ID.
1041      * An identifier is only replaced if it is not found in all scopes above the current scope and if it
1042      * has not been blacklisted within the codeblock determined by the given subtree.
1043      * @param {Object} node
1044      * @param {Boolean} [callValuePar=false] if true, uses $value() instead of $() in createReplacementNode
1045      */
1046     replaceNames: function (node, callValuePar) {
1047         var i, v,
1048             callValue = false;
1049 
1050         if (callValuePar !== undefined) {
1051             callValue = callValuePar;
1052         }
1053 
1054         v = node.value;
1055 
1056         // We are interested only in nodes of type node_var and node_op > op_lhs.
1057         // Currently, we are not checking if the id is a local variable. in this case, we're stuck anyway.
1058 
1059         if (node.type === 'node_op' && v === 'op_lhs' && node.children.length === 1) {
1060             this.isLHS = true;
1061         } else if (node.type === 'node_var') {
1062             if (this.isLHS) {
1063                 this.letvar(v, true);
1064             } else if (!Type.exists(this.getvar(v, true)) && Type.exists(this.board.elementsByName[v])) {
1065                 if (callValue && this.board.elementsByName[v].elType !== 'slider') {
1066                     callValue = false;
1067                 }
1068                 node = this.createReplacementNode(node, callValue);
1069             }
1070         }
1071 
1072         if (Type.isArray(node)) {
1073             for (i = 0; i < node.length; i++) {
1074                 node[i] = this.replaceNames(node[i], callValue);
1075             }
1076         }
1077 
1078         if (node.children) {
1079             // Replace slider reference by call of slider.Value()
1080             if (this.forceValueCall &&              // It must be enforced, see snippet.
1081                 (
1082                     // 1. case: sin(a), max(a, 0), ...
1083                     (node.value === "op_execfun" &&
1084                         // Not in cases V(a), $(a)
1085                         node.children[0].value !== 'V' && node.children[0].value !== '$' &&
1086                         // Function must be a math function. This ensures that a number is required as input.
1087                         (Type.exists(Math[node.children[0].value]) || Type.exists(Mat[node.children[0].value])) &&
1088                         // node.children[1].length === 1 &&
1089                         node.children[1][0].type === 'node_var'
1090                     ) ||
1091                     // 2. case: slider is the whole expression: 'a'
1092                     (node.value === "op_return" &&
1093                         node.children.length === 1 &&
1094                         node.children[0].type === 'node_var'
1095                     )
1096                 )
1097             ) {
1098                     callValue = true;
1099             }
1100 
1101             // Assignments are first evaluated on the right hand side
1102             for (i = node.children.length; i > 0; i--) {
1103                 if (Type.exists(node.children[i - 1])) {
1104                     node.children[i - 1] = this.replaceNames(node.children[i - 1], callValue);
1105                 }
1106             }
1107         }
1108 
1109         if (node.type === 'node_op' && node.value === 'op_lhs' && node.children.length === 1) {
1110             this.isLHS = false;
1111         }
1112 
1113         return node;
1114     },
1115 
1116     /**
1117      * Replaces node_var nodes with node_op>op_execfun nodes, calling the internal $() function with the id of the
1118      * element accessed by the node_var node.
1119      * @param {Object} node
1120      * @param {Boolean} [callValue=undefined] if true, uses $value() instead of $()
1121      * @returns {Object} op_execfun node
1122      */
1123     createReplacementNode: function (node, callValue) {
1124         var v = node.value,
1125             el = this.board.elementsByName[v];
1126 
1127         // If callValue: get handle to this node_var and call its Value method.
1128         // Otherwise return the object.
1129         node = this.createNode('node_op', 'op_execfun',
1130             this.createNode('node_var', ((callValue === true) ? '$value' : '$')),
1131             [this.createNode('node_str', el.id)]);
1132 
1133         node.replaced = true;
1134 
1135         return node;
1136     },
1137 
1138     /**
1139      * Search the parse tree below <tt>node</tt> for <em>stationary</em> dependencies, i.e. dependencies hard coded into
1140      * the function.
1141      * @param {Object} node
1142      * @param {Array} varnames List of variable names of the function
1143      * @param {Object} result An object where the referenced elements will be stored. Access key is their id.
1144      */
1145     collectDependencies: function (node, varnames, result) {
1146         var i, v, e, le;
1147 
1148         if (Type.isArray(node)) {
1149             le = node.length;
1150             for (i = 0; i < le; i++) {
1151                 this.collectDependencies(node[i], varnames, result);
1152             }
1153             return;
1154         }
1155 
1156         v = node.value;
1157 
1158         if (node.type === 'node_var' &&
1159             varnames.indexOf(v) < 0 // v is not contained in the list of variables of that function
1160         ) {
1161             e = this.getvar(v);
1162             if (e && e.visProp && e.elType && e.elementClass && e.id
1163                 // Sliders are the only elements which are given by names.
1164                 // Wrong, a counter example is: circle(c, function() { return p1.Dist(p2); })
1165                 // && e.elType === 'slider'
1166             ) {
1167                 result[e.id] = e;
1168             }
1169         }
1170 
1171         // The $()-function-calls are special because their parameter is given as a string, not as a node_var.
1172         if (node.type === 'node_op' && node.value === 'op_execfun' &&
1173             node.children.length > 1 &&
1174             (node.children[0].value === '$' || node.children[0].value === '$value') &&
1175             node.children[1].length > 0) {
1176 
1177             e = node.children[1][0].value;
1178             result[e] = this.board.objects[e];
1179         }
1180 
1181         if (node.children) {
1182             for (i = node.children.length; i > 0; i--) {
1183                 if (Type.exists(node.children[i - 1])) {
1184                     this.collectDependencies(node.children[i - 1], varnames, result);
1185                 }
1186             }
1187         }
1188     },
1189 
1190     resolveProperty: function (e, v, compile) {
1191         compile = Type.def(compile, false);
1192 
1193         // is it a geometry element or a board?
1194         if (e /*&& e.type && e.elementClass*/ && e.methodMap) {
1195             // yeah, it is. but what does the user want?
1196             if (Type.exists(e.subs) && Type.exists(e.subs[v])) {
1197                 // a subelement it is, good sir.
1198                 e = e.subs;
1199             } else if (Type.exists(e.methodMap[v])) {
1200                 // the user wants to call a method
1201                 v = e.methodMap[v];
1202             } else {
1203                 // the user wants to change an attribute
1204                 e = e.visProp;
1205                 v = v.toLowerCase();
1206             }
1207         }
1208 
1209         if (Type.isFunction(e)) {
1210             this._error('Accessing function properties is not allowed.');
1211         }
1212 
1213         if (!Type.exists(e)) {
1214             this._error(e + ' is not an object');
1215         }
1216 
1217         if (!Type.exists(e[v])) {
1218             this._error('unknown property ' + v);
1219         }
1220 
1221         if (compile && typeof e[v] === 'function') {
1222             return function () { return e[v].apply(e, arguments); };
1223         }
1224 
1225         return e[v];
1226     },
1227 
1228     /**
1229      * Type inspection: check if the string vname appears as function name in the
1230      * AST node. Used in "op_execfun". This allows the JessieCode examples below.
1231      *
1232      * @private
1233      * @param {String} vname
1234      * @param {Object} node
1235      * @returns 'any' or 'function'
1236      * @see JXG.JessieCode#execute
1237      * @see JXG.JessieCode#getvar
1238      *
1239      * @example
1240      *  var p = board.create('point', [2, 0], {name: 'X'});
1241      *  var txt = 'X(X)';
1242      *  console.log(board.jc.parse(txt));
1243      *
1244      * @example
1245      *  var p = board.create('point', [2, 0], {name: 'X'});
1246      *  var txt = 'f = function(el, X) { return X(el); }; f(X, X);';
1247      *  console.log(board.jc.parse(txt));
1248      *
1249      * @example
1250      *  var p = board.create('point', [2, 0], {name: 'point'});
1251      *  var txt = 'B = point(1,3); X(point);';
1252      *  console.log(board.jc.parse(txt));
1253      *
1254      * @example
1255      *  var p = board.create('point', [2, 0], {name: 'A'});
1256      *  var q = board.create('point', [-2, 0], {name: 'X'});
1257      *  var txt = 'getCoord=function(p, f){ return f(p); }; getCoord(A, X);';
1258      *  console.log(board.jc.parse(txt));
1259      */
1260     resolveType: function (vname, node) {
1261         var i, t,
1262             type = 'any'; // Possible values: 'function', 'any'
1263 
1264         if (Type.isArray(node)) {
1265             // node contains the parameters of a function call or function declaration
1266             for (i = 0; i < node.length; i++) {
1267                 t = this.resolveType(vname, node[i]);
1268                 if (t !== 'any') {
1269                     type = t;
1270                     return type;
1271                 }
1272             }
1273         }
1274 
1275         if (node.type === 'node_op' && node.value === 'op_execfun' &&
1276             node.children[0].type === 'node_var' && node.children[0].value === vname) {
1277             return 'function';
1278         }
1279 
1280         if (node.type === 'node_op') {
1281             for (i = 0; i < node.children.length; i++) {
1282                 if (node.children[0].type === 'node_var' && node.children[0].value === vname &&
1283                     (node.value === 'op_add' || node.value === 'op_sub' || node.value === 'op_mul' ||
1284                         node.value === 'op_div' || node.value === 'op_mod' || node.value === 'op_exp' ||
1285                         node.value === 'op_neg')) {
1286                     return 'any';
1287                 }
1288             }
1289 
1290             for (i = 0; i < node.children.length; i++) {
1291                 t = this.resolveType(vname, node.children[i]);
1292                 if (t !== 'any') {
1293                     type = t;
1294                     return type;
1295                 }
1296             }
1297         }
1298 
1299         return 'any';
1300     },
1301 
1302     /**
1303      * Resolves the lefthand side of an assignment operation
1304      * @param node
1305      * @returns {Object} An object with two properties. <strong>o</strong> which contains the object, and
1306      * a string <strong>what</strong> which contains the property name.
1307      */
1308     getLHS: function (node) {
1309         var res;
1310 
1311         if (node.type === 'node_var') {
1312             res = {
1313                 o: this.scope.locals,
1314                 what: node.value
1315             };
1316         } else if (node.type === 'node_op' && node.value === 'op_property') {
1317             res = {
1318                 o: this.execute(node.children[0]),
1319                 what: node.children[1]
1320             };
1321         } else if (node.type === 'node_op' && node.value === 'op_extvalue') {
1322             res = {
1323                 o: this.execute(node.children[0]),
1324                 what: this.execute(node.children[1])
1325             };
1326         } else {
1327             throw new Error('Syntax error: Invalid left-hand side of assignment.');
1328         }
1329 
1330         return res;
1331     },
1332 
1333     getLHSCompiler: function (node, js) {
1334         var res;
1335 
1336         if (node.type === 'node_var') {
1337             res = node.value;
1338         } else if (node.type === 'node_op' && node.value === 'op_property') {
1339             res = [
1340                 this.compile(node.children[0], js),
1341                 "'" + node.children[1] + "'"
1342             ];
1343         } else if (node.type === 'node_op' && node.value === 'op_extvalue') {
1344             res = [
1345                 this.compile(node.children[0], js),
1346                 (node.children[1].type === 'node_const') ? node.children[1].value : this.compile(node.children[1], js)
1347             ];
1348         } else {
1349             throw new Error('Syntax error: Invalid left-hand side of assignment.');
1350         }
1351 
1352         return res;
1353     },
1354 
1355     /**
1356      * Executes a parse subtree.
1357      * @param {Object} node
1358      * @returns {Number|String|Object|Boolean} Something
1359      * @private
1360      */
1361     execute: function (node) {
1362         var ret, v, i, e, l, undef, list, ilist,
1363             parents = [],
1364             // exec fun
1365             fun, attr, sc;
1366 
1367         ret = 0;
1368 
1369         if (!node) {
1370             return ret;
1371         }
1372 
1373         this.line = node.line;
1374         this.col = node.col;
1375 
1376         switch (node.type) {
1377             case 'node_op':
1378                 switch (node.value) {
1379                     case 'op_none':
1380                         if (node.children[0]) {
1381                             this.execute(node.children[0]);
1382                         }
1383                         if (node.children[1]) {
1384                             ret = this.execute(node.children[1]);
1385                         }
1386                         break;
1387                     case 'op_assign':
1388                         v = this.getLHS(node.children[0]);
1389                         this.lhs[this.scope.id] = v.what;
1390 
1391                         if (v.o.type && v.o.elementClass && v.o.methodMap && v.what === 'label') {
1392                             this._error('Left-hand side of assignment is read-only.');
1393                         }
1394 
1395                         ret = this.execute(node.children[1]);
1396                         if (v.o !== this.scope.locals || (Type.isArray(v.o) && typeof v.what === 'number')) {
1397                             // it is either an array component being set or a property of an object.
1398                             this.setProp(v.o, v.what, ret);
1399                         } else {
1400                             // this is just a local variable inside JessieCode
1401                             this.letvar(v.what, ret);
1402                         }
1403                         this.lhs[this.scope.id] = 0;
1404                         break;
1405                     case 'op_if':
1406                         if (this.execute(node.children[0])) {
1407                             ret = this.execute(node.children[1]);
1408                         }
1409                         break;
1410                     case 'op_conditional':
1411                     // fall through
1412                     case 'op_if_else':
1413                         if (this.execute(node.children[0])) {
1414                             ret = this.execute(node.children[1]);
1415                         } else {
1416                             ret = this.execute(node.children[2]);
1417                         }
1418                         break;
1419                     case 'op_while':
1420                         while (this.execute(node.children[0])) {
1421                             this.execute(node.children[1]);
1422                         }
1423                         break;
1424                     case 'op_do':
1425                         do {
1426                             this.execute(node.children[0]);
1427                         } while (this.execute(node.children[1]));
1428                         break;
1429                     case 'op_for':
1430                         for (this.execute(node.children[0]); this.execute(node.children[1]); this.execute(node.children[2])) {
1431                             this.execute(node.children[3]);
1432                         }
1433                         break;
1434                     case 'op_proplst':
1435                         if (node.children[0]) {
1436                             this.execute(node.children[0]);
1437                         }
1438                         if (node.children[1]) {
1439                             this.execute(node.children[1]);
1440                         }
1441                         break;
1442                     case 'op_emptyobject':
1443                         ret = {};
1444                         break;
1445                     case 'op_proplst_val':
1446                         this.propstack.push({});
1447                         this.propscope++;
1448 
1449                         this.execute(node.children[0]);
1450                         ret = this.propstack[this.propscope];
1451 
1452                         this.propstack.pop();
1453                         this.propscope--;
1454                         break;
1455                     case 'op_prop':
1456                         // child 0: Identifier
1457                         // child 1: Value
1458                         this.propstack[this.propscope][node.children[0]] = this.execute(node.children[1]);
1459                         break;
1460                     case 'op_array':
1461                         ret = [];
1462                         l = node.children[0].length;
1463 
1464                         for (i = 0; i < l; i++) {
1465                             ret.push(this.execute(node.children[0][i]));
1466                         }
1467 
1468                         break;
1469                     case 'op_extvalue':
1470                         ret = this.execute(node.children[0]);
1471                         i = this.execute(node.children[1]);
1472 
1473                         if (typeof i === 'number' && Math.abs(Math.round(i) - i) < 1.e-12) {
1474                             ret = ret[i];
1475                         } else {
1476                             ret = undef;
1477                         }
1478                         break;
1479                     case 'op_return':
1480                         if (this.scope === 0) {
1481                             this._error('Unexpected return.');
1482                         } else {
1483                             return this.execute(node.children[0]);
1484                         }
1485                         break;
1486                     case 'op_map':
1487                         if (!node.children[1].isMath && node.children[1].type !== 'node_var') {
1488                             this._error('execute: In a map only function calls and mathematical expressions are allowed.');
1489                         }
1490 
1491                         /** @ignore */
1492                         fun = this.defineFunction(node);
1493                         fun.isMap = true;
1494 
1495                         ret = fun;
1496                         break;
1497                     case 'op_function':
1498                         // parse the parameter list
1499                         // after this, the parameters are in pstack
1500 
1501                         /** @ignore */
1502                         fun = this.defineFunction(node);
1503                         fun.isMap = false;
1504 
1505                         ret = fun;
1506                         break;
1507                     case 'op_execfun':
1508                         // node.children:
1509                         //   [0]: Name of the function
1510                         //   [1]: Parameter list as a parse subtree
1511                         //   [2]: Properties, only used in case of a create function
1512                         this.dpstack.push([]);
1513                         this.pscope++;
1514 
1515                         // parameter parsing is done below
1516                         list = node.children[1];
1517 
1518                         // parse the properties only if given
1519                         if (Type.exists(node.children[2])) {
1520                             if (node.children[3]) {
1521                                 ilist = node.children[2];
1522                                 attr = {};
1523 
1524                                 for (i = 0; i < ilist.length; i++) {
1525                                     attr = Type.deepCopy(attr, this.execute(ilist[i]), true);
1526                                 }
1527                             } else {
1528                                 attr = this.execute(node.children[2]);
1529                             }
1530                         }
1531 
1532                         // look up the variables name in the variable table
1533                         node.children[0]._isFunctionName = true;
1534                         fun = this.execute(node.children[0]);
1535                         delete node.children[0]._isFunctionName;
1536 
1537                         // determine the scope the function wants to run in
1538                         if (Type.exists(fun) && Type.exists(fun.sc)) {
1539                             sc = fun.sc;
1540                         } else {
1541                             sc = this;
1542                         }
1543 
1544                         if (!fun.creator && Type.exists(node.children[2])) {
1545                             this._error('Unexpected value. Only element creators are allowed to have a value after the function call.');
1546                         }
1547 
1548                         // interpret ALL the parameters
1549                         for (i = 0; i < list.length; i++) {
1550                             if (Type.exists(fun.scope) && Type.exists(fun.scope.argtypes) && fun.scope.argtypes[i] === 'function') {
1551                                 // Type inspection
1552                                 list[i]._isFunctionName = true;
1553                                 parents[i] = this.execute(list[i]);
1554                                 delete list[i]._isFunctionName;
1555                             } else {
1556                                 parents[i] = this.execute(list[i]);
1557                             }
1558                             //parents[i] = Type.evalSlider(this.execute(list[i]));
1559                             this.dpstack[this.pscope].push({
1560                                 line: node.children[1][i].line,
1561                                 // SketchBin currently works only if the last column of the
1562                                 // parent position is taken. This is due to how I patched JS/CC
1563                                 // to count the lines and columns. So, ecol will do for now
1564                                 col: node.children[1][i].ecol
1565                             });
1566                         }
1567 
1568                         // check for the function in the variable table
1569                         if (typeof fun === 'function' && !fun.creator) {
1570                             ret = fun.apply(sc, parents);
1571                         } else if (typeof fun === 'function' && !!fun.creator) {
1572                             e = this.line;
1573 
1574                             // creator methods are the only ones that take properties, hence this special case
1575                             try {
1576                                 ret = fun(parents, attr);
1577                                 ret.jcLineStart = e;
1578                                 ret.jcLineEnd = node.eline;
1579 
1580                                 for (i = e; i <= node.line; i++) {
1581                                     this.lineToElement[i] = ret;
1582                                 }
1583 
1584                                 ret.debugParents = this.dpstack[this.pscope];
1585                             } catch (ex) {
1586                                 this._error(ex.toString());
1587                             }
1588                         } else {
1589                             this._error('Function \'' + fun + '\' is undefined.');
1590                         }
1591 
1592                         // clear parameter stack
1593                         this.dpstack.pop();
1594                         this.pscope--;
1595                         break;
1596                     case 'op_property':
1597                         e = this.execute(node.children[0]);
1598                         v = node.children[1];
1599 
1600                         ret = this.resolveProperty(e, v, false);
1601 
1602                         // set the scope, in case this is a method the user wants to call
1603                         if (Type.exists(ret) && ['number', 'string', 'boolean'].indexOf(typeof ret) < 0) {
1604                             ret.sc = e;
1605                         }
1606 
1607                         break;
1608                     case 'op_use':
1609                         this._warn('Use of the \'use\' operator is deprecated.');
1610                         this.use(node.children[0].toString());
1611                         break;
1612                     case 'op_delete':
1613                         this._warn('Use of the \'delete\' operator is deprecated. Please use the remove() function.');
1614                         v = this.getvar(node.children[0]);
1615                         ret = this.del(v);
1616                         break;
1617                     case 'op_eq':
1618                         // == is intentional
1619                         /*jslint eqeq:true*/
1620                         /* eslint-disable eqeqeq */
1621                         ret = this.execute(node.children[0]) == this.execute(node.children[1]);
1622                         /*jslint eqeq:false*/
1623                         /* eslint-enable eqeqeq */
1624                         break;
1625                     case 'op_neq':
1626                         // != is intentional
1627                         /*jslint eqeq:true*/
1628                         /* eslint-disable eqeqeq */
1629                         ret = this.execute(node.children[0]) != this.execute(node.children[1]);
1630                         /*jslint eqeq:true*/
1631                         /* eslint-enable eqeqeq */
1632                         break;
1633                     case 'op_approx':
1634                         ret = Math.abs(this.execute(node.children[0]) - this.execute(node.children[1])) < Mat.eps;
1635                         break;
1636                     case 'op_gt':
1637                         ret = this.execute(node.children[0]) > this.execute(node.children[1]);
1638                         break;
1639                     case 'op_lt':
1640                         ret = this.execute(node.children[0]) < this.execute(node.children[1]);
1641                         break;
1642                     case 'op_geq':
1643                         ret = this.execute(node.children[0]) >= this.execute(node.children[1]);
1644                         break;
1645                     case 'op_leq':
1646                         ret = this.execute(node.children[0]) <= this.execute(node.children[1]);
1647                         break;
1648                     case 'op_or':
1649                         ret = this.execute(node.children[0]) || this.execute(node.children[1]);
1650                         break;
1651                     case 'op_and':
1652                         ret = this.execute(node.children[0]) && this.execute(node.children[1]);
1653                         break;
1654                     case 'op_not':
1655                         ret = !this.execute(node.children[0]);
1656                         break;
1657                     case 'op_add':
1658                         ret = this.add(this.execute(node.children[0]), this.execute(node.children[1]));
1659                         break;
1660                     case 'op_sub':
1661                         ret = this.sub(this.execute(node.children[0]), this.execute(node.children[1]));
1662                         break;
1663                     case 'op_div':
1664                         ret = this.div(this.execute(node.children[0]), this.execute(node.children[1]));
1665                         break;
1666                     case 'op_mod':
1667                         // use mathematical modulo, JavaScript implements the symmetric modulo.
1668                         ret = this.mod(this.execute(node.children[0]), this.execute(node.children[1]), true);
1669                         break;
1670                     case 'op_mul':
1671                         ret = this.mul(this.execute(node.children[0]), this.execute(node.children[1]));
1672                         break;
1673                     case 'op_exp':
1674                         ret = this.pow(this.execute(node.children[0]), this.execute(node.children[1]));
1675                         break;
1676                     case 'op_neg':
1677                         ret = this.neg(this.execute(node.children[0]));
1678                         break;
1679                 }
1680                 break;
1681 
1682             case 'node_var':
1683                 // node._isFunctionName is set in execute: at op_execfun.
1684                 ret = this.getvar(node.value, false, node._isFunctionName);
1685                 break;
1686 
1687             case 'node_const':
1688                 if (node.value === null) {
1689                     ret = null;
1690                 } else {
1691                     ret = Number(node.value);
1692                 }
1693                 break;
1694 
1695             case 'node_const_bool':
1696                 ret = node.value;
1697                 break;
1698 
1699             case 'node_str':
1700                 //ret = node.value.replace(/\\'/, "'").replace(/\\"/, '"').replace(/\\\\/, '\\');
1701                 /*jslint regexp:true*/
1702                 ret = node.value.replace(/\\(.)/g, '$1'); // Remove backslash, important in JessieCode tags
1703                 /*jslint regexp:false*/
1704                 break;
1705         }
1706 
1707         return ret;
1708     },
1709 
1710     /**
1711      * Compiles a parse tree back to JessieCode.
1712      * @param {Object} ast
1713      * @param {Boolean} [js=false] Compile either to JavaScript or back to JessieCode (required for the UI).
1714      * @param {Object} [format] Options for formatting the output. Depending on some options, the function might return a not re-parsable string. This format options have only effect on JessieCode output.<ul>
1715      *     <li>{Boolean} [minParentheses=false]               Use minimal amount of parentheses?</li>
1716      *     <li>{Boolean|Number|Function} [constToFixed=false] Use this number or function to format constant values.</li>
1717      *     <li>{Boolean} [printable=false]                    Adds additional signs or parentheses, e.g. x^0.5 --> x^{0.5}.</li>
1718      *     </ul>
1719      * @returns Something
1720      * @private
1721      */
1722     compile: function (ast, js, format) {
1723         var that = this;
1724 
1725         if (!Type.exists(js)) {
1726             js = false;
1727         }
1728         if (!Type.exists(format) || !Type.isObject(format)) {
1729             format = {};
1730         }
1731         format = Type.deepCopy({
1732             minParentheses: false,
1733             constToFixed: false,
1734             printable: false
1735         }, format);
1736 
1737         // node_const/node_var >> op_execfun >> op_neg >> op_exp >> op_mul/op_div >> op_add/op_sub >> op_map >> op_assign
1738         function prio(node) {
1739             switch (node.type) {
1740                 case "node_const":
1741                 case "node_const_bool":
1742                 case "node_str":
1743                 case "node_var":
1744                     return 10;
1745                 case "node_op":
1746                     switch (node.value) {
1747                         case "op_none":
1748                             return 0;
1749                         case "op_assign":
1750                             return 1;
1751                         case "op_map":
1752                         case "op_function":
1753                         case "op_return":
1754                             return 2;
1755                         case "op_add":
1756                         case "op_sub":
1757                             return 3;
1758                         case "op_mul":
1759                         case "op_div":
1760                         case "op_mod":
1761                             return 5;
1762                         case "op_neg":
1763                             return 4;
1764                         case "op_exp":
1765                             return 6;
1766                         case "op_array":
1767                         case "op_execfun":
1768                             return 7;
1769                         default:
1770                             return 0;
1771                     }
1772                 default:
1773                     return 0;
1774             }
1775         }
1776 
1777         function compile(node, prevOp, position = -1) {
1778             var e, i, c, list, scope, prioParent, prioChild,
1779                 ret = '';
1780 
1781             if (!node) {
1782                 return ret;
1783             }
1784 
1785             switch (node.type) {
1786                 case 'node_op':
1787                     switch (node.value) {
1788                         case 'op_none':
1789                             if (node.children[0]) {
1790                                 ret = compile(node.children[0], "op_none");
1791                             }
1792                             if (node.children[1]) {
1793                                 ret += compile(node.children[1], "op_none");
1794                             }
1795                             break;
1796                         case 'op_block':
1797                             ret = '{\n' + compile(node.children[0], "op_block") + ' }\n';
1798                             break;
1799                         case 'op_assign':
1800                             if (js) {
1801                                 e = that.getLHSCompiler(node.children[0], js);
1802                                 if (Type.isArray(e)) {
1803                                     ret = '$jc$.setProp(' + e[0] + ', ' + e[1] + ', ' + compile(node.children[1], "op_assign") + ');\n';
1804                                 } else {
1805                                     if (that.isLocalVariable(e) !== that.scope) {
1806                                         that.scope.locals[e] = true;
1807                                     }
1808                                     ret = '$jc$.scopes[' + that.scope.id + '].locals[\'' + e + '\'] = ' + compile(node.children[1], "op_assign") + ';\n';
1809                                 }
1810                             } else {
1811                                 e = compile(node.children[0], "op_assign");
1812                                 ret = e + ' = ' + compile(node.children[1], "op_assign") + ';\n';
1813                             }
1814                             break;
1815                         case 'op_if':
1816                             ret = ' if (' + compile(node.children[0], "op_if") + ') ' + compile(node.children[1], "op_if");
1817                             break;
1818                         case 'op_if_else':
1819                             ret = ' if (' + compile(node.children[0], "op_if_else") + ')' + compile(node.children[1], "op_if_else");
1820                             ret += ' else ' + compile(node.children[2], "op_if_else");
1821                             break;
1822                         case 'op_conditional':
1823                             ret = '((' + compile(node.children[0], "op_conditional") + ')?(' + compile(node.children[1], "op_conditional");
1824                             ret += '):(' + compile(node.children[2], "op_conditional") + '))';
1825                             break;
1826                         case 'op_while':
1827                             ret = ' while (' + compile(node.children[0], "op_while") + ') {\n' + compile(node.children[1], "op_while") + '}\n';
1828                             break;
1829                         case 'op_do':
1830                             ret = ' do {\n' + compile(node.children[0], "op_do") + '} while (' + compile(node.children[1], "op_do") + ');\n';
1831                             break;
1832                         case 'op_for':
1833                             //ret = ' for (' + compile(node.children[0]) + '; ' + compile(node.children[1]) + '; ' + compile(node.children[2]) + ') {\n' + compile(node.children[3]) + '\n}\n';
1834                             ret = ' for (' + compile(node.children[0], "op_for") +   // Assignment ends with ";"
1835                                 compile(node.children[1], "op_for") + '; ' +         // Logical test comes without ";"
1836                                 compile(node.children[2], "op_for").slice(0, -2) +   // Counting comes with ";" which has to be removed
1837                                 ') {\n' + compile(node.children[3], "op_for") + '\n}\n';
1838                             break;
1839                         case 'op_proplst':
1840                             if (node.children[0]) {
1841                                 ret = compile(node.children[0], "op_proplst") + ', ';
1842                             }
1843 
1844                             ret += compile(node.children[1], "op_proplst");
1845                             break;
1846                         case 'op_prop':
1847                             // child 0: Identifier
1848                             // child 1: Value
1849                             ret = node.children[0] + ': ' + compile(node.children[1], "op_prop");
1850                             break;
1851                         case 'op_emptyobject':
1852                             ret = js ? '{}' : '<< >>';
1853                             break;
1854                         case 'op_proplst_val':
1855                             ret = compile(node.children[0], "op_proplst_val");
1856                             break;
1857                         case 'op_array':
1858                             list = [];
1859                             for (i = 0; i < node.children[0].length; i++) {
1860                                 list.push(compile(node.children[0][i], "op_array"));
1861                             }
1862                             ret = '[' + list.join(', ') + ']';
1863                             break;
1864                         case 'op_extvalue':
1865                             ret = compile(node.children[0], "op_extvalue") + '[' + compile(node.children[1], "op_extvalue") + ']';
1866                             break;
1867                         case 'op_return':
1868                             ret = ' return ' + compile(node.children[0], "op_return") + ';\n';
1869                             break;
1870                         case 'op_map':
1871                             if (!node.children[1].isMath && node.children[1].type !== 'node_var') {
1872                                 that._error('compile: In a map only function calls and mathematical expressions are allowed.');
1873                             }
1874 
1875                             list = node.children[0];
1876                             if (js) {
1877                                 ret = ' $jc$.makeMap(function (' + list.join(', ') + ') { return ' + compile(node.children[1], "op_map") + '; })';
1878                             } else {
1879                                 ret = 'map (' + list.join(', ') + ') -> ' + compile(node.children[1], "op_map");
1880                             }
1881 
1882                             break;
1883                         case 'op_function':
1884                             list = node.children[0];
1885                             scope = that.pushScope(list);
1886                             if (js) {
1887                                 ret = that.functionCodeJS(node);
1888                             } else {
1889                                 ret = ' function (' + list.join(', ') + ') ' + compile(node.children[1], "op_function");
1890                             }
1891                             that.popScope();
1892                             break;
1893                         case 'op_execfunmath':
1894                             console.log('op_execfunmath: TODO');
1895                             ret = '-1';
1896                             break;
1897                         case 'op_execfun':
1898                             // parse the properties only if given
1899                             if (node.children[2]) {
1900                                 list = [];
1901                                 for (i = 0; i < node.children[2].length; i++) {
1902                                     list.push(compile(node.children[2][i], "op_execfun"));
1903                                 }
1904 
1905                                 if (js) {
1906                                     e = '$jc$.mergeAttributes(' + list.join(', ') + ')';
1907                                 } else {
1908                                     e = list.join(', ');
1909                                 }
1910                             }
1911                             node.children[0].withProps = !!node.children[2];
1912                             list = [];
1913                             for (i = 0; i < node.children[1].length; i++) {
1914                                 list.push(compile(node.children[1][i], "op_execfun"));
1915                             }
1916                             ret = compile(node.children[0], "op_execfun") + '(' + list.join(', ') + (node.children[2] && js ? ', ' + e : '') + ')' + ((node.children[2] && !js) ? ' ' + e : '');
1917                             if (js) {
1918                                 // Inserting a newline here allows simultaneously
1919                                 // - procedural calls like Q.moveTo(...); and
1920                                 // - function calls in expressions like log(x) + 1;
1921                                 // Problem: procedural calls will not be ended by a semicolon.
1922                                 ret += '\n';
1923                             }
1924 
1925                             // save us a function call when compiled to javascript
1926                             if (js && node.children[0].value === '$') {
1927                                 ret = '$jc$.board.objects[' + compile(node.children[1][0], "op_execfun") + ']';
1928                             }
1929                             break;
1930                         case 'op_property':
1931                             if (js && node.children[1] !== 'X' && node.children[1] !== 'Y') {
1932                                 ret = '$jc$.resolveProperty(' + compile(node.children[0], "op_property") + ', \'' + node.children[1] + '\', true)';
1933                             } else {
1934                                 ret = compile(node.children[0], "op_property") + '.' + node.children[1];
1935                             }
1936                             break;
1937                         case 'op_use':
1938                             that._warn('Use of the \'use\' operator is deprecated.');
1939                             if (js) {
1940                                 ret = '$jc$.use(\'';
1941                             } else {
1942                                 ret = 'use(\'';
1943                             }
1944 
1945                             ret += node.children[0].toString() + '\');';
1946                             break;
1947                         case 'op_delete':
1948                             that._warn('Use of the \'delete\' operator is deprecated. Please use the remove() function.');
1949                             if (js) {
1950                                 ret = '$jc$.del(';
1951                             } else {
1952                                 ret = 'remove(';
1953                             }
1954 
1955                             ret += compile(node.children[0], "op_delete") + ')';
1956                             break;
1957                         case 'op_eq':
1958                             ret = '(' + compile(node.children[0], "op_eq") + ' === ' + compile(node.children[1], "op_eq") + ')';
1959                             break;
1960                         case 'op_neq':
1961                             ret = '(' + compile(node.children[0], "op_neq") + ' !== ' + compile(node.children[1], "op_neq") + ')';
1962                             break;
1963                         case 'op_approx':
1964                             ret = '(' + compile(node.children[0], "op_approx") + ' ~= ' + compile(node.children[1], "op_approx") + ')';
1965                             break;
1966                         case 'op_gt':
1967                             if (js) {
1968                                 ret = '$jc$.gt(' + compile(node.children[0], "op_gt") + ', ' + compile(node.children[1], "op_gt") + ')';
1969                             } else {
1970                                 ret = '(' + compile(node.children[0], "op_gt") + ' > ' + compile(node.children[1], "op_gt") + ')';
1971                             }
1972                             break;
1973                         case 'op_lt':
1974                             if (js) {
1975                                 ret = '$jc$.lt(' + compile(node.children[0], "op_lt") + ', ' + compile(node.children[1], "op_lt") + ')';
1976                             } else {
1977                                 ret = '(' + compile(node.children[0], "op_lt") + ' < ' + compile(node.children[1], "op_lt") + ')';
1978                             }
1979                             break;
1980                         case 'op_geq':
1981                             if (js) {
1982                                 ret = '$jc$.geq(' + compile(node.children[0], "op_geq") + ', ' + compile(node.children[1], "op_geq") + ')';
1983                             } else {
1984                                 ret = '(' + compile(node.children[0], "op_geq") + ' >= ' + compile(node.children[1], "op_geq") + ')';
1985                             }
1986                             break;
1987                         case 'op_leq':
1988                             if (js) {
1989                                 ret = '$jc$.leq(' + compile(node.children[0], "op_leq") + ', ' + compile(node.children[1], "op_leq") + ')';
1990                             } else {
1991                                 ret = '(' + compile(node.children[0], "op_leq") + ' <= ' + compile(node.children[1], "op_leq") + ')';
1992                             }
1993                             break;
1994                         case 'op_or':
1995                             ret = '(' + compile(node.children[0], "op_or") + ' || ' + compile(node.children[1], "op_or") + ')';
1996                             break;
1997                         case 'op_and':
1998                             ret = '(' + compile(node.children[0], "op_and") + ' && ' + compile(node.children[1], "op_and") + ')';
1999                             break;
2000                         case 'op_not':
2001                             ret = '!(' + compile(node.children[0], "op_not") + ')';
2002                             break;
2003                         case "op_add":
2004                             if (js) {
2005                                 ret = '$jc$.add(' + compile(node.children[0], "op_add") + ', ' + compile(node.children[1], "op_add") + ')';
2006                             } else if (!format.minParentheses) {
2007                                 ret = '(' + compile(node.children[0], "op_add") + ' + ' + compile(node.children[1], "op_add") + ')';
2008                             } else {
2009                                 prioParent = prio(node);
2010 
2011                                 e = compile(node.children[0], "op_add");
2012                                 prioChild = prio(node.children[0]);
2013                                 ret = (prioParent > prioChild) ? "(" + e + ")" : e;
2014 
2015                                 ret += ' + ';
2016 
2017                                 e = compile(node.children[1], "op_add");
2018                                 prioChild = prio(node.children[1]);
2019                                 ret += (prioParent > prioChild) ? "(" + e + ")" : e;
2020                             }
2021                             break;
2022                         case 'op_sub':
2023                             if (js) {
2024                                 ret = '$jc$.sub(' + compile(node.children[0], "op_sub") + ', ' + compile(node.children[1], "op_sub") + ')';
2025                             } else if (!format.minParentheses) {
2026                                 ret = '(' + compile(node.children[0], "op_sub") + ' - ' + compile(node.children[1], "op_sub") + ')';
2027                             } else {
2028                                 prioParent = prio(node);
2029 
2030                                 e = compile(node.children[0], "op_sub");
2031                                 prioChild = prio(node.children[0]);
2032                                 ret = (prioParent > prioChild) ? "(" + e + ")" : e;
2033 
2034                                 ret += ' - ';
2035 
2036                                 e = compile(node.children[1], "op_sub");
2037                                 prioChild = prio(node.children[1]);
2038                                 ret += (prioParent >= prioChild) ? "(" + e + ")" : e;
2039                             }
2040                             break;
2041                         case 'op_div':
2042                             if (js) {
2043                                 ret = '$jc$.div(' + compile(node.children[0], "op_div") + ', ' + compile(node.children[1], "op_div") + ')';
2044                             } else if (!format.minParentheses) {
2045                                 ret = '(' + compile(node.children[0], "op_div") + ' / ' + compile(node.children[1], "op_div") + ')';
2046                             } else {
2047                                 prioParent = prio(node);
2048 
2049                                 e = compile(node.children[0], "op_div");
2050                                 prioChild = prio(node.children[0]);
2051                                 ret = (prioParent > prioChild) ? "(" + e + ")" : e;
2052 
2053                                 ret += ' / ';
2054 
2055                                 e = compile(node.children[1], "op_div");
2056                                 prioChild = prio(node.children[1]);
2057                                 ret += (prioParent >= prioChild) ? "(" + e + ")" : e;
2058                             }
2059                             break;
2060                         case 'op_mod':
2061                             if (js) {
2062                                 ret = '$jc$.mod(' + compile(node.children[0], "op_mod") + ', ' + compile(node.children[1], "op_mod") + ', true)';
2063                             } else if (!format.minParentheses) {
2064                                 ret = '(' + compile(node.children[0], "op_mod") + ' % ' + compile(node.children[1], "op_mod") + ')';
2065                             } else {
2066                                 prioParent = prio(node);
2067 
2068                                 e = compile(node.children[0], "op_mod");
2069                                 prioChild = prio(node.children[0]);
2070                                 ret = (prioParent > prioChild) ? "(" + e + ")" : e;
2071 
2072                                 ret += ' % ';
2073 
2074                                 e = compile(node.children[1], "op_mod");
2075                                 prioChild = prio(node.children[1]);
2076                                 ret += (prioParent >= prioChild) ? "(" + e + ")" : e;
2077                             }
2078                             break;
2079                         case 'op_mul':
2080                             if (js) {
2081                                 ret = '$jc$.mul(' + compile(node.children[0], "op_mul") + ', ' + compile(node.children[1], "op_mul") + ')';
2082                             } else if (!format.minParentheses) {
2083                                 ret = '(' + compile(node.children[0], "op_mul") + ' * ' + compile(node.children[1], "op_mul") + ')';
2084                             } else {
2085                                 prioParent = prio(node);
2086 
2087                                 e = compile(node.children[0], "op_mul");
2088                                 prioChild = prio(node.children[0]);
2089                                 ret = (prioParent > prioChild) ? "(" + e + ")" : e;
2090 
2091                                 ret += ' * ';
2092 
2093                                 e = compile(node.children[1], "op_mul");
2094                                 prioChild = prio(node.children[1]);
2095                                 ret += (prioParent > prioChild) ? "(" + e + ")" : e;
2096                             }
2097                             break;
2098                         case 'op_exp':
2099                             if (js) {
2100                                 ret = '$jc$.pow(' + compile(node.children[0], "op_exp", 0) + ', ' + compile(node.children[1], "op_exp", 1) + ')';
2101                             } else if (!format.minParentheses) {
2102                                 ret = '('
2103                                     + compile(node.children[0], "op_exp", 0)
2104                                     + '^' + compile(node.children[1], "op_exp", 1)
2105                                     + ')';
2106                             } else {
2107                                 prioParent = prio(node);
2108 
2109                                 e = compile(node.children[0], "op_exp", 0);
2110                                 prioChild = prio(node.children[0]);
2111                                 ret = (prioParent >= prioChild)
2112                                     ? "(" + e + ")"
2113                                     : e;
2114 
2115                                 ret += '^';
2116 
2117                                 e = compile(node.children[1], "op_exp", 1);
2118                                 prioChild = prio(node.children[1]);
2119                                 ret += (prioParent > prioChild && !(format.printable && e[0] === '{' && e[e.length - 1] === '}'))
2120                                     ? "(" + e + ")"
2121                                     : e;
2122                             }
2123                             break;
2124                         case 'op_neg':
2125                             if (js) {
2126                                 ret = '$jc$.neg(' + compile(node.children[0], "op_neg") + ')';
2127                             } else if (!format.minParentheses) {
2128                                 ret = '(-' + compile(node.children[0], "op_neg") + ')';
2129                             } else {
2130                                 prioParent = prio(node);
2131                                 prioChild = prio(node.children[0]);
2132                                 e = compile(node.children[0], "op_neg");
2133                                 if (prioParent >= prioChild) {
2134                                     ret = '-(' + e + ')';
2135                                 } else {
2136                                     ret = '-' + e;
2137                                 }
2138                             }
2139                             break;
2140                     }
2141                     break;
2142 
2143                 case 'node_var':
2144                     if (js) {
2145                         ret = that.getvarJS(node.value, false, node.withProps);
2146                     } else {
2147                         ret = node.value;
2148                     }
2149                     break;
2150 
2151                 case 'node_const':
2152                     if (js) {
2153                         ret = node.value;
2154                         break;
2155                     }
2156 
2157                     c = node.value;
2158                     if (
2159                         format.constToFixed !== false &&
2160                         Type.isNumber(c) &&
2161                         !(prevOp === "op_exp" && position === 1) // exponents will not be formatted
2162                     ) {
2163                         c = parseFloat(c);
2164                         if (Type.isNumber(format.constToFixed)) {
2165                             c = Type.toFixed(c, format.constToFixed);
2166                         } else if (Type.isFunction(format.constToFixed)) {
2167                             c = format.constToFixed(c);
2168                         } else {
2169                             c = node.value;
2170                         }
2171                     }
2172                     if (format.minParentheses && parseFloat(c) < 0 && prevOp !== "op_execfun" && position !== 0) {
2173                         ret = "(" + c + ")";
2174                     } else {
2175                         ret = c;
2176                     }
2177                     break;
2178 
2179                 case 'node_const_bool':
2180                     ret = node.value;
2181                     break;
2182 
2183                 case 'node_str':
2184                     ret = '\'' + node.value + '\'';
2185                     break;
2186             }
2187 
2188             if (node.needsAngleBrackets) {
2189                 if (js) {
2190                     ret = '{\n' + ret + ' }\n';
2191                 } else {
2192                     ret = '<< ' + ret + ' >>\n';
2193                 }
2194             }
2195 
2196             if (format.printable && prevOp === "op_exp" && position === 1) {
2197                 ret = '{' + ret + '}';
2198             }
2199 
2200             if (format.printable && Type.isString(ret)) {
2201                 ret = ret.replaceAll('\n', '');
2202             }
2203 
2204             return ret;
2205         }
2206 
2207         return compile(ast, "");
2208     },
2209 
2210     /**
2211      * This is used as the global getName() function.
2212      * @param {JXG.GeometryElement} obj
2213      * @param {Boolean} useId
2214      * @returns {String}
2215      */
2216     getName: function (obj, useId) {
2217         var name = '';
2218 
2219         if (Type.exists(obj) && Type.exists(obj.getName)) {
2220             name = obj.getName();
2221             if ((!Type.exists(name) || name === '') && useId) {
2222                 name = obj.id;
2223             }
2224         } else if (useId) {
2225             name = obj.id;
2226         }
2227 
2228         return name;
2229     },
2230 
2231     /**
2232      * This is used as the global X() function.
2233      * @param {JXG.Point|JXG.Text} e
2234      * @returns {Number}
2235      */
2236     X: function (e) {
2237         return e.X();
2238     },
2239 
2240     /**
2241      * This is used as the global Y() function.
2242      * @param {JXG.Point|JXG.Text} e
2243      * @returns {Number}
2244      */
2245     Y: function (e) {
2246         return e.Y();
2247     },
2248 
2249     /**
2250      * This is used as the global V() function.
2251      * @param {Glider|Slider} e
2252      * @returns {Number}
2253      */
2254     V: function (e) {
2255         return e.Value();
2256     },
2257 
2258     /**
2259      * This is used as the global L() function.
2260      * @param {JXG.Line} e
2261      * @returns {Number}
2262      */
2263     L: function (e) {
2264         return e.L();
2265     },
2266 
2267     /**
2268      * This is used as the global area() function.
2269      * @param {JXG.Circle|JXG.Polygon} obj
2270      * @returns {Number}
2271      */
2272     area: function (obj) {
2273         if (!Type.exists(obj) || !Type.exists(obj.Area)) {
2274             this._error('Error: Can\'t calculate area.');
2275         }
2276 
2277         return obj.Area();
2278     },
2279 
2280     /**
2281      * This is used as the global perimeter() function.
2282      * @param {JXG.Circle|JXG.Polygon} obj
2283      * @returns {Number}
2284      */
2285     perimeter: function (obj) {
2286         if (!Type.exists(obj) || !Type.exists(obj.Perimeter)) {
2287             this._error('Error: Can\'t calculate perimeter.');
2288         }
2289 
2290         return obj.Perimeter();
2291     },
2292 
2293     /**
2294      * This is used as the global dist() function.
2295      * @param {JXG.Point} p1
2296      * @param {JXG.Point} p2
2297      * @returns {Number}
2298      */
2299     dist: function (p1, p2) {
2300         if (!Type.exists(p1) || !Type.exists(p1.Dist)) {
2301             this._error('Error: Can\'t calculate distance.');
2302         }
2303 
2304         return p1.Dist(p2);
2305     },
2306 
2307     /**
2308      * This is used as the global radius() function.
2309      * @param {JXG.Circle|Sector} obj
2310      * @returns {Number}
2311      */
2312     radius: function (obj) {
2313         if (!Type.exists(obj) || !Type.exists(obj.Radius)) {
2314             this._error('Error: Can\'t calculate radius.');
2315         }
2316 
2317         return obj.Radius();
2318     },
2319 
2320     /**
2321      * This is used as the global slope() function.
2322      * @param {JXG.Line} obj
2323      * @returns {Number}
2324      */
2325     slope: function (obj) {
2326         if (!Type.exists(obj) || !Type.exists(obj.Slope)) {
2327             this._error('Error: Can\'t calculate slope.');
2328         }
2329 
2330         return obj.Slope();
2331     },
2332 
2333     /**
2334      * + operator implementation
2335      * @param {Number|Array|JXG.Point} a
2336      * @param {Number|Array|JXG.Point} b
2337      * @returns {Number|Array}
2338      */
2339     add: function (a, b) {
2340         var i, len, res;
2341 
2342         a = Type.evalSlider(a);
2343         b = Type.evalSlider(b);
2344 
2345         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2346             res = Interval.add(a, b);
2347         } else if (Type.isArray(a) && Type.isArray(b)) {
2348             len = Math.min(a.length, b.length);
2349             res = [];
2350 
2351             for (i = 0; i < len; i++) {
2352                 res[i] = a[i] + b[i];
2353             }
2354         } else if (Type.isNumber(a) && Type.isNumber(b)) {
2355             res = a + b;
2356         } else if (Type.isString(a) || Type.isString(b)) {
2357             res = a.toString() + b.toString();
2358         } else {
2359             this._error('Operation + not defined on operands ' + typeof a + ' and ' + typeof b);
2360         }
2361 
2362         return res;
2363     },
2364 
2365     /**
2366      * - operator implementation
2367      * @param {Number|Array|JXG.Point} a
2368      * @param {Number|Array|JXG.Point} b
2369      * @returns {Number|Array}
2370      */
2371     sub: function (a, b) {
2372         var i, len, res;
2373 
2374         a = Type.evalSlider(a);
2375         b = Type.evalSlider(b);
2376 
2377         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2378             res = Interval.sub(a, b);
2379         } else if (Type.isArray(a) && Type.isArray(b)) {
2380             len = Math.min(a.length, b.length);
2381             res = [];
2382 
2383             for (i = 0; i < len; i++) {
2384                 res[i] = a[i] - b[i];
2385             }
2386         } else if (Type.isNumber(a) && Type.isNumber(b)) {
2387             res = a - b;
2388         } else {
2389             this._error('Operation - not defined on operands ' + typeof a + ' and ' + typeof b);
2390         }
2391 
2392         return res;
2393     },
2394 
2395     /**
2396      * unary - operator implementation
2397      * @param {Number|Array|JXG.Point} a
2398      * @returns {Number|Array}
2399      */
2400     neg: function (a) {
2401         var i, len, res;
2402 
2403         a = Type.evalSlider(a);
2404 
2405         if (Interval.isInterval(a)) {
2406             res = Interval.negative(a);
2407         } else if (Type.isArray(a)) {
2408             len = a.length;
2409             res = [];
2410 
2411             for (i = 0; i < len; i++) {
2412                 res[i] = -a[i];
2413             }
2414         } else if (Type.isNumber(a)) {
2415             res = -a;
2416         } else {
2417             this._error('Unary operation - not defined on operand ' + typeof a);
2418         }
2419 
2420         return res;
2421     },
2422 
2423     /**
2424      * Multiplication of vectors and numbers
2425      * @param {Number|Array} a
2426      * @param {Number|Array} b
2427      * @returns {Number|Array} (Inner) product of the given input values.
2428      */
2429     mul: function (a, b) {
2430         var i, len, res;
2431 
2432         a = Type.evalSlider(a);
2433         b = Type.evalSlider(b);
2434 
2435         if (Type.isArray(a) && Type.isNumber(b)) {
2436             // swap b and a
2437             i = a;
2438             a = b;
2439             b = a;
2440         }
2441 
2442         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2443             res = Interval.mul(a, b);
2444         } else if (Type.isArray(a) && Type.isArray(b)) {
2445             len = Math.min(a.length, b.length);
2446             res = Mat.innerProduct(a, b, len);
2447         } else if (Type.isNumber(a) && Type.isArray(b)) {
2448             len = b.length;
2449             res = [];
2450 
2451             for (i = 0; i < len; i++) {
2452                 res[i] = a * b[i];
2453             }
2454         } else if (Type.isNumber(a) && Type.isNumber(b)) {
2455             res = a * b;
2456         } else {
2457             this._error('Operation * not defined on operands ' + typeof a + ' and ' + typeof b);
2458         }
2459 
2460         return res;
2461     },
2462 
2463     /**
2464      * Implementation of the / operator.
2465      * @param {Number|Array} a
2466      * @param {Number} b
2467      * @returns {Number|Array}
2468      */
2469     div: function (a, b) {
2470         var i, len, res;
2471 
2472         a = Type.evalSlider(a);
2473         b = Type.evalSlider(b);
2474 
2475         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2476             res = Interval.div(a, b);
2477         } else if (Type.isArray(a) && Type.isNumber(b)) {
2478             len = a.length;
2479             res = [];
2480 
2481             for (i = 0; i < len; i++) {
2482                 res[i] = a[i] / b;
2483             }
2484         } else if (Type.isNumber(a) && Type.isNumber(b)) {
2485             res = a / b;
2486         } else {
2487             this._error('Operation * not defined on operands ' + typeof a + ' and ' + typeof b);
2488         }
2489 
2490         return res;
2491     },
2492 
2493     /**
2494      * Implementation of the % operator.
2495      * @param {Number|Array} a
2496      * @param {Number} b
2497      * @returns {Number|Array}
2498      */
2499     mod: function (a, b) {
2500         var i, len, res;
2501 
2502         a = Type.evalSlider(a);
2503         b = Type.evalSlider(b);
2504 
2505         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2506             return Interval.fmod(a, b);
2507         } else if (Type.isArray(a) && Type.isNumber(b)) {
2508             len = a.length;
2509             res = [];
2510 
2511             for (i = 0; i < len; i++) {
2512                 res[i] = Mat.mod(a[i], b, true);
2513             }
2514         } else if (Type.isNumber(a) && Type.isNumber(b)) {
2515             res = Mat.mod(a, b, true);
2516         } else {
2517             this._error('Operation * not defined on operands ' + typeof a + ' and ' + typeof b);
2518         }
2519 
2520         return res;
2521     },
2522 
2523     /**
2524      * Pow function wrapper to allow direct usage of sliders.
2525      * @param {Number|Slider} a
2526      * @param {Number|Slider} b
2527      * @returns {Number}
2528      */
2529     pow: function (a, b) {
2530         a = Type.evalSlider(a);
2531         b = Type.evalSlider(b);
2532 
2533         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2534             return Interval.pow(a, b);
2535         }
2536         return Mat.pow(a, b);
2537     },
2538 
2539     lt: function (a, b) {
2540         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2541             return Interval.lt(a, b);
2542         }
2543         return a < b;
2544     },
2545     leq: function (a, b) {
2546         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2547             return Interval.leq(a, b);
2548         }
2549         return a <= b;
2550     },
2551     gt: function (a, b) {
2552         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2553             return Interval.gt(a, b);
2554         }
2555         return a > b;
2556     },
2557     geq: function (a, b) {
2558         if (Interval.isInterval(a) || Interval.isInterval(b)) {
2559             return Interval.geq(a, b);
2560         }
2561         return a >= b;
2562     },
2563 
2564     randint: function (min, max, step) {
2565         if (!Type.exists(step)) {
2566             step = 1;
2567         }
2568         return Math.round(Math.random() * (max - min) / step) * step + min;
2569     },
2570 
2571     DDD: function (f) {
2572         console.log('Dummy derivative function. This should never appear!');
2573     },
2574 
2575     /**
2576      * Implementation of the ?: operator
2577      * @param {Boolean} cond Condition
2578      * @param {*} v1
2579      * @param {*} v2
2580      * @returns {*} Either v1 or v2.
2581      */
2582     ifthen: function (cond, v1, v2) {
2583         if (cond) {
2584             return v1;
2585         }
2586 
2587         return v2;
2588     },
2589 
2590     /**
2591      * Implementation of the delete() builtin function
2592      * @param {JXG.GeometryElement} element
2593      */
2594     del: function (element) {
2595         if (typeof element === 'object' && JXG.exists(element.type) && JXG.exists(element.elementClass)) {
2596             this.board.removeObject(element);
2597         }
2598     },
2599 
2600     /**
2601      * Implementation of the eval() builtin function. Calls JXG.evaluate().
2602      * @param {String|Number|Function} v
2603      */
2604     eval: function (v) {
2605         return JXG.evaluate(v);
2606     },
2607 
2608     /**
2609      * Implementation of the use() builtin function
2610      * @param {String} board
2611      */
2612     use: function (board) {
2613         var b, ref,
2614             found = false;
2615 
2616         if (typeof board === 'string') {
2617             // search all the boards for the one with the appropriate container div
2618             for (b in JXG.boards) {
2619                 if (JXG.boards.hasOwnProperty(b) && JXG.boards[b].container === board) {
2620                     ref = JXG.boards[b];
2621                     found = true;
2622                     break;
2623                 }
2624             }
2625         } else {
2626             ref = board;
2627             found = true;
2628         }
2629 
2630         if (found) {
2631             this.board = ref;
2632             this.builtIn.$board = ref;
2633             this.builtIn.$board.src = '$jc$.board';
2634         } else {
2635             this._error('Board \'' + board + '\' not found!');
2636         }
2637     },
2638 
2639     /**
2640      * Find the first symbol to the given value from the given scope upwards.
2641      * @param v Value
2642      * @param {Number} [scope=-1] The scope, default is to start with current scope (-1).
2643      * @returns {Array} An array containing the symbol and the scope if a symbol could be found,
2644      * an empty array otherwise;
2645      */
2646     findSymbol: function (v, scope) {
2647         var i, s;
2648 
2649         scope = Type.def(scope, -1);
2650 
2651         if (scope === -1) {
2652             s = this.scope;
2653         } else {
2654             s = this.scopes[scope];
2655         }
2656 
2657         while (s !== null) {
2658             for (i in s.locals) {
2659                 if (s.locals.hasOwnProperty(i) && s.locals[i] === v) {
2660                     return [i, s];
2661                 }
2662             }
2663 
2664             s = s.previous;
2665         }
2666 
2667         return [];
2668     },
2669 
2670     /**
2671      * Import modules into a JessieCode script.
2672      * @param {String} module
2673      */
2674     importModule: function (module) {
2675         return priv.modules[module.toLowerCase()];
2676     },
2677 
2678     /**
2679      * Defines built in methods and constants.
2680      * @returns {Object} BuiltIn control object
2681      */
2682     defineBuiltIn: function () {
2683         var that = this,
2684             builtIn = {
2685                 PI: Math.PI,
2686                 EULER: Math.E,
2687                 D: that.DDD,
2688                 X: that.X,
2689                 Y: that.Y,
2690                 V: that.V,
2691                 Value: that.V,
2692                 L: that.L,
2693                 Length: that.L,
2694 
2695                 acosh: Mat.acosh,
2696                 acot: Mat.acot,
2697                 asinh: Mat.asinh,
2698                 binomial: Mat.binomial,
2699                 cbrt: Mat.cbrt,
2700                 cosh: Mat.cosh,
2701                 cot: Mat.cot,
2702                 deg: Geometry.trueAngle,
2703                 A: that.area,
2704                 area: that.area,
2705                 Area: that.area,
2706                 perimeter: that.perimeter,
2707                 Perimeter: that.perimeter,
2708                 dist: that.dist,
2709                 Dist: that.dist,
2710                 R: that.radius,
2711                 radius: that.radius,
2712                 Radius: that.radius,
2713                 erf: Mat.erf,
2714                 erfc: Mat.erfc,
2715                 erfi: Mat.erfi,
2716                 factorial: Mat.factorial,
2717                 gcd: Mat.gcd,
2718                 lb: Mat.log2,
2719                 lcm: Mat.lcm,
2720                 ld: Mat.log2,
2721                 lg: Mat.log10,
2722                 ln: Math.log,
2723                 log: Mat.log,
2724                 log10: Mat.log10,
2725                 log2: Mat.log2,
2726                 ndtr: Mat.ndtr,
2727                 ndtri: Mat.ndtri,
2728                 nthroot: Mat.nthroot,
2729                 pow: Mat.pow,
2730                 rad: Geometry.rad,
2731                 ratpow: Mat.ratpow,
2732                 trunc: Type.trunc,
2733                 sinh: Mat.sinh,
2734                 slope: that.slope,
2735                 Slope: that.slope,
2736 
2737                 randint: that.randint,
2738 
2739                 IfThen: that.ifthen,
2740                 'import': that.importModule,
2741                 'eval': that.eval,
2742                 'use': that.use,
2743                 'remove': that.del,
2744                 '$': that.getElementById,
2745                 '$value': function(e) {return that.getElementById(e).Value(); },
2746                 getName: that.getName,
2747                 name: that.getName,
2748                 '$board': that.board,
2749                 '$log': that.log
2750             };
2751 
2752         // special scopes for factorial, deg, and rad
2753         builtIn.rad.sc = Geometry;
2754         builtIn.deg.sc = Geometry;
2755         builtIn.factorial.sc = Mat;
2756 
2757         // set the javascript equivalent for the builtIns
2758         // some of the anonymous functions should be replaced by global methods later on
2759         // EULER and PI don't get a source attribute - they will be lost anyways and apparently
2760         // some browser will throw an exception when a property is assigned to a primitive value.
2761         builtIn.X.src = '$jc$.X';
2762         builtIn.Y.src = '$jc$.Y';
2763         builtIn.V.src = '$jc$.V';
2764         builtIn.Value.src = '$jc$.V';
2765         builtIn.L.src = '$jc$.L';
2766         builtIn.Length.src = '$jc$.L';
2767 
2768         builtIn.acosh.src = 'JXG.Math.acosh';
2769         builtIn.acot.src = 'JXG.Math.acot';
2770         builtIn.asinh.src = 'JXG.Math.asinh';
2771         builtIn.binomial.src = 'JXG.Math.binomial';
2772         builtIn.cbrt.src = 'JXG.Math.cbrt';
2773         builtIn.cot.src = 'JXG.Math.cot';
2774         builtIn.cosh.src = 'JXG.Math.cosh';
2775         builtIn.deg.src = 'JXG.Math.Geometry.trueAngle';
2776         builtIn.erf.src = 'JXG.Math.erf';
2777         builtIn.erfc.src = 'JXG.Math.erfc';
2778         builtIn.erfi.src = 'JXG.Math.erfi';
2779         builtIn.A.src = '$jc$.area';
2780         builtIn.area.src = '$jc$.area';
2781         builtIn.Area.src = '$jc$.area';
2782         builtIn.perimeter.src = '$jc$.perimeter';
2783         builtIn.Perimeter.src = '$jc$.perimeter';
2784         builtIn.dist.src = '$jc$.dist';
2785         builtIn.Dist.src = '$jc$.dist';
2786         builtIn.R.src = '$jc$.radius';
2787         builtIn.radius.src = '$jc$.radius';
2788         builtIn.Radius.src = '$jc$.radius';
2789         builtIn.factorial.src = 'JXG.Math.factorial';
2790         builtIn.gcd.src = 'JXG.Math.gcd';
2791         builtIn.lb.src = 'JXG.Math.log2';
2792         builtIn.lcm.src = 'JXG.Math.lcm';
2793         builtIn.ld.src = 'JXG.Math.log2';
2794         builtIn.lg.src = 'JXG.Math.log10';
2795         builtIn.ln.src = 'Math.log';
2796         builtIn.log.src = 'JXG.Math.log';
2797         builtIn.log10.src = 'JXG.Math.log10';
2798         builtIn.log2.src = 'JXG.Math.log2';
2799         builtIn.ndtr.src = 'JXG.Math.ndtr';
2800         builtIn.ndtri.src = 'JXG.Math.ndtri';
2801         builtIn.nthroot.src = 'JXG.Math.nthroot';
2802         builtIn.pow.src = 'JXG.Math.pow';
2803         builtIn.rad.src = 'JXG.Math.Geometry.rad';
2804         builtIn.ratpow.src = 'JXG.Math.ratpow';
2805         builtIn.trunc.src = 'JXG.trunc';
2806         builtIn.sinh.src = 'JXG.Math.sinh';
2807         builtIn.slope.src = '$jc$.slope';
2808         builtIn.Slope.src = '$jc$.slope';
2809 
2810         builtIn.randint.src = '$jc$.randint';
2811 
2812         builtIn['import'].src = '$jc$.importModule';
2813         builtIn.eval.src = '$jc$.eval';
2814         builtIn.use.src = '$jc$.use';
2815         builtIn.remove.src = '$jc$.del';
2816         builtIn.IfThen.src = '$jc$.ifthen';
2817         // usually unused, see node_op > op_execfun
2818         builtIn.$.src = '(function (n) { return $jc$.board.select(n); })';
2819         builtIn.$value.src = '(function (n) { return $jc$.board.select(n).Value(); })';
2820         builtIn.getName.src = '$jc$.getName';
2821         builtIn.name.src = '$jc$.getName';
2822         if (builtIn.$board) {
2823             builtIn.$board.src = '$jc$.board';
2824         }
2825         builtIn.$log.src = '$jc$.log';
2826 
2827         builtIn = JXG.merge(builtIn, that._addedBuiltIn);
2828 
2829         return builtIn;
2830     },
2831 
2832     _addedBuiltIn: {},
2833 
2834     addBuiltIn: function (name, func) {
2835         if (Type.exists(this.builtIn)) {
2836             if (Type.exists(this.builtIn[name])) {
2837                 return;
2838             }
2839             this.builtIn[name] = func;
2840             this.builtIn[name].src = '$jc$.' + name;
2841         }
2842 
2843         if (Type.exists(this._addedBuiltIn[name])) {
2844             return;
2845         }
2846         this._addedBuiltIn[name] = func;
2847         this._addedBuiltIn[name].src = '$jc$.' + name;
2848 
2849         JXG.JessieCode.prototype[name] = func;
2850     },
2851 
2852     /**
2853      * Returns information about the possible functions and constants.
2854      * @returns {Object}
2855      */
2856     getPossibleOperands: function () {
2857         var FORBIDDEN = ['E'],
2858             jessiecode = this.builtIn || this.defineBuiltIn(),
2859             math = Math,
2860             jc, ma, merge,
2861             i, j, p, len, e,
2862             funcs, funcsJC, consts, operands,
2863             sort, pack;
2864 
2865         sort = function (a, b) {
2866             return a.toLowerCase().localeCompare(b.toLowerCase());
2867         };
2868 
2869         pack = function (name, origin) {
2870             var that = null;
2871 
2872             if (origin === 'jc') that = jessiecode[name];
2873             else if (origin === 'Math') that = math[name];
2874             else return;
2875 
2876             if (FORBIDDEN.indexOf(name) >= 0) {
2877                 return;
2878             } else if (JXG.isFunction(that)) {
2879                 return {
2880                     name: name,
2881                     type: 'function',
2882                     numParams: that.length,
2883                     origin: origin,
2884                 };
2885             } else if (JXG.isNumber(that)) {
2886                 return {
2887                     name: name,
2888                     type: 'constant',
2889                     value: that,
2890                     origin: origin,
2891                 };
2892             } else if (name.startsWith('$')) {
2893                 // do nothing
2894             } else if (that !== undefined) {
2895                 console.error('undefined type', that);
2896             }
2897         };
2898 
2899         jc = Object.getOwnPropertyNames(jessiecode).sort(sort);
2900         ma = Object.getOwnPropertyNames(math).sort(sort);
2901         merge = [];
2902         i = 0;
2903         j = 0;
2904 
2905         while (i < jc.length || j < ma.length) {
2906             if (jc[i] === ma[j]) {
2907                 p = pack(ma[j], 'Math');
2908                 if (JXG.exists(p)) merge.push(p);
2909                 i++;
2910                 j++;
2911             } else if (!JXG.exists(ma[j]) || jc[i].toLowerCase().localeCompare(ma[j].toLowerCase()) < 0) {
2912                 p = pack(jc[i], 'jc');
2913                 if (JXG.exists(p)) merge.push(p);
2914                 i++;
2915             } else {
2916                 p = pack(ma[j], 'Math');
2917                 if (JXG.exists(p)) merge.push(p);
2918                 j++;
2919             }
2920         }
2921 
2922         funcs = [];
2923         funcsJC = [];
2924         consts = [];
2925         operands = {};
2926         len = merge.length;
2927         for (i = 0; i < len; i++) {
2928             e = merge[i];
2929             switch (e.type) {
2930                 case 'function':
2931                     funcs.push(e.name);
2932                     if (e.origin === 'jc')
2933                         funcsJC.push(e.name);
2934                     break;
2935                 case 'constant':
2936                     consts.push(e.name);
2937                     break;
2938             }
2939             operands[e.name] = e;
2940         }
2941 
2942         return {
2943             all: operands,
2944             list: merge,
2945             functions: funcs,
2946             functions_jessiecode: funcsJC,
2947             constants: consts,
2948         };
2949     },
2950 
2951     /**
2952      * Output a debugging message. Uses debug console, if available. Otherwise an HTML element with the
2953      * id "debug" and an innerText property is used.
2954      * @param {String} log
2955      * @private
2956      */
2957     _debug: function (log) {
2958         if (typeof console === 'object' && console.log) {
2959             console.log(log);
2960         } else if (Env.isBrowser && document && document.getElementById('debug') !== null) {
2961             document.getElementById('debug').innerText += log + '\n';
2962         }
2963     },
2964 
2965     /**
2966      * Throws an exception with the given error message.
2967      * @param {String} msg Error message
2968      */
2969     _error: function (msg) {
2970         var e = new Error('Error(' + this.line + '): ' + msg);
2971         e.line = this.line;
2972         throw e;
2973     },
2974 
2975     /**
2976      * Output a warning message using {@link JXG#debug} and precedes the message with "Warning: ".
2977      * @param {String} msg
2978      */
2979     _warn: function (msg) {
2980         if (typeof console === 'object' && console.log) {
2981             console.log('Warning(' + this.line + '): ' + msg);
2982         } else if (Env.isBrowser && document && document.getElementById(this.warnLog) !== null) {
2983             document.getElementById(this.warnLog).innerText += 'Warning(' + this.line + '): ' + msg + '\n';
2984         }
2985     },
2986 
2987     _log: function (msg) {
2988         if (typeof window !== 'object' && typeof self === 'object' && self.postMessage) {
2989             self.postMessage({ type: 'log', msg: 'Log: ' + msg.toString() });
2990         } else {
2991             console.log('Log: ', arguments);
2992         }
2993     }
2994 
2995 });
2996 
2997 /* Jison generated parser */
2998 /**
2999  * @class
3000  * @ignore
3001  */
3002 var parser = (function(){
3003 /**
3004  * @class
3005  * @ignore
3006  */
3007 var parser = {trace: function trace () { },
3008 yy: {},
3009 symbols_: {"error":2,"Program":3,"StatementList":4,"EOF":5,"IfStatement":6,"IF":7,"(":8,"Expression":9,")":10,"Statement":11,"ELSE":12,"LoopStatement":13,"WHILE":14,"FOR":15,";":16,"DO":17,"UnaryStatement":18,"USE":19,"IDENTIFIER":20,"DELETE":21,"ReturnStatement":22,"RETURN":23,"EmptyStatement":24,"StatementBlock":25,"{":26,"}":27,"ExpressionStatement":28,"AssignmentExpression":29,"ConditionalExpression":30,"LeftHandSideExpression":31,"=":32,"LogicalORExpression":33,"?":34,":":35,"LogicalANDExpression":36,"||":37,"EqualityExpression":38,"&&":39,"RelationalExpression":40,"==":41,"!=":42,"~=":43,"AdditiveExpression":44,"<":45,">":46,"<=":47,">=":48,"MultiplicativeExpression":49,"+":50,"-":51,"UnaryExpression":52,"*":53,"/":54,"%":55,"ExponentExpression":56,"^":57,"!":58,"MemberExpression":59,"CallExpression":60,"PrimaryExpression":61,"FunctionExpression":62,"MapExpression":63,".":64,"[":65,"]":66,"BasicLiteral":67,"ObjectLiteral":68,"ArrayLiteral":69,"NullLiteral":70,"BooleanLiteral":71,"StringLiteral":72,"NumberLiteral":73,"NULL":74,"TRUE":75,"FALSE":76,"STRING":77,"NUMBER":78,"NAN":79,"INFINITY":80,"ElementList":81,"<<":82,">>":83,"PropertyList":84,"Property":85,",":86,"PropertyName":87,"Arguments":88,"AttributeList":89,"Attribute":90,"FUNCTION":91,"ParameterDefinitionList":92,"MAP":93,"->":94,"$accept":0,"$end":1},
3010 terminals_: {2:"error",5:"EOF",7:"IF",8:"(",10:")",12:"ELSE",14:"WHILE",15:"FOR",16:";",17:"DO",19:"USE",20:"IDENTIFIER",21:"DELETE",23:"RETURN",26:"{",27:"}",32:"=",34:"?",35:":",37:"||",39:"&&",41:"==",42:"!=",43:"~=",45:"<",46:">",47:"<=",48:">=",50:"+",51:"-",53:"*",54:"/",55:"%",57:"^",58:"!",64:".",65:"[",66:"]",74:"NULL",75:"TRUE",76:"FALSE",77:"STRING",78:"NUMBER",79:"NAN",80:"INFINITY",82:"<<",83:">>",86:",",91:"FUNCTION",93:"MAP",94:"->"},
3011 productions_: [0,[3,2],[6,5],[6,7],[13,5],[13,9],[13,7],[18,2],[18,2],[22,2],[22,3],[24,1],[25,3],[4,2],[4,0],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[28,2],[9,1],[29,1],[29,3],[30,1],[30,5],[33,1],[33,3],[36,1],[36,3],[38,1],[38,3],[38,3],[38,3],[40,1],[40,3],[40,3],[40,3],[40,3],[44,1],[44,3],[44,3],[49,1],[49,3],[49,3],[49,3],[56,1],[56,3],[52,1],[52,2],[52,2],[52,2],[31,1],[31,1],[59,1],[59,1],[59,1],[59,3],[59,4],[61,1],[61,1],[61,1],[61,1],[61,3],[67,1],[67,1],[67,1],[67,1],[70,1],[71,1],[71,1],[72,1],[73,1],[73,1],[73,1],[69,2],[69,3],[68,2],[68,3],[84,1],[84,3],[85,3],[87,1],[87,1],[87,1],[60,2],[60,3],[60,2],[60,4],[60,3],[88,2],[88,3],[89,1],[89,3],[90,1],[90,1],[81,1],[81,3],[62,4],[62,5],[63,5],[63,6],[92,1],[92,3]],
3012 /**
3013  * @class
3014  * @ignore
3015  */
3016 performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$
3017 ) {
3018 
3019 var $0 = $$.length - 1;
3020 switch (yystate) {
3021 case 1: return $$[$0-1];
3022 break;
3023 case 2: this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_if', $$[$0-2], $$[$0]);
3024 break;
3025 case 3: this.$ = AST.createNode(lc(_$[$0-6]), 'node_op', 'op_if_else', $$[$0-4], $$[$0-2], $$[$0]);
3026 break;
3027 case 4: this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_while', $$[$0-2], $$[$0]);
3028 break;
3029 case 5: this.$ = AST.createNode(lc(_$[$0-8]), 'node_op', 'op_for', $$[$0-6], $$[$0-4], $$[$0-2], $$[$0]);
3030 break;
3031 case 6: this.$ = AST.createNode(lc(_$[$0-6]), 'node_op', 'op_do', $$[$0-5], $$[$0-2]);
3032 break;
3033 case 7: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_use', $$[$0]);
3034 break;
3035 case 8: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_delete', $$[$0]);
3036 break;
3037 case 9: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_return', undefined);
3038 break;
3039 case 10: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_return', $$[$0-1]);
3040 break;
3041 case 11: this.$ = AST.createNode(lc(_$[$0]), 'node_op', 'op_none');
3042 break;
3043 case 12: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_block', $$[$0-1]);
3044 break;
3045 case 13: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_none', $$[$0-1], $$[$0]);
3046 break;
3047 case 14: this.$ = AST.createNode(lc(_$[$0]), 'node_op', 'op_none');
3048 break;
3049 case 15: this.$ = $$[$0];
3050 break;
3051 case 16: this.$ = $$[$0];
3052 break;
3053 case 17: this.$ = $$[$0];
3054 break;
3055 case 18: this.$ = $$[$0];
3056 break;
3057 case 19: this.$ = $$[$0];
3058 break;
3059 case 20: this.$ = $$[$0];
3060 break;
3061 case 21: this.$ = $$[$0];
3062 break;
3063 case 22: this.$ = $$[$0-1];
3064 break;
3065 case 23: this.$ = $$[$0];
3066 break;
3067 case 24: this.$ = $$[$0];
3068 break;
3069 case 25: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_assign', $$[$0-2], $$[$0]); this.$.isMath = false;
3070 break;
3071 case 26: this.$ = $$[$0];
3072 break;
3073 case 27: this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_conditional', $$[$0-4], $$[$0-2], $$[$0]); this.$.isMath = false;
3074 break;
3075 case 28: this.$ = $$[$0];
3076 break;
3077 case 29: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_or', $$[$0-2], $$[$0]); this.$.isMath = false;
3078 break;
3079 case 30: this.$ = $$[$0];
3080 break;
3081 case 31: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_and', $$[$0-2], $$[$0]); this.$.isMath = false;
3082 break;
3083 case 32: this.$ = $$[$0];
3084 break;
3085 case 33: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_eq', $$[$0-2], $$[$0]); this.$.isMath = false;
3086 break;
3087 case 34: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_neq', $$[$0-2], $$[$0]); this.$.isMath = false;
3088 break;
3089 case 35: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_approx', $$[$0-2], $$[$0]); this.$.isMath = false;
3090 break;
3091 case 36: this.$ = $$[$0];
3092 break;
3093 case 37: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_lt', $$[$0-2], $$[$0]); this.$.isMath = false;
3094 break;
3095 case 38: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_gt', $$[$0-2], $$[$0]); this.$.isMath = false;
3096 break;
3097 case 39: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_leq', $$[$0-2], $$[$0]); this.$.isMath = false;
3098 break;
3099 case 40: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_geq', $$[$0-2], $$[$0]); this.$.isMath = false;
3100 break;
3101 case 41: this.$ = $$[$0];
3102 break;
3103 case 42: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_add', $$[$0-2], $$[$0]); this.$.isMath = true;
3104 break;
3105 case 43: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_sub', $$[$0-2], $$[$0]); this.$.isMath = true;
3106 break;
3107 case 44: this.$ = $$[$0];
3108 break;
3109 case 45: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_mul', $$[$0-2], $$[$0]); this.$.isMath = true;
3110 break;
3111 case 46: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_div', $$[$0-2], $$[$0]); this.$.isMath = true;
3112 break;
3113 case 47: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_mod', $$[$0-2], $$[$0]); this.$.isMath = true;
3114 break;
3115 case 48: this.$ = $$[$0];
3116 break;
3117 case 49: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_exp', $$[$0-2], $$[$0]); this.$.isMath = true;
3118 break;
3119 case 50: this.$ = $$[$0];
3120 break;
3121 case 51: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_not', $$[$0]); this.$.isMath = false;
3122 break;
3123 case 52: this.$ = $$[$0];
3124 break;
3125 case 53: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_neg', $$[$0]); this.$.isMath = true;
3126 break;
3127 case 54: this.$ = $$[$0];
3128 break;
3129 case 55: this.$ = $$[$0];
3130 break;
3131 case 56: this.$ = $$[$0];
3132 break;
3133 case 57: this.$ = $$[$0]; this.$.isMath = false;
3134 break;
3135 case 58: this.$ = $$[$0];
3136 break;
3137 case 59: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_property', $$[$0-2], $$[$0]); this.$.isMath = true;
3138 break;
3139 case 60: this.$ = AST.createNode(lc(_$[$0-3]), 'node_op', 'op_extvalue', $$[$0-3], $$[$0-1]); this.$.isMath = true;
3140 break;
3141 case 61: this.$ = AST.createNode(lc(_$[$0]), 'node_var', $$[$0]);
3142 break;
3143 case 62: this.$ = $$[$0];
3144 break;
3145 case 63: this.$ = $$[$0]; this.$.isMath = false;
3146 break;
3147 case 64: this.$ = $$[$0]; this.$.isMath = false;
3148 break;
3149 case 65: this.$ = $$[$0-1];
3150 break;
3151 case 66: this.$ = $$[$0]; this.$.isMath = false;
3152 break;
3153 case 67: this.$ = $$[$0]; this.$.isMath = false;
3154 break;
3155 case 68: this.$ = $$[$0]; this.$.isMath = false;
3156 break;
3157 case 69: this.$ = $$[$0]; this.$.isMath = true;
3158 break;
3159 case 70: this.$ = AST.createNode(lc(_$[$0]), 'node_const', null);
3160 break;
3161 case 71: this.$ = AST.createNode(lc(_$[$0]), 'node_const_bool', true);
3162 break;
3163 case 72: this.$ = AST.createNode(lc(_$[$0]), 'node_const_bool', false);
3164 break;
3165 case 73: this.$ = AST.createNode(lc(_$[$0]), 'node_str', $$[$0].substring(1, $$[$0].length - 1));
3166 break;
3167 case 74: this.$ = AST.createNode(lc(_$[$0]), 'node_const', parseFloat($$[$0]));
3168 break;
3169 case 75: this.$ = AST.createNode(lc(_$[$0]), 'node_const', NaN);
3170 break;
3171 case 76: this.$ = AST.createNode(lc(_$[$0]), 'node_const', Infinity);
3172 break;
3173 case 77: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_array', []);
3174 break;
3175 case 78: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_array', $$[$0-1]);
3176 break;
3177 case 79: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_emptyobject', {}); this.$.needsAngleBrackets = true;
3178 break;
3179 case 80: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_proplst_val', $$[$0-1]); this.$.needsAngleBrackets = true;
3180 break;
3181 case 81: this.$ = $$[$0];
3182 break;
3183 case 82: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_proplst', $$[$0-2], $$[$0]);
3184 break;
3185 case 83: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_prop', $$[$0-2], $$[$0]);
3186 break;
3187 case 84: this.$ = $$[$0];
3188 break;
3189 case 85: this.$ = $$[$0];
3190 break;
3191 case 86: this.$ = $$[$0];
3192 break;
3193 case 87: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_execfun', $$[$0-1], $$[$0]); this.$.isMath = true;
3194 break;
3195 case 88: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_execfun', $$[$0-2], $$[$0-1], $$[$0], true); this.$.isMath = false;
3196 break;
3197 case 89: this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_execfun', $$[$0-1], $$[$0]); this.$.isMath = true;
3198 break;
3199 case 90: this.$ = AST.createNode(lc(_$[$0-3]), 'node_op', 'op_extvalue', $$[$0-3], $$[$0-1]); this.$.isMath = true;
3200 break;
3201 case 91: this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_property', $$[$0-2], $$[$0]); this.$.isMath = true;
3202 break;
3203 case 92: this.$ = [];
3204 break;
3205 case 93: this.$ = $$[$0-1];
3206 break;
3207 case 94: this.$ = [$$[$0]];
3208 break;
3209 case 95: this.$ = $$[$0-2].concat($$[$0]);
3210 break;
3211 case 96: this.$ = AST.createNode(lc(_$[$0]), 'node_var', $$[$0]); this.$.isMath = true;
3212 break;
3213 case 97: this.$ = $$[$0]; this.$.isMath = false;
3214 break;
3215 case 98: this.$ = [$$[$0]];
3216 break;
3217 case 99: this.$ = $$[$0-2].concat($$[$0]);
3218 break;
3219 case 100: this.$ = AST.createNode(lc(_$[$0-3]), 'node_op', 'op_function', [], $$[$0]); this.$.isMath = false;
3220 break;
3221 case 101: this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_function', $$[$0-2], $$[$0]); this.$.isMath = false;
3222 break;
3223 case 102: this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_map', [], $$[$0]);
3224 break;
3225 case 103: this.$ = AST.createNode(lc(_$[$0-5]), 'node_op', 'op_map', $$[$0-3], $$[$0]);
3226 break;
3227 case 104: this.$ = [$$[$0]];
3228 break;
3229 case 105: this.$ = $$[$0-2].concat($$[$0]);
3230 break;
3231 }
3232 },
3233 table: [{3:1,4:2,5:[2,14],7:[2,14],8:[2,14],14:[2,14],15:[2,14],16:[2,14],17:[2,14],19:[2,14],20:[2,14],21:[2,14],23:[2,14],26:[2,14],50:[2,14],51:[2,14],58:[2,14],65:[2,14],74:[2,14],75:[2,14],76:[2,14],77:[2,14],78:[2,14],79:[2,14],80:[2,14],82:[2,14],91:[2,14],93:[2,14]},{1:[3]},{5:[1,3],6:6,7:[1,13],8:[1,37],9:20,11:4,13:7,14:[1,14],15:[1,15],16:[1,21],17:[1,16],18:8,19:[1,17],20:[1,33],21:[1,18],22:9,23:[1,19],24:11,25:5,26:[1,12],28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{1:[2,1]},{5:[2,13],7:[2,13],8:[2,13],14:[2,13],15:[2,13],16:[2,13],17:[2,13],19:[2,13],20:[2,13],21:[2,13],23:[2,13],26:[2,13],27:[2,13],50:[2,13],51:[2,13],58:[2,13],65:[2,13],74:[2,13],75:[2,13],76:[2,13],77:[2,13],78:[2,13],79:[2,13],80:[2,13],82:[2,13],91:[2,13],93:[2,13]},{5:[2,15],7:[2,15],8:[2,15],12:[2,15],14:[2,15],15:[2,15],16:[2,15],17:[2,15],19:[2,15],20:[2,15],21:[2,15],23:[2,15],26:[2,15],27:[2,15],50:[2,15],51:[2,15],58:[2,15],65:[2,15],74:[2,15],75:[2,15],76:[2,15],77:[2,15],78:[2,15],79:[2,15],80:[2,15],82:[2,15],91:[2,15],93:[2,15]},{5:[2,16],7:[2,16],8:[2,16],12:[2,16],14:[2,16],15:[2,16],16:[2,16],17:[2,16],19:[2,16],20:[2,16],21:[2,16],23:[2,16],26:[2,16],27:[2,16],50:[2,16],51:[2,16],58:[2,16],65:[2,16],74:[2,16],75:[2,16],76:[2,16],77:[2,16],78:[2,16],79:[2,16],80:[2,16],82:[2,16],91:[2,16],93:[2,16]},{5:[2,17],7:[2,17],8:[2,17],12:[2,17],14:[2,17],15:[2,17],16:[2,17],17:[2,17],19:[2,17],20:[2,17],21:[2,17],23:[2,17],26:[2,17],27:[2,17],50:[2,17],51:[2,17],58:[2,17],65:[2,17],74:[2,17],75:[2,17],76:[2,17],77:[2,17],78:[2,17],79:[2,17],80:[2,17],82:[2,17],91:[2,17],93:[2,17]},{5:[2,18],7:[2,18],8:[2,18],12:[2,18],14:[2,18],15:[2,18],16:[2,18],17:[2,18],19:[2,18],20:[2,18],21:[2,18],23:[2,18],26:[2,18],27:[2,18],50:[2,18],51:[2,18],58:[2,18],65:[2,18],74:[2,18],75:[2,18],76:[2,18],77:[2,18],78:[2,18],79:[2,18],80:[2,18],82:[2,18],91:[2,18],93:[2,18]},{5:[2,19],7:[2,19],8:[2,19],12:[2,19],14:[2,19],15:[2,19],16:[2,19],17:[2,19],19:[2,19],20:[2,19],21:[2,19],23:[2,19],26:[2,19],27:[2,19],50:[2,19],51:[2,19],58:[2,19],65:[2,19],74:[2,19],75:[2,19],76:[2,19],77:[2,19],78:[2,19],79:[2,19],80:[2,19],82:[2,19],91:[2,19],93:[2,19]},{5:[2,20],7:[2,20],8:[2,20],12:[2,20],14:[2,20],15:[2,20],16:[2,20],17:[2,20],19:[2,20],20:[2,20],21:[2,20],23:[2,20],26:[2,20],27:[2,20],50:[2,20],51:[2,20],58:[2,20],65:[2,20],74:[2,20],75:[2,20],76:[2,20],77:[2,20],78:[2,20],79:[2,20],80:[2,20],82:[2,20],91:[2,20],93:[2,20]},{5:[2,21],7:[2,21],8:[2,21],12:[2,21],14:[2,21],15:[2,21],16:[2,21],17:[2,21],19:[2,21],20:[2,21],21:[2,21],23:[2,21],26:[2,21],27:[2,21],50:[2,21],51:[2,21],58:[2,21],65:[2,21],74:[2,21],75:[2,21],76:[2,21],77:[2,21],78:[2,21],79:[2,21],80:[2,21],82:[2,21],91:[2,21],93:[2,21]},{4:61,7:[2,14],8:[2,14],14:[2,14],15:[2,14],16:[2,14],17:[2,14],19:[2,14],20:[2,14],21:[2,14],23:[2,14],26:[2,14],27:[2,14],50:[2,14],51:[2,14],58:[2,14],65:[2,14],74:[2,14],75:[2,14],76:[2,14],77:[2,14],78:[2,14],79:[2,14],80:[2,14],82:[2,14],91:[2,14],93:[2,14]},{8:[1,62]},{8:[1,63]},{8:[1,64]},{6:6,7:[1,13],8:[1,37],9:20,11:65,13:7,14:[1,14],15:[1,15],16:[1,21],17:[1,16],18:8,19:[1,17],20:[1,33],21:[1,18],22:9,23:[1,19],24:11,25:5,26:[1,12],28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{20:[1,66]},{20:[1,67]},{8:[1,37],9:69,16:[1,68],20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{16:[1,70]},{5:[2,11],7:[2,11],8:[2,11],12:[2,11],14:[2,11],15:[2,11],16:[2,11],17:[2,11],19:[2,11],20:[2,11],21:[2,11],23:[2,11],26:[2,11],27:[2,11],50:[2,11],51:[2,11],58:[2,11],65:[2,11],74:[2,11],75:[2,11],76:[2,11],77:[2,11],78:[2,11],79:[2,11],80:[2,11],82:[2,11],91:[2,11],93:[2,11]},{8:[2,23],10:[2,23],16:[2,23],32:[2,23],34:[2,23],35:[2,23],37:[2,23],39:[2,23],41:[2,23],42:[2,23],43:[2,23],45:[2,23],46:[2,23],47:[2,23],48:[2,23],50:[2,23],51:[2,23],53:[2,23],54:[2,23],55:[2,23],57:[2,23],64:[2,23],65:[2,23],66:[2,23],83:[2,23],86:[2,23]},{8:[2,24],10:[2,24],16:[2,24],32:[2,24],34:[2,24],35:[2,24],37:[2,24],39:[2,24],41:[2,24],42:[2,24],43:[2,24],45:[2,24],46:[2,24],47:[2,24],48:[2,24],50:[2,24],51:[2,24],53:[2,24],54:[2,24],55:[2,24],57:[2,24],64:[2,24],65:[2,24],66:[2,24],83:[2,24],86:[2,24]},{8:[2,48],10:[2,48],16:[2,48],32:[1,71],34:[2,48],35:[2,48],37:[2,48],39:[2,48],41:[2,48],42:[2,48],43:[2,48],45:[2,48],46:[2,48],47:[2,48],48:[2,48],50:[2,48],51:[2,48],53:[2,48],54:[2,48],55:[2,48],57:[1,72],64:[2,48],65:[2,48],66:[2,48],83:[2,48],86:[2,48]},{8:[2,26],10:[2,26],16:[2,26],32:[2,26],34:[1,73],35:[2,26],37:[1,74],39:[2,26],41:[2,26],42:[2,26],43:[2,26],45:[2,26],46:[2,26],47:[2,26],48:[2,26],50:[2,26],51:[2,26],53:[2,26],54:[2,26],55:[2,26],57:[2,26],64:[2,26],65:[2,26],66:[2,26],83:[2,26],86:[2,26]},{8:[1,78],10:[2,54],16:[2,54],32:[2,54],34:[2,54],35:[2,54],37:[2,54],39:[2,54],41:[2,54],42:[2,54],43:[2,54],45:[2,54],46:[2,54],47:[2,54],48:[2,54],50:[2,54],51:[2,54],53:[2,54],54:[2,54],55:[2,54],57:[2,54],64:[1,75],65:[1,76],66:[2,54],83:[2,54],86:[2,54],88:77},{8:[1,78],10:[2,55],16:[2,55],32:[2,55],34:[2,55],35:[2,55],37:[2,55],39:[2,55],41:[2,55],42:[2,55],43:[2,55],45:[2,55],46:[2,55],47:[2,55],48:[2,55],50:[2,55],51:[2,55],53:[2,55],54:[2,55],55:[2,55],57:[2,55],64:[1,81],65:[1,80],66:[2,55],83:[2,55],86:[2,55],88:79},{8:[2,28],10:[2,28],16:[2,28],32:[2,28],34:[2,28],35:[2,28],37:[2,28],39:[1,82],41:[2,28],42:[2,28],43:[2,28],45:[2,28],46:[2,28],47:[2,28],48:[2,28],50:[2,28],51:[2,28],53:[2,28],54:[2,28],55:[2,28],57:[2,28],64:[2,28],65:[2,28],66:[2,28],83:[2,28],86:[2,28]},{8:[2,56],10:[2,56],16:[2,56],32:[2,56],34:[2,56],35:[2,56],37:[2,56],39:[2,56],41:[2,56],42:[2,56],43:[2,56],45:[2,56],46:[2,56],47:[2,56],48:[2,56],50:[2,56],51:[2,56],53:[2,56],54:[2,56],55:[2,56],57:[2,56],64:[2,56],65:[2,56],66:[2,56],83:[2,56],86:[2,56]},{8:[2,57],10:[2,57],16:[2,57],32:[2,57],34:[2,57],35:[2,57],37:[2,57],39:[2,57],41:[2,57],42:[2,57],43:[2,57],45:[2,57],46:[2,57],47:[2,57],48:[2,57],50:[2,57],51:[2,57],53:[2,57],54:[2,57],55:[2,57],57:[2,57],64:[2,57],65:[2,57],66:[2,57],83:[2,57],86:[2,57]},{8:[2,58],10:[2,58],16:[2,58],32:[2,58],34:[2,58],35:[2,58],37:[2,58],39:[2,58],41:[2,58],42:[2,58],43:[2,58],45:[2,58],46:[2,58],47:[2,58],48:[2,58],50:[2,58],51:[2,58],53:[2,58],54:[2,58],55:[2,58],57:[2,58],64:[2,58],65:[2,58],66:[2,58],83:[2,58],86:[2,58]},{8:[2,30],10:[2,30],16:[2,30],32:[2,30],34:[2,30],35:[2,30],37:[2,30],39:[2,30],41:[1,83],42:[1,84],43:[1,85],45:[2,30],46:[2,30],47:[2,30],48:[2,30],50:[2,30],51:[2,30],53:[2,30],54:[2,30],55:[2,30],57:[2,30],64:[2,30],65:[2,30],66:[2,30],83:[2,30],86:[2,30]},{8:[2,61],10:[2,61],16:[2,61],32:[2,61],34:[2,61],35:[2,61],37:[2,61],39:[2,61],41:[2,61],42:[2,61],43:[2,61],45:[2,61],46:[2,61],47:[2,61],48:[2,61],50:[2,61],51:[2,61],53:[2,61],54:[2,61],55:[2,61],57:[2,61],64:[2,61],65:[2,61],66:[2,61],83:[2,61],86:[2,61]},{8:[2,62],10:[2,62],16:[2,62],32:[2,62],34:[2,62],35:[2,62],37:[2,62],39:[2,62],41:[2,62],42:[2,62],43:[2,62],45:[2,62],46:[2,62],47:[2,62],48:[2,62],50:[2,62],51:[2,62],53:[2,62],54:[2,62],55:[2,62],57:[2,62],64:[2,62],65:[2,62],66:[2,62],83:[2,62],86:[2,62]},{8:[2,63],10:[2,63],16:[2,63],32:[2,63],34:[2,63],35:[2,63],37:[2,63],39:[2,63],41:[2,63],42:[2,63],43:[2,63],45:[2,63],46:[2,63],47:[2,63],48:[2,63],50:[2,63],51:[2,63],53:[2,63],54:[2,63],55:[2,63],57:[2,63],64:[2,63],65:[2,63],66:[2,63],83:[2,63],86:[2,63]},{8:[2,64],10:[2,64],16:[2,64],32:[2,64],34:[2,64],35:[2,64],37:[2,64],39:[2,64],41:[2,64],42:[2,64],43:[2,64],45:[2,64],46:[2,64],47:[2,64],48:[2,64],50:[2,64],51:[2,64],53:[2,64],54:[2,64],55:[2,64],57:[2,64],64:[2,64],65:[2,64],66:[2,64],83:[2,64],86:[2,64]},{8:[1,37],9:86,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,87]},{8:[1,88]},{8:[2,32],10:[2,32],16:[2,32],32:[2,32],34:[2,32],35:[2,32],37:[2,32],39:[2,32],41:[2,32],42:[2,32],43:[2,32],45:[1,89],46:[1,90],47:[1,91],48:[1,92],50:[2,32],51:[2,32],53:[2,32],54:[2,32],55:[2,32],57:[2,32],64:[2,32],65:[2,32],66:[2,32],83:[2,32],86:[2,32]},{8:[2,66],10:[2,66],16:[2,66],32:[2,66],34:[2,66],35:[2,66],37:[2,66],39:[2,66],41:[2,66],42:[2,66],43:[2,66],45:[2,66],46:[2,66],47:[2,66],48:[2,66],50:[2,66],51:[2,66],53:[2,66],54:[2,66],55:[2,66],57:[2,66],64:[2,66],65:[2,66],66:[2,66],83:[2,66],86:[2,66]},{8:[2,67],10:[2,67],16:[2,67],32:[2,67],34:[2,67],35:[2,67],37:[2,67],39:[2,67],41:[2,67],42:[2,67],43:[2,67],45:[2,67],46:[2,67],47:[2,67],48:[2,67],50:[2,67],51:[2,67],53:[2,67],54:[2,67],55:[2,67],57:[2,67],64:[2,67],65:[2,67],66:[2,67],83:[2,67],86:[2,67]},{8:[2,68],10:[2,68],16:[2,68],32:[2,68],34:[2,68],35:[2,68],37:[2,68],39:[2,68],41:[2,68],42:[2,68],43:[2,68],45:[2,68],46:[2,68],47:[2,68],48:[2,68],50:[2,68],51:[2,68],53:[2,68],54:[2,68],55:[2,68],57:[2,68],64:[2,68],65:[2,68],66:[2,68],83:[2,68],86:[2,68]},{8:[2,69],10:[2,69],16:[2,69],32:[2,69],34:[2,69],35:[2,69],37:[2,69],39:[2,69],41:[2,69],42:[2,69],43:[2,69],45:[2,69],46:[2,69],47:[2,69],48:[2,69],50:[2,69],51:[2,69],53:[2,69],54:[2,69],55:[2,69],57:[2,69],64:[2,69],65:[2,69],66:[2,69],83:[2,69],86:[2,69]},{20:[1,97],72:98,73:99,77:[1,51],78:[1,52],79:[1,53],80:[1,54],83:[1,93],84:94,85:95,87:96},{8:[1,37],20:[1,33],29:102,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],66:[1,100],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],81:101,82:[1,45],91:[1,38],93:[1,39]},{8:[2,36],10:[2,36],16:[2,36],32:[2,36],34:[2,36],35:[2,36],37:[2,36],39:[2,36],41:[2,36],42:[2,36],43:[2,36],45:[2,36],46:[2,36],47:[2,36],48:[2,36],50:[1,103],51:[1,104],53:[2,36],54:[2,36],55:[2,36],57:[2,36],64:[2,36],65:[2,36],66:[2,36],83:[2,36],86:[2,36]},{8:[2,70],10:[2,70],16:[2,70],32:[2,70],34:[2,70],35:[2,70],37:[2,70],39:[2,70],41:[2,70],42:[2,70],43:[2,70],45:[2,70],46:[2,70],47:[2,70],48:[2,70],50:[2,70],51:[2,70],53:[2,70],54:[2,70],55:[2,70],57:[2,70],64:[2,70],65:[2,70],66:[2,70],83:[2,70],86:[2,70]},{8:[2,71],10:[2,71],16:[2,71],32:[2,71],34:[2,71],35:[2,71],37:[2,71],39:[2,71],41:[2,71],42:[2,71],43:[2,71],45:[2,71],46:[2,71],47:[2,71],48:[2,71],50:[2,71],51:[2,71],53:[2,71],54:[2,71],55:[2,71],57:[2,71],64:[2,71],65:[2,71],66:[2,71],83:[2,71],86:[2,71]},{8:[2,72],10:[2,72],16:[2,72],32:[2,72],34:[2,72],35:[2,72],37:[2,72],39:[2,72],41:[2,72],42:[2,72],43:[2,72],45:[2,72],46:[2,72],47:[2,72],48:[2,72],50:[2,72],51:[2,72],53:[2,72],54:[2,72],55:[2,72],57:[2,72],64:[2,72],65:[2,72],66:[2,72],83:[2,72],86:[2,72]},{8:[2,73],10:[2,73],16:[2,73],32:[2,73],34:[2,73],35:[2,73],37:[2,73],39:[2,73],41:[2,73],42:[2,73],43:[2,73],45:[2,73],46:[2,73],47:[2,73],48:[2,73],50:[2,73],51:[2,73],53:[2,73],54:[2,73],55:[2,73],57:[2,73],64:[2,73],65:[2,73],66:[2,73],83:[2,73],86:[2,73]},{8:[2,74],10:[2,74],16:[2,74],32:[2,74],34:[2,74],35:[2,74],37:[2,74],39:[2,74],41:[2,74],42:[2,74],43:[2,74],45:[2,74],46:[2,74],47:[2,74],48:[2,74],50:[2,74],51:[2,74],53:[2,74],54:[2,74],55:[2,74],57:[2,74],64:[2,74],65:[2,74],66:[2,74],83:[2,74],86:[2,74]},{8:[2,75],10:[2,75],16:[2,75],32:[2,75],34:[2,75],35:[2,75],37:[2,75],39:[2,75],41:[2,75],42:[2,75],43:[2,75],45:[2,75],46:[2,75],47:[2,75],48:[2,75],50:[2,75],51:[2,75],53:[2,75],54:[2,75],55:[2,75],57:[2,75],64:[2,75],65:[2,75],66:[2,75],83:[2,75],86:[2,75]},{8:[2,76],10:[2,76],16:[2,76],32:[2,76],34:[2,76],35:[2,76],37:[2,76],39:[2,76],41:[2,76],42:[2,76],43:[2,76],45:[2,76],46:[2,76],47:[2,76],48:[2,76],50:[2,76],51:[2,76],53:[2,76],54:[2,76],55:[2,76],57:[2,76],64:[2,76],65:[2,76],66:[2,76],83:[2,76],86:[2,76]},{8:[2,41],10:[2,41],16:[2,41],32:[2,41],34:[2,41],35:[2,41],37:[2,41],39:[2,41],41:[2,41],42:[2,41],43:[2,41],45:[2,41],46:[2,41],47:[2,41],48:[2,41],50:[2,41],51:[2,41],53:[1,105],54:[1,106],55:[1,107],57:[2,41],64:[2,41],65:[2,41],66:[2,41],83:[2,41],86:[2,41]},{8:[2,44],10:[2,44],16:[2,44],32:[2,44],34:[2,44],35:[2,44],37:[2,44],39:[2,44],41:[2,44],42:[2,44],43:[2,44],45:[2,44],46:[2,44],47:[2,44],48:[2,44],50:[2,44],51:[2,44],53:[2,44],54:[2,44],55:[2,44],57:[2,44],64:[2,44],65:[2,44],66:[2,44],83:[2,44],86:[2,44]},{8:[2,50],10:[2,50],16:[2,50],32:[2,50],34:[2,50],35:[2,50],37:[2,50],39:[2,50],41:[2,50],42:[2,50],43:[2,50],45:[2,50],46:[2,50],47:[2,50],48:[2,50],50:[2,50],51:[2,50],53:[2,50],54:[2,50],55:[2,50],57:[2,50],64:[2,50],65:[2,50],66:[2,50],83:[2,50],86:[2,50]},{8:[1,37],20:[1,33],31:109,50:[1,59],51:[1,60],52:108,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,50:[1,59],51:[1,60],52:110,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,50:[1,59],51:[1,60],52:111,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{6:6,7:[1,13],8:[1,37],9:20,11:4,13:7,14:[1,14],15:[1,15],16:[1,21],17:[1,16],18:8,19:[1,17],20:[1,33],21:[1,18],22:9,23:[1,19],24:11,25:5,26:[1,12],27:[1,112],28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],9:113,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],9:114,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],9:115,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{14:[1,116]},{5:[2,7],7:[2,7],8:[2,7],12:[2,7],14:[2,7],15:[2,7],16:[2,7],17:[2,7],19:[2,7],20:[2,7],21:[2,7],23:[2,7],26:[2,7],27:[2,7],50:[2,7],51:[2,7],58:[2,7],65:[2,7],74:[2,7],75:[2,7],76:[2,7],77:[2,7],78:[2,7],79:[2,7],80:[2,7],82:[2,7],91:[2,7],93:[2,7]},{5:[2,8],7:[2,8],8:[2,8],12:[2,8],14:[2,8],15:[2,8],16:[2,8],17:[2,8],19:[2,8],20:[2,8],21:[2,8],23:[2,8],26:[2,8],27:[2,8],50:[2,8],51:[2,8],58:[2,8],65:[2,8],74:[2,8],75:[2,8],76:[2,8],77:[2,8],78:[2,8],79:[2,8],80:[2,8],82:[2,8],91:[2,8],93:[2,8]},{5:[2,9],7:[2,9],8:[2,9],12:[2,9],14:[2,9],15:[2,9],16:[2,9],17:[2,9],19:[2,9],20:[2,9],21:[2,9],23:[2,9],26:[2,9],27:[2,9],50:[2,9],51:[2,9],58:[2,9],65:[2,9],74:[2,9],75:[2,9],76:[2,9],77:[2,9],78:[2,9],79:[2,9],80:[2,9],82:[2,9],91:[2,9],93:[2,9]},{16:[1,117]},{5:[2,22],7:[2,22],8:[2,22],12:[2,22],14:[2,22],15:[2,22],16:[2,22],17:[2,22],19:[2,22],20:[2,22],21:[2,22],23:[2,22],26:[2,22],27:[2,22],50:[2,22],51:[2,22],58:[2,22],65:[2,22],74:[2,22],75:[2,22],76:[2,22],77:[2,22],78:[2,22],79:[2,22],80:[2,22],82:[2,22],91:[2,22],93:[2,22]},{8:[1,37],20:[1,33],29:118,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,50:[1,59],51:[1,60],52:119,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],29:120,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,36:121,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{20:[1,122]},{8:[1,37],9:123,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[2,87],10:[2,87],16:[2,87],20:[1,126],32:[2,87],34:[2,87],35:[2,87],37:[2,87],39:[2,87],41:[2,87],42:[2,87],43:[2,87],45:[2,87],46:[2,87],47:[2,87],48:[2,87],50:[2,87],51:[2,87],53:[2,87],54:[2,87],55:[2,87],57:[2,87],64:[2,87],65:[2,87],66:[2,87],68:127,82:[1,45],83:[2,87],86:[2,87],89:124,90:125},{8:[1,37],10:[1,128],20:[1,33],29:102,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],81:129,82:[1,45],91:[1,38],93:[1,39]},{8:[2,89],10:[2,89],16:[2,89],32:[2,89],34:[2,89],35:[2,89],37:[2,89],39:[2,89],41:[2,89],42:[2,89],43:[2,89],45:[2,89],46:[2,89],47:[2,89],48:[2,89],50:[2,89],51:[2,89],53:[2,89],54:[2,89],55:[2,89],57:[2,89],64:[2,89],65:[2,89],66:[2,89],83:[2,89],86:[2,89]},{8:[1,37],9:130,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{20:[1,131]},{8:[1,37],20:[1,33],31:109,38:132,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,40:133,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,40:134,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,40:135,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{10:[1,136]},{10:[1,137],20:[1,139],92:138},{10:[1,140],20:[1,139],92:141},{8:[1,37],20:[1,33],31:109,44:142,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,44:143,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,44:144,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,44:145,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[2,79],10:[2,79],16:[2,79],32:[2,79],34:[2,79],35:[2,79],37:[2,79],39:[2,79],41:[2,79],42:[2,79],43:[2,79],45:[2,79],46:[2,79],47:[2,79],48:[2,79],50:[2,79],51:[2,79],53:[2,79],54:[2,79],55:[2,79],57:[2,79],64:[2,79],65:[2,79],66:[2,79],83:[2,79],86:[2,79]},{83:[1,146],86:[1,147]},{83:[2,81],86:[2,81]},{35:[1,148]},{35:[2,84]},{35:[2,85]},{35:[2,86]},{8:[2,77],10:[2,77],16:[2,77],32:[2,77],34:[2,77],35:[2,77],37:[2,77],39:[2,77],41:[2,77],42:[2,77],43:[2,77],45:[2,77],46:[2,77],47:[2,77],48:[2,77],50:[2,77],51:[2,77],53:[2,77],54:[2,77],55:[2,77],57:[2,77],64:[2,77],65:[2,77],66:[2,77],83:[2,77],86:[2,77]},{66:[1,149],86:[1,150]},{10:[2,98],66:[2,98],86:[2,98]},{8:[1,37],20:[1,33],31:109,49:151,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,49:152,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,50:[1,59],51:[1,60],52:153,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,50:[1,59],51:[1,60],52:154,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],31:109,50:[1,59],51:[1,60],52:155,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[2,51],10:[2,51],16:[2,51],32:[2,51],34:[2,51],35:[2,51],37:[2,51],39:[2,51],41:[2,51],42:[2,51],43:[2,51],45:[2,51],46:[2,51],47:[2,51],48:[2,51],50:[2,51],51:[2,51],53:[2,51],54:[2,51],55:[2,51],57:[2,51],64:[2,51],65:[2,51],66:[2,51],83:[2,51],86:[2,51]},{8:[2,48],10:[2,48],16:[2,48],32:[2,48],34:[2,48],35:[2,48],37:[2,48],39:[2,48],41:[2,48],42:[2,48],43:[2,48],45:[2,48],46:[2,48],47:[2,48],48:[2,48],50:[2,48],51:[2,48],53:[2,48],54:[2,48],55:[2,48],57:[1,72],64:[2,48],65:[2,48],66:[2,48],83:[2,48],86:[2,48]},{8:[2,52],10:[2,52],16:[2,52],32:[2,52],34:[2,52],35:[2,52],37:[2,52],39:[2,52],41:[2,52],42:[2,52],43:[2,52],45:[2,52],46:[2,52],47:[2,52],48:[2,52],50:[2,52],51:[2,52],53:[2,52],54:[2,52],55:[2,52],57:[2,52],64:[2,52],65:[2,52],66:[2,52],83:[2,52],86:[2,52]},{8:[2,53],10:[2,53],16:[2,53],32:[2,53],34:[2,53],35:[2,53],37:[2,53],39:[2,53],41:[2,53],42:[2,53],43:[2,53],45:[2,53],46:[2,53],47:[2,53],48:[2,53],50:[2,53],51:[2,53],53:[2,53],54:[2,53],55:[2,53],57:[2,53],64:[2,53],65:[2,53],66:[2,53],83:[2,53],86:[2,53]},{5:[2,12],7:[2,12],8:[2,12],10:[2,12],12:[2,12],14:[2,12],15:[2,12],16:[2,12],17:[2,12],19:[2,12],20:[2,12],21:[2,12],23:[2,12],26:[2,12],27:[2,12],32:[2,12],34:[2,12],35:[2,12],37:[2,12],39:[2,12],41:[2,12],42:[2,12],43:[2,12],45:[2,12],46:[2,12],47:[2,12],48:[2,12],50:[2,12],51:[2,12],53:[2,12],54:[2,12],55:[2,12],57:[2,12],58:[2,12],64:[2,12],65:[2,12],66:[2,12],74:[2,12],75:[2,12],76:[2,12],77:[2,12],78:[2,12],79:[2,12],80:[2,12],82:[2,12],83:[2,12],86:[2,12],91:[2,12],93:[2,12]},{10:[1,156]},{10:[1,157]},{16:[1,158]},{8:[1,159]},{5:[2,10],7:[2,10],8:[2,10],12:[2,10],14:[2,10],15:[2,10],16:[2,10],17:[2,10],19:[2,10],20:[2,10],21:[2,10],23:[2,10],26:[2,10],27:[2,10],50:[2,10],51:[2,10],58:[2,10],65:[2,10],74:[2,10],75:[2,10],76:[2,10],77:[2,10],78:[2,10],79:[2,10],80:[2,10],82:[2,10],91:[2,10],93:[2,10]},{8:[2,25],10:[2,25],16:[2,25],32:[2,25],34:[2,25],35:[2,25],37:[2,25],39:[2,25],41:[2,25],42:[2,25],43:[2,25],45:[2,25],46:[2,25],47:[2,25],48:[2,25],50:[2,25],51:[2,25],53:[2,25],54:[2,25],55:[2,25],57:[2,25],64:[2,25],65:[2,25],66:[2,25],83:[2,25],86:[2,25]},{8:[2,49],10:[2,49],16:[2,49],32:[2,49],34:[2,49],35:[2,49],37:[2,49],39:[2,49],41:[2,49],42:[2,49],43:[2,49],45:[2,49],46:[2,49],47:[2,49],48:[2,49],50:[2,49],51:[2,49],53:[2,49],54:[2,49],55:[2,49],57:[2,49],64:[2,49],65:[2,49],66:[2,49],83:[2,49],86:[2,49]},{35:[1,160]},{8:[2,29],10:[2,29],16:[2,29],32:[2,29],34:[2,29],35:[2,29],37:[2,29],39:[1,82],41:[2,29],42:[2,29],43:[2,29],45:[2,29],46:[2,29],47:[2,29],48:[2,29],50:[2,29],51:[2,29],53:[2,29],54:[2,29],55:[2,29],57:[2,29],64:[2,29],65:[2,29],66:[2,29],83:[2,29],86:[2,29]},{8:[2,59],10:[2,59],16:[2,59],32:[2,59],34:[2,59],35:[2,59],37:[2,59],39:[2,59],41:[2,59],42:[2,59],43:[2,59],45:[2,59],46:[2,59],47:[2,59],48:[2,59],50:[2,59],51:[2,59],53:[2,59],54:[2,59],55:[2,59],57:[2,59],64:[2,59],65:[2,59],66:[2,59],83:[2,59],86:[2,59]},{66:[1,161]},{8:[2,88],10:[2,88],16:[2,88],32:[2,88],34:[2,88],35:[2,88],37:[2,88],39:[2,88],41:[2,88],42:[2,88],43:[2,88],45:[2,88],46:[2,88],47:[2,88],48:[2,88],50:[2,88],51:[2,88],53:[2,88],54:[2,88],55:[2,88],57:[2,88],64:[2,88],65:[2,88],66:[2,88],83:[2,88],86:[1,162]},{8:[2,94],10:[2,94],16:[2,94],32:[2,94],34:[2,94],35:[2,94],37:[2,94],39:[2,94],41:[2,94],42:[2,94],43:[2,94],45:[2,94],46:[2,94],47:[2,94],48:[2,94],50:[2,94],51:[2,94],53:[2,94],54:[2,94],55:[2,94],57:[2,94],64:[2,94],65:[2,94],66:[2,94],83:[2,94],86:[2,94]},{8:[2,96],10:[2,96],16:[2,96],32:[2,96],34:[2,96],35:[2,96],37:[2,96],39:[2,96],41:[2,96],42:[2,96],43:[2,96],45:[2,96],46:[2,96],47:[2,96],48:[2,96],50:[2,96],51:[2,96],53:[2,96],54:[2,96],55:[2,96],57:[2,96],64:[2,96],65:[2,96],66:[2,96],83:[2,96],86:[2,96]},{8:[2,97],10:[2,97],16:[2,97],32:[2,97],34:[2,97],35:[2,97],37:[2,97],39:[2,97],41:[2,97],42:[2,97],43:[2,97],45:[2,97],46:[2,97],47:[2,97],48:[2,97],50:[2,97],51:[2,97],53:[2,97],54:[2,97],55:[2,97],57:[2,97],64:[2,97],65:[2,97],66:[2,97],83:[2,97],86:[2,97]},{8:[2,92],10:[2,92],16:[2,92],20:[2,92],32:[2,92],34:[2,92],35:[2,92],37:[2,92],39:[2,92],41:[2,92],42:[2,92],43:[2,92],45:[2,92],46:[2,92],47:[2,92],48:[2,92],50:[2,92],51:[2,92],53:[2,92],54:[2,92],55:[2,92],57:[2,92],64:[2,92],65:[2,92],66:[2,92],82:[2,92],83:[2,92],86:[2,92]},{10:[1,163],86:[1,150]},{66:[1,164]},{8:[2,91],10:[2,91],16:[2,91],32:[2,91],34:[2,91],35:[2,91],37:[2,91],39:[2,91],41:[2,91],42:[2,91],43:[2,91],45:[2,91],46:[2,91],47:[2,91],48:[2,91],50:[2,91],51:[2,91],53:[2,91],54:[2,91],55:[2,91],57:[2,91],64:[2,91],65:[2,91],66:[2,91],83:[2,91],86:[2,91]},{8:[2,31],10:[2,31],16:[2,31],32:[2,31],34:[2,31],35:[2,31],37:[2,31],39:[2,31],41:[1,83],42:[1,84],43:[1,85],45:[2,31],46:[2,31],47:[2,31],48:[2,31],50:[2,31],51:[2,31],53:[2,31],54:[2,31],55:[2,31],57:[2,31],64:[2,31],65:[2,31],66:[2,31],83:[2,31],86:[2,31]},{8:[2,33],10:[2,33],16:[2,33],32:[2,33],34:[2,33],35:[2,33],37:[2,33],39:[2,33],41:[2,33],42:[2,33],43:[2,33],45:[1,89],46:[1,90],47:[1,91],48:[1,92],50:[2,33],51:[2,33],53:[2,33],54:[2,33],55:[2,33],57:[2,33],64:[2,33],65:[2,33],66:[2,33],83:[2,33],86:[2,33]},{8:[2,34],10:[2,34],16:[2,34],32:[2,34],34:[2,34],35:[2,34],37:[2,34],39:[2,34],41:[2,34],42:[2,34],43:[2,34],45:[1,89],46:[1,90],47:[1,91],48:[1,92],50:[2,34],51:[2,34],53:[2,34],54:[2,34],55:[2,34],57:[2,34],64:[2,34],65:[2,34],66:[2,34],83:[2,34],86:[2,34]},{8:[2,35],10:[2,35],16:[2,35],32:[2,35],34:[2,35],35:[2,35],37:[2,35],39:[2,35],41:[2,35],42:[2,35],43:[2,35],45:[1,89],46:[1,90],47:[1,91],48:[1,92],50:[2,35],51:[2,35],53:[2,35],54:[2,35],55:[2,35],57:[2,35],64:[2,35],65:[2,35],66:[2,35],83:[2,35],86:[2,35]},{8:[2,65],10:[2,65],16:[2,65],32:[2,65],34:[2,65],35:[2,65],37:[2,65],39:[2,65],41:[2,65],42:[2,65],43:[2,65],45:[2,65],46:[2,65],47:[2,65],48:[2,65],50:[2,65],51:[2,65],53:[2,65],54:[2,65],55:[2,65],57:[2,65],64:[2,65],65:[2,65],66:[2,65],83:[2,65],86:[2,65]},{25:165,26:[1,12]},{10:[1,166],86:[1,167]},{10:[2,104],86:[2,104]},{94:[1,168]},{10:[1,169],86:[1,167]},{8:[2,37],10:[2,37],16:[2,37],32:[2,37],34:[2,37],35:[2,37],37:[2,37],39:[2,37],41:[2,37],42:[2,37],43:[2,37],45:[2,37],46:[2,37],47:[2,37],48:[2,37],50:[1,103],51:[1,104],53:[2,37],54:[2,37],55:[2,37],57:[2,37],64:[2,37],65:[2,37],66:[2,37],83:[2,37],86:[2,37]},{8:[2,38],10:[2,38],16:[2,38],32:[2,38],34:[2,38],35:[2,38],37:[2,38],39:[2,38],41:[2,38],42:[2,38],43:[2,38],45:[2,38],46:[2,38],47:[2,38],48:[2,38],50:[1,103],51:[1,104],53:[2,38],54:[2,38],55:[2,38],57:[2,38],64:[2,38],65:[2,38],66:[2,38],83:[2,38],86:[2,38]},{8:[2,39],10:[2,39],16:[2,39],32:[2,39],34:[2,39],35:[2,39],37:[2,39],39:[2,39],41:[2,39],42:[2,39],43:[2,39],45:[2,39],46:[2,39],47:[2,39],48:[2,39],50:[1,103],51:[1,104],53:[2,39],54:[2,39],55:[2,39],57:[2,39],64:[2,39],65:[2,39],66:[2,39],83:[2,39],86:[2,39]},{8:[2,40],10:[2,40],16:[2,40],32:[2,40],34:[2,40],35:[2,40],37:[2,40],39:[2,40],41:[2,40],42:[2,40],43:[2,40],45:[2,40],46:[2,40],47:[2,40],48:[2,40],50:[1,103],51:[1,104],53:[2,40],54:[2,40],55:[2,40],57:[2,40],64:[2,40],65:[2,40],66:[2,40],83:[2,40],86:[2,40]},{8:[2,80],10:[2,80],16:[2,80],32:[2,80],34:[2,80],35:[2,80],37:[2,80],39:[2,80],41:[2,80],42:[2,80],43:[2,80],45:[2,80],46:[2,80],47:[2,80],48:[2,80],50:[2,80],51:[2,80],53:[2,80],54:[2,80],55:[2,80],57:[2,80],64:[2,80],65:[2,80],66:[2,80],83:[2,80],86:[2,80]},{20:[1,97],72:98,73:99,77:[1,51],78:[1,52],79:[1,53],80:[1,54],85:170,87:96},{8:[1,37],20:[1,33],29:171,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[2,78],10:[2,78],16:[2,78],32:[2,78],34:[2,78],35:[2,78],37:[2,78],39:[2,78],41:[2,78],42:[2,78],43:[2,78],45:[2,78],46:[2,78],47:[2,78],48:[2,78],50:[2,78],51:[2,78],53:[2,78],54:[2,78],55:[2,78],57:[2,78],64:[2,78],65:[2,78],66:[2,78],83:[2,78],86:[2,78]},{8:[1,37],20:[1,33],29:172,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[2,42],10:[2,42],16:[2,42],32:[2,42],34:[2,42],35:[2,42],37:[2,42],39:[2,42],41:[2,42],42:[2,42],43:[2,42],45:[2,42],46:[2,42],47:[2,42],48:[2,42],50:[2,42],51:[2,42],53:[1,105],54:[1,106],55:[1,107],57:[2,42],64:[2,42],65:[2,42],66:[2,42],83:[2,42],86:[2,42]},{8:[2,43],10:[2,43],16:[2,43],32:[2,43],34:[2,43],35:[2,43],37:[2,43],39:[2,43],41:[2,43],42:[2,43],43:[2,43],45:[2,43],46:[2,43],47:[2,43],48:[2,43],50:[2,43],51:[2,43],53:[1,105],54:[1,106],55:[1,107],57:[2,43],64:[2,43],65:[2,43],66:[2,43],83:[2,43],86:[2,43]},{8:[2,45],10:[2,45],16:[2,45],32:[2,45],34:[2,45],35:[2,45],37:[2,45],39:[2,45],41:[2,45],42:[2,45],43:[2,45],45:[2,45],46:[2,45],47:[2,45],48:[2,45],50:[2,45],51:[2,45],53:[2,45],54:[2,45],55:[2,45],57:[2,45],64:[2,45],65:[2,45],66:[2,45],83:[2,45],86:[2,45]},{8:[2,46],10:[2,46],16:[2,46],32:[2,46],34:[2,46],35:[2,46],37:[2,46],39:[2,46],41:[2,46],42:[2,46],43:[2,46],45:[2,46],46:[2,46],47:[2,46],48:[2,46],50:[2,46],51:[2,46],53:[2,46],54:[2,46],55:[2,46],57:[2,46],64:[2,46],65:[2,46],66:[2,46],83:[2,46],86:[2,46]},{8:[2,47],10:[2,47],16:[2,47],32:[2,47],34:[2,47],35:[2,47],37:[2,47],39:[2,47],41:[2,47],42:[2,47],43:[2,47],45:[2,47],46:[2,47],47:[2,47],48:[2,47],50:[2,47],51:[2,47],53:[2,47],54:[2,47],55:[2,47],57:[2,47],64:[2,47],65:[2,47],66:[2,47],83:[2,47],86:[2,47]},{6:6,7:[1,13],8:[1,37],9:20,11:173,13:7,14:[1,14],15:[1,15],16:[1,21],17:[1,16],18:8,19:[1,17],20:[1,33],21:[1,18],22:9,23:[1,19],24:11,25:5,26:[1,12],28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{6:6,7:[1,13],8:[1,37],9:20,11:174,13:7,14:[1,14],15:[1,15],16:[1,21],17:[1,16],18:8,19:[1,17],20:[1,33],21:[1,18],22:9,23:[1,19],24:11,25:5,26:[1,12],28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],9:175,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],9:176,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],20:[1,33],29:177,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[2,60],10:[2,60],16:[2,60],32:[2,60],34:[2,60],35:[2,60],37:[2,60],39:[2,60],41:[2,60],42:[2,60],43:[2,60],45:[2,60],46:[2,60],47:[2,60],48:[2,60],50:[2,60],51:[2,60],53:[2,60],54:[2,60],55:[2,60],57:[2,60],64:[2,60],65:[2,60],66:[2,60],83:[2,60],86:[2,60]},{20:[1,126],68:127,82:[1,45],90:178},{8:[2,93],10:[2,93],16:[2,93],20:[2,93],32:[2,93],34:[2,93],35:[2,93],37:[2,93],39:[2,93],41:[2,93],42:[2,93],43:[2,93],45:[2,93],46:[2,93],47:[2,93],48:[2,93],50:[2,93],51:[2,93],53:[2,93],54:[2,93],55:[2,93],57:[2,93],64:[2,93],65:[2,93],66:[2,93],82:[2,93],83:[2,93],86:[2,93]},{8:[2,90],10:[2,90],16:[2,90],32:[2,90],34:[2,90],35:[2,90],37:[2,90],39:[2,90],41:[2,90],42:[2,90],43:[2,90],45:[2,90],46:[2,90],47:[2,90],48:[2,90],50:[2,90],51:[2,90],53:[2,90],54:[2,90],55:[2,90],57:[2,90],64:[2,90],65:[2,90],66:[2,90],83:[2,90],86:[2,90]},{8:[2,100],10:[2,100],16:[2,100],32:[2,100],34:[2,100],35:[2,100],37:[2,100],39:[2,100],41:[2,100],42:[2,100],43:[2,100],45:[2,100],46:[2,100],47:[2,100],48:[2,100],50:[2,100],51:[2,100],53:[2,100],54:[2,100],55:[2,100],57:[2,100],64:[2,100],65:[2,100],66:[2,100],83:[2,100],86:[2,100]},{25:179,26:[1,12]},{20:[1,180]},{8:[1,37],9:181,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{94:[1,182]},{83:[2,82],86:[2,82]},{83:[2,83],86:[2,83]},{10:[2,99],66:[2,99],86:[2,99]},{5:[2,2],7:[2,2],8:[2,2],12:[1,183],14:[2,2],15:[2,2],16:[2,2],17:[2,2],19:[2,2],20:[2,2],21:[2,2],23:[2,2],26:[2,2],27:[2,2],50:[2,2],51:[2,2],58:[2,2],65:[2,2],74:[2,2],75:[2,2],76:[2,2],77:[2,2],78:[2,2],79:[2,2],80:[2,2],82:[2,2],91:[2,2],93:[2,2]},{5:[2,4],7:[2,4],8:[2,4],12:[2,4],14:[2,4],15:[2,4],16:[2,4],17:[2,4],19:[2,4],20:[2,4],21:[2,4],23:[2,4],26:[2,4],27:[2,4],50:[2,4],51:[2,4],58:[2,4],65:[2,4],74:[2,4],75:[2,4],76:[2,4],77:[2,4],78:[2,4],79:[2,4],80:[2,4],82:[2,4],91:[2,4],93:[2,4]},{16:[1,184]},{10:[1,185]},{8:[2,27],10:[2,27],16:[2,27],32:[2,27],34:[2,27],35:[2,27],37:[2,27],39:[2,27],41:[2,27],42:[2,27],43:[2,27],45:[2,27],46:[2,27],47:[2,27],48:[2,27],50:[2,27],51:[2,27],53:[2,27],54:[2,27],55:[2,27],57:[2,27],64:[2,27],65:[2,27],66:[2,27],83:[2,27],86:[2,27]},{8:[2,95],10:[2,95],16:[2,95],32:[2,95],34:[2,95],35:[2,95],37:[2,95],39:[2,95],41:[2,95],42:[2,95],43:[2,95],45:[2,95],46:[2,95],47:[2,95],48:[2,95],50:[2,95],51:[2,95],53:[2,95],54:[2,95],55:[2,95],57:[2,95],64:[2,95],65:[2,95],66:[2,95],83:[2,95],86:[2,95]},{8:[2,101],10:[2,101],16:[2,101],32:[2,101],34:[2,101],35:[2,101],37:[2,101],39:[2,101],41:[2,101],42:[2,101],43:[2,101],45:[2,101],46:[2,101],47:[2,101],48:[2,101],50:[2,101],51:[2,101],53:[2,101],54:[2,101],55:[2,101],57:[2,101],64:[2,101],65:[2,101],66:[2,101],83:[2,101],86:[2,101]},{10:[2,105],86:[2,105]},{8:[2,102],10:[2,102],16:[2,102],32:[2,102],34:[2,102],35:[2,102],37:[2,102],39:[2,102],41:[2,102],42:[2,102],43:[2,102],45:[2,102],46:[2,102],47:[2,102],48:[2,102],50:[2,102],51:[2,102],53:[2,102],54:[2,102],55:[2,102],57:[2,102],64:[2,102],65:[2,102],66:[2,102],83:[2,102],86:[2,102]},{8:[1,37],9:186,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{6:6,7:[1,13],8:[1,37],9:20,11:187,13:7,14:[1,14],15:[1,15],16:[1,21],17:[1,16],18:8,19:[1,17],20:[1,33],21:[1,18],22:9,23:[1,19],24:11,25:5,26:[1,12],28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{8:[1,37],9:188,20:[1,33],29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{16:[1,189]},{8:[2,103],10:[2,103],16:[2,103],32:[2,103],34:[2,103],35:[2,103],37:[2,103],39:[2,103],41:[2,103],42:[2,103],43:[2,103],45:[2,103],46:[2,103],47:[2,103],48:[2,103],50:[2,103],51:[2,103],53:[2,103],54:[2,103],55:[2,103],57:[2,103],64:[2,103],65:[2,103],66:[2,103],83:[2,103],86:[2,103]},{5:[2,3],7:[2,3],8:[2,3],12:[2,3],14:[2,3],15:[2,3],16:[2,3],17:[2,3],19:[2,3],20:[2,3],21:[2,3],23:[2,3],26:[2,3],27:[2,3],50:[2,3],51:[2,3],58:[2,3],65:[2,3],74:[2,3],75:[2,3],76:[2,3],77:[2,3],78:[2,3],79:[2,3],80:[2,3],82:[2,3],91:[2,3],93:[2,3]},{10:[1,190]},{5:[2,6],7:[2,6],8:[2,6],12:[2,6],14:[2,6],15:[2,6],16:[2,6],17:[2,6],19:[2,6],20:[2,6],21:[2,6],23:[2,6],26:[2,6],27:[2,6],50:[2,6],51:[2,6],58:[2,6],65:[2,6],74:[2,6],75:[2,6],76:[2,6],77:[2,6],78:[2,6],79:[2,6],80:[2,6],82:[2,6],91:[2,6],93:[2,6]},{6:6,7:[1,13],8:[1,37],9:20,11:191,13:7,14:[1,14],15:[1,15],16:[1,21],17:[1,16],18:8,19:[1,17],20:[1,33],21:[1,18],22:9,23:[1,19],24:11,25:5,26:[1,12],28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:[1,59],51:[1,60],52:56,56:57,58:[1,58],59:26,60:27,61:29,62:30,63:31,65:[1,46],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:[1,48],75:[1,49],76:[1,50],77:[1,51],78:[1,52],79:[1,53],80:[1,54],82:[1,45],91:[1,38],93:[1,39]},{5:[2,5],7:[2,5],8:[2,5],12:[2,5],14:[2,5],15:[2,5],16:[2,5],17:[2,5],19:[2,5],20:[2,5],21:[2,5],23:[2,5],26:[2,5],27:[2,5],50:[2,5],51:[2,5],58:[2,5],65:[2,5],74:[2,5],75:[2,5],76:[2,5],77:[2,5],78:[2,5],79:[2,5],80:[2,5],82:[2,5],91:[2,5],93:[2,5]}],
3234 defaultActions: {3:[2,1],97:[2,84],98:[2,85],99:[2,86]},
3235 parseError: function parseError (str, hash) {
3236     throw new Error(str);
3237 },
3238 /**
3239  * @class
3240  * @ignore
3241  */
3242 parse: function parse(input) {
3243     var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
3244     this.lexer.setInput(input);
3245     this.lexer.yy = this.yy;
3246     this.yy.lexer = this.lexer;
3247     this.yy.parser = this;
3248     if (typeof this.lexer.yylloc == "undefined")
3249         this.lexer.yylloc = {};
3250     var yyloc = this.lexer.yylloc;
3251     lstack.push(yyloc);
3252     var ranges = this.lexer.options && this.lexer.options.ranges;
3253     if (typeof this.yy.parseError === "function")
3254         this.parseError = this.yy.parseError;
3255     function popStack(n) {
3256         stack.length = stack.length - 2 * n;
3257         vstack.length = vstack.length - n;
3258         lstack.length = lstack.length - n;
3259     }
3260     function lex() {
3261         var token;
3262         token = self.lexer.lex() || 1;
3263         if (typeof token !== "number") {
3264             token = self.symbols_[token] || token;
3265         }
3266         return token;
3267     }
3268     var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
3269     while (true) {
3270         state = stack[stack.length - 1];
3271         if (this.defaultActions[state]) {
3272             action = this.defaultActions[state];
3273         } else {
3274             if (symbol === null || typeof symbol == "undefined") {
3275                 symbol = lex();
3276             }
3277             action = table[state] && table[state][symbol];
3278         }
3279         if (typeof action === "undefined" || !action.length || !action[0]) {
3280             var errStr = "";
3281             if (!recovering) {
3282                 expected = [];
3283                 for (p in table[state])
3284                     if (this.terminals_[p] && p > 2) {
3285                         expected.push("'" + this.terminals_[p] + "'");
3286                     }
3287                 if (this.lexer.showPosition) {
3288                     errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
3289                 } else {
3290                     errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
3291                 }
3292                 this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
3293             }
3294         }
3295         if (action[0] instanceof Array && action.length > 1) {
3296             throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
3297         }
3298         switch (action[0]) {
3299         case 1:
3300             stack.push(symbol);
3301             vstack.push(this.lexer.yytext);
3302             lstack.push(this.lexer.yylloc);
3303             stack.push(action[1]);
3304             symbol = null;
3305             if (!preErrorSymbol) {
3306                 yyleng = this.lexer.yyleng;
3307                 yytext = this.lexer.yytext;
3308                 yylineno = this.lexer.yylineno;
3309                 yyloc = this.lexer.yylloc;
3310                 if (recovering > 0)
3311                     recovering--;
3312             } else {
3313                 symbol = preErrorSymbol;
3314                 preErrorSymbol = null;
3315             }
3316             break;
3317         case 2:
3318             len = this.productions_[action[1]][1];
3319             yyval.$ = vstack[vstack.length - len];
3320             yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
3321             if (ranges) {
3322                 yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
3323             }
3324             r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
3325             if (typeof r !== "undefined") {
3326                 return r;
3327             }
3328             if (len) {
3329                 stack = stack.slice(0, -1 * len * 2);
3330                 vstack = vstack.slice(0, -1 * len);
3331                 lstack = lstack.slice(0, -1 * len);
3332             }
3333             stack.push(this.productions_[action[1]][0]);
3334             vstack.push(yyval.$);
3335             lstack.push(yyval._$);
3336             newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
3337             stack.push(newState);
3338             break;
3339         case 3:
3340             return true;
3341         }
3342     }
3343     return true;
3344 }
3345 };
3346 
3347 
3348     var AST = {
3349         node: function (type, value, children) {
3350             return {
3351                 type: type,
3352                 value: value,
3353                 children: children
3354             };
3355         },
3356 
3357         createNode: function (pos, type, value, children) {
3358             var i,
3359                 n = this.node(type, value, []);
3360 
3361             for (i = 3; i < arguments.length; i++) {
3362                 n.children.push(arguments[i]);
3363             }
3364 
3365             n.line = pos[0];
3366             n.col = pos[1];
3367             n.eline = pos[2];
3368             n.ecol = pos[3];
3369 
3370             return n;
3371         }
3372     };
3373 
3374     var lc = function (lc1) {
3375         return [lc1.first_line, lc1.first_column, lc1.last_line, lc1.last_column];
3376     };
3377 
3378 /* Jison generated lexer */
3379 var lexer = (function(){
3380 var lexer = ({EOF:1,
3381 parseError:function parseError(str, hash) {
3382         if (this.yy.parser) {
3383             this.yy.parser.parseError(str, hash);
3384         } else {
3385             throw new Error(str);
3386         }
3387     },
3388 setInput:function (input) {
3389         this._input = input;
3390         this._more = this._less = this.done = false;
3391         this.yylineno = this.yyleng = 0;
3392         this.yytext = this.matched = this.match = '';
3393         this.conditionStack = ['INITIAL'];
3394         this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
3395         if (this.options.ranges) this.yylloc.range = [0,0];
3396         this.offset = 0;
3397         return this;
3398     },
3399 input:function () {
3400         var ch = this._input[0];
3401         this.yytext += ch;
3402         this.yyleng++;
3403         this.offset++;
3404         this.match += ch;
3405         this.matched += ch;
3406         var lines = ch.match(/(?:\r\n?|\n).*/g);
3407         if (lines) {
3408             this.yylineno++;
3409             this.yylloc.last_line++;
3410         } else {
3411             this.yylloc.last_column++;
3412         }
3413         if (this.options.ranges) this.yylloc.range[1]++;
3414 
3415         this._input = this._input.slice(1);
3416         return ch;
3417     },
3418 unput:function (ch) {
3419         var len = ch.length;
3420         var lines = ch.split(/(?:\r\n?|\n)/g);
3421 
3422         this._input = ch + this._input;
3423         this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
3424         //this.yyleng -= len;
3425         this.offset -= len;
3426         var oldLines = this.match.split(/(?:\r\n?|\n)/g);
3427         this.match = this.match.substr(0, this.match.length-1);
3428         this.matched = this.matched.substr(0, this.matched.length-1);
3429 
3430         if (lines.length-1) this.yylineno -= lines.length-1;
3431         var r = this.yylloc.range;
3432 
3433         this.yylloc = {first_line: this.yylloc.first_line,
3434           last_line: this.yylineno+1,
3435           first_column: this.yylloc.first_column,
3436           last_column: lines ?
3437               (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
3438               this.yylloc.first_column - len
3439           };
3440 
3441         if (this.options.ranges) {
3442             this.yylloc.range = [r[0], r[0] + this.yyleng - len];
3443         }
3444         return this;
3445     },
3446 more:function () {
3447         this._more = true;
3448         return this;
3449     },
3450 less:function (n) {
3451         this.unput(this.match.slice(n));
3452     },
3453 pastInput:function () {
3454         var past = this.matched.substr(0, this.matched.length - this.match.length);
3455         return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
3456     },
3457 upcomingInput:function () {
3458         var next = this.match;
3459         if (next.length < 20) {
3460             next += this._input.substr(0, 20-next.length);
3461         }
3462         return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
3463     },
3464 showPosition:function () {
3465         var pre = this.pastInput();
3466         var c = new Array(pre.length + 1).join("-");
3467         return pre + this.upcomingInput() + "\n" + c+"^";
3468     },
3469 next:function () {
3470         if (this.done) {
3471             return this.EOF;
3472         }
3473         if (!this._input) this.done = true;
3474 
3475         var token,
3476             match,
3477             tempMatch,
3478             index,
3479             col,
3480             lines;
3481         if (!this._more) {
3482             this.yytext = '';
3483             this.match = '';
3484         }
3485         var rules = this._currentRules();
3486         for (var i=0;i < rules.length; i++) {
3487             tempMatch = this._input.match(this.rules[rules[i]]);
3488             if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
3489                 match = tempMatch;
3490                 index = i;
3491                 if (!this.options.flex) break;
3492             }
3493         }
3494         if (match) {
3495             lines = match[0].match(/(?:\r\n?|\n).*/g);
3496             if (lines) this.yylineno += lines.length;
3497             this.yylloc = {first_line: this.yylloc.last_line,
3498                            last_line: this.yylineno+1,
3499                            first_column: this.yylloc.last_column,
3500                            last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
3501             this.yytext += match[0];
3502             this.match += match[0];
3503             this.matches = match;
3504             this.yyleng = this.yytext.length;
3505             if (this.options.ranges) {
3506                 this.yylloc.range = [this.offset, this.offset += this.yyleng];
3507             }
3508             this._more = false;
3509             this._input = this._input.slice(match[0].length);
3510             this.matched += match[0];
3511             token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
3512             if (this.done && this._input) this.done = false;
3513             if (token) return token;
3514             else return;
3515         }
3516         if (this._input === "") {
3517             return this.EOF;
3518         } else {
3519             return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
3520                     {text: "", token: null, line: this.yylineno});
3521         }
3522     },
3523 lex:function lex () {
3524         var r = this.next();
3525         if (typeof r !== 'undefined') {
3526             return r;
3527         } else {
3528             return this.lex();
3529         }
3530     },
3531 begin:function begin (condition) {
3532         this.conditionStack.push(condition);
3533     },
3534 popState:function popState () {
3535         return this.conditionStack.pop();
3536     },
3537 _currentRules:function _currentRules () {
3538         return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
3539     },
3540 topState:function () {
3541         return this.conditionStack[this.conditionStack.length-2];
3542     },
3543 pushState:function begin (condition) {
3544         this.begin(condition);
3545     }});
3546 lexer.options = {};
3547 lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START
3548 ) {
3549 
3550 var YYSTATE=YY_START
3551 switch($avoiding_name_collisions) {
3552 case 0:/* ignore */
3553 break;
3554 case 1:return 78  /* New 123.1234e+-12 */
3555 break;
3556 case 2:return 78  /* Old 123.1234 or .1234 */
3557 break;
3558 case 3:return 78  /* Old 123 */
3559 break;
3560 case 4: return 77;
3561 break;
3562 case 5: return 77;
3563 break;
3564 case 6:/* ignore comment */
3565 break;
3566 case 7:/* ignore multiline comment */
3567 break;
3568 case 8:return 7
3569 break;
3570 case 9:return 12
3571 break;
3572 case 10:return 14
3573 break;
3574 case 11:return 17
3575 break;
3576 case 12:return 15
3577 break;
3578 case 13:return 91
3579 break;
3580 case 14:return 93
3581 break;
3582 case 15:return 19
3583 break;
3584 case 16:return 23
3585 break;
3586 case 17:return 21
3587 break;
3588 case 18:return 75
3589 break;
3590 case 19:return 76
3591 break;
3592 case 20:return 74
3593 break;
3594 case 21:return 80
3595 break;
3596 case 22:return 94
3597 break;
3598 case 23:return 94
3599 break;
3600 case 24:return 82
3601 break;
3602 case 25:return 83
3603 break;
3604 case 26:return 26
3605 break;
3606 case 27:return 27
3607 break;
3608 case 28:return 16
3609 break;
3610 case 29:return '#'
3611 break;
3612 case 30:return 34
3613 break;
3614 case 31:return 35
3615 break;
3616 case 32:return 79
3617 break;
3618 case 33:return 64
3619 break;
3620 case 34:return 65
3621 break;
3622 case 35:return 66
3623 break;
3624 case 36:return 8
3625 break;
3626 case 37:return 10
3627 break;
3628 case 38:return 58
3629 break;
3630 case 39:return 57
3631 break;
3632 case 40:return 57
3633 break;
3634 case 41:return 53
3635 break;
3636 case 42:return 54
3637 break;
3638 case 43:return 55
3639 break;
3640 case 44:return 50
3641 break;
3642 case 45:return 51
3643 break;
3644 case 46:return 47
3645 break;
3646 case 47:return 45
3647 break;
3648 case 48:return 48
3649 break;
3650 case 49:return 46
3651 break;
3652 case 50:return 41
3653 break;
3654 case 51:return 43
3655 break;
3656 case 52:return 42
3657 break;
3658 case 53:return 39
3659 break;
3660 case 54:return 37
3661 break;
3662 case 55:return 32
3663 break;
3664 case 56:return 86
3665 break;
3666 case 57:return 5
3667 break;
3668 case 58:return 20
3669 break;
3670 case 59:return 'INVALID'
3671 break;
3672 }
3673 };
3674 lexer.rules = [/^(?:\s+)/,/^(?:[0-9]*\.?[0-9]+([eE][-+]?[0-9]+))/,/^(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+\b)/,/^(?:[0-9]+)/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:\/\/.*)/,/^(?:\/\*(.|\n|\r)*?\*\/)/,/^(?:if\b)/,/^(?:else\b)/,/^(?:while\b)/,/^(?:do\b)/,/^(?:for\b)/,/^(?:function\b)/,/^(?:map\b)/,/^(?:use\b)/,/^(?:return\b)/,/^(?:delete\b)/,/^(?:true\b)/,/^(?:false\b)/,/^(?:null\b)/,/^(?:Infinity\b)/,/^(?:->)/,/^(?:=>)/,/^(?:<<)/,/^(?:>>)/,/^(?:\{)/,/^(?:\})/,/^(?:;)/,/^(?:#)/,/^(?:\?)/,/^(?::)/,/^(?:NaN\b)/,/^(?:\.)/,/^(?:\[)/,/^(?:\])/,/^(?:\()/,/^(?:\))/,/^(?:!)/,/^(?:\^)/,/^(?:\*\*)/,/^(?:\*)/,/^(?:\/)/,/^(?:%)/,/^(?:\+)/,/^(?:-)/,/^(?:<=)/,/^(?:<)/,/^(?:>=)/,/^(?:>)/,/^(?:==)/,/^(?:~=)/,/^(?:!=)/,/^(?:&&)/,/^(?:\|\|)/,/^(?:=)/,/^(?:,)/,/^(?:$)/,/^(?:[A-Za-z_\$][A-Za-z0-9_]*)/,/^(?:.)/];
3675 lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59],"inclusive":true}};
3676 return lexer;})()
3677 parser.lexer = lexer;
3678 /**
3679  * @class
3680  * @ignore
3681  */
3682 function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
3683 return new Parser;
3684 })();
3685 // Work around an issue with browsers that don't support Object.getPrototypeOf()
3686 parser.yy.parseError = parser.parseError;
3687 
3688 export default JXG.JessieCode;
3689