user has a google map displayed no. almost finished with loading coordinates into that map with the appropriate events. events are now ordered and scrollable. Decent UI. going to deploy once the coordinates display.
diff --git a/app.js b/app.js
index 756c216..ac571ea 100644
--- a/app.js
+++ b/app.js
@@ -2,8 +2,9 @@ var express = require('express');
 var app     = express();
 var server  = require('http').createServer(app);
 var Eventbrite = require('eventbrite');
+var _ = require('underscore-node');
+var geolib = require('geolib');
 var eb_client = Eventbrite({'app_key':"XJ3KBH3I7V6GGQYXCD", 'user_key':"137997416174003270775"});
-
 console.log("Node server started on port 5000");

 app.use('/', express.static(__dirname + '/'));
@@ -13,8 +14,24 @@ app.get('/', function(req,res) {
 });

 app.get('/search/:location/:category?/:keywords?', function(req, res){
-  var params = {'within': 20, 'within_unit': 'K' , 'category': req.params.category, 'keywords': req.params.keywords, 'city': req.params.location};
+  var params = {'category': req.params.category, 'keywords': req.params.keywords, 'city': req.params.location};
   eb_client.event_search( params, function(err, data){
+    if(data){data.events.splice(0,1);
+      for (var eventIndex = 1; eventIndex < data.events.length; eventIndex++){
+        var result = geolib.getDistance(
+          {latitude: data.events[0].event.venue.latitude, longitude: data.events[0].event.venue.longitude},
+          {latitude: data.events[eventIndex].event.venue.latitude, longitude: data.events[eventIndex].event.venue.longitude}
+          );
+        if (result <= 20000){
+          data.events[eventIndex].event.distance = result/1000
+        } else {
+          data.events.splice(eventIndex,1);
+        }
+      }
+      data.events = _.sortBy(data.events, function(obj){
+        return obj.event.distance;
+      })
+    }
     res.send(data);
   });
 })
diff --git a/index.html b/index.html
index 30fadd1..3fb72d9 100644
--- a/index.html
+++ b/index.html
@@ -9,30 +9,49 @@
   <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
     <link rel="stylesheet" href="reset.css">
     <link rel="stylesheet" href="web.css">
+  <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
+
+  <script type="text/javascript"
+  src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCFRTRTFJiInfGiTyJXadWE3RxSoaNFd4c">
+  </script>
+    <script src="map.js"></script>
     <script src="script.js"></script>
 </head>
 <body>
   <div id='search' ng-controller="searchCtrl">
-    <form id='sendstuff' action='search' method='get'>
-      <select id='category' ng-model="categories[11]" ng-options = 'category for category in categories'></select>
-      <input id='keywords' type='text' placeholder = 'Enter Keywords'/>
-      <input id='location' type='text' value = 'San Francisco'/>
-      <input type="submit" value="Submit" />
+    <form role="form" id='sendstuff' action='search' method='get'>
+      <div class="form-group">
+        <label>Category: </label>
+        <select id='category' ng-model="categories[12]" ng-options = 'category for category in categories'></select>
+      </div>
+      <div class="form-group">
+        <label>Keywords: </label>
+        <input id='keywords' class="form-control" type='text' placeholder = 'Enter Keywords'/>
+      </div>
+      <div class="form-group">
+        <label>City: </label>
+        <input id='location' class="form-control" type='text' value = 'San Francisco'/>
+      </div>
+      <button type="submit" class="btn btn-default">Submit</button>
     </form>
   </div>

-  <div id='display' ng-controller = 'displayCtrl'>
-    <div ng-repeat = 'event in events track by $index | limitTo:10'>
-      <img width = '100px' height = '50px' ng-src = '{{event.logo}}'/>
-      <h3><a ng-href = "{{event.url}}">{{event.eventTitle}}</a>
-        {{event.price}}
-        {{event.address}}
-        {{event.addressName}}
-        {{event.addressCity}}
-        {{event.time}}
-        {{event.timeZone}}
-        {{event.distance}}
+  <div id='display' class="panel panel-default" ng-controller = 'displayCtrl'>
+    <div id = 'event-container'>
+      <div class="panel-body" ng-repeat = 'event in events track by $index | limitTo:10'>
+        <span class = 'event-logo'><img ng-src = '{{event.logo}}'/></span>
+        <span class = 'event-description'><h3><a ng-href = "{{event.url}}">{{event.eventTitle}}</a>
+          <p>${{event.price}}</p>
+          <p>{{event.address}}</p>
+          <p>{{event.addressName}}</p>
+          <p>{{event.addressCity}}</p>
+          <p>{{event.time}} {{event.timeZone}}</p>
+          <p>{{event.distance}} kilometers away</p>
+        </span>
       </div>
     </div>
