text: define(['exports', './ops'], function (exports, _ops) {
    'use strict';
  
    Object.defineProperty(exports, '__esModule', {
      value: true
    });
  
    var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
  
    var average = function average(body1, body2) {
      var mass = body1.mass + body2.mass;
      var point = (0, _ops.times)(1 / mass, (0, _ops.plus)((0, _ops.times)(body1.mass, body1.point), (0, _ops.times)(body2.mass, body2.point)));
      return [point, mass];
    };
  
    var locate = function locate(_ref, quadrants) {
      var _ref2 = _slicedToArray(_ref, 2);
  
      var x = _ref2[0];
      var y = _ref2[1];
      var _iteratorNormalCompletion = true;
      var _didIteratorError = false;
      var _iteratorError = undefined;
  
      try {
        for (var _iterator = quadrants[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
          var q = _step.value;
          var _q$box = q.box;
          var _top = _q$box.top;
          var bottom = _q$box.bottom;
          var left = _q$box.left;
          var right = _q$box.right;
  
          if (left <= x && x <= right && bottom <= y && y <= _top) {
            return q;
          }
        }
      } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion && _iterator['return']) {
            _iterator['return']();
          }
        } finally {
          if (_didIteratorError) {
            throw _iteratorError;
          }
        }
      }
    };
  
    var makeQuadrant = function makeQuadrant(_ref3, _ref4) {
      var top = _ref3.top;
      var bottom = _ref3.bottom;
      var left = _ref3.left;
      var right = _ref3.right;
  
      var _ref42 = _slicedToArray(_ref4, 2);
  
      var a = _ref42[0];
      var b = _ref42[1];
  
      var halfwayV = (left + right) / 2;
      var halfwayH = (top + bottom) / 2;
  
      return {
        box: {
          top: b ? halfwayH : top,
          bottom: b ? bottom : halfwayH,
          left: a ? halfwayV : left,
          right: a ? right : halfwayV
        }
      };
    };
  
    var subdivide = function subdivide(_ref5) {
      var box = _ref5.box;
      return [makeQuadrant(box, [0, 0]), makeQuadrant(box, [1, 0]), makeQuadrant(box, [0, 1]), makeQuadrant(box, [1, 1])];
    };
  
    var addBody = function addBody(root, body) {
      if (root.body) {
        var oldBody = root.body;
        delete root.body;
        root.children = subdivide(root);
        addBody(root, oldBody);
        addBody(root, body);
      } else {
        if (root.children) {
          var child = locate(body.point, root.children);
  
          var _ref6 = root.point ? average(root, body) : [body.point, body.mass];
  
          var _ref62 = _slicedToArray(_ref6, 2);
  
          var p = _ref62[0];
          var m = _ref62[1];
  
          root.point = p;
          root.mass = m;
          addBody(child, body);
        } else {
          root.body = body;
        }
      }
    };
  
    var makeTree = function makeTree(_x, _x2) {
      var _again = true;
  
      _function: while (_again) {
        var bodies = _x,
            root = _x2;
        _again = false;
  
        if (bodies.length === 0) {
          return root;
        } else {
          var body = bodies.shift();
          addBody(root, body);
          _x = bodies;
          _x2 = root;
          _again = true;
          body = undefined;
          continue _function;
        }
      }
    };
  
    var makeBodies = function makeBodies(positions) {
      return (0, _ops.mapObject)(positions, function (id, position) {
        return { id: id, point: position, mass: 1 };
      });
    };
  
    var makeRoot = function makeRoot(width, height) {
      return {
        box: {
          top: height,
          bottom: 0,
          left: 0,
          right: width
        }
      };
    };
  
    var walkLeaves = function walkLeaves(tree, f) {
      if (tree.body) {
        f(tree);
      } else {
        if (tree.children) {
          var _iteratorNormalCompletion2 = true;
          var _didIteratorError2 = false;
          var _iteratorError2 = undefined;
  
          try {
            for (var _iterator2 = tree.children[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
              var child = _step2.value;
  
              walkLeaves(child, f);
            }
          } catch (err) {
            _didIteratorError2 = true;
            _iteratorError2 = err;
          } finally {
            try {
              if (!_iteratorNormalCompletion2 && _iterator2['return']) {
                _iterator2['return']();
              }
            } finally {
              if (_didIteratorError2) {
                throw _iteratorError2;
              }
            }
          }
        }
      }
    };
  
    var bodyForceOn = function bodyForceOn(b1, b2, repulsion) {
      var segment = (0, _ops.minus)(b1.point, b2.point);
      var d = (0, _ops.length)(segment);
      return (0, _ops.times)(repulsion * b1.mass * b2.mass / (d * d * d), segment);
    };
  
    var boxWidth = function boxWidth(_ref7) {
      var top = _ref7.top;
      var bottom = _ref7.bottom;
      var left = _ref7.left;
      var right = _ref7.right;
      return (0, _ops.length)([top - bottom, right - left]);
    };
  
    var forceOn = function forceOn(leaf, tree, repulsion, threshold) {
      if (tree === leaf) {
        return [0, 0];
      } else if (tree.body) {
        return bodyForceOn(leaf.body, tree.body, repulsion);
      } else if (tree.point) {
        var s = boxWidth(tree.box);
        var d = (0, _ops.length)((0, _ops.minus)(leaf.body.point, tree.point));
  
        if (s / d < threshold) {
          return bodyForceOn(leaf.body, tree, repulsion);
        } else return (0, _ops.sumVectors)(tree.children.map(function (c) {
          return forceOn(leaf, c, repulsion, threshold);
        }));
      } else return [0, 0];
    };
  
    var repulsiveForces = function repulsiveForces(tree, repulsion, threshold) {
      var forces = {};
      walkLeaves(tree, function (leaf) {
        forces[leaf.body.id] = forceOn(leaf, tree, repulsion, threshold);
      });
      return forces;
    };
  
    exports.tree = makeTree;
    exports.bodies = makeBodies;
    exports.root = makeRoot;
    exports.forces = repulsiveForces;
    exports['default'] = {
      tree: makeTree,
      bodies: makeBodies,
      root: makeRoot,
      forces: repulsiveForces
    };
  });