{"ScriptPreparationCode":"\r\nfunction Grid(g, p, size,minc) {\r\n this.MIN = minc * -1;\r\n this.POWER = g;\r\n this.LEVEL = p;\r\n this.SIZE = size;\r\n this.DATA = {};\r\n this.LENGTH = 0;\r\n this.init()\r\n}\r\nGrid.prototype.init = function () {\r\n if (this.SIZE \u003E= 65535) {\r\n throw \u0022Maximum amount of buckets are 65535^2\u0022\r\n } // Max limit is 65535 (16 bits) \r\n // console.log(this.SIZE)\r\n for (var j = this.MIN; j \u003C= this.SIZE; \u002B\u002Bj) {\r\n var x = j \u003C\u003C 16\r\n for (var i = this.MIN; i \u003C= this.SIZE; \u002B\u002Bi) {\r\n\r\n var key = this._getKey(x, i);\r\n // console.log(key)\r\n this.DATA[key] = new Map()\r\n\r\n }\r\n }\r\n\r\n}\r\nGrid.prototype._every = function (m, c) {\r\n var a = m.entries()\r\n var b;\r\n while (b = a.next().value) {\r\n if (!c(b[1], b[0])) return false;\r\n }\r\n return true;\r\n}\r\n\r\nGrid.prototype.getKey = function (x, y) {\r\n return {\r\n x: x \u003E\u003E this.POWER,\r\n y: y \u003E\u003E this.POWER\r\n }\r\n}\r\nGrid.prototype._getKey = function (x, y) {\r\n return x | y\r\n\r\n}\r\nGrid.prototype.checkBorders = function (x, y) {\r\n return !(x \u003E this.SIZE || y \u003E this.SIZE)\r\n\r\n}\r\nGrid.prototype.insert = function (node) {\r\n\r\n // var a = this.getKey(node.bounds.width, node.bounds.height);\r\n // if (a.x \u002B a.y \u003E= 2 \u0026\u0026 this.LEVEL != 0) return false;\r\n this.LENGTH\u002B\u002B;\r\n var x1 = node.bounds.x,\r\n y1 = node.bounds.y,\r\n x2 = node.bounds.x \u002B node.bounds.width,\r\n y2 = node.bounds.y \u002B node.bounds.height;\r\n\r\n var k1 = this.getKey(x1, y1)\r\n var k2 = this.getKey(x2, y2)\r\n node.hash.k1 = k1\r\n node.hash.k2 = k2\r\n node.hash.level = this.LEVEL\r\n var lenX = k2.x \u002B 1,\r\n lenY = k2.y \u002B 1;\r\n for (var j = k1.x; j \u003C lenX; \u002B\u002Bj) {\r\n var x = j \u003C\u003C 16;\r\n for (var i = k1.y; i \u003C lenY; \u002B\u002Bi) {\r\n\r\n var ke = this._getKey(x, i);\r\n // console.log(ke)\r\n this.DATA[ke].set(node._HashID, node)\r\n }\r\n\r\n }\r\n return true;\r\n}\r\nGrid.prototype.delete = function (node) {\r\n var k1 = node.hash.k1\r\n var k2 = node.hash.k2\r\n this.LENGTH--;\r\n var lenX = k2.x \u002B 1,\r\n lenY = k2.y \u002B 1;\r\n for (var j = k1.x; j \u003C lenX; \u002B\u002Bj) {\r\n var x = j \u003C\u003C 16;\r\n for (var i = k1.y; i \u003C lenY; \u002B\u002Bi) {\r\n\r\n\r\n var ke = this._getKey(x, i);\r\n\r\n this.DATA[ke].delete(node._HashID)\r\n }\r\n\r\n }\r\n}\r\nGrid.prototype.toArray = function (array, bounds) {\r\n if (this.LENGTH \u003C= 0) return;\r\n\r\n var x1 = bounds.x,\r\n y1 = bounds.y,\r\n x2 = bounds.x \u002B bounds.width,\r\n y2 = bounds.y \u002B bounds.height,\r\n h = {};\r\n\r\n var k1 = this.getKey(x1, y1)\r\n var k2 = this.getKey(x2, y2)\r\n for (var j = k1.x; j \u003C= k2.x; \u002B\u002Bj) {\r\n var x = j \u003C\u003C 16;\r\n for (var i = k1.y; i \u003C= k2.y; \u002B\u002Bi) {\r\n\r\n var ke = this._getKey(x, i);\r\n\r\n if (this.DATA[ke]) this.DATA[ke].forEach((node, i) =\u003E {\r\n\r\n if (h[i]) return;\r\n h[i] = true;\r\n array.push(node)\r\n })\r\n }\r\n\r\n }\r\n}\r\nGrid.prototype.every = function (bounds, call) {\r\n if (this.LENGTH \u003C= 0) return true;\r\n var x1 = bounds.x,\r\n y1 = bounds.y,\r\n x2 = bounds.x \u002B bounds.width,\r\n y2 = bounds.y \u002B bounds.height,\r\n h = {};\r\n\r\n var k1 = this.getKey(x1, y1)\r\n var k2 = this.getKey(x2, y2)\r\n for (var j = k1.x; j \u003C= k2.x; \u002B\u002Bj) {\r\n var x = j \u003C\u003C 16;\r\n for (var i = k1.y; i \u003C= k2.y; \u002B\u002Bi) {\r\n\r\n var ke = this._getKey(x, i);\r\n\r\n if (this.DATA[ke])\r\n if (!this._every(this.DATA[ke], (a, b) =\u003E {\r\n\r\n if (h[b]) return true;\r\n h[b] = true;\r\n return call(a, b);\r\n })) return false;\r\n }\r\n\r\n }\r\n return true;\r\n}\r\nGrid.prototype.forEach = function (bounds, call) {\r\n if (this.LENGTH \u003C= 0) return;\r\n var x1 = bounds.x,\r\n y1 = bounds.y,\r\n x2 = bounds.x \u002B bounds.width,\r\n y2 = bounds.y \u002B bounds.height,\r\n h = {};\r\n\r\n var k1 = this.getKey(x1, y1)\r\n var k2 = this.getKey(x2, y2)\r\n\r\n for (var j = k1.x; j \u003C= k2.x; \u002B\u002Bj) {\r\n var x = j \u003C\u003C 16;\r\n for (var i = k1.y; i \u003C= k2.y; \u002B\u002Bi) {\r\n\r\n var ke = this._getKey(x, i);\r\n\r\n if (this.DATA[ke])\r\n this.DATA[ke].forEach((a, b) =\u003E {\r\n if (h[b]) return;\r\n h[b] = true;\r\n call(a, b)\r\n })\r\n }\r\n\r\n }\r\n\r\n}\r\n\r\nfunction HashBounds(power, lvl, max,minc) {\r\n this.INITIAL = power;\r\n this.LVL = lvl;\r\nthis.MINC = minc;\r\n this.MAX = max;\r\n this.MIN = power \u002B 1;\r\n this.LEVELS = []\r\n this.lastid = 0;\r\n this.createLevels()\r\n this.SQRT = [];\r\n this.setupSQRT()\r\n}\r\n\r\nHashBounds.prototype.setupSQRT = function () {\r\n for (var i = 0; i \u003C 255; \u002B\u002Bi) {\r\n this.SQRT.push(Math.floor(Math.sqrt(i)))\r\n }\r\n}\r\n\r\nHashBounds.prototype.createLevels = function () {\r\n this.LEVELS = [];\r\n var a = this.INITIAL;\r\n for (var i = 0; i \u003C this.LVL; i\u002B\u002B, a\u002B\u002B) {\r\n\r\n this.LEVELS.push(new Grid(a, i, this.MAX \u003E\u003E a,this.MINC \u003E\u003E a))\r\n }\r\n}\r\nHashBounds.prototype.clear = function () {\r\n this.createLevels();\r\n}\r\nHashBounds.prototype.update = function (node) {\r\n this.delete(node)\r\n this.insert(node)\r\n}\r\nHashBounds.prototype.insert = function (node) {\r\n if (node.hash) throw \u0022ERR: A node cannot be already in a hash!\u0022\r\n var bounds = node.bounds;\r\n node.hash = {}\r\n if (!node._HashID) node._HashID = \u002B\u002Bthis.lastid;\r\n if (node._HashSize == node.bounds.width \u002B node.bounds.height) {\r\n this.LEVELS[node._HashIndex].insert(node);\r\n return;\r\n }\r\n\r\n var index = this.SQRT[(node.bounds.width \u002B node.bounds.height) \u003E\u003E this.MIN]\r\n if (index \u003E= this.LVL) index = this.LVL - 1;\r\n\r\n node._HashIndex = index;\r\n node._HashSize = node.bounds.width \u002B node.bounds.height;\r\n this.LEVELS[index].insert(node);\r\n //for (var i = 0; i \u003C len; \u002B\u002Bi) {\r\n // if (this.LEVELS[len - i - 1].insert(node)) break;\r\n //}\r\n}\r\n\r\n\r\nHashBounds.prototype.delete = function (node) {\r\n if (!node.hash) throw \u0022ERR: Node is not in a hash!\u0022\r\n this.LEVELS[node.hash.level].delete(node)\r\n node.hash = null;\r\n}\r\nHashBounds.prototype.toArray = function (bounds) {\r\n var array = [];\r\n for (var i = 0; i \u003C this.LEVELS.length; i\u002B\u002B) {\r\n this.LEVELS[i].toArray(array, bounds)\r\n }\r\n return array;\r\n}\r\nHashBounds.prototype.every = function (bounds, call) {\r\n for (var i = 0; i \u003C this.LEVELS.length; i\u002B\u002B) {\r\n if (!this.LEVELS[i].every(bounds, call)) return false;\r\n }\r\n return true;\r\n}\r\nHashBounds.prototype.forEach = function (bounds, call) {\r\n for (var i = 0; i \u003C this.LEVELS.length; i\u002B\u002B) {\r\n this.LEVELS[i].forEach(bounds, call)\r\n }\r\n}\r\n\r\n\r\nif (typeof module !== \u0027undefined\u0027 \u0026\u0026 typeof module.exports !== \u0027undefined\u0027) {\r\n module.exports = HashBounds;\r\n} else {\r\n if (typeof define === \u0027function\u0027 \u0026\u0026 define.amd) {\r\n define([], function () {\r\n return HashBounds;\r\n });\r\n } else {\r\n window.HashBounds = HashBounds;\r\n }\r\n}\r\n\r\nvar Hash = new HashBounds(4,4,150)\r\nvar obj = {\r\n bounds: {\r\n x: Math.floor(Math.random() * 100),\r\n y: Math.floor(Math.random() * 100),\r\n width: Math.floor(Math.random() * 49),\r\n height: Math.floor(Math.random() * 49)\r\n \r\n }\r\n \r\n}\r\nHash.insert(obj)\r\n\r\nobj.x = Math.floor(Math.random() * 100)\r\nobj.y = Math.floor(Math.random() * 100)\r\nvar obj2 = {\r\n bounds: {\r\n x: Math.floor(Math.random() * 100),\r\n y: Math.floor(Math.random() * 100),\r\n width: Math.floor(Math.random() * 49),\r\n height: Math.floor(Math.random() * 49)\r\n \r\n }\r\n \r\n}\r\nHash.insert(obj2)\r\n\r\nobj2.x = Math.floor(Math.random() * 100)\r\nobj2.y = Math.floor(Math.random() * 100)","TestCases":[{"Name":"Insert","Code":"Hash.insert({\r\n bounds: {\r\n x: Math.floor(Math.random() * 100),\r\n y: Math.floor(Math.random() * 100),\r\n width: Math.floor(Math.random() * 49),\r\n height: Math.floor(Math.random() * 49)\r\n \r\n }\r\n \r\n})","IsDeferred":false},{"Name":"Update","Code":"Hash.update(obj)","IsDeferred":false},{"Name":"delete-insert","Code":"Hash.delete(obj2)\r\nHash.insert(obj2)\r\n","IsDeferred":false}]}