"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _typeof = require("@babel/runtime/helpers/typeof");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.textToMathText = exports.latexToText = exports["default"] = exports.ave = void 0;

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var mathjs = _interopRequireWildcard(require("mathjs"));

var _mathExpressions = _interopRequireDefault(require("@pie-framework/math-expressions"));

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

var decimalCommaRegex = /,/g;
var decimalRegex = /\.|,/g;
var decimalWithThousandSeparatorNumberRegex = /^(?!0+\.00)(?=.{1,9}(\.|$))(?!0(?!\.))\d{1,3}(,\d{3})*(\.\d+)?$/;

var rationalizeAllPossibleSubNodes = function rationalizeAllPossibleSubNodes(expression) {
  return rationalize(mathjs.parse(expression));
};

var rationalize = function rationalize(tree) {
  var transformedTree = tree.transform(function (node) {
    try {
      var rationalizedNode = mathjs.rationalize(node);
      return rationalizedNode;
    } catch (_unused) {
      return node;
    }
  });
  return transformedTree;
};

function prepareExpression(string, isLatex) {
  var returnValue = string ? string.trim() : '';
  returnValue = returnValue.replace(decimalCommaRegex, '.');
  returnValue = isLatex ? latexToText("".concat(returnValue)) : textToMathText("".concat(returnValue), {
    unknownCommands: 'passthrough'
  }).toString();
  returnValue = returnValue.replace('=', '==');
  return rationalizeAllPossibleSubNodes(returnValue);
}

var latexToAstOpts = {
  missingFactor: function missingFactor(token, e) {
    console.warn('missing factor for: ', token.token_type);

    if (token.token_type === 'NUMBER') {
      throw e;
    }

    return 0;
  },
  unknownCommandBehavior: 'passthrough'
};
var astToTextOpts = {
  unicode_operators: {
    ne: function ne(operands) {
      return operands.join(' != ');
    },
    '%': function _(operands) {
      return "percent(".concat(operands[0], ")");
    }
  }
};

var latexToText = function latexToText(latex) {
  var extraOtps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var la = new _mathExpressions["default"].converters.latexToAstObj(_objectSpread(_objectSpread({}, latexToAstOpts), extraOtps));
  var at = new _mathExpressions["default"].converters.astToTextObj(_objectSpread(_objectSpread({}, astToTextOpts), extraOtps));
  var ast = la.convert(latex);
  return at.convert(ast);
};

exports.latexToText = latexToText;

var textToMathText = function textToMathText(latex) {
  var extraOtps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var la = new _mathExpressions["default"].converters.textToAstObj(_objectSpread(_objectSpread({}, latexToAstOpts), extraOtps));
  var at = new _mathExpressions["default"].converters.astToTextObj(_objectSpread(_objectSpread({}, astToTextOpts), extraOtps));
  var ast = la.convert(latex);
  return at.convert(ast);
};

exports.textToMathText = textToMathText;

function shouldRationalizeEntireTree(tree) {
  var shouldDoIt = true; // we need to iterate the entire tree to check for some conditions that might make rationalization impossible

  try {
    tree.traverse(function (node) {
      // if we have a variable as an exponent for power operation, we should not rationalize
      // try to see if there are power operations with variable exponents
      if (node.type === 'OperatorNode' && node.fn === 'pow') {
        var exponent = node.args[1]; // try to see if it can be compiled and evaluated - if it's a non-numerical value, it'll throw an error

        exponent.compile().eval();
      } // we cannot have variables for unresolved function calls either


      if (node.type === 'FunctionNode') {
        //try to see if the argument that the function is called with can be resolved as non-variable
        var functionParameter = node.args[0]; // if it holds variables, this will throw an error

        functionParameter.compile().eval();
      }
    });
    mathjs.rationalize(tree);
  } catch (_unused2) {
    shouldDoIt = false;
  }

  return shouldDoIt;
}

function containsDecimal() {
  var expression = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  return expression.match(decimalRegex);
}

var SIMPLIFY_RULES = [{
  l: 'n1^(1/n2)',
  r: 'nthRoot(n1, n2)'
}, {
  l: 'sqrt(n1)',
  r: 'nthRoot(n1, 2)'
}];

var simplify = function simplify(v) {
  return mathjs.simplify(v, SIMPLIFY_RULES.concat(mathjs.simplify.rules));
}; //.concat(SIMPLIFY_RULES));


var areValuesEqual = function areValuesEqual(valueOne, valueTwo) {
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  var allowDecimals = options.allowDecimals,
      isLatex = options.isLatex,
      inverse = options.inverse;
  var valueOneToUse = valueOne;
  var valueTwoToUse = valueTwo;

  if (allowDecimals === false) {
    if (containsDecimal(valueOne) || containsDecimal(valueTwo)) {
      return false;
    }
  } else if (allowDecimals === true) {
    if (containsDecimal(valueOne) && decimalWithThousandSeparatorNumberRegex.test(valueOne)) {
      valueOneToUse = valueOne.replace(decimalCommaRegex, '');
    }

    if (containsDecimal(valueTwo) && decimalWithThousandSeparatorNumberRegex.test(valueTwo)) {
      valueTwoToUse = valueTwo.replace(decimalCommaRegex, '');
    }
  }

  var preparedValueOne = prepareExpression(valueOneToUse, isLatex, allowDecimals);
  var preparedValueTwo = prepareExpression(valueTwoToUse, isLatex, allowDecimals);
  var one = shouldRationalizeEntireTree(preparedValueOne) ? mathjs.rationalize(preparedValueOne) : preparedValueOne;
  var two = shouldRationalizeEntireTree(preparedValueTwo) ? mathjs.rationalize(preparedValueTwo) : preparedValueTwo;
  one = simplify(one);
  two = simplify(two);
  var equals = one.equals(two);
  return inverse ? !equals : equals;
};

var ave = function ave(a, b) {
  var am = mathjs.parse(a);
  var bm = mathjs.parse(b);
  var arm = simplify(am);
  var brm = simplify(bm);
  return arm.equals(brm);
};

exports.ave = ave;
var _default = areValuesEqual;
exports["default"] = _default;
//# sourceMappingURL=index.js.map