-  </body>
-  </html>
+    <div class = 'map' id="map-canvas"/>
+  </div>
+
+</body>
+</html>
diff --git a/map.js b/map.js
new file mode 100644
index 0000000..02229c5
--- /dev/null
+++ b/map.js
@@ -0,0 +1,53 @@
+var map;
+function initialize() {
+  var mapOptions = {
+    zoom: 11
+  };
+  map = new google.maps.Map(document.getElementById('map-canvas'),
+    mapOptions);
+
+  // Try HTML5 geolocation
+  if(navigator.geolocation) {
+    navigator.geolocation.getCurrentPosition(function(position) {
+      var pos = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
+      map.setCenter(pos);
+    }, function() {
+      handleNoGeolocation(true);
+    });
+  } else {
+    // Browser doesn't support Geolocation
+    handleNoGeolocation(false);
+  }
+}
+
+function setMarkers(map, locations) {
+  for (var i = 0; i < locations.length; i++) {
+    var beach = locations[i];
+    var myLatLng = new google.maps.LatLng(locations[i][1], locations[i][2]);
+    var marker = new google.maps.Marker({
+      position: myLatLng,
+      map: map,
+      title: locations[i][0]
+    });
+  }
+}
+
+
+function handleNoGeolocation(errorFlag) {
+  if (errorFlag) {
+    var content = 'Error: The Geolocation service failed.';
+  } else {
+    var content = 'Error: Your browser doesn\'t support geolocation.';
+  }
+
+  var options = {
+    map: map,
+    position: new google.maps.LatLng(60, 105),
+    content: content
+  };
+
+  var infowindow = new google.maps.InfoWindow(options);
+  map.setCenter(options.position);
+}
+
+google.maps.event.addDomListener(window, 'load', initialize);
diff --git a/node_modules/geolib/README.md b/node_modules/geolib/README.md
new file mode 100644
index 0000000..2749f5b
--- /dev/null
+++ b/node_modules/geolib/README.md
@@ -0,0 +1,262 @@
+# Geolib v2.0.14
+[![Build Status](https://secure.travis-ci.org/manuelbieh/Geolib.png?branch=master)](http://travis-ci.org/manuelbieh/Geolib)
+
+Library to provide basic geospatial operations like distance calculation, conversion of decimal coordinates to sexagesimal and vice versa, etc.
+
+[View demo](http://www.manuel-bieh.de/publikationen/scripts/geolib/demo.html)
+
+<h2>Methods</h2>
+
+<h3>geolib.getDistance(object start, object end[, int accuracy])</h3>
+
+Calculates the distance between two geo coordinates
+
+Takes 2 or 3 arguments. First 2 arguments must be an object with latitude and a longitude properties (e.g. `{latitude: 52.518611, longitude: 13.408056}`). Coordinates can be in sexagesimal or decimal format. 3rd argument is accuracy (in meters). So a calculated distance of 1248 meters with an accuracy of 100 is returned as `1200` (accuracy 10 = `1250` etc.).
+
+Return value is always an integer and represents the distance in meters.
+
+<h4>Examples</h4>
+
+<pre>geolib.getDistance(
+	{latitude: 51.5103, longitude: 7.49347},
+	{latitude: "51° 31' N", longitude: "7° 28' E"}
+);
+geolib.getDistance(
+	{latitude: 51.5103, longitude: 7.49347},
+	{latitude: "51° 31' N", longitude: "7° 28' E"}
+);
+
+// Working with W3C Geolocation API
+navigator.geolocation.getCurrentPosition(
+	function(position) {
+		alert('You are ' + geolib.getDistance(position.coords, {
+			latitude: 51.525,
+			longitude: 7.4575
+		}) + ' meters away from 51.525, 7.4575');
+	},
+	function() {
+		alert('Position could not be determined.')
+	},
+	{
+		enableHighAccuracy: true
+	}
+);
+</pre>
+
+<h3>geolib.getCenter(array coords)</h3>
+
+Calculates the geographical center of all points in a collection of geo coordinates
+
+Takes an object or array of coordinates and calculates the center of it.
+
+Returns an object: `{"latitude": centerLat, "longitude": centerLng, "distance": diagonalDistance}`
+
+<h4>Examples</h4>
+
+<pre>var spots = {
+	"Brandenburg Gate, Berlin": {latitude: 52.516272, longitude: 13.377722},
+	"Dortmund U-Tower": {latitude: 51.515, longitude: 7.453619},
+	"London Eye": {latitude: 51.503333, longitude: -0.119722},
+	"Kremlin, Moscow": {latitude: 55.751667, longitude: 37.617778},
+	"Eiffel Tower, Paris": {latitude: 48.8583, longitude: 2.2945},
+	"Riksdag building, Stockholm": {latitude: 59.3275, longitude: 18.0675},
+	"Royal Palace, Oslo": {latitude: 59.916911, longitude: 10.727567}
+}
+
+geolib.getCenter(spots);
+
+geolib.getCenter([
+	{latitude: 52.516272, longitude: 13.377722},
+	{latitude: 51.515, longitude: 7.453619},
+	{latitude: 51.503333, longitude: -0.119722}
+]);
+</pre>
+
+<h3>geolib.isPointInside(object latlng, array coords)</h3>
+
+Checks whether a point is inside of a polygon or not.
+Note: the polygon coords must be in correct order!
+
+Returns true or false
+
+<h4>Example</h4>
+
+<pre>
+geolib.isPointInside(
+	{latitude: 51.5125, longitude: 7.485},
+	[
+		{latitude: 51.50, longitude: 7.40},
+		{latitude: 51.555, longitude: 7.40},
+		{latitude: 51.555, longitude: 7.625},
+		{latitude: 51.5125, longitude: 7.625}
+	]
+); // -> true</pre>
+
+<h3>geolib.isPointInCircle(object latlng, object center, integer radius)</h3>
+
+Similar to is point inside: checks whether a point is inside of a circle or not.
+
+Returns true or false
+
+<h4>Example</h4>
+
+<pre>// checks if 51.525, 7.4575 is within a radius of 5km from 51.5175, 7.4678
+geolib.isPointInCircle(
+	{latitude: 51.525, longitude: 7.4575},
+	{latitude: 51.5175, longitude: 7.4678},
+	5000
+);</pre>
+
+<h3>geolib.orderByDistance(object latlng, mixed coords)</h3>
+
+Sorts an object or array of coords by distance from a reference coordinate
+
+Returns a sorted array [{latitude: x, longitude: y, distance: z, key: property}]
+
+<h4>Examples</h4>
+
+<pre>
+// coords array
+geolib.orderByDistance({latitude: 51.515, longitude: 7.453619}, [
+	{latitude: 52.516272, longitude: 13.377722},
+	{latitude: 51.518, longitude: 7.45425},
+	{latitude: 51.503333, longitude: -0.119722}
+]);
+
+// coords object
+geolib.orderByDistance({latitude: 51.515, longitude: 7.453619}, {
+	a: {latitude: 52.516272, longitude: 13.377722},
+	b: {latitude: 51.518, longitude: 7.45425},
+	c: {latitude: 51.503333, longitude: -0.119722}
+});
+</pre>
+
+<h3>geolib.findNearest(object latlng, mixed coords[[, int offset], int limit])</h3>
+
+Finds the nearest coordinate to a reference coordinate.
+
+<h4>Examples</h4>
+
+<pre>var spots = {
+	"Brandenburg Gate, Berlin": {latitude: 52.516272, longitude: 13.377722},
+	"Dortmund U-Tower": {latitude: 51.515, longitude: 7.453619},
+	"London Eye": {latitude: 51.503333, longitude: -0.119722},
+	"Kremlin, Moscow": {latitude: 55.751667, longitude: 37.617778},
+	"Eiffel Tower, Paris": {latitude: 48.8583, longitude: 2.2945},
+	"Riksdag building, Stockholm": {latitude: 59.3275, longitude: 18.0675},
+	"Royal Palace, Oslo": {latitude: 59.916911, longitude: 10.727567}
+}
+
+// in this case set offset to 1 otherwise the nearest point will always be your reference point
+geolib.findNearest(spots['Dortmund U-Tower'], spots, 1)
+</pre>
+
+<h3>geolib.getPathLength(mixed coords)</h3>
+
+Calculates the length of a collection of coordinates
+
+Returns the length of the path in meters
+
+<h4>Example</h4>
+
+<pre>
+// Calculate distance from Berlin via Dortmund to London
+geolib.getPathLength([
+	{latitude: 52.516272, longitude: 13.377722}, // Berlin
+	{latitude: 51.515, longitude: 7.453619}, // Dortmund
+	{latitude: 51.503333, longitude: -0.119722} // London
+]); // -> 945235</pre>
+
+<h3>geolib.getSpeed(coords, coords[, options])</h3>
+
+Calculates the speed between two points within a given time span.
+
+Returns the speed in <em>options.unit</em> (default is km/h).
+
+<h4>Example</h4>
+
+<pre>
+geolib.getSpeed(
+	{lat: 51.567294, lng: 7.38896, time: 1360231200880},
+	{lat: 52.54944, lng: 13.468509, time: 1360245600880},
+	{unit: 'mph'}
+); // -> 66.9408 (mph)</pre>
+
+<h3>geolib.convertUnit(string unit, float distance[, int round])</h3>
+
+Converts a given distance (in meters) to another unit.
+
+<h4>Parameters</h4>
+
+`unit` can be one of:
+
+- m (meter)
+- km (kilometers)
+- cm (centimeters)
+- mm (millimeters)
+- mi (miles)
+- sm (seamiles)
+- ft (foot)
+- in (inch)
+- yd (yards)
+
+`distance` distance to be converted (source must be in meter)
+
+`round` fractional digits
+
+<h4>Example</h4>
+
+`geolib.convertUnit('km', 14213, 2) // -> 14,21`
+
+<h3>geolib.sexagesimal2decimal(string coord)</h3>
+
+Converts a sexagesimal coordinate to decimal format
+
+<h4>Example</h4>
+
+`geolib.sexagesimal2decimal("51° 29' 46\" N")`
+
+<h3>geolib.decimal2sexagesimal(float coord)</h3>
+
+Converts a decimal coordinate to sexagesimal format
+
+<h4>Example</h4>
+
+`geolib.decimal2sexagesimal(51.49611111); // -> 51° 29' 46.00`
+
+<h3>geolib.latitude(object latlng)</h3>
+<h3>geolib.longitude(object latlng)</h3>
+<h3>geolib.elevation(object latlng)</h3>
+
+Returns the latitude/longitude/elevation for a given point and converts it to decimal.
+
+Works with:
+- latitude: `latitude`, `lat`, 0 (GeoJSON array)
+- longitude: `longitude`, `lng`, `lon`, 1 (GeoJSON array)
+- elevation: `elevation`, `elev`, `alt`, `altitude`, 2 (GeoJSON array)
+
+<h4>Examples</h4>
+
+`geolib.latitude({lat: 51.49611, lng: 7.38896}); // -> 51.49611`
+`geolib.longitude({lat: 51.49611, lng: 7.38896}); // -> 7.38896`
+
+<h3>geolib.useDecimal(mixed latlng)</h3>
+
+Checks if a coordinate is already in decimal format and, if not, converts it to
+
+<h4>Example</h4>
+
+<pre>geolib.useDecimal("51° 29' 46\" N"); // -> 51.59611111
+geolib.useDecimal(51.59611111) // -> 51.59611111</pre>
+
+<h2>Changelog</h2>
+<h3>v2.0.0+beta1</h3>
+- Dropped support for IE6, IE7, IE8
+- Added new methods `geolib.latitude()`, `geolib.longitude()`, `geolib.elevation()` to get latitude, longitude or elevation of points. Will be converted to decimal format automatically
+- Added new method `geolib.extend()` to extend geolib object
+- Added support for GeoJSON format (`[lon, lat, elev]`)
+- Added property `geolib.version` to query the currently used version
+- Moved `geolib.elevation` to an optional module (`geolib.elevation.js`)
+- Using `Object.create(Geolib.prototype)` instead of object literal `{}`
+- New folder structure: compiled `geolib.js` can now be found in `dist/` instead of root dir
+- Improved Grunt build task
\ No newline at end of file
diff --git a/node_modules/geolib/dist/geolib.elevation.js b/node_modules/geolib/dist/geolib.elevation.js
new file mode 100644
index 0000000..8318b5a
--- /dev/null
+++ b/node_modules/geolib/dist/geolib.elevation.js
@@ -0,0 +1,190 @@
+/*! geolib.elevation 2.0.14 by Manuel Bieh
+*
+* Elevation Addon for Geolib.js
+*
+* @author Manuel Bieh
+* @url http://www.manuelbieh.com/
+* @version 2.0.14
+* @license MIT
+*/
+;(function(global, geolib, undefined) {
+
+	var elevation = {
+
+		/*global google:true geolib:true require:true module:true elevationResult:true */
+
+		/**
+		*  @param      Array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
+		*  @return     Array [{lat:#lat, lng:#lng, elev:#elev},....]}
+		*/
+		getElevation: function() {
+			if (typeof global.navigator !== 'undefined') {
+				this.getElevationClient.apply(this, arguments);
+			} else {
+				this.getElevationServer.apply(this, arguments);
+			}
+		},
+
+
+		/* Optional elevation addon requires Googlemaps API JS */
+		getElevationClient: function(coords, cb) {
+
+			if (!global.google) {
+				throw new Error("Google maps api not loaded");
+			}
+
+			if (coords.length === 0) {
+				return cb(null, null);
+			}
+
+			if (coords.length === 1) {
+				return cb(new Error("getElevation requires at least 2 points."));
+			}
+
+			var path  = [];
+
+			for(var i = 0; i < coords.length; i++) {
+				path.push(new google.maps.LatLng(
+					this.latitude(coords[i]),
+					this.longitude(coords[i])
+				));
+			}
+
+			var positionalRequest = {
+				'path': path,
+				'samples': path.length
+			};
+
+			var elevationService = new google.maps.ElevationService();
+			var geolib = this;
+
+			elevationService.getElevationAlongPath(positionalRequest, function (results, status) {
+				geolib.elevationHandler(results, status, coords, cb);
+			});
+
+		},
+
+
+		getElevationServer: function(coords, cb) {
+
+			if (coords.length === 0) {
+				return cb(null, null);
+			}
+
+			if (coords.length === 1) {
+				return cb(new Error("getElevation requires at least 2 points."));
+			}
+
+			var gm = require('googlemaps');
+			var path  = [];
+
+			for(var i = 0; i < coords.length; i++) {
+				path.push(
+					this.latitude(coords[i]) + ',' + this.longitude(coords[i])
+				);
+			}
+
+			var geolib = this;
+
+			gm.elevationFromPath(path.join('|'), path.length, function(err, results) {
+				geolib.elevationHandler(results.results, results.status, coords, cb);
+			});
+
+		},
+
+
+		elevationHandler: function(results, status, coords, cb) {
+
+			var latsLngsElevs = [];
+
+			if (status == "OK" ) {
+
+				for (var i = 0; i < results.length; i++) {
+					latsLngsElevs.push({
+						"lat": this.latitude(coords[i]),
+						"lng": this.longitude(coords[i]),
+						"elev":results[i].elevation
+					});
+				}
+
+				cb(null, latsLngsElevs);
+
+			} else {
+
+				cb(new Error("Could not get elevation using Google's API"), elevationResult.status);
+
+			}
+
+		},
+
+
+		/**
+		*  @param      Array [{lat:#lat, lng:#lng, elev:#elev},....]}
+		*  @return     Number % grade
+		*/
+		getGrade: function(coords) {
+
+			var rise = Math.abs(
+				this.elevation(coords[coords.length-1]) - this.elevation(coords[0])
+			);
+
+			var run = this.getPathLength(coords);
+
+			return Math.floor((rise/run)*100);
+
+		},
+
+
+		/**
+		*  @param      Array [{lat:#lat, lng:#lng, elev:#elev},....]}
+		*  @return     Object {gain:#gain, loss:#loss}
+		*/
+		getTotalElevationGainAndLoss: function(coords) {
+
+			var gain = 0;
+			var loss = 0;
+
+			for(var i = 0; i < coords.length - 1; i++) {
+
+				var deltaElev = this.elevation(coords[i]) - this.elevation(coords[i + 1]);
+
+				if (deltaElev > 0) {
+					loss += deltaElev;
+				} else {
+					gain += Math.abs(deltaElev);
+				}
+
+			}
+
+			return {
+				"gain": gain,
+				"loss": loss
+			};
+
+		}
+
+	};
+
+	// Node module
+	if (typeof module !== 'undefined' &&
+		typeof module.exports !== 'undefined') {
+
+		geolib = require('geolib');
+		geolib.extend(elevation);
+
+	// AMD module
+	} else if (typeof define === "function" && define.amd) {
+
+		define(["geolib"], function (geolib) {
+			geolib.extend(elevation);
+			return geolib;
+		});
+
+	// we're in a browser
+	} else {
+
+		geolib.extend(elevation);
+
+	}
+
+}(this, this.geolib));
\ No newline at end of file
diff --git a/node_modules/geolib/dist/geolib.js b/node_modules/geolib/dist/geolib.js
new file mode 100644
index 0000000..b51b79c
--- /dev/null
+++ b/node_modules/geolib/dist/geolib.js
@@ -0,0 +1,1150 @@
+/*! geolib 2.0.14 by Manuel Bieh
+* Library to provide geo functions like distance calculation,
+* conversion of decimal coordinates to sexagesimal and vice versa, etc.
+* WGS 84 (World Geodetic System 1984)
+*
+* @author Manuel Bieh
+* @url http://www.manuelbieh.com/
+* @version 2.0.14
+* @license MIT
+**/;(function(global, undefined) {
+
+	"use strict";
+
+	function Geolib() {}
+
+	// Setting readonly defaults
+	var geolib = Object.create(Geolib.prototype, {
+		version: {
+			value: "2.0.14"
+		},
+		radius: {
+			value: 6378137
+		},
+		minLat: {
+			value: -90
+		},
+		maxLat: {
+			value: 90
+		},
+		minLon: {
+			value: -180
+		},
+		maxLon: {
+			value: 180
+		},
+		sexagesimalPattern: {
+			value: /^([0-9]{1,3})°\s*([0-9]{1,3}(?:\.(?:[0-9]{1,2}))?)'\s*(([0-9]{1,3}(\.([0-9]{1,2}))?)"\s*)?([NEOSW]?)$/
+		},
+		measures: {
+			value: Object.create(Object.prototype, {
+				"m" : {value: 1},
+				"km": {value: 0.001},
+				"cm": {value: 100},
+				"mm": {value: 1000},
+				"mi": {value: (1 / 1609.344)},
+				"sm": {value: (1 / 1852.216)},
+				"ft": {value: (100 / 30.48)},
+				"in": {value: (100 / 2.54)},
+				"yd": {value: (1 / 0.9144)}
+			})
+		},
+		prototype: {
+			value: Geolib.prototype
+		},
+		extend: {
+			value: function(methods, overwrite) {
+				for(var prop in methods) {
+					if(typeof geolib.prototype[prop] === 'undefined' || overwrite === true) {
+						geolib.prototype[prop] = methods[prop];
+					}
+				}
+			}
+		}
+	});
+
+	if (typeof(Number.prototype.toRad) === "undefined") {
+		Number.prototype.toRad = function() {
+			return this * Math.PI / 180;
+		};
+	}
+
+	if (typeof(Number.prototype.toDeg) === "undefined") {
+		Number.prototype.toDeg = function() {
+			return this * 180 / Math.PI;
+		};
+	}
+
+	// Here comes the magic
+	geolib.extend({
+
+		decimal: {},
+
+		sexagesimal: {},
+
+		distance: null,
+
+		getKeys: function(point) {
+
+			// GeoJSON Array [longitude, latitude(, elevation)]
+			if(Object.prototype.toString.call(point) == '[object Array]') {
+
+				return {
+					longitude: point.length >= 1 ? 0 : undefined,
+					latitude: point.length >= 2 ? 1 : undefined,
+					elevation: point.length >= 3 ? 2 : undefined
+				};
+
+			}
+
+			var getKey = function(possibleValues) {
+
+				var key;
+
+				possibleValues.every(function(val) {
+					// TODO: check if point is an object
+					if(typeof point != 'object') {
+						return true;
+					}
+					return point.hasOwnProperty(val) ? (function() { key = val; return false; }()) : true;
+				});
+
+				return key;
+
+			};
+
+			var longitude = getKey(['lng', 'lon', 'longitude']);
+			var latitude = getKey(['lat', 'latitude']);
+			var elevation = getKey(['alt', 'altitude', 'elevation', 'elev']);
+
+			// return undefined if not at least one valid property was found
+			if(typeof latitude == 'undefined' &&
+				typeof longitude == 'undefined' &&
+				typeof elevation == 'undefined') {
+				return undefined;
+			}
+
+			return {
+				latitude: latitude,
+				longitude: longitude,
+				elevation: elevation
+			};
+
+		},
+
+		// returns latitude of a given point, converted to decimal
+		// set raw to true to avoid conversion
+		getLat: function(point, raw) {
+			return raw === true ? point[this.getKeys(point).latitude] : this.useDecimal(point[this.getKeys(point).latitude]);
+		},
+
+		// Alias for getLat
+		latitude: function(point) {
+			return this.getLat.call(this, point);
+		},
+
+		// returns longitude of a given point, converted to decimal
+		// set raw to true to avoid conversion
+		getLon: function(point, raw) {
+			return raw === true ? point[this.getKeys(point).longitude] : this.useDecimal(point[this.getKeys(point).longitude]);
+		},
+
+		// Alias for getLon
+		longitude: function(point) {
+			return this.getLon.call(this, point);
+		},
+
+		getElev: function(point) {
+			return point[this.getKeys(point).elevation];
+		},
+
+		// Alias for getElev
+		elevation: function(point) {
+			return this.getElev.call(this, point);
+		},
+
+		coords: function(point, raw) {
+
+			var retval = {
+				latitude: raw === true ? point[this.getKeys(point).latitude] : this.useDecimal(point[this.getKeys(point).latitude]),
+				longitude: raw === true ? point[this.getKeys(point).longitude] : this.useDecimal(point[this.getKeys(point).longitude])
+			};
+
+			var elev = point[this.getKeys(point).elevation];
+
+			if(typeof elev !== 'undefined') {
+				retval['elevation'] = elev;
+			}
+
+			return retval;
+
+		},
+
+		// checks if a variable contains a valid latlong object
+		validate: function(point) {
+
+			var keys = this.getKeys(point);
+
+			if(typeof keys === 'undefined' || typeof keys.latitude === 'undefined' || keys.longitude === 'undefined') {
+				return false;
+			}
+
+			var lat = point[keys.latitude];
+			var lng = point[keys.longitude];
+
+			if(typeof lat === 'undefined' || !this.isDecimal(lat) && !this.isSexagesimal(lat)) {
+				return false;
+			}
+
+			if(typeof lng === 'undefined' || !this.isDecimal(lng) && !this.isSexagesimal(lng)) {
+				return false;
+			}
+
+			lat = this.useDecimal(lat);
+			lng = this.useDecimal(lng);
+
+			if(lat < this.minLat || lat > this.maxLat || lng < this.minLon || lng > this.maxLon) {
+				return false;
+			}
+
+			return true;
+
+		},
+
+		/**
+		* Calculates geodetic distance between two points specified by latitude/longitude using
+		* Vincenty inverse formula for ellipsoids
+		* Vincenty Inverse Solution of Geodesics on the Ellipsoid (c) Chris Veness 2002-2010
+		* (Licensed under CC BY 3.0)
+		*
+		* @param    object    Start position {latitude: 123, longitude: 123}
+		* @param    object    End position {latitude: 123, longitude: 123}
+		* @param    integer   Accuracy (in meters)
+		* @return   integer   Distance (in meters)
+		*/
+		getDistance: function(start, end, accuracy) {
+
+			accuracy = Math.floor(accuracy) || 1;
+
+			var s = this.coords(start);
+			var e = this.coords(end);
+
+			var a = 6378137, b = 6356752.314245,  f = 1/298.257223563;  // WGS-84 ellipsoid params
+			var L = (e['longitude']-s['longitude']).toRad();
+
+			var cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM, sinSigma;
+
+			var U1 = Math.atan((1-f) * Math.tan(parseFloat(s['latitude']).toRad()));
+			var U2 = Math.atan((1-f) * Math.tan(parseFloat(e['latitude']).toRad()));
+			var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
+			var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
+
+			var lambda = L, lambdaP, iterLimit = 100;
+			do {
+				var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
+				sinSigma = (
+					Math.sqrt(
+						(
+							cosU2 * sinLambda
+						) * (
+							cosU2 * sinLambda
+						) + (
+							cosU1 * sinU2 - sinU1 * cosU2 * cosLambda
+						) * (
+							cosU1 * sinU2 - sinU1 * cosU2 * cosLambda
+						)
+					)
+				);
+				if (sinSigma === 0) {
+					return geolib.distance = 0;  // co-incident points
+				}
+
+				cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
+				sigma = Math.atan2(sinSigma, cosSigma);
+				sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
+				cosSqAlpha = 1 - sinAlpha * sinAlpha;
+				cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
+
+				if (isNaN(cos2SigmaM)) {
+					cos2SigmaM = 0;  // equatorial line: cosSqAlpha=0 (§6)
+				}
+				var C = (
+					f / 16 * cosSqAlpha * (
+						4 + f * (
+							4 - 3 * cosSqAlpha
+						)
+					)
+				);
+				lambdaP = lambda;
+				lambda = (
+					L + (
+						1 - C
+					) * f * sinAlpha * (
+						sigma + C * sinSigma * (
+							cos2SigmaM + C * cosSigma * (
+								-1 + 2 * cos2SigmaM * cos2SigmaM
+							)
+						)
+					)
+				);
+
+			} while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0);
+
+			if (iterLimit === 0) {
+				return NaN;  // formula failed to converge
+			}
+
+			var uSq = (
+				cosSqAlpha * (
+					a * a - b * b
+				) / (
+					b*b
+				)
+			);
+
+			var A = (
+				1 + uSq / 16384 * (
+					4096 + uSq * (
+						-768 + uSq * (
+							320 - 175 * uSq
+						)
+					)
+				)
+			);
+
+			var B = (
+				uSq / 1024 * (
+					256 + uSq * (
+						-128 + uSq * (
+							74-47 * uSq
+						)
+					)
+				)
+			);
+
+			var deltaSigma = (
+				B * sinSigma * (
+					cos2SigmaM + B / 4 * (
+						cosSigma * (
+							-1 + 2 * cos2SigmaM * cos2SigmaM
+						) -B / 6 * cos2SigmaM * (
+							-3 + 4 * sinSigma * sinSigma
+						) * (
+							-3 + 4 * cos2SigmaM * cos2SigmaM
+						)
+					)
+				)
+			);
+
+			var distance = b * A * (sigma - deltaSigma);
+
+			distance = distance.toFixed(3); // round to 1mm precision
+
+			//if (start.hasOwnProperty(elevation) && end.hasOwnProperty(elevation)) {
+			if (typeof this.elevation(start) !== 'undefined' && typeof this.elevation(end) !== 'undefined') {
+				var climb = Math.abs(this.elevation(start) - this.elevation(end));
+				distance = Math.sqrt(distance * distance + climb * climb);
+			}
+
+			return this.distance = Math.floor(
+				Math.round(distance / accuracy) * accuracy
+			);
+
+			/*
+			// note: to return initial/final bearings in addition to distance, use something like:
+			var fwdAz = Math.atan2(cosU2*sinLambda,  cosU1*sinU2-sinU1*cosU2*cosLambda);
+			var revAz = Math.atan2(cosU1*sinLambda, -sinU1*cosU2+cosU1*sinU2*cosLambda);
+
+			return { distance: s, initialBearing: fwdAz.toDeg(), finalBearing: revAz.toDeg() };
+			*/
+
+		},
+
+
+		/**
+		* Calculates the distance between two spots.
+		* This method is more simple but also far more inaccurate
+		*
+		* @param    object    Start position {latitude: 123, longitude: 123}
+		* @param    object    End position {latitude: 123, longitude: 123}
+		* @param    integer   Accuracy (in meters)
+		* @return   integer   Distance (in meters)
+		*/
+		getDistanceSimple: function(start, end, accuracy) {
+
+			accuracy = Math.floor(accuracy) || 1;
+
+			var distance =
+				Math.round(
+					Math.acos(
+						Math.sin(
+							this.latitude(end).toRad()
+						) *
+						Math.sin(
+							this.latitude(start).toRad()
+						) +
+						Math.cos(
+							this.latitude(end).toRad()
+						) *
+						Math.cos(
+							this.latitude(start).toRad()
+						) *
+						Math.cos(
+							this.longitude(start).toRad() - this.longitude(end).toRad()
+						)
+					) * this.radius
+				);
+
+			return geolib.distance = Math.floor(Math.round(distance/accuracy)*accuracy);
+
+		},
+
+
+		/**
+		* Calculates the center of a collection of geo coordinates
+		*
+		* @param		array		Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
+		* @return		object		{latitude: centerLat, longitude: centerLng, distance: diagonalDistance}
+		*/
+		getCenter: function(coords) {
+
+			if (!coords.length) {
+				return false;
+			}
+
+			var max = function( array ){
+				return Math.max.apply( Math, array );
+			};
+
+			var min = function( array ){
+				return Math.min.apply( Math, array );
+			};
+
+			var	latitude;
+			var longitude;
+			var splitCoords = {latitude: [], longitude: []};
+
+			for(var coord in coords) {
+
+				splitCoords.latitude.push(
+					this.latitude(coords[coord])
+				);
+
+				splitCoords.longitude.push(
+					this.longitude(coords[coord])
+				);
+
+			}
+
+			var minLat = min(splitCoords.latitude);
+			var minLon = min(splitCoords.longitude);
+			var maxLat = max(splitCoords.latitude);
+			var maxLon = max(splitCoords.longitude);
+
+			latitude = ((minLat + maxLat)/2).toFixed(6);
+			longitude = ((minLon + maxLon)/2).toFixed(6);
+
+			// distance from the deepest left to the highest right point (diagonal distance)
+			var distance = this.convertUnit('km', this.getDistance({latitude: minLat, longitude: minLon}, {latitude: maxLat, longitude: maxLon}));
+
+			return {
+				latitude: latitude,
+				longitude: longitude,
+				distance: distance
+			};
+
+		},
+
+
+
+		/**
+		* Gets the max and min, latitude, longitude, and elevation (if provided).
+		* @param		array		array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
+		* @return	object		{maxLat: maxLat,
+		*                     minLat: minLat
+		*                     maxLng: maxLng,
+		*                     minLng: minLng,
+		*                     maxElev: maxElev,
+		*                     minElev: minElev}
+		*/
+		getBounds: function(coords) {
+
+			if (!coords.length) {
+				return false;
+			}
+
+			var useElevation = this.elevation(coords[0]);
+
+			var stats = {
+				maxLat: -Infinity,
+				minLat: Infinity,
+				maxLng: -Infinity,
+				minLng: Infinity
+			};
+
+			if (typeof useElevation != 'undefined') {
+				stats.maxElev = 0;
+				stats.minElev = Infinity;
+			}
+
+			for (var i = 0, l = coords.length; i < l; ++i) {
+
+				stats.maxLat = Math.max(this.latitude(coords[i]), stats.maxLat);
+				stats.minLat = Math.min(this.latitude(coords[i]), stats.minLat);
+				stats.maxLng = Math.max(this.longitude(coords[i]), stats.maxLng);
+				stats.minLng = Math.min(this.longitude(coords[i]), stats.minLng);
+
+				if (useElevation) {
+					stats.maxElev = Math.max(this.elevation(coords[i]), stats.maxElev);
+					stats.minElev = Math.min(this.elevation(coords[i]), stats.minElev);
+				}
+
+			}
+
+			return stats;
+
+		},
+
+
+		/**
+		* Computes the bounding coordinates of all points on the surface
+		* of the earth less than or equal to the specified great circle
+		* distance.
+		*
+		* @param object Point position {latitude: 123, longitude: 123}
+		* @param number Distance (in meters).
+		* @return array Collection of two points defining the SW and NE corners.
+		*/
+		getBoundsOfDistance: function(point, distance) {
+
+			var latitude = this.latitude(point);
+			var longitude = this.longitude(point);
+
+			var radLat = latitude.toRad();
+			var radLon = longitude.toRad();
+
+			var radDist = distance / this.radius;
+			var minLat = radLat - radDist;
+			var maxLat = radLat + radDist;
+
+			var MAX_LAT_RAD = this.maxLat.toRad();
+			var MIN_LAT_RAD = this.minLat.toRad();
+			var MAX_LON_RAD = this.maxLon.toRad();
+			var MIN_LON_RAD = this.minLon.toRad();
+
+			var minLon;
+			var maxLon;
+
+			if (minLat > MIN_LAT_RAD && maxLat < MAX_LAT_RAD) {
+
+				var deltaLon = Math.asin(Math.sin(radDist) / Math.cos(radLat));
+				minLon = radLon - deltaLon;
+
+				if (minLon < MIN_LON_RAD) {
+					minLon += 2 * Math.PI;
+				}
+
+				maxLon = radLon + deltaLon;
+
+				if (maxLon > MAX_LON_RAD) {
+					maxLon -= 2 * Math.PI;
+				}
+
+			} else {
+				// A pole is within the distance.
+				minLat = Math.max(minLat, MIN_LAT_RAD);
+				maxLat = Math.min(maxLat, MAX_LAT_RAD);
+				minLon = MIN_LON_RAD;
+				maxLon = MAX_LON_RAD;
+			}
+
+			return [
+				// Southwest
+				{
+					latitude: minLat.toDeg(),
+					longitude: minLon.toDeg()
+				},
+				// Northeast
+				{
+					latitude: maxLat.toDeg(),
+					longitude: maxLon.toDeg()
+				}
+			];
+
+		},
+
+
+		/**
+		* Checks whether a point is inside of a polygon or not.
+		* Note that the polygon coords must be in correct order!
+		*
+		* @param		object		coordinate to check e.g. {latitude: 51.5023, longitude: 7.3815}
+		* @param		array		array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
+		* @return		bool		true if the coordinate is inside the given polygon
+		*/
+		isPointInside: function(latlng, coords) {
+
+			for(var c = false, i = -1, l = coords.length, j = l - 1; ++i < l; j = i) {
+
+				if(
+					(
+						(this.longitude(coords[i]) <= this.longitude(latlng) && this.longitude(latlng) < this.longitude(coords[j])) ||
+						(this.longitude(coords[j]) <= this.longitude(latlng) && this.longitude(latlng) < this.longitude(coords[i]))
+					) &&
+					(
+						this.latitude(latlng) < (this.latitude(coords[j]) - this.latitude(coords[i])) *
+						(this.longitude(latlng) - this.longitude(coords[i])) /
+						(this.longitude(coords[j]) - this.longitude(coords[i])) +
+						this.latitude(coords[i])
+					)
+				) {
+					c = !c;
+				}
+
+			}
+
+			return c;
+
+		},
+
+
+		/**
+		* Shortcut for geolib.isPointInside()
+		*/
+		isInside: function() {
+			return this.isPointInside.apply(this, arguments);
+		},
+
+
+		/**
+		* Checks whether a point is inside of a circle or not.
+		*
+		* @param		object		coordinate to check (e.g. {latitude: 51.5023, longitude: 7.3815})
+		* @param		object		coordinate of the circle's center (e.g. {latitude: 51.4812, longitude: 7.4025})
+		* @param		integer		maximum radius in meters
+		* @return		bool		true if the coordinate is within the given radius
+		*/
+		isPointInCircle: function(latlng, center, radius) {
+			return this.getDistance(latlng, center) < radius;
+		},
+
+
+		/**
+		* Shortcut for geolib.isPointInCircle()
+		*/
+		withinRadius: function() {
+			return this.isPointInCircle.apply(this, arguments);
+		},
+
+
+		/**
+		* Gets rhumb line bearing of two points. Find out about the difference between rhumb line and
+		* great circle bearing on Wikipedia. It's quite complicated. Rhumb line should be fine in most cases:
+		*
+		* http://en.wikipedia.org/wiki/Rhumb_line#General_and_mathematical_description
+		*
+		* Function heavily based on Doug Vanderweide's great PHP version (licensed under GPL 3.0)
+		* http://www.dougv.com/2009/07/13/calculating-the-bearing-and-compass-rose-direction-between-two-latitude-longitude-coordinates-in-php/
+		*
+		* @param		object		origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
+		* @param		object		destination coordinate
+		* @return		integer		calculated bearing
+		*/
+		getRhumbLineBearing: function(originLL, destLL) {
+
+			// difference of longitude coords
+			var diffLon = this.longitude(destLL).toRad() - this.longitude(originLL).toRad();
+
+			// difference latitude coords phi
+			var diffPhi = Math.log(
+				Math.tan(
+					this.latitude(destLL).toRad() / 2 + Math.PI / 4
+				) /
+				Math.tan(
+					this.latitude(originLL).toRad() / 2 + Math.PI / 4
+				)
+			);
+
+			// recalculate diffLon if it is greater than pi
+			if(Math.abs(diffLon) > Math.PI) {
+				if(diffLon > 0) {
+					diffLon = (2 * Math.PI - diffLon) * -1;
+				}
+				else {
+					diffLon = 2 * Math.PI + diffLon;
+				}
+			}
+
+			//return the angle, normalized
+			return (Math.atan2(diffLon, diffPhi).toDeg() + 360) % 360;
+
+		},
+
+
+		/**
+		* Gets great circle bearing of two points. See description of getRhumbLineBearing for more information
+		*
+		* @param		object		origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
+		* @param		object		destination coordinate
+		* @return		integer		calculated bearing
+		*/
+		getBearing: function(originLL, destLL) {
+
+			destLL['latitude'] = this.latitude(destLL);
+			destLL['longitude'] = this.longitude(destLL);
+			originLL['latitude'] = this.latitude(originLL);
+			originLL['longitude'] = this.longitude(originLL);
+
+			var bearing = (
+				(
+					Math.atan2(
+						Math.sin(
+							destLL['longitude'].toRad() -
+							originLL['longitude'].toRad()
+						) *
+						Math.cos(
+							destLL['latitude'].toRad()
+						),
+						Math.cos(
+							originLL['latitude'].toRad()
+						) *
+						Math.sin(
+							destLL['latitude'].toRad()
+						) -
+						Math.sin(
+							originLL['latitude'].toRad()
+						) *
+						Math.cos(
+							destLL['latitude'].toRad()
+						) *
+						Math.cos(
+							destLL['longitude'].toRad() - originLL['longitude'].toRad()
+						)
+					)
+				).toDeg() + 360
+			) % 360;
+
+			return bearing;
+
+		},
+
+
+		/**
+		* Gets the compass direction from an origin coordinate to a destination coordinate.
+		*
+		* @param		object		origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
+		* @param		object		destination coordinate
+		* @param		string		Bearing mode. Can be either circle or rhumbline
+		* @return		object		Returns an object with a rough (NESW) and an exact direction (NNE, NE, ENE, E, ESE, etc).
+		*/
+		getCompassDirection: function(originLL, destLL, bearingMode) {
+
+			var direction;
+			var bearing;
+
+			if(bearingMode == 'circle') {
+				// use great circle bearing
+				bearing = this.getBearing(originLL, destLL);
+			} else {
+				// default is rhumb line bearing
+				bearing = this.getRhumbLineBearing(originLL, destLL);
+			}
+
+			switch(Math.round(bearing/22.5)) {
+				case 1:
+					direction = {exact: "NNE", rough: "N"};
+					break;
+				case 2:
+					direction = {exact: "NE", rough: "N"};
+					break;
+				case 3:
+					direction = {exact: "ENE", rough: "E"};
+					break;
+				case 4:
+					direction = {exact: "E", rough: "E"};
+					break;
+				case 5:
+					direction = {exact: "ESE", rough: "E"};
+					break;
+				case 6:
+					direction = {exact: "SE", rough: "E"};
+					break;
+				case 7:
+					direction = {exact: "SSE", rough: "S"};
+					break;
+				case 8:
+					direction = {exact: "S", rough: "S"};
+					break;
+				case 9:
+					direction = {exact: "SSW", rough: "S"};
+					break;
+				case 10:
+					direction = {exact: "SW", rough: "S"};
+					break;
+				case 11:
+					direction = {exact: "WSW", rough: "W"};
+					break;
+				case 12:
+					direction = {exact: "W", rough: "W"};
+					break;
+				case 13:
+					direction = {exact: "WNW", rough: "W"};
+					break;
+				case 14:
+					direction = {exact: "NW", rough: "W"};
+					break;
+				case 15:
+					direction = {exact: "NNW", rough: "N"};
+					break;
+				default:
+					direction = {exact: "N", rough: "N"};
+			}
+
+			direction['bearing'] = bearing;
+			return direction;
+
+		},
+
+
+		/**
+		* Shortcut for getCompassDirection
+		*/
+		getDirection: function(originLL, destLL, bearingMode) {
+			return this.getCompassDirection.apply(this, arguments);
+		},
+
+
+		/**
+		* Sorts an array of coords by distance from a reference coordinate
+		*
+		* @param		object		reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}
+		* @param		mixed		array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
+		* @return		array		ordered array
+		*/
+		orderByDistance: function(latlng, coords) {
+
+			var coordsArray = [];
+
+			for(var coord in coords) {
+
+				var d = this.getDistance(latlng, coords[coord]);
+
+				coordsArray.push({
+					key: coord,
+					latitude: this.latitude(coords[coord]),
+					longitude: this.longitude(coords[coord]),
+					distance: d
+				});
+
+			}
+
+			return coordsArray.sort(function(a, b) { return a.distance - b.distance; });
+
+		},
+
+
+		/**
+		* Finds the nearest coordinate to a reference coordinate
+		*
+		* @param		object		reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}
+		* @param		mixed		array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
+		* @return		array		ordered array
+		*/
+		findNearest: function(latlng, coords, offset, limit) {
+
+			offset = offset || 0;
+			limit = limit || 1;
+			var ordered = this.orderByDistance(latlng, coords);
+
+			if(limit === 1) {
+				return ordered[offset];
+			} else {
+				return ordered.splice(offset, limit);
+			}
+
+		},
+
+
+		/**
+		* Calculates the length of a given path
+		*
+		* @param		mixed		array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
+		* @return		integer		length of the path (in meters)
+		*/
+		getPathLength: function(coords) {
+
+			var dist = 0;
+			var last;
+
+			for (var i = 0, l = coords.length; i < l; ++i) {
+				if(last) {
+					//console.log(coords[i], last, this.getDistance(coords[i], last));
+					dist += this.getDistance(this.coords(coords[i]), last);
+				}
+				last = this.coords(coords[i]);
+			}
+
+			return dist;
+
+		},
+
+
+		/**
+		* Calculates the speed between to points within a given time span.
+		*
+		* @param		object		coords with javascript timestamp {latitude: 51.5143, longitude: 7.4138, time: 1360231200880}
+		* @param		object		coords with javascript timestamp {latitude: 51.5502, longitude: 7.4323, time: 1360245600460}
+		* @param		object		options (currently "unit" is the only option. Default: km(h));
+		* @return		float		speed in unit per hour
+		*/
+		getSpeed: function(start, end, options) {
+
+			var unit = options && options.unit || 'km';
+
+			if(unit == 'mph') {
+				unit = 'mi';
+			} else if(unit == 'kmh') {
+				unit = 'km';
+			}
+
+			var distance = geolib.getDistance(start, end);
+			var time = ((end.time*1)/1000) - ((start.time*1)/1000);
+			var mPerHr = (distance/time)*3600;
+			var speed = Math.round(mPerHr * this.measures[unit] * 10000)/10000;
+			return speed;
+
+		},
+
+
+		/**
+		* Converts a distance from meters to km, mm, cm, mi, ft, in or yd
+		*
+		* @param		string		Format to be converted in
+		* @param		float		Distance in meters
+		* @param		float		Decimal places for rounding (default: 4)
+		* @return		float		Converted distance
+		*/
+		convertUnit: function(unit, distance, round) {
+
+			if(distance === 0 || typeof distance === 'undefined') {
+
+				if(this.distance === 0) {
+					// throw 'No distance given.';
+					return 0;
+				} else {
+					distance = this.distance;
+				}
+
+			}
+
+			unit = unit || 'm';
+			round = (null == round ? 4 : round);
+
+			if(typeof this.measures[unit] !== 'undefined') {
+				return this.round(distance * this.measures[unit], round);
+			} else {
+				throw new Error('Unknown unit for conversion.');
+			}
+
+		},
+
+
+		/**
+		* Checks if a value is in decimal format or, if neccessary, converts to decimal
+		*
+		* @param		mixed		Value(s) to be checked/converted (array of latlng objects, latlng object, sexagesimal string, float)
+		* @return		float		Input data in decimal format
+		*/
+		useDecimal: function(value) {
+
+			if(Object.prototype.toString.call(value) === '[object Array]') {
+
+				var geolib = this;
+
+				value = value.map(function(val) {
+
+					//if(!isNaN(parseFloat(val))) {
+					if(geolib.isDecimal(val)) {
+
+						return geolib.useDecimal(val);
+
+					} else if(typeof val == 'object') {
+
+						if(geolib.validate(val)) {
+
+							return geolib.coords(val);
+
+						} else {
+
+							for(var prop in val) {
+								val[prop] = geolib.useDecimal(val[prop]);
+							}
+
+							return val;
+
+						}
+
+					} else if(geolib.isSexagesimal(val)) {
+
+						return geolib.sexagesimal2decimal(val);
+
+					} else {
+
+						return val;
+
+					}
+
+				});
+
+				return value;
+
+			} else if(typeof value === 'object' && this.validate(value)) {
+
+				return this.coords(value);
+
+			} else if(typeof value === 'object') {
+
+				for(var prop in value) {
+					value[prop] = this.useDecimal(value[prop]);
+				}
+
+				return value;
+
+			}
+
+
+			if (this.isDecimal(value)) {
+
+				return parseFloat(value);
+
+			} else if(this.isSexagesimal(value) === true) {
+
+				return parseFloat(this.sexagesimal2decimal(value));
+
+			}
+
+			throw new Error('Unknown format.');
+
+		},
+
+		/**
+		* Converts a decimal coordinate value to sexagesimal format
+		*
+		* @param		float		decimal
+		* @return		string		Sexagesimal value (XX° YY' ZZ")
+		*/
+		decimal2sexagesimal: function(dec) {
+
+			if (dec in this.sexagesimal) {
+				return this.sexagesimal[dec];
+			}
+
+			var tmp = dec.toString().split('.');
+
+			var deg = Math.abs(tmp[0]);
+			var min = ('0.' + tmp[1])*60;
+			var sec = min.toString().split('.');
+
+			min = Math.floor(min);
+			sec = (('0.' + sec[1]) * 60).toFixed(2);
+
+			this.sexagesimal[dec] = (deg + '° ' + min + "' " + sec + '"');
+
+			return this.sexagesimal[dec];
+
+		},
+
+
+		/**
+		* Converts a sexagesimal coordinate to decimal format
+		*
+		* @param		float		Sexagesimal coordinate
+		* @return		string		Decimal value (XX.XXXXXXXX)
+		*/
+		sexagesimal2decimal: function(sexagesimal) {
+
+			if (sexagesimal in this.decimal) {
+				return this.decimal[sexagesimal];
+			}
+
+			var	regEx = new RegExp(this.sexagesimalPattern);
+			var	data = regEx.exec(sexagesimal);
+			var min = 0, sec = 0;
+
+			if(data) {
+				min = parseFloat(data[2]/60);
+				sec = parseFloat(data[4]/3600) || 0;
+			}
+
+			var	dec = ((parseFloat(data[1]) + min + sec)).toFixed(8);
+			//var	dec = ((parseFloat(data[1]) + min + sec));
+
+				// South and West are negative decimals
+				dec = (data[7] == 'S' || data[7] == 'W') ? parseFloat(-dec) : parseFloat(dec);
+				//dec = (data[7] == 'S' || data[7] == 'W') ? -dec : dec;
+
+			this.decimal[sexagesimal] = dec;
+
+			return dec;
+
+		},
+
+
+		/**
+		* Checks if a value is in decimal format
+		*
+		* @param		string		Value to be checked
+		* @return		bool		True if in sexagesimal format
+		*/
+		isDecimal: function(value) {
+
+			value = value.toString().replace(/\s*/, '');
+
+			// looks silly but works as expected
+			// checks if value is in decimal format
+			return (!isNaN(parseFloat(value)) && parseFloat(value) == value);
+
+		},
+
+
+		/**
+		* Checks if a value is in sexagesimal format
+		*
+		* @param		string		Value to be checked
+		* @return		bool		True if in sexagesimal format
+		*/
+		isSexagesimal: function(value) {
+
+			value = value.toString().replace(/\s*/, '');
+
+			return this.sexagesimalPattern.test(value);
+
+		},
+
+		round: function(value, n) {
+			var decPlace = Math.pow(10, n);
+			return Math.round(value * decPlace)/decPlace;
+		}
+
+	});
+
+	// Node module
+	if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
+
+		global.geolib = module.exports = geolib;
+
+	// AMD module
+	} else if (typeof define === "function" && define.amd) {
+
+		define("geolib", [], function () {
+			return geolib;
+		});
+
+	// we're in a browser
+	} else {
+
+		global.geolib = geolib;
+
+	}
+
+}(this));
\ No newline at end of file
diff --git a/node_modules/geolib/package.json b/node_modules/geolib/package.json
new file mode 100644
index 0000000..d616b92
--- /dev/null
+++ b/node_modules/geolib/package.json
@@ -0,0 +1,75 @@
+{
+  "name": "geolib",
+  "homepage": "http://github.com/manuelbieh/Geolib",
+  "author": {
+    "name": "Manuel Bieh",
+    "url": "http://www.manuelbieh.com/"
+  },
+  "repository": {
+    "type": "git",
+    "url": "http://github.com/manuelbieh/geolib.git"
+  },
+  "devDependencies": {
+    "grunt": "~0.4",
+    "grunt-cli": "*",
+    "grunt-contrib-uglify": "~0.2",
+    "grunt-contrib-concat": "~0.3",
+    "grunt-contrib-clean": "~0.5.0",
+    "grunt-contrib-copy": "~0.4",
+    "grunt-contrib-qunit": "~0.2.0",
+    "grunt-text-replace": "~0.3.6",
+    "grunt-contrib-jshint": "~0.6.2",
+    "phantomjs": "~1.8.0",
+    "grunt-jslint": "~1.0.0",
+    "time-grunt": "~0.3.1",
+    "load-grunt-tasks": "~0.4.0"
+  },
+  "licenses": [
+    {
+      "type": "MIT",
+      "url": "http://opensource.org/licenses/MIT"
+    }
+  ],
+  "files": [
+    "dist/geolib.js",
+    "dist/geolib.elevation.js"
+  ],
+  "description": "Library to perform geo specific tasks",
+  "keywords": [
+    "geolocation",
+    "geo",
+    "distance",
+    "geojson",
+    "geospatial",
+    "lbs",
+    "location"
+  ],
+  "scripts": {
+    "test": "grunt travis --verbose"
+  },
+  "version": "2.0.14",
+  "main": "dist/geolib.js",
+  "bugs": {
+    "url": "https://github.com/manuelbieh/geolib/issues"
+  },
+  "_id": "geolib@2.0.14",
+  "dist": {
+    "shasum": "2b3da953462c9f5471896f10ec1d9d0ed3bb7cb8",
+    "tarball": "http://registry.npmjs.org/geolib/-/geolib-2.0.14.tgz"
+  },
+  "_from": "geolib@",
+  "_npmVersion": "1.3.14",
+  "_npmUser": {
+    "name": "manuelbieh",
+    "email": "node@manuelbieh.de"
+  },
+  "maintainers": [
+    {
+      "name": "manuelbieh",
+      "email": "node@manuelbieh.de"
+    }
+  ],
+  "directories": {},
+  "_shasum": "2b3da953462c9f5471896f10ec1d9d0ed3bb7cb8",
+  "_resolved": "https://registry.npmjs.org/geolib/-/geolib-2.0.14.tgz"
+}
diff --git a/node_modules/sync-prompt/build/Makefile b/node_modules/sync-prompt/build/Makefile
index 9749fa4..25b2ccb 100644
--- a/node_modules/sync-prompt/build/Makefile
+++ b/node_modules/sync-prompt/build/Makefile
@@ -334,7 +334,7 @@ ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
 endif

 quiet_cmd_regen_makefile = ACTION Regenerating $@
-cmd_regen_makefile = cd $(srcdir); /usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "--toplevel-dir=." -I/Users/apprentice/Desktop/glass-congress/node_modules/sync-prompt/build/config.gypi -I/usr/local/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/Users/apprentice/.node-gyp/0.10.29/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/apprentice/.node-gyp/0.10.29" "-Dmodule_root_dir=/Users/apprentice/Desktop/glass-congress/node_modules/sync-prompt" binding.gyp
+cmd_regen_makefile = cd $(srcdir); /usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "--toplevel-dir=." -I/Users/apprentice/Desktop/eventSearch/node_modules/sync-prompt/build/config.gypi -I/usr/local/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/Users/apprentice/.node-gyp/0.10.29/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/apprentice/.node-gyp/0.10.29" "-Dmodule_root_dir=/Users/apprentice/Desktop/eventSearch/node_modules/sync-prompt" binding.gyp
 Makefile: $(srcdir)/../../../../.node-gyp/0.10.29/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../usr/local/lib/node_modules/npm/node_modules/node-gyp/addon.gypi
 	$(call do_cmd,regen_makefile)

diff --git a/node_modules/sync-prompt/build/Release/.deps/Release/obj.target/sync_prompt/src/sync_prompt.o.d b/node_modules/sync-prompt/build/Release/.deps/Release/obj.target/sync_prompt/src/sync_prompt.o.d
deleted file mode 100644
index dcc6d6f..0000000
--- a/node_modules/sync-prompt/build/Release/.deps/Release/obj.target/sync_prompt/src/sync_prompt.o.d
+++ /dev/null
@@ -1,19 +0,0 @@
-cmd_Release/obj.target/sync_prompt/src/sync_prompt.o := c++ '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/Users/apprentice/.node-gyp/0.10.29/src -I/Users/apprentice/.node-gyp/0.10.29/deps/uv/include -I/Users/apprentice/.node-gyp/0.10.29/deps/v8/include  -Os -gdwarf-2 -mmacosx-version-min=10.5 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -fno-rtti -fno-exceptions -fno-threadsafe-statics -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/sync_prompt/src/sync_prompt.o.d.raw  -c -o Release/obj.target/sync_prompt/src/sync_prompt.o ../src/sync_prompt.cc
-Release/obj.target/sync_prompt/src/sync_prompt.o: ../src/sync_prompt.cc \
-  /Users/apprentice/.node-gyp/0.10.29/src/node.h \
-  /Users/apprentice/.node-gyp/0.10.29/deps/uv/include/uv.h \
-  /Users/apprentice/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-unix.h \
-  /Users/apprentice/.node-gyp/0.10.29/deps/uv/include/uv-private/ngx-queue.h \
-  /Users/apprentice/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-darwin.h \
-  /Users/apprentice/.node-gyp/0.10.29/deps/v8/include/v8.h \
-  /Users/apprentice/.node-gyp/0.10.29/deps/v8/include/v8stdint.h \
-  /Users/apprentice/.node-gyp/0.10.29/src/node_object_wrap.h
-../src/sync_prompt.cc:
-/Users/apprentice/.node-gyp/0.10.29/src/node.h:
-/Users/apprentice/.node-gyp/0.10.29/deps/uv/include/uv.h:
-/Users/apprentice/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-unix.h:
-/Users/apprentice/.node-gyp/0.10.29/deps/uv/include/uv-private/ngx-queue.h:
-/Users/apprentice/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-darwin.h:
-/Users/apprentice/.node-gyp/0.10.29/deps/v8/include/v8.h:
-/Users/apprentice/.node-gyp/0.10.29/deps/v8/include/v8stdint.h:
-/Users/apprentice/.node-gyp/0.10.29/src/node_object_wrap.h:
diff --git a/node_modules/sync-prompt/build/Release/.deps/Release/sync_prompt.node.d b/node_modules/sync-prompt/build/Release/.deps/Release/sync_prompt.node.d
deleted file mode 100644
index 0bdf6be..0000000
--- a/node_modules/sync-prompt/build/Release/.deps/Release/sync_prompt.node.d
+++ /dev/null
@@ -1 +0,0 @@
-cmd_Release/sync_prompt.node := ./gyp-mac-tool flock ./Release/linker.lock c++ -bundle -Wl,-search_paths_first -mmacosx-version-min=10.5 -arch x86_64 -L./Release  -o Release/sync_prompt.node Release/obj.target/sync_prompt/src/sync_prompt.o -undefined dynamic_lookup
diff --git a/node_modules/sync-prompt/build/Release/linker.lock b/node_modules/sync-prompt/build/Release/linker.lock
deleted file mode 100644
index e69de29..0000000
diff --git a/node_modules/sync-prompt/build/Release/obj.target/sync_prompt/src/sync_prompt.o b/node_modules/sync-prompt/build/Release/obj.target/sync_prompt/src/sync_prompt.o
deleted file mode 100644
index a5ccd9f..0000000
Binary files a/node_modules/sync-prompt/build/Release/obj.target/sync_prompt/src/sync_prompt.o and /dev/null differ
diff --git a/node_modules/sync-prompt/build/Release/sync_prompt.node b/node_modules/sync-prompt/build/Release/sync_prompt.node
deleted file mode 100755
index 43a85c4..0000000
Binary files a/node_modules/sync-prompt/build/Release/sync_prompt.node and /dev/null differ
diff --git a/package.json b/package.json
index 363582b..900821d 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
     "express": "*",
     "node-env-file": "*",
     "eventbrite": "*",
+    "geolib": "*",
     "underscore-node": "*"
   },
   "description": "Twitter visualization project using Node, Express, & Firebase",
