From 48414bf81ad3f4ca86c287cb8d063e200e7bcabe Mon Sep 17 00:00:00 2001 From: Carlo C Date: Mon, 11 Jun 2018 16:48:22 -0700 Subject: [PATCH] Update build --- dist/geofire.js | 102 +++++++++++++++++++++++++------------------- dist/geofire.min.js | 2 +- 2 files changed, 58 insertions(+), 46 deletions(-) diff --git a/dist/geofire.js b/dist/geofire.js index 77670e07..7afd71d0 100644 --- a/dist/geofire.js +++ b/dist/geofire.js @@ -10,13 +10,9 @@ * License: MIT */ -// Include RSVP if this is being run in node -if (typeof module !== "undefined" && typeof process !== "undefined") { - var RSVP = require("rsvp"); -} - var GeoFire = (function() { "use strict"; + /** * Creates a GeoCallbackRegistration instance. * @@ -112,17 +108,7 @@ var GeoFire = function(firebaseRef) { } }); - return new RSVP.Promise(function(resolve, reject) { - function onComplete(error) { - if (error !== null) { - reject("Error: Firebase synchronization failed: " + error); - } - else { - resolve(); - } - } - _firebaseRef.update(newData, onComplete); - }); + return _firebaseRef.update(newData); }; /** @@ -135,16 +121,13 @@ var GeoFire = function(firebaseRef) { */ this.get = function(key) { validateKey(key); - return new RSVP.Promise(function(resolve, reject) { - _firebaseRef.child(key).once("value", function(dataSnapshot) { - if (dataSnapshot.val() === null) { - resolve(null); - } else { - resolve(decodeGeoFireObject(dataSnapshot.val())); - } - }, function (error) { - reject("Error: Firebase synchronization failed: " + error); - }); + return _firebaseRef.child(key).once("value").then(function(dataSnapshot) { + var snapshotVal = dataSnapshot.val(); + if (snapshotVal === null) { + return null; + } else { + return decodeGeoFireObject(snapshotVal); + } }); }; @@ -155,22 +138,21 @@ var GeoFire = function(firebaseRef) { * If the provided key does not exist in the index, the returned promise is fulfilled with null. * * @param {string} key The key of the geofire object to retrieve - * @return {RSVP.Promise} A promise that is fulfilled with an object of {key, location, data} + * @return {Promise.>} A promise that is fulfilled with an object of {key, location, data} */ this.getWithData = function(key) { - validateKey(key); - return new RSVP.Promise(function(resolve, reject) { - _firebaseRef.child(key).once("value", function(dataSnapshot) { - var dsv = dataSnapshot.val(); - if(dsv === null) { - resolve(null); - } else { - resolve({key: key, location: decodeGeoFireObject(dsv), data: decodeGeoFireDataObject(dsv)}); - } - }, function (error) { - reject("Error: Firebase synchronization failed: " + error); - }); - }); + validateKey(key); + return _firebaseRef.child(key).once("value").then(function(dataSnapshot) { + var dsv = dataSnapshot.val(); + if(dsv === null) { + return null; + } else { + return { + key: key, + location: decodeGeoFireObject(dsv), + data: decodeGeoFireDataObject(dsv)}; + } + }); }; /** @@ -700,6 +682,24 @@ function decodeGeoFireObject(geoFireObj) { } } +/** + * Returns the key of a Firebase snapshot across SDK versions. + * + * @param {DataSnapshot} snapshot A Firebase snapshot. + * @return {string|null} key The Firebase snapshot's key. + */ + function getKey(snapshot) { + var key; + if (typeof snapshot.key === "function") { + key = snapshot.key(); + } else if (typeof snapshot.key === "string" || snapshot.key === null) { + key = snapshot.key; + } else { + key = snapshot.name(); + } + return key; + } + /** * Creates a GeoQuery instance. * @@ -906,8 +906,8 @@ var GeoQuery = function (firebaseRef, queryCriteria) { * @param {Firebase DataSnapshot} locationDataSnapshot A snapshot of the data stored for this location. */ function _childAddedCallback(locationDataSnapshot) { - var val = locationDataSnapshot.val(); - _updateLocation(locationDataSnapshot.key(), decodeGeoFireObject(val), decodeGeoFireDataObject(val)); + var val = locationDataSnapshot.val(); + _updateLocation(getKey(locationDataSnapshot), decodeGeoFireObject(locationDataSnapshot.val()), decodeGeoFireDataObject(val)); } /** @@ -916,8 +916,8 @@ var GeoQuery = function (firebaseRef, queryCriteria) { * @param {Firebase DataSnapshot} locationDataSnapshot A snapshot of the data stored for this location. */ function _childChangedCallback(locationDataSnapshot) { - var val = locationDataSnapshot.val(); - _updateLocation(locationDataSnapshot.key(), decodeGeoFireObject(val), decodeGeoFireDataObject(val)); + var val = locationDataSnapshot.val(); + _updateLocation(getKey(locationDataSnapshot), decodeGeoFireObject(val), decodeGeoFireDataObject(val)); } /** @@ -926,7 +926,7 @@ var GeoQuery = function (firebaseRef, queryCriteria) { * @param {Firebase DataSnapshot} locationDataSnapshot A snapshot of the data stored for this location. */ function _childRemovedCallback(locationDataSnapshot) { - var key = locationDataSnapshot.key(); + var key = getKey(locationDataSnapshot); if (_locationsTracked.hasOwnProperty(key)) { _firebaseRef.child(key).once("value", function(snapshot) { var location = snapshot.val() === null ? null : decodeGeoFireObject(snapshot.val()); @@ -1078,6 +1078,12 @@ var GeoQuery = function (firebaseRef, queryCriteria) { for (var i = 0; i < numKeys; ++i) { var key = keys[i]; + // If the query was cancelled while going through this loop, stop updating locations and stop + // firing events + if (_cancelled === true) { + break; + } + // Get the cached information for this location var locationDict = _locationsTracked[key]; @@ -1181,6 +1187,9 @@ var GeoQuery = function (firebaseRef, queryCriteria) { * query via on() will be cancelled. This query can no longer be used in the future. */ this.cancel = function () { + // Mark this query as cancelled + _cancelled = true; + // Cancel all callbacks in this query's callback list _callbacks = { ready: [], @@ -1224,6 +1233,9 @@ var GeoQuery = function (firebaseRef, queryCriteria) { key_moved: [] }; + // Variable to track when the query is cancelled + var _cancelled = false; + // Variables used to keep track of when to fire the "ready" event var _valueEventFired = false; var _outstandingGeohashReadyEvents; diff --git a/dist/geofire.min.js b/dist/geofire.min.js index c7e22cdd..1b7018ce 100644 --- a/dist/geofire.min.js +++ b/dist/geofire.min.js @@ -9,4 +9,4 @@ * https://github.com/firebase/geofire-js/ * License: MIT */ -if("undefined"!=typeof module&&"undefined"!=typeof process)var RSVP=require("rsvp");var GeoFire=function(){"use strict";function e(e,n,t){return"undefined"==typeof t&&(t=null),v(e),m(n),{".priority":n,g:n,l:e,d:t}}function n(e){return null!==e&&e.hasOwnProperty("d")?e.d:null}function t(e){if(null!==e&&e.hasOwnProperty("l")&&Array.isArray(e.l)&&2===e.l.length)return e.l;throw new Error("Unexpected GeoFire location object encountered: "+JSON.stringify(e))}var r=function(e){if(this.cancel=function(){"undefined"!=typeof n&&(n(),n=void 0)},"function"!=typeof e)throw new Error("callback must be a function");var n=e},i=function(r){if(this.ref=function(){return i},this.set=function(n,t,r){var o;if("string"==typeof n&&0!==n.length)o={},o[n]=t;else{if("object"!=typeof n)throw new Error("keyOrLocations must be a string or a mapping of key - location pairs.");if("undefined"!=typeof t)throw new Error("The location argument should not be used if you pass an object to set().");o=n}var a={};return Object.keys(o).forEach(function(n){y(n);var t=o[n];if(null===t)a[n]=null;else{v(t);var i=p(t);a[n]=e(t,i,r)}}),new RSVP.Promise(function(e,n){function t(t){null!==t?n("Error: Firebase synchronization failed: "+t):e()}i.update(a,t)})},this.get=function(e){return y(e),new RSVP.Promise(function(n,r){i.child(e).once("value",function(e){n(null===e.val()?null:t(e.val()))},function(e){r("Error: Firebase synchronization failed: "+e)})})},this.getWithData=function(e){return y(e),new RSVP.Promise(function(r,o){i.child(e).once("value",function(i){var o=i.val();r(null===o?null:{key:e,location:t(o),data:n(o)})},function(e){o("Error: Firebase synchronization failed: "+e)})})},this.remove=function(e){return this.set(e,null)},this.query=function(e){return new F(i,e)},"[object Object]"!==Object.prototype.toString.call(r))throw new Error("firebaseRef must be an instance of Firebase");var i=r};i.distance=function(e,n){v(e),v(n);var t=6371,r=g(n[0]-e[0]),i=g(n[1]-e[1]),o=Math.sin(r/2)*Math.sin(r/2)+Math.cos(g(e[0]))*Math.cos(g(n[0]))*Math.sin(i/2)*Math.sin(i/2),a=2*Math.atan2(Math.sqrt(o),Math.sqrt(1-o));return t*a};var o=10,a="0123456789bcdefghjkmnpqrstuvwxyz",u=40007860,f=110574,c=5,l=22*c,s=6378137,d=.00669447819799,h=1e-12;Math.log2=Math.log2||function(e){return Math.log(e)/Math.log(2)};var y=function(e){var n;if("string"!=typeof e?n="key must be a string":0===e.length?n="key cannot be the empty string":1+o+e.length>755?n="key is too long to be stored in Firebase":/[\[\].#$\/\u0000-\u001F\u007F]/.test(e)&&(n="key cannot contain any of the following characters: . # $ ] [ /"),"undefined"!=typeof n)throw new Error("Invalid GeoFire key '"+e+"': "+n)},v=function(e){var n;if(Array.isArray(e))if(2!==e.length)n="expected array of length 2, got length "+e.length;else{var t=e[0],r=e[1];"number"!=typeof t||isNaN(t)?n="latitude must be a number":-90>t||t>90?n="latitude must be within the range [-90, 90]":"number"!=typeof r||isNaN(r)?n="longitude must be a number":(-180>r||r>180)&&(n="longitude must be within the range [-180, 180]")}else n="location must be an array";if("undefined"!=typeof n)throw new Error("Invalid GeoFire location '"+e+"': "+n)},m=function(e){var n;if("string"!=typeof e)n="geohash must be a string";else if(0===e.length)n="geohash cannot be the empty string";else for(var t=0,r=e.length;r>t;++t)-1===a.indexOf(e[t])&&(n='geohash cannot contain "'+e[t]+'"');if("undefined"!=typeof n)throw new Error("Invalid GeoFire geohash '"+e+"': "+n)},b=function(e,n){if("object"!=typeof e)throw new Error("query criteria must be an object");if("undefined"==typeof e.center&&"undefined"==typeof e.radius)throw new Error("radius and/or center must be specified");if(n&&("undefined"==typeof e.center||"undefined"==typeof e.radius))throw new Error("query criteria for a new query must contain both a center and a radius");for(var t=Object.keys(e),r=t.length,i=0;r>i;++i){var o=t[i];if("center"!==o&&"radius"!==o)throw new Error("Unexpected attribute '"+o+"'' found in query criteria")}if("undefined"!=typeof e.center&&v(e.center),"undefined"!=typeof e.radius){if("number"!=typeof e.radius||isNaN(e.radius))throw new Error("radius must be a number");if(e.radius<0)throw new Error("radius must be greater than or equal to 0")}},g=function(e){if("number"!=typeof e||isNaN(e))throw new Error("Error: degrees must be a number");return e*Math.PI/180},p=function(e,n){if(v(e),"undefined"!=typeof n){if("number"!=typeof n||isNaN(n))throw new Error("precision must be a number");if(0>=n)throw new Error("precision must be greater than 0");if(n>22)throw new Error("precision cannot be greater than 22");if(Math.round(n)!==n)throw new Error("precision must be an integer")}n=n||o;for(var t={min:-90,max:90},r={min:-180,max:180},i="",u=0,f=0,c=1;i.lengthd?(u=(u<<1)+1,s.min=d):(u=(u<<1)+0,s.max=d),c=!c,4>f?f++:(f=0,i+=a[u],u=0)}return i},w=function(e,n){var t=g(n),r=Math.cos(t)*s*Math.PI/180,i=1/Math.sqrt(1-d*Math.sin(t)*Math.sin(t)),o=r*i;return h>o?e>0?360:0:Math.min(360,e/o)},k=function(e,n){var t=w(e,n);return Math.abs(t)>1e-6?Math.max(1,Math.log2(360/t)):1},M=function(e){return Math.min(Math.log2(u/2/e),l)},E=function(e){if(180>=e&&e>=-180)return e;var n=e+180;return n>0?n%360-180:180- -n%360},O=function(e,n){var t=n/f,r=Math.min(90,e[0]+t),i=Math.max(-90,e[0]-t),o=2*Math.floor(M(n)),a=2*Math.floor(k(n,r))-1,u=2*Math.floor(k(n,i))-1;return Math.min(o,a,u,l)},x=function(e,n){var t=n/f,r=Math.min(90,e[0]+t),i=Math.max(-90,e[0]-t),o=w(n,r),a=w(n,i),u=Math.max(o,a);return[[e[0],e[1]],[e[0],E(e[1]-u)],[e[0],E(e[1]+u)],[r,e[1]],[r,E(e[1]-u)],[r,E(e[1]+u)],[i,e[1]],[i,E(e[1]-u)],[i,E(e[1]+u)]]},_=function(e,n){m(e);var t=Math.ceil(n/c);if(e.length>u<31?[r+a[f],r+"~"]:[r+a[f],r+a[l]]},j=function(e,n){v(e);var t=Math.max(1,O(e,n)),r=Math.ceil(t/c),i=x(e,n),o=i.map(function(e){return _(p(e,r),t)});return o.filter(function(e,n){return!o.some(function(t,r){return n>r&&e[0]===t[0]&&e[1]===t[1]})})},F=function(e,a){function u(e,n,t,r,i){_[e].forEach(function(e){"undefined"==typeof t||null===t?e(n,null,null,null):e(n,t,r,i)})}function f(){_.ready.forEach(function(e){e()})}function c(e){var n=e.split(":");if(2!==n.length)throw new Error("Invalid internal state! Not a valid geohash query: "+e);return n}function l(e){if(2!==e.length)throw new Error("Not a valid geohash query: "+e);return e[0]+":"+e[1]}function s(e,n){var t=x.orderByChild("g").startAt(e[0]).endAt(e[1]);t.off("child_added",n.childAddedCallback),t.off("child_removed",n.childRemovedCallback),t.off("child_changed",n.childChangedCallback),t.off("value",n.valueCallback)}function d(){for(var e=Object.keys(I),n=e.length,t=0;n>t;++t){var r=e[t],i=I[r];if(i.active===!1){var o=c(r);s(o,i),delete I[r]}}for(e=Object.keys(C),n=e.length,t=0;n>t;++t){var a=e[t];if(!y(C[a].geohash)){if(C[a].isInQuery)throw new Error("Internal State error, trying to remove location that is still in query");delete C[a]}}P=!1,null!==q&&(clearTimeout(q),q=null)}function h(e,n,t){v(n);var r,a,f=C.hasOwnProperty(e)?C[e].isInQuery:!1,c=C.hasOwnProperty(e)?C[e].location:null;r=i.distance(n,A),a=Q>=r,C[e]={location:n,data:t,distanceFromCenter:r,isInQuery:a,geohash:p(n,o)},a&&!f?u("key_entered",e,n,r,t):!a||null===c||n[0]===c[0]&&n[1]===c[1]?!a&&f&&u("key_exited",e,n,r):u("key_moved",e,n,r,t)}function y(e){for(var n=Object.keys(I),t=n.length,r=0;t>r;++r){var i=n[r];if(I.hasOwnProperty(i)){var o=c(i);if(e>=o[0]&&e<=o[1])return!0}}return!1}function m(e,n){var t=C[e];if(delete C[e],"undefined"!=typeof t&&t.isInQuery){var r=n?i.distance(n,A):null;u("key_exited",e,n,r)}}function g(e){var r=e.val();h(e.key(),t(r),n(r))}function w(e){var r=e.val();h(e.key(),t(r),n(r))}function k(e){var n=e.key();C.hasOwnProperty(n)&&x.child(n).once("value",function(e){var r=null===e.val()?null:t(e.val()),i=null!==r?p(r):null;y(i)||m(n,r)})}function M(e){var n=O.indexOf(e);n>-1&&O.splice(n,1),F=0===O.length,F&&f()}function E(){var e=j(A,1e3*Q).map(l);e=e.filter(function(n,t){return e.indexOf(n)===t});for(var n=Object.keys(I),t=n.length,r=0;t>r;++r){var i=n[r],o=e.indexOf(i);-1===o?I[i].active=!1:(I[i].active=!0,e.splice(o,1))}P===!1&&Object.keys(I).length>25&&(P=!0,q=setTimeout(d,10)),O=e.slice(),e.forEach(function(e){var n=c(e),t=x.orderByChild("g").startAt(n[0]).endAt(n[1]),r=t.on("child_added",g),i=t.on("child_removed",k),o=t.on("child_changed",w),a=t.on("value",function(){t.off("value",a),M(e)});I[e]={active:!0,childAddedCallback:r,childRemovedCallback:i,childChangedCallback:o,valueCallback:a}}),0===e.length&&M()}if(this.center=function(){return A},this.radius=function(){return Q},this.updateCriteria=function(e){b(e),A=e.center||A,Q=e.radius||Q;for(var n=Object.keys(C),t=n.length,r=0;t>r;++r){var o=n[r],a=C[o],f=a.isInQuery;a.distanceFromCenter=i.distance(a.location,A),a.isInQuery=a.distanceFromCenter<=Q,f&&!a.isInQuery?u("key_exited",o,a.location,a.distanceFromCenter):!f&&a.isInQuery&&u("key_entered",o,a.location,a.distanceFromCenter,a.data)}F=!1,E()},this.on=function(e,n){if(-1===["ready","key_entered","key_exited","key_moved"].indexOf(e))throw new Error('event type must be "ready", "key_entered", "key_exited", or "key_moved"');if("function"!=typeof n)throw new Error("callback must be a function");if(_[e].push(n),"key_entered"===e)for(var t=Object.keys(C),i=t.length,o=0;i>o;++o){var a=t[o],u=C[a];"undefined"!=typeof u&&u.isInQuery&&n(a,u.location,u.distanceFromCenter,u.data)}return"ready"===e&&F&&n(),new r(function(){_[e].splice(_[e].indexOf(n),1)})},this.cancel=function(){_={ready:[],key_entered:[],key_exited:[],key_moved:[]};for(var e=Object.keys(I),n=e.length,t=0;n>t;++t){var r=e[t],i=c(r);s(i,I[r]),delete I[r]}C={},clearInterval(N)},"[object Object]"!==Object.prototype.toString.call(e))throw new Error("firebaseRef must be an instance of Firebase");var O,x=e,_={ready:[],key_entered:[],key_exited:[],key_moved:[]},F=!1,C={},I={},P=!1,q=null,N=setInterval(function(){P===!1&&d()},1e4);b(a,!0);var A=a.center,Q=a.radius;E()};return i}();"undefined"!=typeof module&&"undefined"!=typeof process&&(module.exports=GeoFire); \ No newline at end of file +var GeoFire=function(){"use strict";function e(e,n,t){return"undefined"==typeof t&&(t=null),g(e),m(n),{".priority":n,g:n,l:e,d:t}}function n(e){return null!==e&&e.hasOwnProperty("d")?e.d:null}function t(e){if(null!==e&&e.hasOwnProperty("l")&&Array.isArray(e.l)&&2===e.l.length)return e.l;throw new Error("Unexpected GeoFire location object encountered: "+JSON.stringify(e))}function r(e){var n;return n="function"==typeof e.key?e.key():"string"==typeof e.key||null===e.key?e.key:e.name()}var i=function(e){if(this.cancel=function(){"undefined"!=typeof n&&(n(),n=void 0)},"function"!=typeof e)throw new Error("callback must be a function");var n=e},a=function(r){if(this.ref=function(){return i},this.set=function(n,t,r){var a;if("string"==typeof n&&0!==n.length)a={},a[n]=t;else{if("object"!=typeof n)throw new Error("keyOrLocations must be a string or a mapping of key - location pairs.");if("undefined"!=typeof t)throw new Error("The location argument should not be used if you pass an object to set().");a=n}var o={};return Object.keys(a).forEach(function(n){v(n);var t=a[n];if(null===t)o[n]=null;else{g(t);var i=w(t);o[n]=e(t,i,r)}}),i.update(o)},this.get=function(e){return v(e),i.child(e).once("value").then(function(e){var n=e.val();return null===n?null:t(n)})},this.getWithData=function(e){return v(e),i.child(e).once("value").then(function(r){var i=r.val();return null===i?null:{key:e,location:t(i),data:n(i)}})},this.remove=function(e){return this.set(e,null)},this.query=function(e){return new I(i,e)},"[object Object]"!==Object.prototype.toString.call(r))throw new Error("firebaseRef must be an instance of Firebase");var i=r};a.distance=function(e,n){g(e),g(n);var t=6371,r=p(n[0]-e[0]),i=p(n[1]-e[1]),a=Math.sin(r/2)*Math.sin(r/2)+Math.cos(p(e[0]))*Math.cos(p(n[0]))*Math.sin(i/2)*Math.sin(i/2),o=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));return t*o};var o=10,u="0123456789bcdefghjkmnpqrstuvwxyz",f=40007860,c=110574,l=5,s=22*l,d=6378137,h=.00669447819799,y=1e-12;Math.log2=Math.log2||function(e){return Math.log(e)/Math.log(2)};var v=function(e){var n;if("string"!=typeof e?n="key must be a string":0===e.length?n="key cannot be the empty string":1+o+e.length>755?n="key is too long to be stored in Firebase":/[\[\].#$\/\u0000-\u001F\u007F]/.test(e)&&(n="key cannot contain any of the following characters: . # $ ] [ /"),"undefined"!=typeof n)throw new Error("Invalid GeoFire key '"+e+"': "+n)},g=function(e){var n;if(Array.isArray(e))if(2!==e.length)n="expected array of length 2, got length "+e.length;else{var t=e[0],r=e[1];"number"!=typeof t||isNaN(t)?n="latitude must be a number":-90>t||t>90?n="latitude must be within the range [-90, 90]":"number"!=typeof r||isNaN(r)?n="longitude must be a number":(-180>r||r>180)&&(n="longitude must be within the range [-180, 180]")}else n="location must be an array";if("undefined"!=typeof n)throw new Error("Invalid GeoFire location '"+e+"': "+n)},m=function(e){var n;if("string"!=typeof e)n="geohash must be a string";else if(0===e.length)n="geohash cannot be the empty string";else for(var t=0,r=e.length;r>t;++t)-1===u.indexOf(e[t])&&(n='geohash cannot contain "'+e[t]+'"');if("undefined"!=typeof n)throw new Error("Invalid GeoFire geohash '"+e+"': "+n)},b=function(e,n){if("object"!=typeof e)throw new Error("query criteria must be an object");if("undefined"==typeof e.center&&"undefined"==typeof e.radius)throw new Error("radius and/or center must be specified");if(n&&("undefined"==typeof e.center||"undefined"==typeof e.radius))throw new Error("query criteria for a new query must contain both a center and a radius");for(var t=Object.keys(e),r=t.length,i=0;r>i;++i){var a=t[i];if("center"!==a&&"radius"!==a)throw new Error("Unexpected attribute '"+a+"'' found in query criteria")}if("undefined"!=typeof e.center&&g(e.center),"undefined"!=typeof e.radius){if("number"!=typeof e.radius||isNaN(e.radius))throw new Error("radius must be a number");if(e.radius<0)throw new Error("radius must be greater than or equal to 0")}},p=function(e){if("number"!=typeof e||isNaN(e))throw new Error("Error: degrees must be a number");return e*Math.PI/180},w=function(e,n){if(g(e),"undefined"!=typeof n){if("number"!=typeof n||isNaN(n))throw new Error("precision must be a number");if(0>=n)throw new Error("precision must be greater than 0");if(n>22)throw new Error("precision cannot be greater than 22");if(Math.round(n)!==n)throw new Error("precision must be an integer")}n=n||o;for(var t={min:-90,max:90},r={min:-180,max:180},i="",a=0,f=0,c=1;i.lengthd?(a=(a<<1)+1,s.min=d):(a=(a<<1)+0,s.max=d),c=!c,4>f?f++:(f=0,i+=u[a],a=0)}return i},k=function(e,n){var t=p(n),r=Math.cos(t)*d*Math.PI/180,i=1/Math.sqrt(1-h*Math.sin(t)*Math.sin(t)),a=r*i;return y>a?e>0?360:0:Math.min(360,e/a)},M=function(e,n){var t=k(e,n);return Math.abs(t)>1e-6?Math.max(1,Math.log2(360/t)):1},E=function(e){return Math.min(Math.log2(f/2/e),s)},O=function(e){if(180>=e&&e>=-180)return e;var n=e+180;return n>0?n%360-180:180- -n%360},x=function(e,n){var t=n/c,r=Math.min(90,e[0]+t),i=Math.max(-90,e[0]-t),a=2*Math.floor(E(n)),o=2*Math.floor(M(n,r))-1,u=2*Math.floor(M(n,i))-1;return Math.min(a,o,u,s)},_=function(e,n){var t=n/c,r=Math.min(90,e[0]+t),i=Math.max(-90,e[0]-t),a=k(n,r),o=k(n,i),u=Math.max(a,o);return[[e[0],e[1]],[e[0],O(e[1]-u)],[e[0],O(e[1]+u)],[r,e[1]],[r,O(e[1]-u)],[r,O(e[1]+u)],[i,e[1]],[i,O(e[1]-u)],[i,O(e[1]+u)]]},j=function(e,n){m(e);var t=Math.ceil(n/l);if(e.length>o<31?[r+u[f],r+"~"]:[r+u[f],r+u[c]]},C=function(e,n){g(e);var t=Math.max(1,x(e,n)),r=Math.ceil(t/l),i=_(e,n),a=i.map(function(e){return j(w(e,r),t)});return a.filter(function(e,n){return!a.some(function(t,r){return n>r&&e[0]===t[0]&&e[1]===t[1]})})},I=function(e,u){function f(e,n,t,r,i){j[e].forEach(function(e){"undefined"==typeof t||null===t?e(n,null,null,null):e(n,t,r,i)})}function c(){j.ready.forEach(function(e){e()})}function l(e){var n=e.split(":");if(2!==n.length)throw new Error("Invalid internal state! Not a valid geohash query: "+e);return n}function s(e){if(2!==e.length)throw new Error("Not a valid geohash query: "+e);return e[0]+":"+e[1]}function d(e,n){var t=_.orderByChild("g").startAt(e[0]).endAt(e[1]);t.off("child_added",n.childAddedCallback),t.off("child_removed",n.childRemovedCallback),t.off("child_changed",n.childChangedCallback),t.off("value",n.valueCallback)}function h(){for(var e=Object.keys(N),n=e.length,t=0;n>t;++t){var r=e[t],i=N[r];if(i.active===!1){var a=l(r);d(a,i),delete N[r]}}for(e=Object.keys(q),n=e.length,t=0;n>t;++t){var o=e[t];if(!v(q[o].geohash)){if(q[o].isInQuery)throw new Error("Internal State error, trying to remove location that is still in query");delete q[o]}}A=!1,null!==Q&&(clearTimeout(Q),Q=null)}function y(e,n,t){g(n);var r,i,u=q.hasOwnProperty(e)?q[e].isInQuery:!1,c=q.hasOwnProperty(e)?q[e].location:null;r=a.distance(n,G),i=R>=r,q[e]={location:n,data:t,distanceFromCenter:r,isInQuery:i,geohash:w(n,o)},i&&!u?f("key_entered",e,n,r,t):!i||null===c||n[0]===c[0]&&n[1]===c[1]?!i&&u&&f("key_exited",e,n,r):f("key_moved",e,n,r,t)}function v(e){for(var n=Object.keys(N),t=n.length,r=0;t>r;++r){var i=n[r];if(N.hasOwnProperty(i)){var a=l(i);if(e>=a[0]&&e<=a[1])return!0}}return!1}function m(e,n){var t=q[e];if(delete q[e],"undefined"!=typeof t&&t.isInQuery){var r=n?a.distance(n,G):null;f("key_exited",e,n,r)}}function p(e){var i=e.val();y(r(e),t(e.val()),n(i))}function k(e){var i=e.val();y(r(e),t(i),n(i))}function M(e){var n=r(e);q.hasOwnProperty(n)&&_.child(n).once("value",function(e){var r=null===e.val()?null:t(e.val()),i=null!==r?w(r):null;v(i)||m(n,r)})}function E(e){var n=x.indexOf(e);n>-1&&x.splice(n,1),F=0===x.length,F&&c()}function O(){var e=C(G,1e3*R).map(s);e=e.filter(function(n,t){return e.indexOf(n)===t});for(var n=Object.keys(N),t=n.length,r=0;t>r;++r){var i=n[r],a=e.indexOf(i);-1===a?N[i].active=!1:(N[i].active=!0,e.splice(a,1))}A===!1&&Object.keys(N).length>25&&(A=!0,Q=setTimeout(h,10)),x=e.slice(),e.forEach(function(e){var n=l(e),t=_.orderByChild("g").startAt(n[0]).endAt(n[1]),r=t.on("child_added",p),i=t.on("child_removed",M),a=t.on("child_changed",k),o=t.on("value",function(){t.off("value",o),E(e)});N[e]={active:!0,childAddedCallback:r,childRemovedCallback:i,childChangedCallback:a,valueCallback:o}}),0===e.length&&E()}if(this.center=function(){return G},this.radius=function(){return R},this.updateCriteria=function(e){b(e),G=e.center||G,R=e.radius||R;for(var n=Object.keys(q),t=n.length,r=0;t>r;++r){var i=n[r];if(I===!0)break;var o=q[i],u=o.isInQuery;o.distanceFromCenter=a.distance(o.location,G),o.isInQuery=o.distanceFromCenter<=R,u&&!o.isInQuery?f("key_exited",i,o.location,o.distanceFromCenter):!u&&o.isInQuery&&f("key_entered",i,o.location,o.distanceFromCenter,o.data)}F=!1,O()},this.on=function(e,n){if(-1===["ready","key_entered","key_exited","key_moved"].indexOf(e))throw new Error('event type must be "ready", "key_entered", "key_exited", or "key_moved"');if("function"!=typeof n)throw new Error("callback must be a function");if(j[e].push(n),"key_entered"===e)for(var t=Object.keys(q),r=t.length,a=0;r>a;++a){var o=t[a],u=q[o];"undefined"!=typeof u&&u.isInQuery&&n(o,u.location,u.distanceFromCenter,u.data)}return"ready"===e&&F&&n(),new i(function(){j[e].splice(j[e].indexOf(n),1)})},this.cancel=function(){I=!0,j={ready:[],key_entered:[],key_exited:[],key_moved:[]};for(var e=Object.keys(N),n=e.length,t=0;n>t;++t){var r=e[t],i=l(r);d(i,N[r]),delete N[r]}q={},clearInterval(P)},"[object Object]"!==Object.prototype.toString.call(e))throw new Error("firebaseRef must be an instance of Firebase");var x,_=e,j={ready:[],key_entered:[],key_exited:[],key_moved:[]},I=!1,F=!1,q={},N={},A=!1,Q=null,P=setInterval(function(){A===!1&&h()},1e4);b(u,!0);var G=u.center,R=u.radius;O()};return a}();"undefined"!=typeof module&&"undefined"!=typeof process&&(module.exports=GeoFire); \ No newline at end of file