diff --git a/README.md b/README.md index 5080c52a..c0fa5c90 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ Currently there are 10 path-finders bundled in this library, namely: * `IDAStarFinder.js` * * `JumpPointFinder` * * `OrthogonalJumpPointFinder` * +* `ThetaStarFinder` * * `BiAStarFinder` * `BiBestFirstFinder` * `BiBreadthFirstFinder` * diff --git a/src/PathFinding.js b/src/PathFinding.js index 5435d026..97943d10 100644 --- a/src/PathFinding.js +++ b/src/PathFinding.js @@ -15,4 +15,5 @@ module.exports = { 'BiDijkstraFinder' : require('./finders/BiDijkstraFinder'), 'IDAStarFinder' : require('./finders/IDAStarFinder'), 'JumpPointFinder' : require('./finders/JumpPointFinder'), + 'ThetaStarFinder' : require('./finders/ThetaStarFinder'), }; diff --git a/src/finders/ThetaStarFinder.js b/src/finders/ThetaStarFinder.js new file mode 100644 index 00000000..b581ea00 --- /dev/null +++ b/src/finders/ThetaStarFinder.js @@ -0,0 +1,240 @@ +var Heap = require('heap'); +var Util = require('../core/Util'); +var Heuristic = require('../core/Heuristic'); +var DiagonalMovement = require('../core/DiagonalMovement'); +/** + * Theta* path-finder. + * @constructor + * @param {object} opt + */ +function ThetaStarFinder(opt) { + opt = opt || {}; + this.allowDiagonal = true; + this.dontCrossCorners = true; + this.heuristic = Heuristic.euclidean; + this.weight = opt.weight || 1.1; + this.diagonalMovement = DiagonalMovement.OnlyWhenNoObstacles; +} + +ThetaStarFinder.prototype.distance = function(startX, startY, endX, endY) { + startX -= endX; + startY -= endY; + return Math.sqrt(startX * startX + startY * startY); +} + +ThetaStarFinder.prototype.lineOfSight = function(startX, startY, endX, endY, grid) { + var sx, sy, f, s0, s1, + x0 = startX, + y0 = startY, + x1 = endX, + y1 = endY, + dx = x1 - x0, + dy = y1 - y0; + if (dx < 0) { + dx = -dx; + sx = -1; + } else { + sx = 1; + } + if (dy < 0) { + dy = -dy; + sy = -1; + } else { + sy = 1; + } + if (dx == 0) { + for (y0 += sy; y0 != y1; y0 += sy) { + if (!grid.isWalkableAt(x0, y0)) { + return false; + } + } + return true; + } + if (dy == 0) { + for (x0 += sx; x0 != x1; x0 += sx) { + if (!grid.isWalkableAt(x0, y0)) { + return false; + } + } + return true; + } + if (dx >= dy) { + if (!grid.isWalkableAt(x0, y0 + sy) || !grid.isWalkableAt(x1, y1 - sy)) { + return false; + } + for (s0 = y0, s1 = y1, f = dy; ;) { + f += dy; + if (f >= dx) { + x0 += sx; + y0 += sy; + x1 -= sx; + y1 -= sy; + f -= dx; + } else { + x0 += sx; + x1 -= sx; + } + if (x0 == x1 + sx) { + break; + } + if (x0 == x1) { + if (y0 == y1) { + if (!grid.isWalkableAt(x0, y0 - sy) || !grid.isWalkableAt(x0, y0) || !grid.isWalkableAt(x0, y0 + sy)) { + return false; + } + } else { + if (!grid.isWalkableAt(x0, y0) || !grid.isWalkableAt(x1, y1)) { + return false; + } + } + break; + } + if (y0 != s0 && !grid.isWalkableAt(x0, y0 - sy)) { + return false; + } + if (!grid.isWalkableAt(x0, y0) || !grid.isWalkableAt(x0, y0 + sy)) { + return false; + } + if (y1 != s1 && !grid.isWalkableAt(x1, y1 + sy)) { + return false; + } + if (!grid.isWalkableAt(x1, y1) || !grid.isWalkableAt(x1, y1 - sy)) { + return false; + } + } + } + else { + if (!grid.isWalkableAt(x0 + sx, y0) || !grid.isWalkableAt(x1 - sx, y1)) { + return false; + } + for (s0 = x0, s1 = x1, f = dx; ;) { + f += dx; + if (f >= dy) { + x0 += sx; + y0 += sy; + x1 -= sx; + y1 -= sy; + f -= dy; + } else { + y0 += sy; + y1 -= sy; + } + if (y0 == y1 + sy) { + break; + } + if (y0 == y1) { + if (x0 == x1) { + if (!grid.isWalkableAt(x0 - sx, y0) || !grid.isWalkableAt(x0, y0) || !grid.isWalkableAt(x0 + sx, y0)) { + return false; + } + } else { + if (!grid.isWalkableAt(x0, y0) || !grid.isWalkableAt(x1, y1)) { + return false; + } + } + break; + } + if (x0 != s0 && !grid.isWalkableAt(x0 - sx, y0)) { + return false; + } + if (!grid.isWalkableAt(x0, y0) || !grid.isWalkableAt(x0 + sx, y0)) { + return false; + } + if (x1 != s1 && !grid.isWalkableAt(x1 + sx, y1)) { + return false; + } + if (!grid.isWalkableAt(x1, y1) || !grid.isWalkableAt(x1 - sx, y1)) { + return false; + } + } + } + return true; +} + +/** + * Find and return the the path. + * @return {Array.<[number, number]>} The path, including both start and + * end positions. + */ +ThetaStarFinder.prototype.findPath = function(startX, startY, endX, endY, grid) { + var openList = new Heap(function(nodeA, nodeB) { + return nodeA.f - nodeB.f; + }), + startNode = grid.getNodeAt(startX, startY), + endNode = grid.getNodeAt(endX, endY), + distance = this.distance, + lineOfSight = this.lineOfSight, + diagonalMovement = this.diagonalMovement, + weight = this.weight, + node, neighbors, neighbor, i, l, x, y, ng; + + // set the `g` and `f` value of the start node to be 0 + startNode.g = 0; + startNode.f = 0; + + // push the start node into the open list + openList.push(startNode); + startNode.opened = true; + + // while the open list is not empty + while (!openList.empty()) { + // pop the position of node which has the minimum `f` value. + node = openList.pop(); + node.closed = true; + + // if reached the end position, construct the path and return it + if (node === endNode) { + return Util.backtrace(endNode); + } + + // get neigbours of the current node + neighbors = grid.getNeighbors(node, diagonalMovement); + for (i = 0, l = neighbors.length; i < l; ++i) { + neighbor = neighbors[i]; + + if (neighbor.closed) { + continue; + } + x = neighbor.x; + y = neighbor.y; + + // check if the neighbor has not been inspected yet, or + // can be reached with smaller cost from the current node + if (node.parent && lineOfSight(x, y, node.parent.x, node.parent.y, grid)) { + ng = node.parent.g + distance(x, y, node.parent.x, node.parent.y); + if (!neighbor.opened || ng < neighbor.g) { + neighbor.g = ng; + neighbor.parent = node.parent; + } else { + continue; + } + } + else { + ng = node.g + distance(x, y, node.x, node.y); + if (!neighbor.opened || ng < neighbor.g) { + neighbor.g = ng; + neighbor.parent = node; + } else { + continue; + } + } + neighbor.h = neighbor.h || weight * distance(x, y, endX, endY); + neighbor.f = neighbor.g + neighbor.h; + + if (!neighbor.opened) { + openList.push(neighbor); + neighbor.opened = true; + } else { + // the neighbor can be reached with smaller cost. + // Since its f value has been updated, we have to + // update its position in the open list + openList.updateItem(neighbor); + } + } // end for each neighbor + } // end while not open list empty + + // fail to find the path + return []; +}; + +module.exports = ThetaStarFinder; diff --git a/test/PathTest.js b/test/PathTest.js index 3cc4de68..09967942 100644 --- a/test/PathTest.js +++ b/test/PathTest.js @@ -81,7 +81,12 @@ pathTests({ }); // finders NOT guaranteed to find the shortest path +// ThetaStar guaranteed to find the shortest path , but it's not compatible to our test ... pathTests({ + name: 'ThetaStar', + finder: new PF.ThetaStarFinder(), + optimal: false +}, { name: 'BiAStar', finder: new PF.BiAStarFinder(), optimal: false @@ -103,7 +108,7 @@ pathTests({ diagonalMovement: PF.DiagonalMovement.IfAtMostOneObstacle }), optimal: false -}, { +}, { name: 'JPFNeverMoveDiagonally', finder: new PF.JumpPointFinder({ diagonalMovement: PF.DiagonalMovement.Never diff --git a/visual/index.html b/visual/index.html index 59710a9e..1af760c9 100644 --- a/visual/index.html +++ b/visual/index.html @@ -70,7 +70,7 @@

Options



- +

@@ -98,9 +98,9 @@

Options


- +
- +

@@ -119,7 +119,7 @@

Options



- +
@@ -148,7 +148,7 @@

Options



- +
@@ -163,7 +163,7 @@

Options



- +
@@ -192,7 +192,7 @@

Options

-

Orthogonal Jump Point Search

+

Orthogonal Jump Point Search

Heuristic

@@ -215,6 +215,18 @@

Options


+ +

Theta*

+
+ +
+

Options

+
+
+ +
+
+
diff --git a/visual/js/panel.js b/visual/js/panel.js index 19185d58..dfe41b25 100644 --- a/visual/js/panel.js +++ b/visual/js/panel.js @@ -138,6 +138,7 @@ var Panel = { diagonalMovement: PF.DiagonalMovement.IfAtMostOneObstacle }); break; + case 'orth_jump_point_header': trackRecursion = typeof $('#orth_jump_point_section ' + '.track_recursion:checked').val() !== 'undefined'; @@ -149,6 +150,7 @@ var Panel = { diagonalMovement: PF.DiagonalMovement.Never }); break; + case 'ida_header': allowDiagonal = typeof $('#ida_section ' + '.allow_diagonal:checked').val() !== 'undefined'; @@ -159,7 +161,7 @@ var Panel = { heuristic = $('input[name=jump_point_heuristic]:checked').val(); - weight = parseInt($('#ida_section input[name=astar_weight]').val()) || 1; + weight = parseInt($('#ida_section input[name=ida_weight]').val()) || 1; weight = weight >= 1 ? weight : 1; /* if negative or 0, use 1 */ timeLimit = parseInt($('#ida_section input[name=time_limit]').val()); @@ -177,6 +179,15 @@ var Panel = { }); break; + + case 'thetastar_header': + weight = parseFloat($('#thetastar_section input[name=thetastar_weight]').val()) || 1.1; + weight = weight >= 1 ? weight : 1; /* if negative or 0, use 1 */ + + finder = new PF.ThetaStarFinder({ + weight: weight + }); + break; } return finder; diff --git a/visual/lib/pathfinding-browser.min.js b/visual/lib/pathfinding-browser.min.js index 76ec7840..90ff6546 100644 --- a/visual/lib/pathfinding-browser.min.js +++ b/visual/lib/pathfinding-browser.min.js @@ -1 +1 @@ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;"undefined"!=typeof window?e=window:"undefined"!=typeof global?e=global:"undefined"!=typeof self&&(e=self),e.PF=t()}}(function(){return function t(e,r,i){function n(s,a){if(!r[s]){if(!e[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var h=new Error("Cannot find module '"+s+"'");throw h.code="MODULE_NOT_FOUND",h}var l=r[s]={exports:{}};e[s][0].call(l.exports,function(t){var r=e[s][1][t];return n(r?r:t)},l,l.exports,t,e,r,i)}return r[s].exports}for(var o="function"==typeof require&&require,s=0;st?-1:t>e?1:0},h=function(t,e,n,o,s){var a;if(null==n&&(n=0),null==s&&(s=r),0>n)throw new Error("lo must be non-negative");for(null==o&&(o=t.length);o>n;)a=i((n+o)/2),s(e,t[a])<0?o=a:n=a+1;return[].splice.apply(t,[n,n-n].concat(e)),e},s=function(t,e,i){return null==i&&(i=r),t.push(e),d(t,0,t.length-1,i)},o=function(t,e){var i,n;return null==e&&(e=r),i=t.pop(),t.length?(n=t[0],t[0]=i,g(t,0,e)):n=i,n},u=function(t,e,i){var n;return null==i&&(i=r),n=t[0],t[0]=e,g(t,0,i),n},a=function(t,e,i){var n;return null==i&&(i=r),t.length&&i(t[0],e)<0&&(n=[t[0],e],e=n[0],t[0]=n[1],g(t,0,i)),e},n=function(t,e){var n,o,s,a,u,h;for(null==e&&(e=r),a=function(){h=[];for(var e=0,r=i(t.length/2);r>=0?r>e:e>r;r>=0?e++:e--)h.push(e);return h}.apply(this).reverse(),u=[],o=0,s=a.length;s>o;o++)n=a[o],u.push(g(t,n,e));return u},f=function(t,e,i){var n;return null==i&&(i=r),n=t.indexOf(e),-1!==n?(d(t,0,n,i),g(t,n,i)):void 0},p=function(t,e,i){var o,s,u,h,l;if(null==i&&(i=r),s=t.slice(0,e),!s.length)return s;for(n(s,i),l=t.slice(e),u=0,h=l.length;h>u;u++)o=l[u],a(s,o,i);return s.sort(i).reverse()},c=function(t,e,i){var s,a,u,p,c,f,d,g,b,y;if(null==i&&(i=r),10*e<=t.length){if(p=t.slice(0,e).sort(i),!p.length)return p;for(u=p[p.length-1],g=t.slice(e),c=0,d=g.length;d>c;c++)s=g[c],i(s,u)<0&&(h(p,s,0,null,i),p.pop(),u=p[p.length-1]);return p}for(n(t,i),y=[],a=f=0,b=l(e,t.length);b>=0?b>f:f>b;a=b>=0?++f:--f)y.push(o(t,i));return y},d=function(t,e,i,n){var o,s,a;for(null==n&&(n=r),o=t[i];i>e&&(a=i-1>>1,s=t[a],n(o,s)<0);)t[i]=s,i=a;return t[i]=o},g=function(t,e,i){var n,o,s,a,u;for(null==i&&(i=r),o=t.length,u=e,s=t[e],n=2*e+1;o>n;)a=n+1,o>a&&!(i(t[n],t[a])<0)&&(n=a),t[e]=t[n],e=n,n=2*e+1;return t[e]=s,d(t,u,e,i)},t=function(){function t(t){this.cmp=null!=t?t:r,this.nodes=[]}return t.push=s,t.pop=o,t.replace=u,t.pushpop=a,t.heapify=n,t.nlargest=p,t.nsmallest=c,t.prototype.push=function(t){return s(this.nodes,t,this.cmp)},t.prototype.pop=function(){return o(this.nodes,this.cmp)},t.prototype.peek=function(){return this.nodes[0]},t.prototype.contains=function(t){return-1!==this.nodes.indexOf(t)},t.prototype.replace=function(t){return u(this.nodes,t,this.cmp)},t.prototype.pushpop=function(t){return a(this.nodes,t,this.cmp)},t.prototype.heapify=function(){return n(this.nodes,this.cmp)},t.prototype.updateItem=function(t){return f(this.nodes,t,this.cmp)},t.prototype.clear=function(){return this.nodes=[]},t.prototype.empty=function(){return 0===this.nodes.length},t.prototype.size=function(){return this.nodes.length},t.prototype.clone=function(){var e;return e=new t,e.nodes=this.nodes.slice(0),e},t.prototype.toArray=function(){return this.nodes.slice(0)},t.prototype.insert=t.prototype.push,t.prototype.remove=t.prototype.pop,t.prototype.top=t.prototype.peek,t.prototype.front=t.prototype.peek,t.prototype.has=t.prototype.contains,t.prototype.copy=t.prototype.clone,t}(),("undefined"!=typeof e&&null!==e?e.exports:void 0)?e.exports=t:window.Heap=t}.call(this)},{}],3:[function(t,e){function r(t,e,r){this.width=t,this.height=e,this.nodes=this._buildNodes(t,e,r)}var i=t("./Node");r.prototype._buildNodes=function(t,e,r){var n,o,s=new Array(e);for(n=0;e>n;++n)for(s[n]=new Array(t),o=0;t>o;++o)s[n][o]=new i(o,n);if(void 0===r)return s;if(r.length!==e||r[0].length!==t)throw new Error("Matrix size does not fit");for(n=0;e>n;++n)for(o=0;t>o;++o)r[n][o]&&(s[n][o].walkable=!1);return s},r.prototype.getNodeAt=function(t,e){return this.nodes[e][t]},r.prototype.isWalkableAt=function(t,e){return this.isInside(t,e)&&this.nodes[e][t].walkable},r.prototype.isInside=function(t,e){return t>=0&&t=0&&et;++t)for(u[t]=new Array(n),e=0;n>e;++e)u[t][e]=new i(e,t,s[t][e].walkable);return a.nodes=u,a},e.exports=r},{"./Node":5}],4:[function(t,e){e.exports={manhattan:function(t,e){return t+e},euclidean:function(t,e){return Math.sqrt(t*t+e*e)},octile:function(t,e){var r=Math.SQRT2-1;return e>t?r*t+e:r*e+t},chebyshev:function(t,e){return Math.max(t,e)}}},{}],5:[function(t,e){function r(t,e,r){this.x=t,this.y=e,this.walkable=void 0===r?!0:r}e.exports=r},{}],6:[function(t,e,r){function i(t){for(var e=[[t.x,t.y]];t.parent;)t=t.parent,e.push([t.x,t.y]);return e.reverse()}function n(t,e){var r=i(t),n=i(e);return r.concat(n.reverse())}function o(t){var e,r,i,n,o,s=0;for(e=1;et?1:-1,o=i>e?1:-1,u=s-a;;){if(p.push([t,e]),t===r&&e===i)break;h=2*u,h>-a&&(u-=a,t+=n),s>h&&(u+=s,e+=o)}return p}function a(t){var e,r,i,n,o,a,u=[],h=t.length;if(2>h)return u;for(o=0;h-1>o;++o)for(e=t[o],r=t[o+1],i=s(e[0],e[1],r[0],r[1]),n=i.length,a=0;n-1>a;++a)u.push(i[a]);return u.push(t[h-1]),u}function u(t,e){var r,i,n,o,a,u,h,l,p,c,f,d=e.length,g=e[0][0],b=e[0][1],y=e[d-1][0],A=e[d-1][1];for(r=g,i=b,a=[[r,i]],u=2;d>u;++u){for(l=e[u],n=l[0],o=l[1],p=s(r,i,n,o),f=!1,h=1;hl;++l)h=u[l],h.closed||(c=h.x,f=h.y,d=a.g+(0===c-a.x||0===f-a.y?1:x),(!h.opened||dl;++l)if(h=u[l],!h.closed){if(h.opened===C)return n.biBacktrace(a,h);c=h.x,f=h.y,d=a.g+(0===c-a.x||0===f-a.y?1:W),(!h.opened||dl;++l)if(h=u[l],!h.closed){if(h.opened===N)return n.biBacktrace(h,a);c=h.x,f=h.y,d=a.g+(0===c-a.x||0===f-a.y?1:W),(!h.opened||dh;++h)if(a=s[h],!a.closed)if(a.opened){if(a.by===A)return i.biBacktrace(u,a)}else f.push(a),a.parent=u,a.opened=!0,a.by=y;for(u=d.shift(),u.closed=!0,s=o.getNeighbors(u,g,b),h=0,l=s.length;l>h;++h)if(a=s[h],!a.closed)if(a.opened){if(a.by===y)return i.biBacktrace(a,u)}else d.push(a),a.parent=u,a.opened=!0,a.by=A}return[]},e.exports=r},{"../core/Util":6}],12:[function(t,e){function r(t){i.call(this,t),this.heuristic=function(){return 0}}var i=t("./BiAStarFinder");r.prototype=new i,r.prototype.constructor=r,e.exports=r},{"./BiAStarFinder":9}],13:[function(t,e){function r(t){t=t||{},this.allowDiagonal=t.allowDiagonal,this.dontCrossCorners=t.dontCrossCorners}var i=t("../core/Util");r.prototype.findPath=function(t,e,r,n,o){var s,a,u,h,l,p=[],c=this.allowDiagonal,f=this.dontCrossCorners,d=o.getNodeAt(t,e),g=o.getNodeAt(r,n);for(p.push(d),d.opened=!0;p.length;){if(u=p.shift(),u.closed=!0,u===g)return i.backtrace(g);for(s=o.getNeighbors(u,c,f),h=0,l=s.length;l>h;++h)a=s[h],a.closed||a.opened||(p.push(a),a.opened=!0,a.parent=u)}return[]},e.exports=r},{"../core/Util":6}],14:[function(t,e){function r(t){i.call(this,t),this.heuristic=function(){return 0}}var i=t("./AStarFinder");r.prototype=new i,r.prototype.constructor=r,e.exports=r},{"./AStarFinder":7}],15:[function(t,e){function r(t){t=t||{},this.allowDiagonal=t.allowDiagonal,this.dontCrossCorners=t.dontCrossCorners,this.heuristic=t.heuristic||i.manhattan,this.weight=t.weight||1,this.trackRecursion=t.trackRecursion||!1,this.timeLimit=t.timeLimit||1/0}t("../core/Util");var i=t("../core/Heuristic"),n=t("../core/Node");r.prototype.findPath=function(t,e,r,i,o){var s,a,u,h=0,l=(new Date).getTime(),p=function(t,e){return this.heuristic(Math.abs(e.x-t.x),Math.abs(e.y-t.y))}.bind(this),c=function(t,e){return t.x===e.x||t.y===e.y?1:Math.SQRT2},f=function(t,e,r,i,s){if(h++,this.timeLimit>0&&(new Date).getTime()-l>1e3*this.timeLimit)return 1/0;var a=e+p(t,g)*this.weight;if(a>r)return a;if(t==g)return i[s]=[t.x,t.y],t;var u,d,b,y,A=o.getNeighbors(t,this.allowDiagonal,this.dontCrossCorners);for(b=0,u=1/0;y=A[b];++b){if(this.trackRecursion&&(y.retainCount=y.retainCount+1||1,y.tested!==!0&&(y.tested=!0)),d=f(y,e+c(t,y),r,i,s+1),d instanceof n)return i[s]=[t.x,t.y],d;this.trackRecursion&&0===--y.retainCount&&(y.tested=!1),u>d&&(u=d)}return u}.bind(this),d=o.getNodeAt(t,e),g=o.getNodeAt(r,i),b=p(d,g);for(s=0;!0;++s){if(a=[],u=f(d,0,b,a,0),1/0===u)return[];if(u instanceof n)return a;b=u}return[]},e.exports=r},{"../core/Heuristic":4,"../core/Node":5,"../core/Util":6}],16:[function(t,e){function r(t){t=t||{},this.heuristic=t.heuristic||o.manhattan,this.trackJumpRecursion=t.trackJumpRecursion||!1}var i=t("heap"),n=t("../core/Util"),o=t("../core/Heuristic");r.prototype.findPath=function(t,e,r,o,s){var a,u=this.openList=new i(function(t,e){return t.f-e.f}),h=this.startNode=s.getNodeAt(t,e),l=this.endNode=s.getNodeAt(r,o);for(this.grid=s,h.g=0,h.f=0,u.push(h),h.opened=!0;!u.empty();){if(a=u.pop(),a.closed=!0,a===l)return n.expandPath(n.backtrace(l));this._identifySuccessors(a)}return[]},r.prototype._identifySuccessors=function(t){var e,r,i,n,s,a,u,h,l,p,c=this.grid,f=this.heuristic,d=this.openList,g=this.endNode.x,b=this.endNode.y,y=t.x,A=t.y,k=Math.abs;for(Math.max,e=this._findNeighbors(t),n=0,s=e.length;s>n;++n)if(r=e[n],i=this._jump(r[0],r[1],y,A)){if(a=i[0],u=i[1],p=c.getNodeAt(a,u),p.closed)continue;h=o.octile(k(a-y),k(u-A)),l=t.g+h,(!p.opened||la;++a)s=o[a],f.push([s.x,s.y]);return f},e.exports=r},{"../core/Heuristic":4,"../core/Util":6,heap:1}],17:[function(t,e){function r(t){n.call(this,t),t=t||{},this.heuristic=t.heuristic||i.manhattan}var i=t("../core/Heuristic"),n=t("./JumpPointFinder");r.prototype=new n,r.prototype.constructor=r,r.prototype._jump=function(t,e,r,i){var n=this.grid,o=t-r,s=e-i;if(!n.isWalkableAt(t,e))return null;if(this.trackJumpRecursion===!0&&(n.getNodeAt(t,e).tested=!0),n.getNodeAt(t,e)===this.endNode)return[t,e];if(0!==o){if(n.isWalkableAt(t,e-1)&&!n.isWalkableAt(t-o,e-1)||n.isWalkableAt(t,e+1)&&!n.isWalkableAt(t-o,e+1))return[t,e]}else{if(0===s)throw new Error("Only horizontal and vertical movements are allowed");if(n.isWalkableAt(t-1,e)&&!n.isWalkableAt(t-1,e-s)||n.isWalkableAt(t+1,e)&&!n.isWalkableAt(t+1,e-s))return[t,e];if(this._jump(t+1,e,t,e)||this._jump(t-1,e,t,e))return[t,e]}return this._jump(t+o,e+s,t,e)},r.prototype._findNeighbors=function(t){var e,r,i,n,o,s,a,u,h=t.parent,l=t.x,p=t.y,c=this.grid,f=[];if(h)e=h.x,r=h.y,i=(l-e)/Math.max(Math.abs(l-e),1),n=(p-r)/Math.max(Math.abs(p-r),1),0!==i?(c.isWalkableAt(l,p-1)&&f.push([l,p-1]),c.isWalkableAt(l,p+1)&&f.push([l,p+1]),c.isWalkableAt(l+i,p)&&f.push([l+i,p])):0!==n&&(c.isWalkableAt(l-1,p)&&f.push([l-1,p]),c.isWalkableAt(l+1,p)&&f.push([l+1,p]),c.isWalkableAt(l,p+n)&&f.push([l,p+n]));else for(o=c.getNeighbors(t,!1),a=0,u=o.length;u>a;++a)s=o[a],f.push([s.x,s.y]);return f},e.exports=r},{"../core/Heuristic":4,"./JumpPointFinder":16}],18:[function(t,e){e.exports={Heap:t("heap"),Node:t("./core/Node"),Grid:t("./core/Grid"),Util:t("./core/Util"),Heuristic:t("./core/Heuristic"),AStarFinder:t("./finders/AStarFinder"),BestFirstFinder:t("./finders/BestFirstFinder"),BreadthFirstFinder:t("./finders/BreadthFirstFinder"),DijkstraFinder:t("./finders/DijkstraFinder"),BiAStarFinder:t("./finders/BiAStarFinder"),BiBestFirstFinder:t("./finders/BiBestFirstFinder"),BiBreadthFirstFinder:t("./finders/BiBreadthFirstFinder"),BiDijkstraFinder:t("./finders/BiDijkstraFinder"),IDAStarFinder:t("./finders/IDAStarFinder"),JumpPointFinder:t("./finders/JumpPointFinder"),OrthogonalJumpPointFinder:t("./finders/OrthogonalJumpPointFinder")}},{"./core/Grid":3,"./core/Heuristic":4,"./core/Node":5,"./core/Util":6,"./finders/AStarFinder":7,"./finders/BestFirstFinder":8,"./finders/BiAStarFinder":9,"./finders/BiBestFirstFinder":10,"./finders/BiBreadthFirstFinder":11,"./finders/BiDijkstraFinder":12,"./finders/BreadthFirstFinder":13,"./finders/DijkstraFinder":14,"./finders/IDAStarFinder":15,"./finders/JumpPointFinder":16,"./finders/OrthogonalJumpPointFinder":17,heap:1}]},{},[18])(18)}); \ No newline at end of file +!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.PF=e()}}(function(){return function e(t,i,n){function r(a,s){if(!i[a]){if(!t[a]){var l="function"==typeof require&&require;if(!s&&l)return l(a,!0);if(o)return o(a,!0);throw new Error("Cannot find module '"+a+"'")}var u=i[a]={exports:{}};t[a][0].call(u.exports,function(e){var i=t[a][1][e];return r(i?i:e)},u,u.exports,e,t,i,n)}return i[a].exports}for(var o="function"==typeof require&&require,a=0;ae?-1:e>t?1:0},u=function(e,t,r,o,a){var s;if(null==r&&(r=0),null==a&&(a=i),0>r)throw new Error("lo must be non-negative");for(null==o&&(o=e.length);o>r;)s=n((r+o)/2),a(t,e[s])<0?o=s:r=s+1;return[].splice.apply(e,[r,r-r].concat(t)),t},a=function(e,t,n){return null==n&&(n=i),e.push(t),d(e,0,e.length-1,n)},o=function(e,t){var n,r;return null==t&&(t=i),n=e.pop(),e.length?(r=e[0],e[0]=n,g(e,0,t)):r=n,r},l=function(e,t,n){var r;return null==n&&(n=i),r=e[0],e[0]=t,g(e,0,n),r},s=function(e,t,n){var r;return null==n&&(n=i),e.length&&n(e[0],t)<0&&(r=[e[0],t],t=r[0],e[0]=r[1],g(e,0,n)),t},r=function(e,t){var r,o,a,s,l,u;for(null==t&&(t=i),s=function(){u=[];for(var t=0,i=n(e.length/2);i>=0?i>t:t>i;i>=0?t++:t--)u.push(t);return u}.apply(this).reverse(),l=[],o=0,a=s.length;a>o;o++)r=s[o],l.push(g(e,r,t));return l},f=function(e,t,n){var r;return null==n&&(n=i),r=e.indexOf(t),-1!==r?(d(e,0,r,n),g(e,r,n)):void 0},p=function(e,t,n){var o,a,l,u,h;if(null==n&&(n=i),a=e.slice(0,t),!a.length)return a;for(r(a,n),h=e.slice(t),l=0,u=h.length;u>l;l++)o=h[l],s(a,o,n);return a.sort(n).reverse()},c=function(e,t,n){var a,s,l,p,c,f,d,g,b,A;if(null==n&&(n=i),10*t<=e.length){if(p=e.slice(0,t).sort(n),!p.length)return p;for(l=p[p.length-1],g=e.slice(t),c=0,d=g.length;d>c;c++)a=g[c],n(a,l)<0&&(u(p,a,0,null,n),p.pop(),l=p[p.length-1]);return p}for(r(e,n),A=[],s=f=0,b=h(t,e.length);b>=0?b>f:f>b;s=b>=0?++f:--f)A.push(o(e,n));return A},d=function(e,t,n,r){var o,a,s;for(null==r&&(r=i),o=e[n];n>t&&(s=n-1>>1,a=e[s],r(o,a)<0);)e[n]=a,n=s;return e[n]=o},g=function(e,t,n){var r,o,a,s,l;for(null==n&&(n=i),o=e.length,l=t,a=e[t],r=2*t+1;o>r;)s=r+1,o>s&&!(n(e[r],e[s])<0)&&(r=s),e[t]=e[r],t=r,r=2*t+1;return e[t]=a,d(e,l,t,n)},e=function(){function e(e){this.cmp=null!=e?e:i,this.nodes=[]}return e.push=a,e.pop=o,e.replace=l,e.pushpop=s,e.heapify=r,e.updateItem=f,e.nlargest=p,e.nsmallest=c,e.prototype.push=function(e){return a(this.nodes,e,this.cmp)},e.prototype.pop=function(){return o(this.nodes,this.cmp)},e.prototype.peek=function(){return this.nodes[0]},e.prototype.contains=function(e){return-1!==this.nodes.indexOf(e)},e.prototype.replace=function(e){return l(this.nodes,e,this.cmp)},e.prototype.pushpop=function(e){return s(this.nodes,e,this.cmp)},e.prototype.heapify=function(){return r(this.nodes,this.cmp)},e.prototype.updateItem=function(e){return f(this.nodes,e,this.cmp)},e.prototype.clear=function(){return this.nodes=[]},e.prototype.empty=function(){return 0===this.nodes.length},e.prototype.size=function(){return this.nodes.length},e.prototype.clone=function(){var t;return t=new e,t.nodes=this.nodes.slice(0),t},e.prototype.toArray=function(){return this.nodes.slice(0)},e.prototype.insert=e.prototype.push,e.prototype.top=e.prototype.peek,e.prototype.front=e.prototype.peek,e.prototype.has=e.prototype.contains,e.prototype.copy=e.prototype.clone,e}(),("undefined"!=typeof t&&null!==t?t.exports:void 0)?t.exports=e:window.Heap=e}).call(this)},{}],3:[function(e,t){var i={Always:1,Never:2,IfAtMostOneObstacle:3,OnlyWhenNoObstacles:4};t.exports=i},{}],4:[function(e,t){function i(e,t,i){this.width=e,this.height=t,this.nodes=this._buildNodes(e,t,i)}var n=e("./Node"),r=e("./DiagonalMovement");i.prototype._buildNodes=function(e,t,i){var r,o,a=new Array(t);for(r=0;t>r;++r)for(a[r]=new Array(e),o=0;e>o;++o)a[r][o]=new n(o,r);if(void 0===i)return a;if(i.length!==t||i[0].length!==e)throw new Error("Matrix size does not fit");for(r=0;t>r;++r)for(o=0;e>o;++o)i[r][o]&&(a[r][o].walkable=!1);return a},i.prototype.getNodeAt=function(e,t){return this.nodes[t][e]},i.prototype.isWalkableAt=function(e,t){return this.isInside(e,t)&&this.nodes[t][e].walkable},i.prototype.isInside=function(e,t){return e>=0&&e=0&&te;++e)for(l[e]=new Array(r),t=0;r>t;++t)l[e][t]=new n(t,e,a[e][t].walkable);return s.nodes=l,s},t.exports=i},{"./DiagonalMovement":3,"./Node":6}],5:[function(e,t){t.exports={manhattan:function(e,t){return e+t},euclidean:function(e,t){return Math.sqrt(e*e+t*t)},octile:function(e,t){var i=Math.SQRT2-1;return t>e?i*e+t:i*t+e},chebyshev:function(e,t){return Math.max(e,t)}}},{}],6:[function(e,t){function i(e,t,i){this.x=e,this.y=t,this.walkable=void 0===i?!0:i}t.exports=i},{}],7:[function(e,t,i){function n(e){for(var t=[[e.x,e.y]];e.parent;)e=e.parent,t.push([e.x,e.y]);return t.reverse()}function r(e,t){var i=n(e),r=n(t);return i.concat(r.reverse())}function o(e){var t,i,n,r,o,a=0;for(t=1;te?1:-1,o=n>t?1:-1,l=a-s;;){if(p.push([e,t]),e===i&&t===n)break;u=2*l,u>-s&&(l-=s,e+=r),a>u&&(l+=a,t+=o)}return p}function s(e){var t,i,n,r,o,s,l=[],u=e.length;if(2>u)return l;for(o=0;u-1>o;++o)for(t=e[o],i=e[o+1],n=a(t[0],t[1],i[0],i[1]),r=n.length,s=0;r-1>s;++s)l.push(n[s]);return l.push(e[u-1]),l}function l(e,t){var i,n,r,o,s,l,u,h,p,c,f,d=t.length,g=t[0][0],b=t[0][1],A=t[d-1][0],v=t[d-1][1];for(i=g,n=b,s=[[i,n]],l=2;d>l;++l){for(h=t[l],r=h[0],o=h[1],p=a(i,n,r,o),f=!1,u=1;uh;++h)u=l[h],u.closed||(c=u.x,f=u.y,d=s.g+(c-s.x===0||f-s.y===0?1:W),(!u.opened||dh;++h)if(u=l[h],!u.closed){if(u.opened===x)return r.biBacktrace(s,u);c=u.x,f=u.y,d=s.g+(c-s.x===0||f-s.y===0?1:w),(!u.opened||dh;++h)if(u=l[h],!u.closed){if(u.opened===N)return r.biBacktrace(u,s);c=u.x,f=u.y,d=s.g+(c-s.x===0||f-s.y===0?1:w),(!u.opened||du;++u)if(s=a[u],!s.closed)if(s.opened){if(s.by===A)return n.biBacktrace(l,s)}else f.push(s),s.parent=l,s.opened=!0,s.by=b;for(l=d.shift(),l.closed=!0,a=o.getNeighbors(l,g),u=0,h=a.length;h>u;++u)if(s=a[u],!s.closed)if(s.opened){if(s.by===b)return n.biBacktrace(s,l)}else d.push(s),s.parent=l,s.opened=!0,s.by=A}return[]},t.exports=i},{"../core/DiagonalMovement":3,"../core/Util":7}],14:[function(e,t){function i(e){n.call(this,e),this.heuristic=function(){return 0}}var n=e("./BiAStarFinder");i.prototype=new n,i.prototype.constructor=i,t.exports=i},{"./BiAStarFinder":11}],15:[function(e,t){function i(e){e=e||{},this.allowDiagonal=e.allowDiagonal,this.dontCrossCorners=e.dontCrossCorners,this.diagonalMovement=e.diagonalMovement,this.diagonalMovement||(this.diagonalMovement=this.allowDiagonal?this.dontCrossCorners?r.OnlyWhenNoObstacles:r.IfAtMostOneObstacle:r.Never)}var n=e("../core/Util"),r=e("../core/DiagonalMovement");i.prototype.findPath=function(e,t,i,r,o){var a,s,l,u,h,p=[],c=this.diagonalMovement,f=o.getNodeAt(e,t),d=o.getNodeAt(i,r);for(p.push(f),f.opened=!0;p.length;){if(l=p.shift(),l.closed=!0,l===d)return n.backtrace(d);for(a=o.getNeighbors(l,c),u=0,h=a.length;h>u;++u)s=a[u],s.closed||s.opened||(p.push(s),s.opened=!0,s.parent=l)}return[]},t.exports=i},{"../core/DiagonalMovement":3,"../core/Util":7}],16:[function(e,t){function i(e){n.call(this,e),this.heuristic=function(){return 0}}var n=e("./AStarFinder");i.prototype=new n,i.prototype.constructor=i,t.exports=i},{"./AStarFinder":9}],17:[function(e,t){function i(e){e=e||{},this.allowDiagonal=e.allowDiagonal,this.dontCrossCorners=e.dontCrossCorners,this.diagonalMovement=e.diagonalMovement,this.heuristic=e.heuristic||n.manhattan,this.weight=e.weight||1,this.trackRecursion=e.trackRecursion||!1,this.timeLimit=e.timeLimit||1/0,this.diagonalMovement||(this.diagonalMovement=this.allowDiagonal?this.dontCrossCorners?o.OnlyWhenNoObstacles:o.IfAtMostOneObstacle:o.Never),this.heuristic=this.diagonalMovement===o.Never?e.heuristic||n.manhattan:e.heuristic||n.octile}var n=(e("../core/Util"),e("../core/Heuristic")),r=e("../core/Node"),o=e("../core/DiagonalMovement");i.prototype.findPath=function(e,t,i,n,o){var a,s,l,u=0,h=(new Date).getTime(),p=function(e,t){return this.heuristic(Math.abs(t.x-e.x),Math.abs(t.y-e.y))}.bind(this),c=function(e,t){return e.x===t.x||e.y===t.y?1:Math.SQRT2},f=function(e,t,i,n,a){if(u++,this.timeLimit>0&&(new Date).getTime()-h>1e3*this.timeLimit)return 1/0;var s=t+p(e,g)*this.weight;if(s>i)return s;if(e==g)return n[a]=[e.x,e.y],e;var l,d,b,A,v=o.getNeighbors(e,this.diagonalMovement);for(b=0,l=1/0;A=v[b];++b){if(this.trackRecursion&&(A.retainCount=A.retainCount+1||1,A.tested!==!0&&(A.tested=!0)),d=f(A,t+c(e,A),i,n,a+1),d instanceof r)return n[a]=[e.x,e.y],d;this.trackRecursion&&0===--A.retainCount&&(A.tested=!1),l>d&&(l=d)}return l}.bind(this),d=o.getNodeAt(e,t),g=o.getNodeAt(i,n),b=p(d,g);for(a=0;!0;++a){if(s=[],l=f(d,0,b,s,0),1/0===l)return[];if(l instanceof r)return s;b=l}return[]},t.exports=i},{"../core/DiagonalMovement":3,"../core/Heuristic":5,"../core/Node":6,"../core/Util":7}],18:[function(e,t){function i(e){n.call(this,e)}var n=e("./JumpPointFinderBase"),r=e("../core/DiagonalMovement");i.prototype=new n,i.prototype.constructor=i,i.prototype._jump=function(e,t,i,n){var r=this.grid,o=e-i,a=t-n;if(!r.isWalkableAt(e,t))return null;if(this.trackJumpRecursion===!0&&(r.getNodeAt(e,t).tested=!0),r.getNodeAt(e,t)===this.endNode)return[e,t];if(0!==o&&0!==a){if(r.isWalkableAt(e-o,t+a)&&!r.isWalkableAt(e-o,t)||r.isWalkableAt(e+o,t-a)&&!r.isWalkableAt(e,t-a))return[e,t];if(this._jump(e+o,t,e,t)||this._jump(e,t+a,e,t))return[e,t]}else if(0!==o){if(r.isWalkableAt(e+o,t+1)&&!r.isWalkableAt(e,t+1)||r.isWalkableAt(e+o,t-1)&&!r.isWalkableAt(e,t-1))return[e,t]}else if(r.isWalkableAt(e+1,t+a)&&!r.isWalkableAt(e+1,t)||r.isWalkableAt(e-1,t+a)&&!r.isWalkableAt(e-1,t))return[e,t];return this._jump(e+o,t+a,e,t)},i.prototype._findNeighbors=function(e){var t,i,n,o,a,s,l,u,h=e.parent,p=e.x,c=e.y,f=this.grid,d=[];if(h)t=h.x,i=h.y,n=(p-t)/Math.max(Math.abs(p-t),1),o=(c-i)/Math.max(Math.abs(c-i),1),0!==n&&0!==o?(f.isWalkableAt(p,c+o)&&d.push([p,c+o]),f.isWalkableAt(p+n,c)&&d.push([p+n,c]),f.isWalkableAt(p+n,c+o)&&d.push([p+n,c+o]),f.isWalkableAt(p-n,c)||d.push([p-n,c+o]),f.isWalkableAt(p,c-o)||d.push([p+n,c-o])):0===n?(f.isWalkableAt(p,c+o)&&d.push([p,c+o]),f.isWalkableAt(p+1,c)||d.push([p+1,c+o]),f.isWalkableAt(p-1,c)||d.push([p-1,c+o])):(f.isWalkableAt(p+n,c)&&d.push([p+n,c]),f.isWalkableAt(p,c+1)||d.push([p+n,c+1]),f.isWalkableAt(p,c-1)||d.push([p+n,c-1]));else for(a=f.getNeighbors(e,r.Always),l=0,u=a.length;u>l;++l)s=a[l],d.push([s.x,s.y]);return d},t.exports=i},{"../core/DiagonalMovement":3,"./JumpPointFinderBase":23}],19:[function(e,t){function i(e){n.call(this,e)}var n=e("./JumpPointFinderBase"),r=e("../core/DiagonalMovement");i.prototype=new n,i.prototype.constructor=i,i.prototype._jump=function(e,t,i,n){var r=this.grid,o=e-i,a=t-n;if(!r.isWalkableAt(e,t))return null;if(this.trackJumpRecursion===!0&&(r.getNodeAt(e,t).tested=!0),r.getNodeAt(e,t)===this.endNode)return[e,t];if(0!==o&&0!==a){if(r.isWalkableAt(e-o,t+a)&&!r.isWalkableAt(e-o,t)||r.isWalkableAt(e+o,t-a)&&!r.isWalkableAt(e,t-a))return[e,t];if(this._jump(e+o,t,e,t)||this._jump(e,t+a,e,t))return[e,t]}else if(0!==o){if(r.isWalkableAt(e+o,t+1)&&!r.isWalkableAt(e,t+1)||r.isWalkableAt(e+o,t-1)&&!r.isWalkableAt(e,t-1))return[e,t]}else if(r.isWalkableAt(e+1,t+a)&&!r.isWalkableAt(e+1,t)||r.isWalkableAt(e-1,t+a)&&!r.isWalkableAt(e-1,t))return[e,t];return r.isWalkableAt(e+o,t)||r.isWalkableAt(e,t+a)?this._jump(e+o,t+a,e,t):null},i.prototype._findNeighbors=function(e){var t,i,n,o,a,s,l,u,h=e.parent,p=e.x,c=e.y,f=this.grid,d=[];if(h)t=h.x,i=h.y,n=(p-t)/Math.max(Math.abs(p-t),1),o=(c-i)/Math.max(Math.abs(c-i),1),0!==n&&0!==o?(f.isWalkableAt(p,c+o)&&d.push([p,c+o]),f.isWalkableAt(p+n,c)&&d.push([p+n,c]),(f.isWalkableAt(p,c+o)||f.isWalkableAt(p+n,c))&&d.push([p+n,c+o]),!f.isWalkableAt(p-n,c)&&f.isWalkableAt(p,c+o)&&d.push([p-n,c+o]),!f.isWalkableAt(p,c-o)&&f.isWalkableAt(p+n,c)&&d.push([p+n,c-o])):0===n?f.isWalkableAt(p,c+o)&&(d.push([p,c+o]),f.isWalkableAt(p+1,c)||d.push([p+1,c+o]),f.isWalkableAt(p-1,c)||d.push([p-1,c+o])):f.isWalkableAt(p+n,c)&&(d.push([p+n,c]),f.isWalkableAt(p,c+1)||d.push([p+n,c+1]),f.isWalkableAt(p,c-1)||d.push([p+n,c-1]));else for(a=f.getNeighbors(e,r.IfAtMostOneObstacle),l=0,u=a.length;u>l;++l)s=a[l],d.push([s.x,s.y]);return d},t.exports=i},{"../core/DiagonalMovement":3,"./JumpPointFinderBase":23}],20:[function(e,t){function i(e){n.call(this,e)}var n=e("./JumpPointFinderBase"),r=e("../core/DiagonalMovement");i.prototype=new n,i.prototype.constructor=i,i.prototype._jump=function(e,t,i,n){var r=this.grid,o=e-i,a=t-n;if(!r.isWalkableAt(e,t))return null;if(this.trackJumpRecursion===!0&&(r.getNodeAt(e,t).tested=!0),r.getNodeAt(e,t)===this.endNode)return[e,t];if(0!==o&&0!==a){if(this._jump(e+o,t,e,t)||this._jump(e,t+a,e,t))return[e,t]}else if(0!==o){if(r.isWalkableAt(e,t-1)&&!r.isWalkableAt(e-o,t-1)||r.isWalkableAt(e,t+1)&&!r.isWalkableAt(e-o,t+1))return[e,t]}else if(0!==a&&(r.isWalkableAt(e-1,t)&&!r.isWalkableAt(e-1,t-a)||r.isWalkableAt(e+1,t)&&!r.isWalkableAt(e+1,t-a)))return[e,t];return r.isWalkableAt(e+o,t)&&r.isWalkableAt(e,t+a)?this._jump(e+o,t+a,e,t):null},i.prototype._findNeighbors=function(e){var t,i,n,o,a,s,l,u,h=e.parent,p=e.x,c=e.y,f=this.grid,d=[];if(h)if(t=h.x,i=h.y,n=(p-t)/Math.max(Math.abs(p-t),1),o=(c-i)/Math.max(Math.abs(c-i),1),0!==n&&0!==o)f.isWalkableAt(p,c+o)&&d.push([p,c+o]),f.isWalkableAt(p+n,c)&&d.push([p+n,c]),f.isWalkableAt(p,c+o)&&f.isWalkableAt(p+n,c)&&d.push([p+n,c+o]);else{var g;if(0!==n){g=f.isWalkableAt(p+n,c);var b=f.isWalkableAt(p,c+1),A=f.isWalkableAt(p,c-1);g&&(d.push([p+n,c]),b&&d.push([p+n,c+1]),A&&d.push([p+n,c-1])),b&&d.push([p,c+1]),A&&d.push([p,c-1])}else if(0!==o){g=f.isWalkableAt(p,c+o);var v=f.isWalkableAt(p+1,c),k=f.isWalkableAt(p-1,c);g&&(d.push([p,c+o]),v&&d.push([p+1,c+o]),k&&d.push([p-1,c+o])),v&&d.push([p+1,c]),k&&d.push([p-1,c])}}else for(a=f.getNeighbors(e,r.OnlyWhenNoObstacles),l=0,u=a.length;u>l;++l)s=a[l],d.push([s.x,s.y]);return d},t.exports=i},{"../core/DiagonalMovement":3,"./JumpPointFinderBase":23}],21:[function(e,t){function i(e){n.call(this,e)}var n=e("./JumpPointFinderBase"),r=e("../core/DiagonalMovement");i.prototype=new n,i.prototype.constructor=i,i.prototype._jump=function(e,t,i,n){var r=this.grid,o=e-i,a=t-n;if(!r.isWalkableAt(e,t))return null;if(this.trackJumpRecursion===!0&&(r.getNodeAt(e,t).tested=!0),r.getNodeAt(e,t)===this.endNode)return[e,t];if(0!==o){if(r.isWalkableAt(e,t-1)&&!r.isWalkableAt(e-o,t-1)||r.isWalkableAt(e,t+1)&&!r.isWalkableAt(e-o,t+1))return[e,t]}else{if(0===a)throw new Error("Only horizontal and vertical movements are allowed");if(r.isWalkableAt(e-1,t)&&!r.isWalkableAt(e-1,t-a)||r.isWalkableAt(e+1,t)&&!r.isWalkableAt(e+1,t-a))return[e,t];if(this._jump(e+1,t,e,t)||this._jump(e-1,t,e,t))return[e,t]}return this._jump(e+o,t+a,e,t)},i.prototype._findNeighbors=function(e){var t,i,n,o,a,s,l,u,h=e.parent,p=e.x,c=e.y,f=this.grid,d=[];if(h)t=h.x,i=h.y,n=(p-t)/Math.max(Math.abs(p-t),1),o=(c-i)/Math.max(Math.abs(c-i),1),0!==n?(f.isWalkableAt(p,c-1)&&d.push([p,c-1]),f.isWalkableAt(p,c+1)&&d.push([p,c+1]),f.isWalkableAt(p+n,c)&&d.push([p+n,c])):0!==o&&(f.isWalkableAt(p-1,c)&&d.push([p-1,c]),f.isWalkableAt(p+1,c)&&d.push([p+1,c]),f.isWalkableAt(p,c+o)&&d.push([p,c+o]));else for(a=f.getNeighbors(e,r.Never),l=0,u=a.length;u>l;++l)s=a[l],d.push([s.x,s.y]);return d},t.exports=i},{"../core/DiagonalMovement":3,"./JumpPointFinderBase":23}],22:[function(e,t){function i(e){return e=e||{},e.diagonalMovement===n.Never?new r(e):e.diagonalMovement===n.Always?new o(e):e.diagonalMovement===n.OnlyWhenNoObstacles?new a(e):new s(e)}var n=e("../core/DiagonalMovement"),r=e("./JPFNeverMoveDiagonally"),o=e("./JPFAlwaysMoveDiagonally"),a=e("./JPFMoveDiagonallyIfNoObstacles"),s=e("./JPFMoveDiagonallyIfAtMostOneObstacle");t.exports=i},{"../core/DiagonalMovement":3,"./JPFAlwaysMoveDiagonally":18,"./JPFMoveDiagonallyIfAtMostOneObstacle":19,"./JPFMoveDiagonallyIfNoObstacles":20,"./JPFNeverMoveDiagonally":21}],23:[function(e,t){function i(e){e=e||{},this.heuristic=e.heuristic||o.manhattan,this.trackJumpRecursion=e.trackJumpRecursion||!1}{var n=e("heap"),r=e("../core/Util"),o=e("../core/Heuristic");e("../core/DiagonalMovement")}i.prototype.findPath=function(e,t,i,o,a){var s,l=this.openList=new n(function(e,t){return e.f-t.f}),u=this.startNode=a.getNodeAt(e,t),h=this.endNode=a.getNodeAt(i,o);for(this.grid=a,u.g=0,u.f=0,l.push(u),u.opened=!0;!l.empty();){if(s=l.pop(),s.closed=!0,s===h)return r.expandPath(r.backtrace(h));this._identifySuccessors(s)}return[]},i.prototype._identifySuccessors=function(e){{var t,i,n,r,a,s,l,u,h,p,c=this.grid,f=this.heuristic,d=this.openList,g=this.endNode.x,b=this.endNode.y,A=e.x,v=e.y,k=Math.abs;Math.max}for(t=this._findNeighbors(e),r=0,a=t.length;a>r;++r)if(i=t[r],n=this._jump(i[0],i[1],A,v)){if(s=n[0],l=n[1],p=c.getNodeAt(s,l),p.closed)continue;u=o.octile(k(s-A),k(l-v)),h=e.g+u,(!p.opened||hd?(d=-d,o=-1):o=1,0>g?(g=-g,a=-1):a=1,0==d){for(p+=a;p!=f;p+=a)if(!r.isWalkableAt(h,p))return!1;return!0}if(0==g){for(h+=o;h!=c;h+=o)if(!r.isWalkableAt(h,p))return!1;return!0}if(d>=g){if(!r.isWalkableAt(h,p+a)||!r.isWalkableAt(c,f-a))return!1;for(l=p,u=f,s=g;s+=g,s>=d?(h+=o,p+=a,c-=o,f-=a,s-=d):(h+=o,c-=o),h!=c+o;){if(h==c){if(p==f){if(!r.isWalkableAt(h,p-a)||!r.isWalkableAt(h,p)||!r.isWalkableAt(h,p+a))return!1}else if(!r.isWalkableAt(h,p)||!r.isWalkableAt(c,f))return!1;break}if(p!=l&&!r.isWalkableAt(h,p-a))return!1;if(!r.isWalkableAt(h,p)||!r.isWalkableAt(h,p+a))return!1;if(f!=u&&!r.isWalkableAt(c,f+a))return!1;if(!r.isWalkableAt(c,f)||!r.isWalkableAt(c,f-a))return!1}}else{if(!r.isWalkableAt(h+o,p)||!r.isWalkableAt(c-o,f))return!1;for(l=h,u=c,s=d;s+=d,s>=g?(h+=o,p+=a,c-=o,f-=a,s-=g):(p+=a,f-=a),p!=f+a;){if(p==f){if(h==c){if(!r.isWalkableAt(h-o,p)||!r.isWalkableAt(h,p)||!r.isWalkableAt(h+o,p))return!1}else if(!r.isWalkableAt(h,p)||!r.isWalkableAt(c,f))return!1;break}if(h!=l&&!r.isWalkableAt(h-o,p))return!1;if(!r.isWalkableAt(h,p)||!r.isWalkableAt(h+o,p))return!1;if(c!=u&&!r.isWalkableAt(c+o,f))return!1;if(!r.isWalkableAt(c,f)||!r.isWalkableAt(c-o,f))return!1}}return!0},i.prototype.findPath=function(e,t,i,o,a){var s,l,u,h,p,c,f,d,g=new n(function(e,t){return e.f-t.f}),b=a.getNodeAt(e,t),A=a.getNodeAt(i,o),v=this.distance,k=this.lineOfSight,y=this.diagonalMovement,m=this.weight;for(b.g=0,b.f=0,g.push(b),b.opened=!0;!g.empty();){if(s=g.pop(),s.closed=!0,s===A)return r.backtrace(A);for(l=a.getNeighbors(s,y),h=0,p=l.length;p>h;++h)if(u=l[h],!u.closed){if(c=u.x,f=u.y,s.parent&&k(c,f,s.parent.x,s.parent.y,a)){if(d=s.parent.g+v(c,f,s.parent.x,s.parent.y),u.opened&&!(d