diff --git a/script.js b/script.js
index 63e49c5..5e3f000 100644
--- a/script.js
+++ b/script.js
@@ -2,8 +2,9 @@ var app = angular.module('eventSearch', []).run(function($rootScope){
   $rootScope.events = []
 })
 app.controller('searchCtrl', function($scope, $http) {
+  sanFranGoogleObj = new google.maps.LatLng(37.7583, -122.4367);
   $scope.categories = [
-  'conferences', 'conventions', 'entertainment',
+  'sports', 'conferences', 'conventions', 'entertainment',
   'fundraisers', 'meetings', 'other',
   'performances', 'reunions', 'sales',
   'seminars', 'social', 'sports',
@@ -17,21 +18,27 @@ app.controller('searchCtrl', function($scope, $http) {
       type: 'GET',
       dataType: 'json'      
     }).success(function(data) {
-      console.log(data)
       $scope.events.length = 0;
-      for (var eventIndex = 1; eventIndex < data.events.length; eventIndex++){
-        $scope.events.push({
-          "eventTitle": data.events[eventIndex].event.title,
-          "url": data.events[eventIndex].event.url,
-          "time": data.events[eventIndex].event.start_date,
-          "price": data.events[eventIndex].event.tickets[0].ticket.display_price,
-          "timeZone": data.events[eventIndex].event.timezone_offset,
-          "address": data.events[eventIndex].event.venue.address,
-          "addressName": data.events[eventIndex].event.venue.name,
-          "addressCity": data.events[eventIndex].event.venue.city,
-          "distance": data.events[eventIndex].event.distance,
-          "logo": data.events[eventIndex].event.logo
-        })
+      if (data){
+        for (var eventIndex = 0; eventIndex < data.events.length; eventIndex++){
+          $scope.events.push({
+            "eventTitle": data.events[eventIndex].event.title,
+            "url": data.events[eventIndex].event.url,
+            "time": data.events[eventIndex].event.start_date,
+            "price": data.events[eventIndex].event.tickets[0].ticket.display_price,
+            "timeZone": data.events[eventIndex].event.timezone_offset,
+            "address": data.events[eventIndex].event.venue.address,
+            "addressName": data.events[eventIndex].event.venue.name,
+            "addressCity": data.events[eventIndex].event.venue.city,
+            "distance": data.events[eventIndex].event.distance,
+            "logo": data.events[eventIndex].event.logo
+          })
+          if(eventIndex == data.events.length-1){
+            setMarkers(map)
+          }
+        }
+      } else {
+        alert('No events were found!')
       }
     })    
   })
diff --git a/web.css b/web.css
index 86c26fb..3b57d13 100644
--- a/web.css
+++ b/web.css
@@ -35,3 +35,47 @@
 .date, .voteValue{
   padding-right: 5em;
 }
+
+.event-logo img{
+  float: left;
+  /*height: 100px;*/
+  height: 125px;
+  width: 125px;
+  display: inline;
+}
+
+.description{
+
+}
+
+.panel-body, #map-canvas{
+  background-color: beige;
+  margin: 10px;
+  height: 150px;
+  overflow-x: visible;
+}
+
+#display{
+
+}
+
+#search{
+  margin: 10px;
+}
+
+#event-container{
+  float: left;
+  width: 49%;
+  white-space: nowrap;
+  top: 50px;
+  overflow-y: scroll;
+  height: 80%;
+}
+
+#map-canvas{
+  float: right;
+  width: 49%;
+  /*position: fixed;*/
+  white-space: nowrap;
+  height: 67%
+}
done. user's first event comes up on google maps, and event are sorted by category and distance. no event is more than 20 kilometers away.