@khanacademy/kas 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -1,5 +1,11 @@
1
+ import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-core';
1
2
  import _ from 'underscore';
2
3
 
4
+ // This file is processed by a Rollup plugin (replace) to inject the production
5
+ const libName = "@khanacademy/kas";
6
+ const libVersion = "0.3.2";
7
+ addLibraryVersionToPerseusDebug(libName, libVersion);
8
+
3
9
  // this is a @generated file
4
10
 
5
11
  /* parser generated by jison 0.4.15 */
@@ -77,8 +83,7 @@ import _ from 'underscore';
77
83
  */
78
84
  var parser$1 = function () {
79
85
  var o = function o(k, v, _o, l) {
80
- for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v) {
81
- }
86
+ for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v);
82
87
  return _o;
83
88
  },
84
89
  $V0 = [1, 11],
@@ -424,7 +429,7 @@ var parser$1 = function () {
424
429
  }
425
430
  },
426
431
  // resets the lexer, sets new input
427
- setInput: function setInput(input, yy) {
432
+ setInput: function (input, yy) {
428
433
  this.yy = yy || this.yy || {};
429
434
  this._input = input;
430
435
  this._more = this._backtrack = this.done = false;
@@ -444,7 +449,7 @@ var parser$1 = function () {
444
449
  return this;
445
450
  },
446
451
  // consumes and returns one char from the input
447
- input: function input() {
452
+ input: function () {
448
453
  var ch = this._input[0];
449
454
  this.yytext += ch;
450
455
  this.yyleng++;
@@ -465,7 +470,7 @@ var parser$1 = function () {
465
470
  return ch;
466
471
  },
467
472
  // unshifts one char (or a string) into the input
468
- unput: function unput(ch) {
473
+ unput: function (ch) {
469
474
  var len = ch.length;
470
475
  var lines = ch.split(/(?:\r\n?|\n)/g);
471
476
  this._input = ch + this._input;
@@ -492,12 +497,12 @@ var parser$1 = function () {
492
497
  return this;
493
498
  },
494
499
  // When called from action, caches matched text and appends it on next action
495
- more: function more() {
500
+ more: function () {
496
501
  this._more = true;
497
502
  return this;
498
503
  },
499
504
  // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
500
- reject: function reject() {
505
+ reject: function () {
501
506
  if (this.options.backtrack_lexer) {
502
507
  this._backtrack = true;
503
508
  } else {
@@ -510,16 +515,16 @@ var parser$1 = function () {
510
515
  return this;
511
516
  },
512
517
  // retain first n characters of the match
513
- less: function less(n) {
518
+ less: function (n) {
514
519
  this.unput(this.match.slice(n));
515
520
  },
516
521
  // displays already matched input, i.e. for error messages
517
- pastInput: function pastInput() {
522
+ pastInput: function () {
518
523
  var past = this.matched.substr(0, this.matched.length - this.match.length);
519
524
  return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
520
525
  },
521
526
  // displays upcoming input, i.e. for error messages
522
- upcomingInput: function upcomingInput() {
527
+ upcomingInput: function () {
523
528
  var next = this.match;
524
529
  if (next.length < 20) {
525
530
  next += this._input.substr(0, 20 - next.length);
@@ -527,13 +532,13 @@ var parser$1 = function () {
527
532
  return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
528
533
  },
529
534
  // displays the character position where the lexing error occurred, i.e. for error messages
530
- showPosition: function showPosition() {
535
+ showPosition: function () {
531
536
  var pre = this.pastInput();
532
537
  var c = new Array(pre.length + 1).join("-");
533
538
  return pre + this.upcomingInput() + "\n" + c + "^";
534
539
  },
535
540
  // test the lexed token: return FALSE when not a match, otherwise return token
536
- test_match: function test_match(match, indexed_rule) {
541
+ test_match: function (match, indexed_rule) {
537
542
  var token, lines, backup;
538
543
  if (this.options.backtrack_lexer) {
539
544
  // save context
@@ -599,7 +604,7 @@ var parser$1 = function () {
599
604
  return false;
600
605
  },
601
606
  // return next match in input
602
- next: function next() {
607
+ next: function () {
603
608
  if (this.done) {
604
609
  return this.EOF;
605
610
  }
@@ -750,7 +755,7 @@ var parser$1 = function () {
750
755
  parser.Parser = Parser;
751
756
  return new Parser();
752
757
  }();
753
- var unitParser = parser$1;
758
+ const unitParser = parser$1;
754
759
 
755
760
  // This is a @generated file
756
761
 
@@ -829,8 +834,7 @@ var unitParser = parser$1;
829
834
  */
830
835
  var parser = function () {
831
836
  var o = function o(k, v, _o, l) {
832
- for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v) {
833
- }
837
+ for (_o = _o || {}, l = k.length; l--; _o[k[l]] = v);
834
838
  return _o;
835
839
  },
836
840
  $V0 = [1, 7],
@@ -2103,7 +2107,7 @@ var parser = function () {
2103
2107
  }
2104
2108
  },
2105
2109
  // resets the lexer, sets new input
2106
- setInput: function setInput(input, yy) {
2110
+ setInput: function (input, yy) {
2107
2111
  this.yy = yy || this.yy || {};
2108
2112
  this._input = input;
2109
2113
  this._more = this._backtrack = this.done = false;
@@ -2123,7 +2127,7 @@ var parser = function () {
2123
2127
  return this;
2124
2128
  },
2125
2129
  // consumes and returns one char from the input
2126
- input: function input() {
2130
+ input: function () {
2127
2131
  var ch = this._input[0];
2128
2132
  this.yytext += ch;
2129
2133
  this.yyleng++;
@@ -2144,7 +2148,7 @@ var parser = function () {
2144
2148
  return ch;
2145
2149
  },
2146
2150
  // unshifts one char (or a string) into the input
2147
- unput: function unput(ch) {
2151
+ unput: function (ch) {
2148
2152
  var len = ch.length;
2149
2153
  var lines = ch.split(/(?:\r\n?|\n)/g);
2150
2154
  this._input = ch + this._input;
@@ -2171,12 +2175,12 @@ var parser = function () {
2171
2175
  return this;
2172
2176
  },
2173
2177
  // When called from action, caches matched text and appends it on next action
2174
- more: function more() {
2178
+ more: function () {
2175
2179
  this._more = true;
2176
2180
  return this;
2177
2181
  },
2178
2182
  // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
2179
- reject: function reject() {
2183
+ reject: function () {
2180
2184
  if (this.options.backtrack_lexer) {
2181
2185
  this._backtrack = true;
2182
2186
  } else {
@@ -2189,16 +2193,16 @@ var parser = function () {
2189
2193
  return this;
2190
2194
  },
2191
2195
  // retain first n characters of the match
2192
- less: function less(n) {
2196
+ less: function (n) {
2193
2197
  this.unput(this.match.slice(n));
2194
2198
  },
2195
2199
  // displays already matched input, i.e. for error messages
2196
- pastInput: function pastInput() {
2200
+ pastInput: function () {
2197
2201
  var past = this.matched.substr(0, this.matched.length - this.match.length);
2198
2202
  return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
2199
2203
  },
2200
2204
  // displays upcoming input, i.e. for error messages
2201
- upcomingInput: function upcomingInput() {
2205
+ upcomingInput: function () {
2202
2206
  var next = this.match;
2203
2207
  if (next.length < 20) {
2204
2208
  next += this._input.substr(0, 20 - next.length);
@@ -2206,13 +2210,13 @@ var parser = function () {
2206
2210
  return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
2207
2211
  },
2208
2212
  // displays the character position where the lexing error occurred, i.e. for error messages
2209
- showPosition: function showPosition() {
2213
+ showPosition: function () {
2210
2214
  var pre = this.pastInput();
2211
2215
  var c = new Array(pre.length + 1).join("-");
2212
2216
  return pre + this.upcomingInput() + "\n" + c + "^";
2213
2217
  },
2214
2218
  // test the lexed token: return FALSE when not a match, otherwise return token
2215
- test_match: function test_match(match, indexed_rule) {
2219
+ test_match: function (match, indexed_rule) {
2216
2220
  var token, lines, backup;
2217
2221
  if (this.options.backtrack_lexer) {
2218
2222
  // save context
@@ -2278,7 +2282,7 @@ var parser = function () {
2278
2282
  return false;
2279
2283
  },
2280
2284
  // return next match in input
2281
- next: function next() {
2285
+ next: function () {
2282
2286
  if (this.done) {
2283
2287
  return this.EOF;
2284
2288
  }
@@ -2681,13 +2685,13 @@ _.extend(Expr.prototype, {
2681
2685
  // an array of the arguments to this node's immediate constructor
2682
2686
  args: abstract,
2683
2687
  // make a new node with the given arguments
2684
- construct: function construct(args) {
2688
+ construct: function (args) {
2685
2689
  var instance = new this.func();
2686
2690
  this.func.apply(instance, args);
2687
2691
  return instance;
2688
2692
  },
2689
2693
  // an abstraction for chainable, bottom-up recursion
2690
- recurse: function recurse(method) {
2694
+ recurse: function (method) {
2691
2695
  var passed = Array.prototype.slice.call(arguments, 1);
2692
2696
  var args = _.map(this.args(), function (arg) {
2693
2697
  return _.isString(arg) ? arg : arg[method].apply(arg, passed);
@@ -2697,7 +2701,7 @@ _.extend(Expr.prototype, {
2697
2701
  // evaluate numerically with given variable mapping
2698
2702
  eval: abstract,
2699
2703
  codegen: abstract,
2700
- compile: function compile() {
2704
+ compile: function () {
2701
2705
  var code = this.codegen();
2702
2706
  try {
2703
2707
  return new Function("vars", "return " + code + ";");
@@ -2712,7 +2716,7 @@ _.extend(Expr.prototype, {
2712
2716
  // returns a TeX string representing the expression
2713
2717
  tex: abstract,
2714
2718
  // returns a TeX string, modified by the given options
2715
- asTex: function asTex(options) {
2719
+ asTex: function (options) {
2716
2720
  options = options || {};
2717
2721
  _.defaults(options, {
2718
2722
  display: true,
@@ -2734,7 +2738,7 @@ _.extend(Expr.prototype, {
2734
2738
  },
2735
2739
  // returns the name of this expression's constructor as a string
2736
2740
  // only used for testing and debugging (the ugly regex is for IE8)
2737
- name: function name() {
2741
+ name: function () {
2738
2742
  if (this.func.name) {
2739
2743
  return this.func.name;
2740
2744
  } else {
@@ -2742,37 +2746,37 @@ _.extend(Expr.prototype, {
2742
2746
  }
2743
2747
  },
2744
2748
  // returns a string representing current node structure
2745
- repr: function repr() {
2749
+ repr: function () {
2746
2750
  return this.name() + "(" + _.map(this.args(), function (arg) {
2747
2751
  return _.isString(arg) ? arg : arg.repr();
2748
2752
  }).join(",") + ")";
2749
2753
  },
2750
2754
  // removes all negative signs
2751
- strip: function strip() {
2755
+ strip: function () {
2752
2756
  return this.recurse("strip");
2753
2757
  },
2754
2758
  // canonically reorders all commutative elements
2755
- normalize: function normalize() {
2759
+ normalize: function () {
2756
2760
  return this.recurse("normalize");
2757
2761
  },
2758
2762
  // expands the expression
2759
- expand: function expand() {
2763
+ expand: function () {
2760
2764
  return this.recurse("expand");
2761
2765
  },
2762
2766
  // naively factors out like terms
2763
- factor: function factor(options) {
2767
+ factor: function (options) {
2764
2768
  return this.recurse("factor", options);
2765
2769
  },
2766
2770
  // collect all like terms
2767
- collect: function collect(options) {
2771
+ collect: function (options) {
2768
2772
  return this.recurse("collect", options);
2769
2773
  },
2770
2774
  // strict syntactic equality check
2771
- equals: function equals(other) {
2775
+ equals: function (other) {
2772
2776
  return this.normalize().print() === other.normalize().print();
2773
2777
  },
2774
2778
  // expand and collect until the expression no longer changes
2775
- simplify: function simplify(options) {
2779
+ simplify: function (options) {
2776
2780
  options = _.extend({
2777
2781
  once: false
2778
2782
  }, options);
@@ -2804,31 +2808,31 @@ _.extend(Expr.prototype, {
2804
2808
  }
2805
2809
  },
2806
2810
  // check whether this expression is simplified
2807
- isSimplified: function isSimplified() {
2811
+ isSimplified: function () {
2808
2812
  return this.equals(this.simplify());
2809
2813
  },
2810
2814
  // return the child nodes of this node
2811
- exprArgs: function exprArgs() {
2815
+ exprArgs: function () {
2812
2816
  return _.filter(this.args(), function (arg) {
2813
2817
  return arg instanceof Expr;
2814
2818
  });
2815
2819
  },
2816
2820
  // return the variables (function and non) within the expression
2817
- getVars: function getVars(excludeFunc) {
2821
+ getVars: function (excludeFunc) {
2818
2822
  return _.uniq(_.flatten(_.invoke(this.exprArgs(), "getVars", excludeFunc))).sort();
2819
2823
  },
2820
- getConsts: function getConsts() {
2824
+ getConsts: function () {
2821
2825
  return _.uniq(_.flatten(_.invoke(this.exprArgs(), "getConsts"))).sort();
2822
2826
  },
2823
- getUnits: function getUnits() {
2827
+ getUnits: function () {
2824
2828
  return _.flatten(_.invoke(this.exprArgs(), "getUnits"));
2825
2829
  },
2826
2830
  // check whether this expression node is of a particular type
2827
- is: function is(func) {
2831
+ is: function (func) {
2828
2832
  return this instanceof func;
2829
2833
  },
2830
2834
  // check whether this expression has a particular node type
2831
- has: function has(func) {
2835
+ has: function (func) {
2832
2836
  if (this instanceof func) {
2833
2837
  return true;
2834
2838
  }
@@ -2838,26 +2842,26 @@ _.extend(Expr.prototype, {
2838
2842
  },
2839
2843
  // raise this expression to a given exponent
2840
2844
  // most useful for eventually implementing i^3 = -i, etc.
2841
- raiseToThe: function raiseToThe(exp) {
2845
+ raiseToThe: function (exp) {
2842
2846
  return new Pow(this, exp);
2843
2847
  },
2844
2848
  // does this expression have a specific rendering hint?
2845
2849
  // rendering hints are picked up while parsing, but are lost during transformations
2846
- isSubtract: function isSubtract() {
2850
+ isSubtract: function () {
2847
2851
  return false;
2848
2852
  },
2849
- isDivide: function isDivide() {
2853
+ isDivide: function () {
2850
2854
  return false;
2851
2855
  },
2852
- isRoot: function isRoot() {
2856
+ isRoot: function () {
2853
2857
  return false;
2854
2858
  },
2855
2859
  // whether this node needs an explicit multiplication sign if following a Num
2856
- needsExplicitMul: function needsExplicitMul() {
2860
+ needsExplicitMul: function () {
2857
2861
  return this.args()[0].needsExplicitMul();
2858
2862
  },
2859
2863
  // check that the variables in both expressions are the same
2860
- sameVars: function sameVars(other) {
2864
+ sameVars: function (other) {
2861
2865
  var vars1 = this.getVars();
2862
2866
  var vars2 = other.getVars();
2863
2867
 
@@ -2879,7 +2883,7 @@ _.extend(Expr.prototype, {
2879
2883
  // semantic equality check, call after sameVars() to avoid potential false positives
2880
2884
  // plug in random numbers for the variables in both expressions
2881
2885
  // if they both consistently evaluate the same, then they're the same
2882
- compare: function compare(other) {
2886
+ compare: function (other) {
2883
2887
  // equation comparisons are handled by Eq.compare()
2884
2888
  if (other instanceof Eq) {
2885
2889
  return false;
@@ -2967,7 +2971,7 @@ _.extend(Expr.prototype, {
2967
2971
  return true;
2968
2972
  },
2969
2973
  // evaluate as much of the expression as possible
2970
- partialEval: function partialEval(vars) {
2974
+ partialEval: function (vars) {
2971
2975
  if (this instanceof Unit) {
2972
2976
  return this;
2973
2977
  } else if (!this.has(Func)) {
@@ -2982,19 +2986,19 @@ _.extend(Expr.prototype, {
2982
2986
  // all negative signs are stripped and the expressions are converted to
2983
2987
  // a canonical commutative form
2984
2988
  // should only be done after compare() returns true to avoid false positives
2985
- sameForm: function sameForm(other) {
2989
+ sameForm: function (other) {
2986
2990
  return this.strip().equals(other.strip());
2987
2991
  },
2988
2992
  // returns the GCD of this expression and the given factor
2989
- findGCD: function findGCD(factor) {
2993
+ findGCD: function (factor) {
2990
2994
  return this.equals(factor) ? factor : Num.One;
2991
2995
  },
2992
2996
  // return this expression's denominator
2993
- getDenominator: function getDenominator() {
2997
+ getDenominator: function () {
2994
2998
  return Num.One;
2995
2999
  },
2996
3000
  // return this expression as a Mul
2997
- asMul: function asMul() {
3001
+ asMul: function () {
2998
3002
  return new Mul(Num.One, this);
2999
3003
  },
3000
3004
  // TODO(alex): rename to isDefinitePositive or similar?
@@ -3002,15 +3006,15 @@ _.extend(Expr.prototype, {
3002
3006
  isPositive: abstract,
3003
3007
  // TODO(alex): rename to hasNegativeSign or similar?
3004
3008
  // return whether this expression has a negative sign
3005
- isNegative: function isNegative() {
3009
+ isNegative: function () {
3006
3010
  return false;
3007
3011
  },
3008
3012
  // return a factor of this expression that is 100% positive
3009
- asPositiveFactor: function asPositiveFactor() {
3013
+ asPositiveFactor: function () {
3010
3014
  return this.isPositive() ? this : Num.One;
3011
3015
  },
3012
3016
  // return a copy of the expression with a new hint set (preserves hints)
3013
- addHint: function addHint(hint) {
3017
+ addHint: function (hint) {
3014
3018
  if (!hint) {
3015
3019
  return this;
3016
3020
  }
@@ -3023,15 +3027,15 @@ _.extend(Expr.prototype, {
3023
3027
  parens: false
3024
3028
  },
3025
3029
  // currently unused!
3026
- asExpr: function asExpr() {
3030
+ asExpr: function () {
3027
3031
  return this;
3028
3032
  },
3029
3033
  // complete parse by performing a few necessary transformations
3030
- completeParse: function completeParse() {
3034
+ completeParse: function () {
3031
3035
  return this.recurse("completeParse");
3032
3036
  },
3033
3037
  abs: abstract,
3034
- negate: function negate() {
3038
+ negate: function () {
3035
3039
  return new Mul(Num.Neg, this);
3036
3040
  }
3037
3041
  });
@@ -3040,21 +3044,21 @@ _.extend(Expr.prototype, {
3040
3044
  function Seq() {}
3041
3045
  Seq.prototype = new Expr();
3042
3046
  _.extend(Seq.prototype, {
3043
- args: function args() {
3047
+ args: function () {
3044
3048
  return this.terms;
3045
3049
  },
3046
- normalize: function normalize() {
3050
+ normalize: function () {
3047
3051
  var terms = _.sortBy(_.invoke(this.terms, "normalize"), function (term) {
3048
3052
  return term.print();
3049
3053
  });
3050
3054
  return new this.func(terms);
3051
3055
  },
3052
- expand: function expand() {
3056
+ expand: function () {
3053
3057
  return this.recurse("expand").flatten();
3054
3058
  },
3055
3059
  // partition the sequence into its numeric and non-numeric parts
3056
3060
  // makes no guarantees about the validity of either part!
3057
- partition: function partition() {
3061
+ partition: function () {
3058
3062
  var terms = _.groupBy(this.terms, function (term) {
3059
3063
  return term instanceof Num;
3060
3064
  });
@@ -3068,7 +3072,7 @@ _.extend(Seq.prototype, {
3068
3072
  },
3069
3073
  // ensure that sequences have 2+ terms and no nested sequences of the same type
3070
3074
  // this is a shallow flattening and will return a non-Seq if terms.length <= 1
3071
- flatten: function flatten() {
3075
+ flatten: function () {
3072
3076
  var type = this;
3073
3077
  var terms = _.reject(this.terms, function (term) {
3074
3078
  return term.equals(type.identity);
@@ -3093,14 +3097,14 @@ _.extend(Seq.prototype, {
3093
3097
  identity: undefined,
3094
3098
  // reduce a numeric sequence to a Num
3095
3099
  reduce: abstract,
3096
- isPositive: function isPositive() {
3100
+ isPositive: function () {
3097
3101
  var terms = _.invoke(this.terms, "collect");
3098
3102
  return _.all(_.invoke(terms, "isPositive"));
3099
3103
  },
3100
3104
  // return a new Seq with a given term replaced by a different term
3101
3105
  // (or array of terms). given term can be passed directly, or by index
3102
3106
  // if no new term is provided, the old one is simply removed
3103
- replace: function replace(oldTerm, newTerm) {
3107
+ replace: function (oldTerm, newTerm) {
3104
3108
  var index;
3105
3109
  if (oldTerm instanceof Expr) {
3106
3110
  index = _.indexOf(this.terms, oldTerm);
@@ -3117,10 +3121,10 @@ _.extend(Seq.prototype, {
3117
3121
  return new this.func(terms);
3118
3122
  },
3119
3123
  // syntactic sugar for replace()
3120
- remove: function remove(term) {
3124
+ remove: function (term) {
3121
3125
  return this.replace(term);
3122
3126
  },
3123
- getDenominator: function getDenominator() {
3127
+ getDenominator: function () {
3124
3128
  // TODO(alex): find and return LCM
3125
3129
  return new Mul(_.invoke(this.terms, "getDenominator")).flatten();
3126
3130
  }
@@ -3137,20 +3141,20 @@ function Add() {
3137
3141
  Add.prototype = new Seq();
3138
3142
  _.extend(Add.prototype, {
3139
3143
  func: Add,
3140
- eval: function _eval(vars, options) {
3144
+ eval: function (vars, options) {
3141
3145
  return _.reduce(this.terms, function (memo, term) {
3142
3146
  return memo + term.eval(vars, options);
3143
3147
  }, 0);
3144
3148
  },
3145
- codegen: function codegen() {
3149
+ codegen: function () {
3146
3150
  return _.map(this.terms, function (term) {
3147
3151
  return "(" + term.codegen() + ")";
3148
3152
  }).join(" + ") || "0";
3149
3153
  },
3150
- print: function print() {
3154
+ print: function () {
3151
3155
  return _.invoke(this.terms, "print").join("+");
3152
3156
  },
3153
- tex: function tex() {
3157
+ tex: function () {
3154
3158
  var tex = "";
3155
3159
  _.each(this.terms, function (term) {
3156
3160
  if (!tex || term.isSubtract()) {
@@ -3161,7 +3165,7 @@ _.extend(Add.prototype, {
3161
3165
  });
3162
3166
  return tex;
3163
3167
  },
3164
- collect: function collect(options) {
3168
+ collect: function (options) {
3165
3169
  var terms = _.invoke(this.terms, "collect", options);
3166
3170
 
3167
3171
  // [Expr expr, Num coefficient]
@@ -3195,7 +3199,7 @@ _.extend(Add.prototype, {
3195
3199
  },
3196
3200
  // naively factor out anything that is common to all terms
3197
3201
  // if options.keepNegative is specified, won't factor out a common -1
3198
- factor: function factor(options) {
3202
+ factor: function (options) {
3199
3203
  options = _.extend({
3200
3204
  keepNegative: false
3201
3205
  }, options);
@@ -3221,19 +3225,19 @@ _.extend(Add.prototype, {
3221
3225
  remainder = new Add(remainder).flatten();
3222
3226
  return Mul.createOrAppend(factors, remainder).flatten();
3223
3227
  },
3224
- reduce: function reduce(options) {
3228
+ reduce: function (options) {
3225
3229
  return _.reduce(this.terms, function (memo, term) {
3226
3230
  return memo.add(term, options);
3227
3231
  }, this.identity);
3228
3232
  },
3229
- needsExplicitMul: function needsExplicitMul() {
3233
+ needsExplicitMul: function () {
3230
3234
  return false;
3231
3235
  },
3232
- isNegative: function isNegative() {
3236
+ isNegative: function () {
3233
3237
  var terms = _.invoke(this.terms, "collect");
3234
3238
  return _.all(_.invoke(terms, "isNegative"));
3235
3239
  },
3236
- negate: function negate() {
3240
+ negate: function () {
3237
3241
  return new Add(_.invoke(this.terms, "negate"));
3238
3242
  }
3239
3243
  });
@@ -3249,22 +3253,22 @@ function Mul() {
3249
3253
  Mul.prototype = new Seq();
3250
3254
  _.extend(Mul.prototype, {
3251
3255
  func: Mul,
3252
- eval: function _eval(vars, options) {
3256
+ eval: function (vars, options) {
3253
3257
  return _.reduce(this.terms, function (memo, term) {
3254
3258
  return memo * term.eval(vars, options);
3255
3259
  }, 1);
3256
3260
  },
3257
- codegen: function codegen() {
3261
+ codegen: function () {
3258
3262
  return _.map(this.terms, function (term) {
3259
3263
  return "(" + term.codegen() + ")";
3260
3264
  }).join(" * ") || "0";
3261
3265
  },
3262
- print: function print() {
3266
+ print: function () {
3263
3267
  return _.map(this.terms, function (term) {
3264
3268
  return term instanceof Add ? "(" + term.print() + ")" : term.print();
3265
3269
  }).join("*");
3266
3270
  },
3267
- getUnits: function getUnits() {
3271
+ getUnits: function () {
3268
3272
  var tmUnits = _(this.terms).chain().map(function (term) {
3269
3273
  return term.getUnits();
3270
3274
  }).flatten().value();
@@ -3273,7 +3277,7 @@ _.extend(Mul.prototype, {
3273
3277
  },
3274
3278
  // since we don't care about commutativity, we can render a Mul any way we choose
3275
3279
  // so we follow convention: first any negatives, then any numbers, then everything else
3276
- tex: function tex() {
3280
+ tex: function () {
3277
3281
  var cdot = " \\cdot ";
3278
3282
  var terms = _.groupBy(this.terms, function (term) {
3279
3283
  if (term.isDivide()) {
@@ -3354,14 +3358,14 @@ _.extend(Mul.prototype, {
3354
3358
  return negatives + "\\frac{" + numerator + "}{" + denominator + "}";
3355
3359
  }
3356
3360
  },
3357
- strip: function strip() {
3361
+ strip: function () {
3358
3362
  var terms = _.map(this.terms, function (term) {
3359
3363
  return term instanceof Num ? term.abs() : term.strip();
3360
3364
  });
3361
3365
  return new Mul(terms).flatten();
3362
3366
  },
3363
3367
  // expand numerator and denominator separately
3364
- expand: function expand() {
3368
+ expand: function () {
3365
3369
  var isAdd = function isAdd(term) {
3366
3370
  return term instanceof Add;
3367
3371
  };
@@ -3408,7 +3412,7 @@ _.extend(Mul.prototype, {
3408
3412
  }
3409
3413
  return new Mul(normals.concat(inverses)).flatten();
3410
3414
  },
3411
- factor: function factor(options) {
3415
+ factor: function (options) {
3412
3416
  var factored = this.recurse("factor", options).flatten();
3413
3417
  if (!(factored instanceof Mul)) {
3414
3418
  return factored;
@@ -3438,7 +3442,7 @@ _.extend(Mul.prototype, {
3438
3442
  }
3439
3443
  return new Mul((grouped[false] || []).concat(rational)).flatten();
3440
3444
  },
3441
- collect: function collect(options) {
3445
+ collect: function (options) {
3442
3446
  var partitioned = this.recurse("collect", options).partition();
3443
3447
  var number = partitioned[0].reduce(options);
3444
3448
 
@@ -3569,14 +3573,14 @@ _.extend(Mul.prototype, {
3569
3573
  });
3570
3574
  return new Mul([number].concat(collected)).flatten();
3571
3575
  },
3572
- isSubtract: function isSubtract() {
3576
+ isSubtract: function () {
3573
3577
  return _.any(this.terms, function (term) {
3574
3578
  return term instanceof Num && term.hints.subtract;
3575
3579
  });
3576
3580
  },
3577
3581
  // factor a single -1 in to the Mul
3578
3582
  // combine with a Num if all Nums are positive, else add as a term
3579
- factorIn: function factorIn(hint) {
3583
+ factorIn: function (hint) {
3580
3584
  var partitioned = this.partition();
3581
3585
  var numbers = partitioned[0].terms;
3582
3586
  var fold = numbers.length && _.all(numbers, function (num) {
@@ -3595,7 +3599,7 @@ _.extend(Mul.prototype, {
3595
3599
  },
3596
3600
  // factor out a single hinted -1 (assume it is the division hint)
3597
3601
  // TODO(alex): make more general or rename to be more specific
3598
- factorOut: function factorOut() {
3602
+ factorOut: function () {
3599
3603
  var factored = false;
3600
3604
  var terms = _.compact(_.map(this.terms, function (term, i, list) {
3601
3605
  if (!factored && term instanceof Num && term.hints.divide) {
@@ -3611,18 +3615,18 @@ _.extend(Mul.prototype, {
3611
3615
  return new Mul(terms);
3612
3616
  }
3613
3617
  },
3614
- reduce: function reduce(options) {
3618
+ reduce: function (options) {
3615
3619
  return _.reduce(this.terms, function (memo, term) {
3616
3620
  return memo.mul(term, options);
3617
3621
  }, this.identity);
3618
3622
  },
3619
- findGCD: function findGCD(factor) {
3623
+ findGCD: function (factor) {
3620
3624
  return new Mul(_.invoke(this.terms, "findGCD", factor)).flatten();
3621
3625
  },
3622
- asMul: function asMul() {
3626
+ asMul: function () {
3623
3627
  return this;
3624
3628
  },
3625
- asPositiveFactor: function asPositiveFactor() {
3629
+ asPositiveFactor: function () {
3626
3630
  if (this.isPositive()) {
3627
3631
  return this;
3628
3632
  } else {
@@ -3630,13 +3634,13 @@ _.extend(Mul.prototype, {
3630
3634
  return new Mul(terms).flatten();
3631
3635
  }
3632
3636
  },
3633
- isNegative: function isNegative() {
3637
+ isNegative: function () {
3634
3638
  return _.any(_.invoke(this.collect().terms, "isNegative"));
3635
3639
  },
3636
- fold: function fold() {
3640
+ fold: function () {
3637
3641
  return Mul.fold(this);
3638
3642
  },
3639
- negate: function negate() {
3643
+ negate: function () {
3640
3644
  var isNum = function isNum(expr) {
3641
3645
  return expr instanceof Num;
3642
3646
  };
@@ -3653,7 +3657,7 @@ _.extend(Mul.prototype, {
3653
3657
  _.each([Add, Mul], function (type) {
3654
3658
  _.extend(type, {
3655
3659
  // create a new sequence unless left is already one (returns a copy)
3656
- createOrAppend: function createOrAppend(left, right) {
3660
+ createOrAppend: function (left, right) {
3657
3661
  if (left instanceof type) {
3658
3662
  return new type(left.terms.concat(right));
3659
3663
  } else {
@@ -3667,7 +3671,7 @@ _.extend(Mul, {
3667
3671
  // never fold into a Num that's already negative or a Mul that has a negative Num
3668
3672
  // an optional hint is kept track of to properly render user input
3669
3673
  // an empty hint means negation
3670
- handleNegative: function handleNegative(expr, hint) {
3674
+ handleNegative: function (expr, hint) {
3671
3675
  if (expr instanceof Num && expr.n > 0) {
3672
3676
  // e.g. - 2 -> -2
3673
3677
  var negated = expr.negate();
@@ -3685,7 +3689,7 @@ _.extend(Mul, {
3685
3689
  }
3686
3690
  },
3687
3691
  // division can create either a Rational or a Mul
3688
- handleDivide: function handleDivide(left, right) {
3692
+ handleDivide: function (left, right) {
3689
3693
  // dividing by a Mul is the same as repeated division by its terms
3690
3694
  if (right instanceof Mul) {
3691
3695
  var first = Mul.handleDivide(left, right.terms[0]);
@@ -3791,7 +3795,7 @@ _.extend(Mul, {
3791
3795
  // e.g. sin(x)*x -> sin(x)*x
3792
3796
  // e.g. sin(x)*(x) -> sin(x)*x
3793
3797
  // e.g. sin(x)*sin(y) -> sin(x)*sin(y)
3794
- fold: function fold(expr) {
3798
+ fold: function (expr) {
3795
3799
  if (expr instanceof Mul) {
3796
3800
  // assuming that this will be second to last
3797
3801
  var trigLog = _.find(_.initial(expr.terms), function (term) {
@@ -3851,10 +3855,10 @@ function Pow(base, exp) {
3851
3855
  Pow.prototype = new Expr();
3852
3856
  _.extend(Pow.prototype, {
3853
3857
  func: Pow,
3854
- args: function args() {
3858
+ args: function () {
3855
3859
  return [this.base, this.exp];
3856
3860
  },
3857
- eval: function _eval(vars, options) {
3861
+ eval: function (vars, options) {
3858
3862
  var evaledBase = this.base.eval(vars, options);
3859
3863
  var evaledExp = this.exp.eval(vars, options);
3860
3864
 
@@ -3889,7 +3893,7 @@ _.extend(Pow.prototype, {
3889
3893
  }
3890
3894
  return Math.pow(evaledBase, evaledExp);
3891
3895
  },
3892
- getUnits: function getUnits() {
3896
+ getUnits: function () {
3893
3897
  return this.base.getUnits().map(function (unit) {
3894
3898
  return {
3895
3899
  unit: unit.unit,
@@ -3897,17 +3901,17 @@ _.extend(Pow.prototype, {
3897
3901
  };
3898
3902
  }.bind(this));
3899
3903
  },
3900
- codegen: function codegen() {
3904
+ codegen: function () {
3901
3905
  return "Math.pow(" + this.base.codegen() + ", " + this.exp.codegen() + ")";
3902
3906
  },
3903
- print: function print() {
3907
+ print: function () {
3904
3908
  var base = this.base.print();
3905
3909
  if (this.base instanceof Seq || this.base instanceof Pow) {
3906
3910
  base = "(" + base + ")";
3907
3911
  }
3908
3912
  return base + "^(" + this.exp.print() + ")";
3909
3913
  },
3910
- tex: function tex() {
3914
+ tex: function () {
3911
3915
  if (this.isDivide()) {
3912
3916
  // e.g. x ^ -1 w/hint -> 1/x
3913
3917
  return "\\frac{1}{" + this.asDivide().tex() + "}";
@@ -3941,10 +3945,10 @@ _.extend(Pow.prototype, {
3941
3945
  return base + "^{" + this.exp.tex() + "}";
3942
3946
  }
3943
3947
  },
3944
- needsExplicitMul: function needsExplicitMul() {
3948
+ needsExplicitMul: function () {
3945
3949
  return this.isRoot() ? false : this.base.needsExplicitMul();
3946
3950
  },
3947
- expand: function expand() {
3951
+ expand: function () {
3948
3952
  var pow = this.recurse("expand");
3949
3953
  if (pow.base instanceof Mul) {
3950
3954
  // e.g. (ab)^c -> a^c*b^c
@@ -3998,7 +4002,7 @@ _.extend(Pow.prototype, {
3998
4002
  return pow;
3999
4003
  }
4000
4004
  },
4001
- factor: function factor() {
4005
+ factor: function () {
4002
4006
  var pow = this.recurse("factor");
4003
4007
  if (pow.base instanceof Mul) {
4004
4008
  var terms = _.map(pow.base.terms, function (term) {
@@ -4015,7 +4019,7 @@ _.extend(Pow.prototype, {
4015
4019
  return pow;
4016
4020
  }
4017
4021
  },
4018
- collect: function collect(options) {
4022
+ collect: function (options) {
4019
4023
  if (this.base instanceof Pow) {
4020
4024
  // collect this first to avoid having to deal with float precision
4021
4025
  // e.g. sqrt(2)^2 -> 2, not 2.0000000000000004
@@ -4075,14 +4079,14 @@ _.extend(Pow.prototype, {
4075
4079
  }
4076
4080
  },
4077
4081
  // checks whether this Pow represents user-entered division
4078
- isDivide: function isDivide() {
4082
+ isDivide: function () {
4079
4083
  var isDiv = function isDiv(arg) {
4080
4084
  return arg instanceof Num && arg.hints.divide;
4081
4085
  };
4082
4086
  return isDiv(this.exp) || this.exp instanceof Mul && _.any(this.exp.terms, isDiv);
4083
4087
  },
4084
4088
  // assuming this Pow represents user-entered division, returns the denominator
4085
- asDivide: function asDivide() {
4089
+ asDivide: function () {
4086
4090
  if (this.exp instanceof Num) {
4087
4091
  if (this.exp.eval() === -1) {
4088
4092
  return this.base;
@@ -4098,15 +4102,15 @@ _.extend(Pow.prototype, {
4098
4102
  error("called asDivide() on an Expr that wasn't a Num or Mul");
4099
4103
  }
4100
4104
  },
4101
- isRoot: function isRoot() {
4105
+ isRoot: function () {
4102
4106
  return this.exp instanceof Rational && this.exp.hints.root;
4103
4107
  },
4104
- isSquaredTrig: function isSquaredTrig() {
4108
+ isSquaredTrig: function () {
4105
4109
  return this.base instanceof Trig && !this.base.isInverse() && this.exp instanceof Num && this.exp.eval() === 2;
4106
4110
  },
4107
4111
  // extract whatever denominator makes sense, ignoring hints
4108
4112
  // if negative exponent, will recursively include the base's denominator as well
4109
- getDenominator: function getDenominator() {
4113
+ getDenominator: function () {
4110
4114
  if (this.exp instanceof Num && this.exp.eval() === -1) {
4111
4115
  return Mul.createOrAppend(this.base, this.base.getDenominator()).flatten();
4112
4116
  } else if (this.exp.isNegative()) {
@@ -4118,7 +4122,7 @@ _.extend(Pow.prototype, {
4118
4122
  return Num.One;
4119
4123
  }
4120
4124
  },
4121
- findGCD: function findGCD(factor) {
4125
+ findGCD: function (factor) {
4122
4126
  var base, exp;
4123
4127
  if (factor instanceof Pow) {
4124
4128
  base = factor.base;
@@ -4155,14 +4159,14 @@ _.extend(Pow.prototype, {
4155
4159
  }
4156
4160
  return Num.One;
4157
4161
  },
4158
- isPositive: function isPositive() {
4162
+ isPositive: function () {
4159
4163
  if (this.base.isPositive()) {
4160
4164
  return true;
4161
4165
  }
4162
4166
  var exp = this.exp.simplify();
4163
4167
  return exp instanceof Int && exp.eval() % 2 === 0;
4164
4168
  },
4165
- asPositiveFactor: function asPositiveFactor() {
4169
+ asPositiveFactor: function () {
4166
4170
  if (this.isPositive()) {
4167
4171
  return this;
4168
4172
  } else {
@@ -4182,10 +4186,10 @@ _.extend(Pow.prototype, {
4182
4186
  }
4183
4187
  });
4184
4188
  _.extend(Pow, {
4185
- sqrt: function sqrt(arg) {
4189
+ sqrt: function (arg) {
4186
4190
  return new Pow(arg, Num.Sqrt);
4187
4191
  },
4188
- nthroot: function nthroot(radicand, degree) {
4192
+ nthroot: function (radicand, degree) {
4189
4193
  var exp = Mul.fold(Mul.handleDivide(new Int(1), degree));
4190
4194
 
4191
4195
  // FIXME(johnsullivan): If oneOverDegree ends up being a pow object,
@@ -4202,16 +4206,16 @@ function Log(base, power) {
4202
4206
  Log.prototype = new Expr();
4203
4207
  _.extend(Log.prototype, {
4204
4208
  func: Log,
4205
- args: function args() {
4209
+ args: function () {
4206
4210
  return [this.base, this.power];
4207
4211
  },
4208
- eval: function _eval(vars, options) {
4212
+ eval: function (vars, options) {
4209
4213
  return Math.log(this.power.eval(vars, options)) / Math.log(this.base.eval(vars, options));
4210
4214
  },
4211
- codegen: function codegen() {
4215
+ codegen: function () {
4212
4216
  return "(Math.log(" + this.power.codegen() + ") / Math.log(" + this.base.codegen() + "))";
4213
4217
  },
4214
- print: function print() {
4218
+ print: function () {
4215
4219
  var power = "(" + this.power.print() + ")";
4216
4220
  if (this.isNatural()) {
4217
4221
  return "ln" + power;
@@ -4219,7 +4223,7 @@ _.extend(Log.prototype, {
4219
4223
  return "log_(" + this.base.print() + ") " + power;
4220
4224
  }
4221
4225
  },
4222
- tex: function tex() {
4226
+ tex: function () {
4223
4227
  var power = "(" + this.power.tex() + ")";
4224
4228
  if (this.isNatural()) {
4225
4229
  return "\\ln" + power;
@@ -4227,7 +4231,7 @@ _.extend(Log.prototype, {
4227
4231
  return "\\log_{" + this.base.tex() + "}" + power;
4228
4232
  }
4229
4233
  },
4230
- collect: function collect(options) {
4234
+ collect: function (options) {
4231
4235
  var log = this.recurse("collect", options);
4232
4236
  if (log.power instanceof Num && log.power.eval() === 1) {
4233
4237
  // e.g. ln(1) -> 0
@@ -4242,7 +4246,7 @@ _.extend(Log.prototype, {
4242
4246
  return log;
4243
4247
  }
4244
4248
  },
4245
- expand: function expand() {
4249
+ expand: function () {
4246
4250
  var log = this.recurse("expand");
4247
4251
  if (log.power instanceof Mul) {
4248
4252
  // might want behind super-simplify() flag
@@ -4268,7 +4272,7 @@ _.extend(Log.prototype, {
4268
4272
  hints: _.extend(Log.prototype.hints, {
4269
4273
  open: false
4270
4274
  }),
4271
- isPositive: function isPositive() {
4275
+ isPositive: function () {
4272
4276
  var log = this.collect();
4273
4277
  if (log.base instanceof Num && log.power instanceof Num) {
4274
4278
  return this.eval() > 0;
@@ -4276,21 +4280,21 @@ _.extend(Log.prototype, {
4276
4280
  return false;
4277
4281
  }
4278
4282
  },
4279
- needsExplicitMul: function needsExplicitMul() {
4283
+ needsExplicitMul: function () {
4280
4284
  return false;
4281
4285
  },
4282
- isNatural: function isNatural() {
4286
+ isNatural: function () {
4283
4287
  return this.base.equals(Const.e);
4284
4288
  }
4285
4289
  });
4286
4290
  _.extend(Log, {
4287
- natural: function natural() {
4291
+ natural: function () {
4288
4292
  return Const.e;
4289
4293
  },
4290
- common: function common() {
4294
+ common: function () {
4291
4295
  return Num.Ten;
4292
4296
  },
4293
- create: function create(base, power) {
4297
+ create: function (base, power) {
4294
4298
  var log = new Log(base, power);
4295
4299
  if (!power.hints.parens) {
4296
4300
  log = log.addHint("open");
@@ -4307,7 +4311,7 @@ function Trig(type, arg) {
4307
4311
  Trig.prototype = new Expr();
4308
4312
  _.extend(Trig.prototype, {
4309
4313
  func: Trig,
4310
- args: function args() {
4314
+ args: function () {
4311
4315
  return [this.type, this.arg];
4312
4316
  },
4313
4317
  functions: {
@@ -4315,7 +4319,7 @@ _.extend(Trig.prototype, {
4315
4319
  eval: Math.sin,
4316
4320
  codegen: "Math.sin((",
4317
4321
  tex: "\\sin",
4318
- expand: function expand() {
4322
+ expand: function () {
4319
4323
  return this;
4320
4324
  }
4321
4325
  },
@@ -4323,7 +4327,7 @@ _.extend(Trig.prototype, {
4323
4327
  eval: Math.cos,
4324
4328
  codegen: "Math.cos((",
4325
4329
  tex: "\\cos",
4326
- expand: function expand() {
4330
+ expand: function () {
4327
4331
  return this;
4328
4332
  }
4329
4333
  },
@@ -4331,37 +4335,37 @@ _.extend(Trig.prototype, {
4331
4335
  eval: Math.tan,
4332
4336
  codegen: "Math.tan((",
4333
4337
  tex: "\\tan",
4334
- expand: function expand() {
4338
+ expand: function () {
4335
4339
  return Mul.handleDivide(Trig.sin(this.arg), Trig.cos(this.arg));
4336
4340
  }
4337
4341
  },
4338
4342
  csc: {
4339
- eval: function _eval(arg) {
4343
+ eval: function (arg) {
4340
4344
  return 1 / Math.sin(arg);
4341
4345
  },
4342
4346
  codegen: "(1/Math.sin(",
4343
4347
  tex: "\\csc",
4344
- expand: function expand() {
4348
+ expand: function () {
4345
4349
  return Mul.handleDivide(Num.One, Trig.sin(this.arg));
4346
4350
  }
4347
4351
  },
4348
4352
  sec: {
4349
- eval: function _eval(arg) {
4353
+ eval: function (arg) {
4350
4354
  return 1 / Math.cos(arg);
4351
4355
  },
4352
4356
  codegen: "(1/Math.cos(",
4353
4357
  tex: "\\sec",
4354
- expand: function expand() {
4358
+ expand: function () {
4355
4359
  return Mul.handleDivide(Num.One, Trig.cos(this.arg));
4356
4360
  }
4357
4361
  },
4358
4362
  cot: {
4359
- eval: function _eval(arg) {
4363
+ eval: function (arg) {
4360
4364
  return 1 / Math.tan(arg);
4361
4365
  },
4362
4366
  codegen: "(1/Math.tan(",
4363
4367
  tex: "\\cot",
4364
- expand: function expand() {
4368
+ expand: function () {
4365
4369
  return Mul.handleDivide(Trig.cos(this.arg), Trig.sin(this.arg));
4366
4370
  }
4367
4371
  },
@@ -4381,114 +4385,114 @@ _.extend(Trig.prototype, {
4381
4385
  tex: "\\arctan"
4382
4386
  },
4383
4387
  arccsc: {
4384
- eval: function _eval(arg) {
4388
+ eval: function (arg) {
4385
4389
  return Math.asin(1 / arg);
4386
4390
  },
4387
4391
  codegen: "Math.asin(1/(",
4388
4392
  tex: "\\operatorname{arccsc}"
4389
4393
  },
4390
4394
  arcsec: {
4391
- eval: function _eval(arg) {
4395
+ eval: function (arg) {
4392
4396
  return Math.acos(1 / arg);
4393
4397
  },
4394
4398
  codegen: "Math.acos(1/(",
4395
4399
  tex: "\\operatorname{arcsec}"
4396
4400
  },
4397
4401
  arccot: {
4398
- eval: function _eval(arg) {
4402
+ eval: function (arg) {
4399
4403
  return Math.atan(1 / arg);
4400
4404
  },
4401
4405
  codegen: "Math.atan(1/(",
4402
4406
  tex: "\\operatorname{arccot}"
4403
4407
  },
4404
4408
  sinh: {
4405
- eval: function _eval(arg) {
4409
+ eval: function (arg) {
4406
4410
  return (Math.exp(arg) - Math.exp(-arg)) / 2;
4407
4411
  },
4408
- codegen: function codegen(argStr) {
4412
+ codegen: function (argStr) {
4409
4413
  return "((Math.exp(" + argStr + ") - Math.exp(-(" + argStr + "))) / 2)";
4410
4414
  },
4411
4415
  tex: "\\sinh",
4412
- expand: function expand() {
4416
+ expand: function () {
4413
4417
  return this;
4414
4418
  }
4415
4419
  },
4416
4420
  cosh: {
4417
- eval: function _eval(arg) {
4421
+ eval: function (arg) {
4418
4422
  return (Math.exp(arg) + Math.exp(-arg)) / 2;
4419
4423
  },
4420
- codegen: function codegen(argStr) {
4424
+ codegen: function (argStr) {
4421
4425
  return "((Math.exp(" + argStr + ") + Math.exp(-(" + argStr + "))) / 2)";
4422
4426
  },
4423
4427
  tex: "\\cosh",
4424
- expand: function expand() {
4428
+ expand: function () {
4425
4429
  return this;
4426
4430
  }
4427
4431
  },
4428
4432
  tanh: {
4429
- eval: function _eval(arg) {
4433
+ eval: function (arg) {
4430
4434
  return (Math.exp(arg) - Math.exp(-arg)) / (Math.exp(arg) + Math.exp(-arg));
4431
4435
  },
4432
- codegen: function codegen(argStr) {
4436
+ codegen: function (argStr) {
4433
4437
  return "(" + "(Math.exp(" + argStr + ") - Math.exp(-(" + argStr + ")))" + " / " + "(Math.exp(" + argStr + ") + Math.exp(-(" + argStr + ")))" + ")";
4434
4438
  },
4435
4439
  tex: "\\tanh",
4436
- expand: function expand() {
4440
+ expand: function () {
4437
4441
  return Mul.handleDivide(Trig.sinh(this.arg), Trig.cosh(this.arg));
4438
4442
  }
4439
4443
  },
4440
4444
  csch: {
4441
- eval: function _eval(arg) {
4445
+ eval: function (arg) {
4442
4446
  return 2 / (Math.exp(arg) - Math.exp(-arg));
4443
4447
  },
4444
- codegen: function codegen(argStr) {
4448
+ codegen: function (argStr) {
4445
4449
  return "(2 / (Math.exp(" + argStr + ") - Math.exp(-(" + argStr + "))))";
4446
4450
  },
4447
4451
  tex: "\\csch",
4448
- expand: function expand() {
4452
+ expand: function () {
4449
4453
  return Mul.handleDivide(Num.One, Trig.sinh(this.arg));
4450
4454
  }
4451
4455
  },
4452
4456
  sech: {
4453
- eval: function _eval(arg) {
4457
+ eval: function (arg) {
4454
4458
  return 2 / (Math.exp(arg) + Math.exp(-arg));
4455
4459
  },
4456
- codegen: function codegen(argStr) {
4460
+ codegen: function (argStr) {
4457
4461
  return "(2 / (Math.exp(" + argStr + ") + Math.exp(-(" + argStr + "))))";
4458
4462
  },
4459
4463
  tex: "\\sech",
4460
- expand: function expand() {
4464
+ expand: function () {
4461
4465
  return Mul.handleDivide(Num.One, Trig.cosh(this.arg));
4462
4466
  }
4463
4467
  },
4464
4468
  coth: {
4465
- eval: function _eval(arg) {
4469
+ eval: function (arg) {
4466
4470
  return (Math.exp(arg) + Math.exp(-arg)) / (Math.exp(arg) - Math.exp(-arg));
4467
4471
  },
4468
- codegen: function codegen(argStr) {
4472
+ codegen: function (argStr) {
4469
4473
  return "(" + "(Math.exp(" + argStr + ") + Math.exp(-(" + argStr + ")))" + " / " + "(Math.exp(" + argStr + ") - Math.exp(-(" + argStr + ")))" + ")";
4470
4474
  },
4471
4475
  tex: "\\coth",
4472
- expand: function expand() {
4476
+ expand: function () {
4473
4477
  return Mul.handleDivide(Trig.cosh(this.arg), Trig.sinh(this.arg));
4474
4478
  }
4475
4479
  }
4476
4480
  },
4477
- isEven: function isEven() {
4481
+ isEven: function () {
4478
4482
  return _.contains(["cos", "sec"], this.type);
4479
4483
  },
4480
- isInverse: function isInverse() {
4484
+ isInverse: function () {
4481
4485
  return this.type.indexOf("arc") === 0;
4482
4486
  },
4483
- isBasic: function isBasic() {
4487
+ isBasic: function () {
4484
4488
  return _.contains(["sin", "cos"], this.type);
4485
4489
  },
4486
- eval: function _eval(vars, options) {
4490
+ eval: function (vars, options) {
4487
4491
  var func = this.functions[this.type].eval;
4488
4492
  var arg = this.arg.eval(vars, options);
4489
4493
  return func(arg);
4490
4494
  },
4491
- codegen: function codegen() {
4495
+ codegen: function () {
4492
4496
  var func = this.functions[this.type].codegen;
4493
4497
  if (typeof func === "function") {
4494
4498
  return func(this.arg.codegen());
@@ -4498,10 +4502,10 @@ _.extend(Trig.prototype, {
4498
4502
  throw new Error("codegen not implemented for " + this.type);
4499
4503
  }
4500
4504
  },
4501
- print: function print() {
4505
+ print: function () {
4502
4506
  return this.type + "(" + this.arg.print() + ")";
4503
4507
  },
4504
- tex: function tex(options) {
4508
+ tex: function (options) {
4505
4509
  var func = this.functions[this.type].tex;
4506
4510
  var arg = "(" + this.arg.tex() + ")";
4507
4511
  return options && options.split ? [func, arg] : func + arg;
@@ -4509,7 +4513,7 @@ _.extend(Trig.prototype, {
4509
4513
  hints: _.extend(Trig.prototype.hints, {
4510
4514
  open: false
4511
4515
  }),
4512
- isPositive: function isPositive() {
4516
+ isPositive: function () {
4513
4517
  var trig = this.collect();
4514
4518
  if (trig.arg instanceof Num) {
4515
4519
  return this.eval() > 0;
@@ -4517,7 +4521,7 @@ _.extend(Trig.prototype, {
4517
4521
  return false;
4518
4522
  }
4519
4523
  },
4520
- completeParse: function completeParse() {
4524
+ completeParse: function () {
4521
4525
  if (this.exp) {
4522
4526
  var pow = new Pow(this, this.exp);
4523
4527
  this.exp = undefined;
@@ -4527,10 +4531,10 @@ _.extend(Trig.prototype, {
4527
4531
  }
4528
4532
  },
4529
4533
  // TODO(alex): does every new node type need to redefine these?
4530
- needsExplicitMul: function needsExplicitMul() {
4534
+ needsExplicitMul: function () {
4531
4535
  return false;
4532
4536
  },
4533
- expand: function expand() {
4537
+ expand: function () {
4534
4538
  var trig = this.recurse("expand");
4535
4539
  if (!trig.isInverse()) {
4536
4540
  // e.g. tan(x) -> sin(x)/cos(x)
@@ -4540,7 +4544,7 @@ _.extend(Trig.prototype, {
4540
4544
  return trig;
4541
4545
  }
4542
4546
  },
4543
- collect: function collect(options) {
4547
+ collect: function (options) {
4544
4548
  var trig = this.recurse("collect", options);
4545
4549
  if (!trig.isInverse() && trig.arg.isNegative()) {
4546
4550
  var arg;
@@ -4562,7 +4566,7 @@ _.extend(Trig.prototype, {
4562
4566
  }
4563
4567
  });
4564
4568
  _.extend(Trig, {
4565
- create: function create(pair, arg) {
4569
+ create: function (pair, arg) {
4566
4570
  var type = pair[0];
4567
4571
  var exp = pair[1];
4568
4572
  if (exp && exp.equals(Num.Neg)) {
@@ -4579,16 +4583,16 @@ _.extend(Trig, {
4579
4583
  }
4580
4584
  return trig;
4581
4585
  },
4582
- sin: function sin(arg) {
4586
+ sin: function (arg) {
4583
4587
  return new Trig("sin", arg);
4584
4588
  },
4585
- cos: function cos(arg) {
4589
+ cos: function (arg) {
4586
4590
  return new Trig("cos", arg);
4587
4591
  },
4588
- sinh: function sinh(arg) {
4592
+ sinh: function (arg) {
4589
4593
  return new Trig("sinh", arg);
4590
4594
  },
4591
- cosh: function cosh(arg) {
4595
+ cosh: function (arg) {
4592
4596
  return new Trig("cosh", arg);
4593
4597
  }
4594
4598
  });
@@ -4598,22 +4602,22 @@ function Abs(arg) {
4598
4602
  Abs.prototype = new Expr();
4599
4603
  _.extend(Abs.prototype, {
4600
4604
  func: Abs,
4601
- args: function args() {
4605
+ args: function () {
4602
4606
  return [this.arg];
4603
4607
  },
4604
- eval: function _eval(vars, options) {
4608
+ eval: function (vars, options) {
4605
4609
  return Math.abs(this.arg.eval(vars, options));
4606
4610
  },
4607
- codegen: function codegen() {
4611
+ codegen: function () {
4608
4612
  return "Math.abs(" + this.arg.codegen() + ")";
4609
4613
  },
4610
- print: function print() {
4614
+ print: function () {
4611
4615
  return "abs(" + this.arg.print() + ")";
4612
4616
  },
4613
- tex: function tex() {
4617
+ tex: function () {
4614
4618
  return "\\left|" + this.arg.tex() + "\\right|";
4615
4619
  },
4616
- collect: function collect(options) {
4620
+ collect: function (options) {
4617
4621
  var abs = this.recurse("collect", options);
4618
4622
  if (abs.arg.isPositive()) {
4619
4623
  // e.g. |2^x| -> 2^x
@@ -4642,7 +4646,7 @@ _.extend(Abs.prototype, {
4642
4646
  }
4643
4647
  },
4644
4648
  // this should definitely be behind a super-simplify flag
4645
- expand: function expand() {
4649
+ expand: function () {
4646
4650
  var abs = this.recurse("expand");
4647
4651
  if (abs.arg instanceof Mul) {
4648
4652
  // e.g. |xyz| -> |x|*|y|*|z|
@@ -4654,7 +4658,7 @@ _.extend(Abs.prototype, {
4654
4658
  return abs;
4655
4659
  }
4656
4660
  },
4657
- isPositive: function isPositive() {
4661
+ isPositive: function () {
4658
4662
  return true;
4659
4663
  }
4660
4664
  });
@@ -4668,13 +4672,13 @@ function Eq(left, type, right) {
4668
4672
  Eq.prototype = new Expr();
4669
4673
  _.extend(Eq.prototype, {
4670
4674
  func: Eq,
4671
- args: function args() {
4675
+ args: function () {
4672
4676
  return [this.left, this.type, this.right];
4673
4677
  },
4674
- needsExplicitMul: function needsExplicitMul() {
4678
+ needsExplicitMul: function () {
4675
4679
  return false;
4676
4680
  },
4677
- print: function print() {
4681
+ print: function () {
4678
4682
  return this.left.print() + this.type + this.right.print();
4679
4683
  },
4680
4684
  signs: {
@@ -4685,10 +4689,10 @@ _.extend(Eq.prototype, {
4685
4689
  "<=": " \\le ",
4686
4690
  ">=": " \\ge "
4687
4691
  },
4688
- tex: function tex() {
4692
+ tex: function () {
4689
4693
  return this.left.tex() + this.signs[this.type] + this.right.tex();
4690
4694
  },
4691
- normalize: function normalize() {
4695
+ normalize: function () {
4692
4696
  var eq = this.recurse("normalize");
4693
4697
  if (_.contains([">", ">="], eq.type)) {
4694
4698
  // inequalities should have the smaller side on the left
@@ -4701,7 +4705,7 @@ _.extend(Eq.prototype, {
4701
4705
  // the expression is normalized to a canonical form
4702
4706
  // e.g. y/2=x/4 -> y/2-x/4(=0) -> 2y-x(=0)
4703
4707
  // unless unfactored is specified, will then divide through
4704
- asExpr: function asExpr(unfactored) {
4708
+ asExpr: function (unfactored) {
4705
4709
  var isZero = function isZero(expr) {
4706
4710
  return expr instanceof Num && expr.isSimple() && expr.eval() === 0;
4707
4711
  };
@@ -4753,7 +4757,7 @@ _.extend(Eq.prototype, {
4753
4757
  // e.g. 2y-4x(=0) -> y-2x(=0)
4754
4758
  // TODO(alex): Make it an option to only divide by variables/expressions
4755
4759
  // guaranteed to be nonzero
4756
- divideThrough: function divideThrough(expr) {
4760
+ divideThrough: function (expr) {
4757
4761
  var isInequality = !this.isEquality();
4758
4762
  var simplified = expr.simplify({
4759
4763
  once: true
@@ -4809,10 +4813,10 @@ _.extend(Eq.prototype, {
4809
4813
  return dividedResult;
4810
4814
  }
4811
4815
  },
4812
- isEquality: function isEquality() {
4816
+ isEquality: function () {
4813
4817
  return _.contains(["=", "<>"], this.type);
4814
4818
  },
4815
- compare: function compare(other) {
4819
+ compare: function (other) {
4816
4820
  // expression comparisons are handled by Expr.compare()
4817
4821
  if (!(other instanceof Eq)) {
4818
4822
  return false;
@@ -4835,7 +4839,7 @@ _.extend(Eq.prototype, {
4835
4839
  }
4836
4840
  },
4837
4841
  // should only be done after compare() returns true to avoid false positives
4838
- sameForm: function sameForm(other) {
4842
+ sameForm: function (other) {
4839
4843
  var eq1 = this.normalize();
4840
4844
  var eq2 = other.normalize();
4841
4845
  var same = eq1.left.sameForm(eq2.left) && eq1.right.sameForm(eq2.right);
@@ -4848,7 +4852,7 @@ _.extend(Eq.prototype, {
4848
4852
  },
4849
4853
  // we don't want to override collect because it would turn y=x into y-x(=0)
4850
4854
  // instead, we ask if the equation was in that form, would it be simplified?
4851
- isSimplified: function isSimplified() {
4855
+ isSimplified: function () {
4852
4856
  var expr = this.asExpr( /* unfactored */true);
4853
4857
  var simplified = this.divideThrough(expr).simplify();
4854
4858
  return expr.equals(simplified) && this.left.isSimplified() && this.right.isSimplified();
@@ -4856,7 +4860,7 @@ _.extend(Eq.prototype, {
4856
4860
  });
4857
4861
  _.extend(Eq.prototype, {
4858
4862
  // Assumptions: Expression is of the form a+bx, and we solve for x
4859
- solveLinearEquationForVariable: function solveLinearEquationForVariable(variable) {
4863
+ solveLinearEquationForVariable: function (variable) {
4860
4864
  var expr = this.asExpr();
4861
4865
  if (!expr.is(Add) || expr.terms.length !== 2) {
4862
4866
  throw new Error("Can only handle linear equations of the form " + "a + bx (= 0)");
@@ -4880,10 +4884,10 @@ _.extend(Eq.prototype, {
4880
4884
  function Symbol() {}
4881
4885
  Symbol.prototype = new Expr();
4882
4886
  _.extend(Symbol.prototype, {
4883
- needsExplicitMul: function needsExplicitMul() {
4887
+ needsExplicitMul: function () {
4884
4888
  return false;
4885
4889
  },
4886
- findGCD: function findGCD(factor) {
4890
+ findGCD: function (factor) {
4887
4891
  if (factor instanceof Symbol || factor instanceof Num) {
4888
4892
  return this.equals(factor) ? this : Num.One;
4889
4893
  } else {
@@ -4900,16 +4904,16 @@ function Func(symbol, arg) {
4900
4904
  Func.prototype = new Symbol();
4901
4905
  _.extend(Func.prototype, {
4902
4906
  func: Func,
4903
- args: function args() {
4907
+ args: function () {
4904
4908
  return [this.symbol, this.arg];
4905
4909
  },
4906
- print: function print() {
4910
+ print: function () {
4907
4911
  return this.symbol + "(" + this.arg.print() + ")";
4908
4912
  },
4909
- tex: function tex() {
4913
+ tex: function () {
4910
4914
  return this.symbol + "(" + this.arg.tex() + ")";
4911
4915
  },
4912
- eval: function _eval(vars, options) {
4916
+ eval: function (vars, options) {
4913
4917
  var arg = this.arg;
4914
4918
  var func = vars[this.symbol];
4915
4919
  var newVars = _.extend(_.clone(vars), {
@@ -4922,20 +4926,20 @@ _.extend(Func.prototype, {
4922
4926
  // If parsedFunc isn't actually parsed, return its error
4923
4927
  return parsedFunc;
4924
4928
  },
4925
- codegen: function codegen() {
4929
+ codegen: function () {
4926
4930
  return 'vars["' + this.symbol + '"](' + this.arg.codegen() + ")";
4927
4931
  },
4928
- getUnits: function getUnits() {
4932
+ getUnits: function () {
4929
4933
  return this.arg.getUnits();
4930
4934
  },
4931
- getVars: function getVars(excludeFunc) {
4935
+ getVars: function (excludeFunc) {
4932
4936
  if (excludeFunc) {
4933
4937
  return this.arg.getVars();
4934
4938
  } else {
4935
4939
  return _.union(this.arg.getVars(), [this.symbol]).sort();
4936
4940
  }
4937
4941
  },
4938
- getConsts: function getConsts() {
4942
+ getConsts: function () {
4939
4943
  return this.arg.getConsts();
4940
4944
  }
4941
4945
  });
@@ -4948,16 +4952,16 @@ function Var(symbol, subscript) {
4948
4952
  Var.prototype = new Symbol();
4949
4953
  _.extend(Var.prototype, {
4950
4954
  func: Var,
4951
- args: function args() {
4955
+ args: function () {
4952
4956
  return [this.symbol, this.subscript];
4953
4957
  },
4954
- exprArgs: function exprArgs() {
4958
+ exprArgs: function () {
4955
4959
  return [];
4956
4960
  },
4957
- recurse: function recurse() {
4961
+ recurse: function () {
4958
4962
  return this;
4959
4963
  },
4960
- print: function print() {
4964
+ print: function () {
4961
4965
  var sub = "";
4962
4966
  if (this.subscript) {
4963
4967
  sub = "_(" + this.subscript.print() + ")";
@@ -4966,7 +4970,7 @@ _.extend(Var.prototype, {
4966
4970
  },
4967
4971
  // Provide a way to easily evalate expressions with the common case,
4968
4972
  // subscripts that consist of a single number or symbol e.g. x_a or x_42
4969
- prettyPrint: function prettyPrint() {
4973
+ prettyPrint: function () {
4970
4974
  var sub = this.subscript;
4971
4975
  if (sub && (sub instanceof Num || sub instanceof Symbol)) {
4972
4976
  return this.symbol + "_" + sub.print();
@@ -4974,7 +4978,7 @@ _.extend(Var.prototype, {
4974
4978
  return this.print();
4975
4979
  }
4976
4980
  },
4977
- tex: function tex() {
4981
+ tex: function () {
4978
4982
  var sub = "";
4979
4983
  if (this.subscript) {
4980
4984
  sub = "_{" + this.subscript.tex() + "}";
@@ -4982,19 +4986,19 @@ _.extend(Var.prototype, {
4982
4986
  var prefix = this.symbol.length > 1 ? "\\" : "";
4983
4987
  return prefix + this.symbol + sub;
4984
4988
  },
4985
- repr: function repr() {
4989
+ repr: function () {
4986
4990
  return "Var(" + this.print() + ")";
4987
4991
  },
4988
- eval: function _eval(vars, options) {
4992
+ eval: function (vars, options) {
4989
4993
  return vars[this.prettyPrint()];
4990
4994
  },
4991
- codegen: function codegen() {
4995
+ codegen: function () {
4992
4996
  return 'vars["' + this.prettyPrint() + '"]';
4993
4997
  },
4994
- getVars: function getVars() {
4998
+ getVars: function () {
4995
4999
  return [this.prettyPrint()];
4996
5000
  },
4997
- isPositive: function isPositive() {
5001
+ isPositive: function () {
4998
5002
  return false;
4999
5003
  }
5000
5004
  });
@@ -5006,47 +5010,47 @@ function Const(symbol) {
5006
5010
  Const.prototype = new Symbol();
5007
5011
  _.extend(Const.prototype, {
5008
5012
  func: Const,
5009
- args: function args() {
5013
+ args: function () {
5010
5014
  return [this.symbol];
5011
5015
  },
5012
- recurse: function recurse() {
5016
+ recurse: function () {
5013
5017
  return this;
5014
5018
  },
5015
- eval: function _eval(vars, options) {
5019
+ eval: function (vars, options) {
5016
5020
  if (this.symbol === "pi") {
5017
5021
  return Math.PI;
5018
5022
  } else if (this.symbol === "e") {
5019
5023
  return Math.E;
5020
5024
  }
5021
5025
  },
5022
- codegen: function codegen() {
5026
+ codegen: function () {
5023
5027
  if (this.symbol === "pi") {
5024
5028
  return "Math.PI";
5025
5029
  } else if (this.symbol === "e") {
5026
5030
  return "Math.E";
5027
5031
  }
5028
5032
  },
5029
- print: function print() {
5033
+ print: function () {
5030
5034
  return this.symbol;
5031
5035
  },
5032
- tex: function tex() {
5036
+ tex: function () {
5033
5037
  if (this.symbol === "pi") {
5034
5038
  return "\\pi ";
5035
5039
  } else if (this.symbol === "e") {
5036
5040
  return "e";
5037
5041
  }
5038
5042
  },
5039
- isPositive: function isPositive() {
5043
+ isPositive: function () {
5040
5044
  return this.eval() > 0;
5041
5045
  },
5042
- abs: function abs() {
5046
+ abs: function () {
5043
5047
  if (this.eval() > 0) {
5044
5048
  return this;
5045
5049
  } else {
5046
5050
  return Mul.handleNegative(this);
5047
5051
  }
5048
5052
  },
5049
- getConsts: function getConsts() {
5053
+ getConsts: function () {
5050
5054
  return [this.print()];
5051
5055
  }
5052
5056
  });
@@ -5057,16 +5061,16 @@ Const.pi = new Const("pi");
5057
5061
  function Num() {}
5058
5062
  Num.prototype = new Expr();
5059
5063
  _.extend(Num.prototype, {
5060
- repr: function repr() {
5064
+ repr: function () {
5061
5065
  return this.print();
5062
5066
  },
5063
- strip: function strip() {
5067
+ strip: function () {
5064
5068
  return this.abs();
5065
5069
  },
5066
- recurse: function recurse() {
5070
+ recurse: function () {
5067
5071
  return this;
5068
5072
  },
5069
- codegen: function codegen() {
5073
+ codegen: function () {
5070
5074
  return this.print();
5071
5075
  },
5072
5076
  // takes another Num and returns a new Num
@@ -5074,22 +5078,22 @@ _.extend(Num.prototype, {
5074
5078
  mul: abstract,
5075
5079
  // returns this Num's additive inverse
5076
5080
  negate: abstract,
5077
- isSubtract: function isSubtract() {
5081
+ isSubtract: function () {
5078
5082
  return this.hints.subtract;
5079
5083
  },
5080
5084
  // return the absolute value of the number
5081
5085
  abs: abstract,
5082
- needsExplicitMul: function needsExplicitMul() {
5086
+ needsExplicitMul: function () {
5083
5087
  return true;
5084
5088
  },
5085
5089
  findGCD: abstract,
5086
- isPositive: function isPositive() {
5090
+ isPositive: function () {
5087
5091
  return this.eval() > 0;
5088
5092
  },
5089
- isNegative: function isNegative() {
5093
+ isNegative: function () {
5090
5094
  return this.eval() < 0;
5091
5095
  },
5092
- asPositiveFactor: function asPositiveFactor() {
5096
+ asPositiveFactor: function () {
5093
5097
  return this.isPositive() ? this : this.abs();
5094
5098
  },
5095
5099
  // hints for interpreting and rendering user input
@@ -5105,7 +5109,7 @@ _.extend(Num.prototype, {
5105
5109
  // e.g. for reals, ints and floats are simple
5106
5110
  isSimple: abstract,
5107
5111
  // Based on http://stackoverflow.com/a/10454560/2571482
5108
- getDecimalPlaces: function getDecimalPlaces() {
5112
+ getDecimalPlaces: function () {
5109
5113
  var match = ("" + this.n).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
5110
5114
  if (match) {
5111
5115
  return Math.max(0,
@@ -5134,34 +5138,34 @@ function Rational(numerator, denominator) {
5134
5138
  Rational.prototype = new Num();
5135
5139
  _.extend(Rational.prototype, {
5136
5140
  func: Rational,
5137
- args: function args() {
5141
+ args: function () {
5138
5142
  return [this.n, this.d];
5139
5143
  },
5140
- eval: function _eval() {
5144
+ eval: function () {
5141
5145
  return this.n / this.d;
5142
5146
  },
5143
- print: function print() {
5147
+ print: function () {
5144
5148
  return this.n.toString() + "/" + this.d.toString();
5145
5149
  },
5146
- tex: function tex() {
5150
+ tex: function () {
5147
5151
  var tex = "\\frac{" + Math.abs(this.n).toString() + "}{" + this.d.toString() + "}";
5148
5152
  return this.n < 0 ? "-" + tex : tex;
5149
5153
  },
5150
- add: function add(num, options) {
5154
+ add: function (num, options) {
5151
5155
  if (num instanceof Rational) {
5152
5156
  return new Rational(this.n * num.d + this.d * num.n, this.d * num.d).collect();
5153
5157
  } else {
5154
5158
  return num.add(this, options);
5155
5159
  }
5156
5160
  },
5157
- mul: function mul(num, options) {
5161
+ mul: function (num, options) {
5158
5162
  if (num instanceof Rational) {
5159
5163
  return new Rational(this.n * num.n, this.d * num.d).collect();
5160
5164
  } else {
5161
5165
  return num.mul(this, options);
5162
5166
  }
5163
5167
  },
5164
- collect: function collect() {
5168
+ collect: function () {
5165
5169
  var gcd = Num.findGCD(this.n, this.d);
5166
5170
  var n = this.n / gcd;
5167
5171
  var d = this.d / gcd;
@@ -5171,13 +5175,13 @@ _.extend(Rational.prototype, {
5171
5175
  return new Rational(n, d);
5172
5176
  }
5173
5177
  },
5174
- negate: function negate() {
5178
+ negate: function () {
5175
5179
  return new Rational(-this.n, this.d);
5176
5180
  },
5177
- abs: function abs() {
5181
+ abs: function () {
5178
5182
  return new Rational(Math.abs(this.n), this.d);
5179
5183
  },
5180
- findGCD: function findGCD(factor) {
5184
+ findGCD: function (factor) {
5181
5185
  // Attempt to factor out common numerators and denominators to return
5182
5186
  // a Rational instead of a Float
5183
5187
  if (factor instanceof Rational) {
@@ -5194,7 +5198,7 @@ _.extend(Rational.prototype, {
5194
5198
  }
5195
5199
  },
5196
5200
  // for now, assuming that exp is a Num
5197
- raiseToThe: function raiseToThe(exp) {
5201
+ raiseToThe: function (exp) {
5198
5202
  if (exp instanceof Int) {
5199
5203
  var positive = exp.eval() > 0;
5200
5204
  var abs = exp.abs().eval();
@@ -5209,13 +5213,13 @@ _.extend(Rational.prototype, {
5209
5213
  return new Float(this.eval()).raiseToThe(exp);
5210
5214
  }
5211
5215
  },
5212
- getDenominator: function getDenominator() {
5216
+ getDenominator: function () {
5213
5217
  return new Int(this.d);
5214
5218
  },
5215
- isSimple: function isSimple() {
5219
+ isSimple: function () {
5216
5220
  return false;
5217
5221
  },
5218
- asRational: function asRational() {
5222
+ asRational: function () {
5219
5223
  return this;
5220
5224
  }
5221
5225
  });
@@ -5227,25 +5231,25 @@ function Int(number) {
5227
5231
  Int.prototype = new Rational(0, 1);
5228
5232
  _.extend(Int.prototype, {
5229
5233
  func: Int,
5230
- args: function args() {
5234
+ args: function () {
5231
5235
  return [this.n];
5232
5236
  },
5233
- print: function print() {
5237
+ print: function () {
5234
5238
  return this.n.toString();
5235
5239
  },
5236
- tex: function tex() {
5240
+ tex: function () {
5237
5241
  return this.n.toString();
5238
5242
  },
5239
- negate: function negate() {
5243
+ negate: function () {
5240
5244
  return new Int(-this.n);
5241
5245
  },
5242
- abs: function abs() {
5246
+ abs: function () {
5243
5247
  return new Int(Math.abs(this.n));
5244
5248
  },
5245
- isSimple: function isSimple() {
5249
+ isSimple: function () {
5246
5250
  return true;
5247
5251
  },
5248
- findGCD: function findGCD(factor) {
5252
+ findGCD: function (factor) {
5249
5253
  if (factor instanceof Int) {
5250
5254
  return new Int(Num.findGCD(this.n, factor.n));
5251
5255
  } else {
@@ -5254,7 +5258,7 @@ _.extend(Int.prototype, {
5254
5258
  }
5255
5259
  });
5256
5260
  _.extend(Int, {
5257
- create: function create(n) {
5261
+ create: function (n) {
5258
5262
  return new Int(n).addHint("entered");
5259
5263
  }
5260
5264
  });
@@ -5266,46 +5270,46 @@ function Float(number) {
5266
5270
  Float.prototype = new Num();
5267
5271
  _.extend(Float.prototype, {
5268
5272
  func: Float,
5269
- args: function args() {
5273
+ args: function () {
5270
5274
  return [this.n];
5271
5275
  },
5272
- eval: function _eval() {
5276
+ eval: function () {
5273
5277
  return this.n;
5274
5278
  },
5275
5279
  // TODO(alex): when we internationalize number parsing/display
5276
5280
  // we should make sure to use the appropriate decimal mark here
5277
- print: function print() {
5281
+ print: function () {
5278
5282
  return this.n.toString();
5279
5283
  },
5280
- tex: function tex() {
5284
+ tex: function () {
5281
5285
  return this.n.toString();
5282
5286
  },
5283
- add: function add(num, options) {
5287
+ add: function (num, options) {
5284
5288
  if (options && options.preciseFloats) {
5285
5289
  return Float.toDecimalPlaces(this.n + num.eval(), Math.max(this.getDecimalPlaces(), num.getDecimalPlaces()));
5286
5290
  } else {
5287
5291
  return new Float(this.n + num.eval()).collect();
5288
5292
  }
5289
5293
  },
5290
- mul: function mul(num, options) {
5294
+ mul: function (num, options) {
5291
5295
  if (options && options.preciseFloats) {
5292
5296
  return Float.toDecimalPlaces(this.n * num.eval(), this.getDecimalPlaces() + num.getDecimalPlaces());
5293
5297
  } else {
5294
5298
  return new Float(this.n * num.eval()).collect();
5295
5299
  }
5296
5300
  },
5297
- collect: function collect() {
5301
+ collect: function () {
5298
5302
  // We used to simplify Floats to Ints here whenever possible, but no
5299
5303
  // longer do so in order to preserve significant figures.
5300
5304
  return this;
5301
5305
  },
5302
- negate: function negate() {
5306
+ negate: function () {
5303
5307
  return new Float(-this.n);
5304
5308
  },
5305
- abs: function abs() {
5309
+ abs: function () {
5306
5310
  return new Float(Math.abs(this.n));
5307
5311
  },
5308
- findGCD: function findGCD(factor) {
5312
+ findGCD: function (factor) {
5309
5313
  if (factor instanceof Num) {
5310
5314
  return new Float(Num.findGCD(this.eval(), factor.eval())).collect();
5311
5315
  } else {
@@ -5313,7 +5317,7 @@ _.extend(Float.prototype, {
5313
5317
  }
5314
5318
  },
5315
5319
  // for now, assuming that exp is a Num
5316
- raiseToThe: function raiseToThe(exp, options) {
5320
+ raiseToThe: function (exp, options) {
5317
5321
  if (options && options.preciseFloats && exp instanceof Int && exp.n > 1) {
5318
5322
  return Float.toDecimalPlaces(new Pow(this, exp).eval(), this.getDecimalPlaces() * exp.n);
5319
5323
  } else {
@@ -5321,7 +5325,7 @@ _.extend(Float.prototype, {
5321
5325
  }
5322
5326
  },
5323
5327
  // only to be used on non-repeating decimals (e.g. user-provided)
5324
- asRational: function asRational() {
5328
+ asRational: function () {
5325
5329
  var parts = this.n.toString().split(".");
5326
5330
  if (parts.length === 1) {
5327
5331
  return new Rational(this.n, 1);
@@ -5331,27 +5335,27 @@ _.extend(Float.prototype, {
5331
5335
  return new Rational(numerator, denominator).collect();
5332
5336
  }
5333
5337
  },
5334
- getDenominator: function getDenominator() {
5338
+ getDenominator: function () {
5335
5339
  return this.asRational().getDenominator();
5336
5340
  },
5337
- isSimple: function isSimple() {
5341
+ isSimple: function () {
5338
5342
  return true;
5339
5343
  }
5340
5344
  });
5341
5345
  _.extend(Float, {
5342
- create: function create(n) {
5346
+ create: function (n) {
5343
5347
  return new Float(n).addHint("entered");
5344
5348
  },
5345
5349
  // Account for floating point imprecision by explicitly controlling the
5346
5350
  // number of decimal places in common operations (e.g. +, *, ^)
5347
- toDecimalPlaces: function toDecimalPlaces(n, places) {
5351
+ toDecimalPlaces: function (n, places) {
5348
5352
  return new Float(+n.toFixed(Math.min(places, 20))).collect();
5349
5353
  }
5350
5354
  });
5351
5355
 
5352
5356
  // static methods and fields that are best defined on Num
5353
5357
  _.extend(Num, {
5354
- negativeOne: function negativeOne(hint) {
5358
+ negativeOne: function (hint) {
5355
5359
  if (hint === "subtract") {
5356
5360
  return Num.Sub;
5357
5361
  } else if (hint === "divide") {
@@ -5361,7 +5365,7 @@ _.extend(Num, {
5361
5365
  }
5362
5366
  },
5363
5367
  // find the greatest common denominator
5364
- findGCD: function findGCD(a, b) {
5368
+ findGCD: function (a, b) {
5365
5369
  var mod;
5366
5370
  a = Math.abs(a);
5367
5371
  b = Math.abs(b);
@@ -5379,12 +5383,12 @@ _.extend(Num, {
5379
5383
  }
5380
5384
  return a;
5381
5385
  },
5382
- min: function min() {
5386
+ min: function () {
5383
5387
  return _.min(_.toArray(arguments), function (num) {
5384
5388
  return num.eval();
5385
5389
  });
5386
5390
  },
5387
- max: function max() {
5391
+ max: function () {
5388
5392
  return _.max(_.toArray(arguments), function (num) {
5389
5393
  return num.eval();
5390
5394
  });
@@ -5423,7 +5427,7 @@ parser.yy = {
5423
5427
  Float: Float,
5424
5428
  parseError: parseError,
5425
5429
  constants: ["e"],
5426
- symbolLexer: function symbolLexer(symbol) {
5430
+ symbolLexer: function (symbol) {
5427
5431
  if (_.contains(parser.yy.constants, symbol)) {
5428
5432
  return "CONST";
5429
5433
  } else if (_.contains(parser.yy.functions, symbol)) {
@@ -5433,7 +5437,7 @@ parser.yy = {
5433
5437
  }
5434
5438
  }
5435
5439
  };
5436
- var parse = function parse(input, options) {
5440
+ const parse = function parse(input, options) {
5437
5441
  try {
5438
5442
  if (options && options.functions) {
5439
5443
  // reserve the symbol "i" for complex numbers
@@ -5499,7 +5503,7 @@ var unprefixify = function unprefixify(symbol) {
5499
5503
  return new Unit(symbol);
5500
5504
  }
5501
5505
  };
5502
- var unitParse = function unitParse(input) {
5506
+ const unitParse = function unitParse(input) {
5503
5507
  try {
5504
5508
  var parseResult = unitParser.parse(input);
5505
5509
 
@@ -5555,13 +5559,13 @@ var unitParse = function unitParse(input) {
5555
5559
  };
5556
5560
  _.extend(Unit.prototype, {
5557
5561
  func: Unit,
5558
- args: function args() {
5562
+ args: function () {
5559
5563
  return [this.symbol];
5560
5564
  },
5561
- recurse: function recurse() {
5565
+ recurse: function () {
5562
5566
  return this;
5563
5567
  },
5564
- eval: function _eval(vars, options) {
5568
+ eval: function (vars, options) {
5565
5569
  // This is called when comparing units. A unit doesn't affect the
5566
5570
  // numerical value of its coefficient, so this needs to be 1.
5567
5571
  //
@@ -5571,23 +5575,23 @@ _.extend(Unit.prototype, {
5571
5575
  // However, there are a couple tests checking this.
5572
5576
  return 1;
5573
5577
  },
5574
- getUnits: function getUnits() {
5578
+ getUnits: function () {
5575
5579
  return [{
5576
5580
  unit: this.symbol,
5577
5581
  pow: 1
5578
5582
  }];
5579
5583
  },
5580
- codegen: function codegen() {
5584
+ codegen: function () {
5581
5585
  return "1";
5582
5586
  },
5583
- print: function print() {
5587
+ print: function () {
5584
5588
  return this.symbol;
5585
5589
  },
5586
- tex: function tex() {
5590
+ tex: function () {
5587
5591
  return this.symbol;
5588
5592
  },
5589
5593
  // Simplify units by replacing prefixes with multiplication
5590
- collect: function collect(options) {
5594
+ collect: function (options) {
5591
5595
  if (_(baseUnits).has(this.symbol)) {
5592
5596
  return this;
5593
5597
  } else if (_(derivedUnits).has(this.symbol)) {
@@ -5810,14 +5814,14 @@ var derivedUnits = {
5810
5814
  // other
5811
5815
  Hz: makeAlias("| / s", hasPrefixes)
5812
5816
  };
5813
- var Zero = Num.Zero;
5814
- var One = Num.One;
5817
+ const Zero = Num.Zero;
5818
+ const One = Num.One;
5815
5819
 
5816
5820
  /* eslint-disable */
5817
5821
 
5818
5822
  // Assumes that both expressions have already been parsed
5819
5823
  // TODO(alex): be able to pass a random() function to compare()
5820
- var compare = function compare(expr1, expr2, options) {
5824
+ const compare = function compare(expr1, expr2, options) {
5821
5825
  var defaults = {
5822
5826
  form: false,
5823
5827
  // Check that the two expressions have the same form
@@ -5825,10 +5829,10 @@ var compare = function compare(expr1, expr2, options) {
5825
5829
  };
5826
5830
 
5827
5831
  /* Options that could be added in the future:
5828
- * - Allow ratios: e.g. 3/1 and 3 should both be accepted for something
5829
- * like slope
5830
- * - Allow student to choose their own variable names
5831
- */
5832
+ * - Allow ratios: e.g. 3/1 and 3 should both be accepted for something
5833
+ * like slope
5834
+ * - Allow student to choose their own variable names
5835
+ */
5832
5836
 
5833
5837
  if (options !== undefined) {
5834
5838
  // eslint-disable-next-line no-undef
@@ -5885,5 +5889,5 @@ var compare = function compare(expr1, expr2, options) {
5885
5889
  };
5886
5890
  };
5887
5891
 
5888
- export { Abs, Add, Const, Eq, Float, Func, Int, Log, Mul, One, Pow, Rational, Trig, Unit, Var, Zero, compare, parse, unitParse };
5892
+ export { Abs, Add, Const, Eq, Float, Func, Int, Log, Mul, One, Pow, Rational, Trig, Unit, Var, Zero, compare, libVersion, parse, unitParse };
5889
5893
  //# sourceMappingURL=index.js.map