| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 | "use strict";Object.defineProperty(exports, "__esModule", {  value: true});exports.default = void 0;var _convertUnit = _interopRequireDefault(require("./convertUnit"));function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }function isValueType(type) {  switch (type) {    case 'LengthValue':    case 'AngleValue':    case 'TimeValue':    case 'FrequencyValue':    case 'ResolutionValue':    case 'EmValue':    case 'ExValue':    case 'ChValue':    case 'RemValue':    case 'VhValue':    case 'VwValue':    case 'VminValue':    case 'VmaxValue':    case 'PercentageValue':    case 'Number':      return true;  }  return false;}function flip(operator) {  return operator === '+' ? '-' : '+';}function isAddSubOperator(operator) {  return operator === '+' || operator === '-';}function collectAddSubItems(preOperator, node, collected, precision) {  if (!isAddSubOperator(preOperator)) {    throw new Error(`invalid operator ${preOperator}`);  }  var type = node.type;  if (isValueType(type)) {    var itemIndex = collected.findIndex(function (x) {      return x.node.type === type;    });    if (itemIndex >= 0) {      if (node.value === 0) {        return;      }      var _covertNodesUnits = covertNodesUnits(collected[itemIndex].node, node, precision),          reducedNode = _covertNodesUnits.left,          current = _covertNodesUnits.right;      if (collected[itemIndex].preOperator === '-') {        collected[itemIndex].preOperator = '+';        reducedNode.value *= -1;      }      if (preOperator === "+") {        reducedNode.value += current.value;      } else {        reducedNode.value -= current.value;      } // make sure reducedNode.value >= 0      if (reducedNode.value >= 0) {        collected[itemIndex] = {          node: reducedNode,          preOperator: '+'        };      } else {        reducedNode.value *= -1;        collected[itemIndex] = {          node: reducedNode,          preOperator: '-'        };      }    } else {      // make sure node.value >= 0      if (node.value >= 0) {        collected.push({          node,          preOperator        });      } else {        node.value *= -1;        collected.push({          node,          preOperator: flip(preOperator)        });      }    }  } else if (type === "MathExpression") {    if (isAddSubOperator(node.operator)) {      collectAddSubItems(preOperator, node.left, collected, precision);      var collectRightOperator = preOperator === '-' ? flip(node.operator) : node.operator;      collectAddSubItems(collectRightOperator, node.right, collected, precision);    } else {      // * or /      var _reducedNode = reduce(node, precision); // prevent infinite recursive call      if (_reducedNode.type !== "MathExpression" || isAddSubOperator(_reducedNode.operator)) {        collectAddSubItems(preOperator, _reducedNode, collected, precision);      } else {        collected.push({          node: _reducedNode,          preOperator        });      }    }  } else {    collected.push({      node,      preOperator    });  }}function reduceAddSubExpression(node, precision) {  var collected = [];  collectAddSubItems('+', node, collected, precision);  var withoutZeroItem = collected.filter(function (item) {    return !(isValueType(item.node.type) && item.node.value === 0);  });  var firstNonZeroItem = withoutZeroItem[0]; // could be undefined  // prevent producing "calc(-var(--a))" or "calc()"  // which is invalid css  if (!firstNonZeroItem || firstNonZeroItem.preOperator === '-' && !isValueType(firstNonZeroItem.node.type)) {    var firstZeroItem = collected.find(function (item) {      return isValueType(item.node.type) && item.node.value === 0;    });    withoutZeroItem.unshift(firstZeroItem);  } // make sure the preOperator of the first item is +  if (withoutZeroItem[0].preOperator === '-' && isValueType(withoutZeroItem[0].node.type)) {    withoutZeroItem[0].node.value *= -1;    withoutZeroItem[0].preOperator = '+';  }  var root = withoutZeroItem[0].node;  for (var i = 1; i < withoutZeroItem.length; i++) {    root = {      type: 'MathExpression',      operator: withoutZeroItem[i].preOperator,      left: root,      right: withoutZeroItem[i].node    };  }  return root;}function reduceDivisionExpression(node) {  if (!isValueType(node.right.type)) {    return node;  }  if (node.right.type !== 'Number') {    throw new Error(`Cannot divide by "${node.right.unit}", number expected`);  }  return applyNumberDivision(node.left, node.right.value);} // apply (expr) / numberfunction applyNumberDivision(node, divisor) {  if (divisor === 0) {    throw new Error('Cannot divide by zero');  }  if (isValueType(node.type)) {    node.value /= divisor;    return node;  }  if (node.type === "MathExpression" && isAddSubOperator(node.operator)) {    // turn (a + b) / num into a/num + b/num    // is good for further reduction    // checkout the test case    // "should reduce division before reducing additions"    return {      type: "MathExpression",      operator: node.operator,      left: applyNumberDivision(node.left, divisor),      right: applyNumberDivision(node.right, divisor)    };  } // it is impossible to reduce it into a single value  // .e.g the node contains css variable  // so we just preserve the division and let browser do it  return {    type: "MathExpression",    operator: '/',    left: node,    right: {      type: "Number",      value: divisor    }  };}function reduceMultiplicationExpression(node) {  // (expr) * number  if (node.right.type === 'Number') {    return applyNumberMultiplication(node.left, node.right.value);  } // number * (expr)  if (node.left.type === 'Number') {    return applyNumberMultiplication(node.right, node.left.value);  }  return node;} // apply (expr) / numberfunction applyNumberMultiplication(node, multiplier) {  if (isValueType(node.type)) {    node.value *= multiplier;    return node;  }  if (node.type === "MathExpression" && isAddSubOperator(node.operator)) {    // turn (a + b) * num into a*num + b*num    // is good for further reduction    // checkout the test case    // "should reduce multiplication before reducing additions"    return {      type: "MathExpression",      operator: node.operator,      left: applyNumberMultiplication(node.left, multiplier),      right: applyNumberMultiplication(node.right, multiplier)    };  } // it is impossible to reduce it into a single value  // .e.g the node contains css variable  // so we just preserve the division and let browser do it  return {    type: "MathExpression",    operator: '*',    left: node,    right: {      type: "Number",      value: multiplier    }  };}function covertNodesUnits(left, right, precision) {  switch (left.type) {    case 'LengthValue':    case 'AngleValue':    case 'TimeValue':    case 'FrequencyValue':    case 'ResolutionValue':      if (right.type === left.type && right.unit && left.unit) {        var converted = (0, _convertUnit.default)(right.value, right.unit, left.unit, precision);        right = {          type: left.type,          value: converted,          unit: left.unit        };      }      return {        left,        right      };    default:      return {        left,        right      };  }}function reduce(node, precision) {  if (node.type === "MathExpression") {    if (isAddSubOperator(node.operator)) {      // reduceAddSubExpression will call reduce recursively      return reduceAddSubExpression(node, precision);    }    node.left = reduce(node.left, precision);    node.right = reduce(node.right, precision);    switch (node.operator) {      case "/":        return reduceDivisionExpression(node, precision);      case "*":        return reduceMultiplicationExpression(node, precision);    }    return node;  }  return node;}var _default = reduce;exports.default = _default;module.exports = exports.default;
 |