Misc formatting fixes like only show iOS stuff on those devices, don't show letters on nearby when have no nearby stuff
Misc formatting fixes like only show iOS stuff on those devices, don't show letters on nearby when have no nearby stuff

--- a/common-geo.inc.php
+++ b/common-geo.inc.php
@@ -51,7 +51,7 @@
 	if ($collapsible) $output.= '</div>';
 	return $output;
 }
-function distance($lat1, $lng1, $lat2, $lng2)
+function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false)
 {
 	$pi80 = M_PI / 180;
 	$lat1*= $pi80;
@@ -64,7 +64,10 @@
 	$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
 	$c = 2 * atan2(sqrt($a) , sqrt(1 - $a));
 	$km = $r * $c;
-	return $km * 1000;
+	if ($roundLargeValues) {
+	  if ($km < 1) return floor($km * 1000);
+	  else return round($km,2)."k";
+	} else return floor($km * 1000);
 }
 function decodePolylineToArray($encoded)
 {

--- a/common-template.inc.php
+++ b/common-template.inc.php
@@ -1,28 +1,26 @@
 <?php
-function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false)
+function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false)
 {
 	echo '
 <!DOCTYPE html> 
 <html> 
 	<head> 
 	<title>' . $pageTitle . '</title>';
+	if ($datepicker) echo '<link rel="stylesheet"  href="css/jquery.ui.datepicker.mobile.css" />';
 	if (isDebugServer()) echo '<link rel="stylesheet"  href="css/jquery-mobile-1.0a3.css" />
          <script type="text/javascript" src="js/jquery-1.5.js"></script>
         <script type="text/javascript" src="js/jquery-mobile-1.0a3.js"></script>';
-	else echo '<link rel="stylesheet"  href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.css" />
-        <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.js"></script>
-        <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.js"></script>';
-	echo '
-<link rel="stylesheet"  href="css/jquery.ui.datepicker.mobile.css" />
-	<script> 
+	else echo '<link rel="stylesheet"  href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.css" />
+        <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
+        <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.js"></script>';
+	if ($datepicker) echo '<script> 
 		//reset type=date inputs to text
 		$( document ).bind( "mobileinit", function(){
 			$.mobile.page.prototype.options.degradeInputs.date = true;
 		});	
 	</script> 
-	<script src="js/jQuery.ui.datepicker.js"></script> 
-	<script src="js/jquery.ui.datepicker.mobile.js"></script> 
-     <style type="text/css">
+	<script src="js/jQuery.ui.datepicker.js"></script>';
+	echo '<style type="text/css">
      .ui-navbar {
      width: 100%;
      }
@@ -46,11 +44,13 @@
     body {
         background-color: #F0F0F0;
     }
-</style>
-<meta name="apple-mobile-web-app-capable" content="yes" />
+</style>';
+	if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod')) {
+		echo '<meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  <link rel="apple-touch-startup-image" href="startup.png" />
  <link rel="apple-touch-icon" href="apple-touch-icon.png" />';
+	}
 	if ($geolocate) {
 		echo "<script>
 
@@ -65,7 +65,12 @@
 }
 
 if (navigator.geolocation) {
-  navigator.geolocation.getCurrentPosition(success, error);
+var options = {
+      enableHighAccuracy: false,
+      timeout: 60000,
+      maximumAge: 10000
+}
+  navigator.geolocation.getCurrentPosition(success, error, options);
 }
 
 </script> ";
@@ -73,17 +78,6 @@
 	echo '</head>
 <body>
  ';
-	if (isMetricsOn()) {
-		require_once ('owa/owa_env.php');
-		require_once (OWA_DIR . 'owa_php.php');
-		$owa = new owa_php();
-		global $owaSiteID;
-		$owa->setSiteId($owaSiteID);
-		$owa->setPageTitle($pageTitle);
-		$owa->setPageType($pageType);
-		$owa->trackPageView();
-		$owa->placeHelperPageTags();
-	}
 	if ($opendiv) {
 		echo '<div data-role="page"> 
  <script>
@@ -122,7 +116,7 @@
         or enter an address/co-ordinates in the box below.</div>';
 	}
 	echo '<div data-role="collapsible" data-collapsed="' . !$geoerror . '">
-        <h3>Change Time/Place...</h3>
+        <h3>Change Time/Place (' . (isset($_SESSION['time']) ? $_SESSION['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...</h3>
         <form action="" method="post">
         <div class="ui-body"> 
 		<div data-role="fieldcontain">
@@ -148,3 +142,4 @@
             </div></div>';
 }
 ?>
+

--- a/common.inc.php
+++ b/common.inc.php
@@ -4,12 +4,12 @@
 $cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6";
 $googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q";
 $otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/';
-$owaSiteID = 'fe5b819fa8c424a99ff0764d955d23f3';
 //$debugOkay = Array("session","json","phperror","other");
 $debugOkay = Array(
 	"session",
 	"json",
-	"phperror"
+	"phperror",
+	"other"
 );
 if (isDebug("phperror")) error_reporting(E_ALL ^ E_NOTICE);
 include_once ("common-geo.inc.php");
@@ -27,36 +27,30 @@
 if (isset($_REQUEST['geolocate'])) {
 	$geocoded = false;
 	if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) {
-		$_SESSION['lat'] = filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
-		$_SESSION['lon'] = filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
+		$_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
+		$_SESSION['lon'] = trim(filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
 	}
 	else {
-		$contents = geocode(filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL) , true);
-		if (isset($contents[0]->centroid)) {
-			$geocoded = true;
-			$_SESSION['lat'] = $contents[0]->centroid->coordinates[0];
-			$_SESSION['lon'] = $contents[0]->centroid->coordinates[1];
+		$geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL);
+		echo $_REQUEST['geolocate'];
+		if (startsWith($geolocate, "-")) {
+			$locateparts = explode(",", $geolocate);
+			$_SESSION['lat'] = $locateparts[0];
+			$_SESSION['lon'] = $locateparts[1];
 		}
 		else {
-			$_SESSION['lat'] = "";
-			$_SESSION['lon'] = "";
+			$contents = geocode($geolocate, true);
+			print_r($contents);
+			if (isset($contents[0]->centroid)) {
+				$geocoded = true;
+				$_SESSION['lat'] = $contents[0]->centroid->coordinates[0];
+				$_SESSION['lon'] = $contents[0]->centroid->coordinates[1];
+			}
+			else {
+				$_SESSION['lat'] = "";
+				$_SESSION['lon'] = "";
+			}
 		}
-	}
-	if ($_SESSION['lat'] != "" && isMetricsOn()) {
-		// Create a new Instance of the tracker
-		$owa = new owa_php($config);
-		// Set the ID of the site being tracked
-		$owa->setSiteId($owaSiteID);
-		// Create a new event object
-		$event = $owa->makeEvent();
-		// Set the Event Type, in this case a "video_play"
-		$event->setEventType('geolocate');
-		// Set a property
-		$event->set('lat', $_SESSION['lat']);
-		$event->set('lon', $_SESSION['lon']);
-		$event->set('geocoded', $geocoded);
-		// Track the event
-		$owa->trackEvent($event);
 	}
 }
 debug(print_r($_SESSION, true) , "session");
@@ -69,13 +63,34 @@
 	global $debugOkay;
 	return in_array($debugReason, $debugOkay, false) && isDebugServer();
 }
-function isMetricsOn()
-{
-	return !isDebugServer();
-}
 function debug($msg, $debugReason = "other")
 {
 	if (isDebug($debugReason)) echo "\n<!-- " . date(DATE_RFC822) . "\n $msg -->\n";
+}
+function isJQueryMobileDevice()
+{
+   // http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897
+	$user_agent = $_SERVER['HTTP_USER_AGENT'];   
+	return preg_match('/iphone/i', $user_agent)
+	|| preg_match('/android/i', $user_agent)
+	|| preg_match('/webos/i', $user_agent)
+	|| preg_match('/ios/i', $user_agent)
+	|| preg_match('/bada/i', $user_agent)
+	|| preg_match('/maemo/i', $user_agent)
+	|| preg_match('/meego/i', $user_agent)
+	|| preg_match('/fennec/i', $user_agent)
+	|| (preg_match('/symbian/i', $user_agent)
+	    && preg_match('/s60/i', $user_agent)
+	    && $browser['majorver'] >= 5)
+	|| (preg_match('/symbian/i', $user_agent)
+	    && preg_match('/platform/i', $user_agent)
+	    && $browser['majorver'] >= 3)
+	|| (preg_match('/blackberry/i', $user_agent)
+	    && $browser['majorver'] >= 5)
+	|| (preg_match('/opera mobile/i', $user_agent)
+	    && $browser['majorver'] >= 10)
+	|| (preg_match('/opera mini/i', $user_agent)
+	    && $browser['majorver'] >= 5);
 }
 function isFastDevice()
 {
@@ -139,5 +154,27 @@
 {
 	return str_replace(")", "</small>", str_replace("(", "<br><small>", $input));
 }
+function sksort(&$array, $subkey = "id", $sort_ascending = false)
+{
+	if (count($array)) $temp_array[key($array) ] = array_shift($array);
+	foreach ($array as $key => $val) {
+		$offset = 0;
+		$found = false;
+		foreach ($temp_array as $tmp_key => $tmp_val) {
+			if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) {
+				$temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array(
+					$key => $val
+				) , array_slice($temp_array, $offset));
+				$found = true;
+			}
+			$offset++;
+		}
+		if (!$found) $temp_array = array_merge($temp_array, array(
+			$key => $val
+		));
+	}
+	if ($sort_ascending) $array = array_reverse($temp_array);
+	else $array = $temp_array;
+}
 ?>
 

 Binary files a/css/images/113-navigation.png and b/css/images/113-navigation.png differ
--- a/css/jquery.ui.datepicker.mobile.css
+++ b/css/jquery.ui.datepicker.mobile.css
@@ -1,30 +1,18 @@
-/*
- * jQuery UI Datepicker @VERSION
- *
- * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Datepicker#theming
- */
-div.hasDatepicker{ display: block; padding: 0; overflow: visible;  margin: 8px 0; }
-.ui-datepicker {  overflow: visible; margin: 0; max-width: 500px;  }
-.ui-datepicker .ui-datepicker-header { position:relative; padding:.4em 0; border-bottom: 0; font-weight: bold; }
-.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { padding: 1px 0 1px 2px; position:absolute; top: .5em; margin-top: 0; text-indent: -9999px; }
+div.hasDatepicker{display:block;padding:0;overflow:visible;margin:8px 0;}
+.ui-datepicker{overflow:visible;margin:0;max-width:500px;}
+.ui-datepicker .ui-datepicker-header{position:relative;padding:.4em 0;border-bottom:0;font-weight:bold;}
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next{padding:1px 0 1px 2px;position:absolute;top:.5em;margin-top:0;text-indent:-9999px;}
+.ui-datepicker .ui-datepicker-prev{left:6px;}
+.ui-datepicker .ui-datepicker-next{right:6px;}
+.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center;}
+.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0;}
+.ui-datepicker select.ui-datepicker-month-year{width:100%;}
+.ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year{width:49%;}
+.ui-datepicker table{width:100%;border-collapse:collapse;margin:0;}
+.ui-datepicker td{border-width:1px;padding:0;text-align:center;}
+.ui-datepicker td span, .ui-datepicker td a{display:block;padding:.2em 0;font-weight:bold;margin:0;border-width:0;text-align:center;text-decoration:none;}
+.ui-datepicker-calendar th{padding-top:.3em;padding-bottom:.3em;}
+.ui-datepicker-calendar th span, .ui-datepicker-calendar span.ui-state-default{opacity:.3;}
+.ui-datepicker-calendar td a{padding-top:.5em;padding-bottom:.5em;}
+.min-width-480px div.hasDatepicker{width:63%;display:inline-block;margin:0;}
 
-.ui-datepicker .ui-datepicker-prev { left:6px; }
-.ui-datepicker .ui-datepicker-next { right:6px; }
-.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
-.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
-.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
-.ui-datepicker select.ui-datepicker-month, 
-.ui-datepicker select.ui-datepicker-year { width: 49%;}
-.ui-datepicker table {width: 100%; border-collapse: collapse; margin:0; }
-.ui-datepicker td { border-width: 1px; padding: 0; text-align: center; }
-.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em 0; font-weight: bold; margin: 0; border-width: 0; text-align: center; text-decoration: none; }
-
-.ui-datepicker-calendar th { padding-top: .3em; padding-bottom: .3em; }
-.ui-datepicker-calendar th span, .ui-datepicker-calendar span.ui-state-default { opacity: .3; }
-.ui-datepicker-calendar td a { padding-top: .5em; padding-bottom: .5em; }
-
-.min-width-480px div.hasDatepicker  { width: 63%; display: inline-block; margin: 0; } 

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -19,6 +19,7 @@
                 <li data-role="list-divider">Timetables - Routes</li>
                 <li><a href="routeList.php">Routes By Final Destination</a></li>
 		<li><a href="routeList.php?bynumber=yes">Routes By Number</a></li>
+		<li><a href="routeList.php?bysuburb=yes">Stops By Suburb</a></li>
 		<li><a class="nearby" href="routeList.php?nearby=yes">Nearby Routes</a></li>
             </ul>
 <?php

--- a/js/jQuery.ui.datepicker.js
+++ b/js/jQuery.ui.datepicker.js
@@ -95,4 +95,62 @@
 "dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=
 function(a){if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));
 return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new L;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.5";window["DP_jQuery_"+y]=d})(jQuery);
-;
+;/*
+* jQuery Mobile Framework : temporary extension to port jQuery UI's datepicker for mobile
+* Copyright (c) jQuery Project
+* Dual licensed under the MIT or GPL Version 2 licenses.
+* http://jquery.org/license
+*/
+(function($, undefined ) {
+
+	//cache previous datepicker ui method
+	var prevDp = $.fn.datepicker;
+	
+	//rewrite datepicker
+	$.fn.datepicker = function( options ){
+		
+		var dp = this;
+	
+		//call cached datepicker plugin
+		prevDp.call( this, options );
+		
+		//extend with some dom manipulation to update the markup for jQM
+		//call immediately
+		function updateDatepicker(){
+			$( ".ui-datepicker-header", dp ).addClass("ui-body-c ui-corner-top").removeClass("ui-corner-all");
+			$( ".ui-datepicker-prev, .ui-datepicker-next", dp ).attr("href", "#");
+			$( ".ui-datepicker-prev", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-l", shadow: true, corners: true});
+			$( ".ui-datepicker-next", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-r", shadow: true, corners: true});
+			$( ".ui-datepicker-calendar th", dp ).addClass("ui-bar-c");
+			$( ".ui-datepicker-calendar td", dp ).addClass("ui-body-c");
+			$( ".ui-datepicker-calendar a", dp ).buttonMarkup({corners: false, shadow: false}); 
+			$( ".ui-datepicker-calendar a.ui-state-active", dp ).addClass("ui-btn-active"); // selected date
+			$( ".ui-datepicker-calendar a.ui-state-highlight", dp ).addClass("ui-btn-up-e"); // today"s date
+	        $( ".ui-datepicker-calendar .ui-btn", dp ).each(function(){
+				var el = $(this);
+				// remove extra button markup - necessary for date value to be interpreted correctly
+				el.html( el.find( ".ui-btn-text" ).text() ); 
+	        });
+		};
+		
+		//update now
+		updateDatepicker();
+		
+		// and on click
+		$( dp ).click( updateDatepicker );
+		
+		//return jqm obj 
+		return this;
+	};
+		
+	//bind to pagecreate to automatically enhance date inputs	
+	$( ".ui-page" ).live( "pagecreate", function(){     
+		$( "#date, input[type='date'], input[data-type='date']" ).each(function(){
+		    if ($(this).hasClass("hasDatepicker") == false) {
+			$(this).after( $( "<div />" ).datepicker({ altField: "#" + $(this).attr( "id" ), showOtherMonths: true }) );
+			$(this).addClass("hasDatepicker");
+		    }
+		}); 
+    });
+})( jQuery );
+

--- a/js/jquery.ui.datepicker.mobile.js
+++ /dev/null
@@ -1,59 +1,1 @@
-/*
-* jQuery Mobile Framework : temporary extension to port jQuery UI's datepicker for mobile
-* Copyright (c) jQuery Project
-* Dual licensed under the MIT or GPL Version 2 licenses.
-* http://jquery.org/license
-*/
-(function($, undefined ) {
 
-	//cache previous datepicker ui method
-	var prevDp = $.fn.datepicker;
-	
-	//rewrite datepicker
-	$.fn.datepicker = function( options ){
-		
-		var dp = this;
-	
-		//call cached datepicker plugin
-		prevDp.call( this, options );
-		
-		//extend with some dom manipulation to update the markup for jQM
-		//call immediately
-		function updateDatepicker(){
-			$( ".ui-datepicker-header", dp ).addClass("ui-body-c ui-corner-top").removeClass("ui-corner-all");
-			$( ".ui-datepicker-prev, .ui-datepicker-next", dp ).attr("href", "#");
-			$( ".ui-datepicker-prev", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-l", shadow: true, corners: true});
-			$( ".ui-datepicker-next", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-r", shadow: true, corners: true});
-			$( ".ui-datepicker-calendar th", dp ).addClass("ui-bar-c");
-			$( ".ui-datepicker-calendar td", dp ).addClass("ui-body-c");
-			$( ".ui-datepicker-calendar a", dp ).buttonMarkup({corners: false, shadow: false}); 
-			$( ".ui-datepicker-calendar a.ui-state-active", dp ).addClass("ui-btn-active"); // selected date
-			$( ".ui-datepicker-calendar a.ui-state-highlight", dp ).addClass("ui-btn-up-e"); // today"s date
-	        $( ".ui-datepicker-calendar .ui-btn", dp ).each(function(){
-				var el = $(this);
-				// remove extra button markup - necessary for date value to be interpreted correctly
-				el.html( el.find( ".ui-btn-text" ).text() ); 
-	        });
-		};
-		
-		//update now
-		updateDatepicker();
-		
-		// and on click
-		$( dp ).click( updateDatepicker );
-		
-		//return jqm obj 
-		return this;
-	};
-		
-	//bind to pagecreate to automatically enhance date inputs	
-	$( ".ui-page" ).live( "pagecreate", function(){     
-		$( "#date, input[type='date'], input[data-type='date']" ).each(function(){
-		    if ($(this).hasClass("hasDatepicker") == false) {
-			$(this).after( $( "<div />" ).datepicker({ altField: "#" + $(this).attr( "id" ), showOtherMonths: true }) );
-			$(this).addClass("hasDatepicker");
-		    }
-		}); 
-    });
-})( jQuery );
-

--- a/layar_api.php
+++ b/layar_api.php
@@ -9,7 +9,6 @@
 $page_end = $max_page + filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT);
 $lat = filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
 $lon = filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
-if (isset($_REQUEST['radius'])) $radius = filter_var($_REQUEST['radius'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
 $url = $APIurl . "/json/neareststops?lat=$lat&lon=$lon&limit=50";
 $contents = json_decode(getPage($url));
 debug(print_r($contents, true));
@@ -24,24 +23,22 @@
 		$hotspot['lat'] = floor($row[2] * 1000000);
 		$hotspot['lon'] = floor($row[3] * 1000000);
 		$hotspot['distance'] = distance($row[2], $row[3], $_REQUEST['lat'], $_REQUEST['lon']);
-		if (!isset($_REQUEST['radius']) || $hotspot['distance'] < $radius) {
-			$hotspot['actions'] = Array(
-				Array(
-					"label" => 'View more trips/information',
-					'uri' => 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $row[0]
-				)
-			);
-			$url = $APIurl . "/json/stoptrips?stop=" . $row[0] . "&time=" . midnight_seconds() . "&service_period=" . service_period() . "&limit=4&time_range=" . str(90 * 60);
-			$trips = json_decode(getPage($url));
-			debug(print_r($trips, true));
-			foreach ($trips as $key => $row) {
-				if ($key < 3) {
-					$hotspot['line' . strval($key + 2) ] = $row[1][1] . ' @ ' . midnight_seconds_to_time($row[0]);
-				}
+		$hotspot['actions'] = Array(
+			Array(
+				"label" => 'View more trips/information',
+				'uri' => 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $row[0]
+			)
+		);
+		$url = $APIurl . "/json/stoptrips?stop=" . $row[0] . "&time=" . midnight_seconds() . "&service_period=" . service_period() . "&limit=4&time_range=" . strval(90 * 60);
+		$trips = json_decode(getPage($url));
+		debug(print_r($trips, true));
+		foreach ($trips as $key => $row) {
+			if ($key < 3) {
+				$hotspot['line' . strval($key + 2) ] = $row[1][1] . ' @ ' . midnight_seconds_to_time($row[0]);
 			}
-			if (sizeof($trips) == 0) $hotspot['line2'] = 'No trips in the near future.';
-			$output['hotspots'][] = $hotspot;
 		}
+		if (sizeof($trips) == 0) $hotspot['line2'] = 'No trips in the near future.';
+		$output['hotspots'][] = $hotspot;
 	}
 }
 if (sizeof($hotspot) > 0) {

--- a/myway_api.json.php
+++ b/myway_api.json.php
@@ -72,6 +72,7 @@
 	//close connection
 	curl_close($ch);
 }
+
 if (!isset($return['error'])) {
 	include_once ('simple_html_dom.php');
 	$page = str_get_html($pageHTML);
@@ -97,7 +98,8 @@
 			foreach ($table->find("tr") as $tr) {
 				$tableColumnNum = 0;
 				foreach ($tr->find("td") as $td) {
-					$return[$tableName[$tableNum]][$tableRowNum][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext);
+					if ($tableNum == 1) $return[$tableName[$tableNum]][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext);
+					else $return[$tableName[$tableNum]][$tableRowNum][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext);
 					$tableColumnNum++;
 				}
 				$tableRowNum++;
@@ -107,8 +109,8 @@
 }
 if (sizeof($return) == 0) {
 $return['error'][] = "No data extracted from MyWay website - API may be out of date";
-print $pageHTML;
 }
+
 header('Content-Type: text/javascript; charset=utf8');
 // header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/');
 header('Access-Control-Max-Age: 3628800');

file:b/mywaybalance.php (new)
--- /dev/null
+++ b/mywaybalance.php
@@ -1,1 +1,64 @@
+<?php
+include ('common.inc.php');
+include_header("MyWay Balance", "mywayBalance", true, false, true);
+$return = Array();
+function printBalance($cardNumber, $date, $pwrd)
+{
+	global $return;
+	$return = json_decode(getPage(curPageURL() . "/myway_api.json.php?card_number=$cardNumber&DOBday={$date[0]}&DOBmonth={$date[1]}&DOByear={$date[2]}&secret_answer=$pwrd"), true);
+    
+        if (isset($return['error'])) {
+            echo "<font color=red>" . var_dump($return['error']) . "</font>";
+        } else {
+		echo "<h2>Balance: " . $return['myway_carddetails']['Card Balance'] . "</h2>";
+		echo '<ul data-role="listview" data-inset="true"><li data-role="list-divider"> Recent Transactions </li>';
+		foreach ($return['myway_transactions'] as $transaction) {
+			echo "<li><b>" . $transaction["Date / Time"] . "</b>";
+                        echo "<br><small>" . $transaction["TX Reference No / Type"]. "</small>";
+                        echo '<p class="ui-li-aside">'.$transaction["TX Amount"].'</p>';
+			echo "</li>";
+		}
+		echo "</ul>";
+	}
+}
+if (isset($_REQUEST['card_number']) && isset($_REQUEST['date']) && isset($_REQUEST['secret_answer'])) {
+	$cardNumber = $_REQUEST['card_number'];
+	$date = explode("/", $_REQUEST['date']);
+	$pwrd = $_REQUEST['secret_answer'];
+	if ($_REQUEST['remember'] == true) {
+		$_COOKIE['card_number'] = $cardNumber;
+		$_COOKIE['date'] = $date;
+		$_COOKIE['secret_answer'] = $pwrd;
+	}
+	printBalance($cardNumber, $date, $pwrd);
+}
+else if (isset($_COOKIE['card_number']) && isset($_COOKIE['date']) && isset($_COOKIE['secret_answer'])) {
+	$cardNumber = $_COOKIE['card_number'];
+	$date = explode("/", $_COOKIE['date']);
+	$pwrd = $_COOKIE['secret_answer'];
+	printBalance($cardNumber, $date, $pwrd);
+}
+else {
+	$date = (isset($_REQUEST['date']) ? filter_var($_REQUEST['date'], FILTER_SANITIZE_STRING) : date("m/d/Y"));
+	echo '<form action="" method="post">
+    <div data-role="fieldcontain">
+        <label for="card_number">Card number</label>
+        <input type="text" name="card_number" id="card_number" value="' . $card_number . '"  />
+    </div>
+    <div data-role="fieldcontain">
+        <label for="date"> Date of birth </label>
+        <input type="text" name="date" id="date" value="' . $date . '"  />
+    </div>
+        <div data-role="fieldcontain">
+        <label for="secret_answer"> Secret question answer </label>
+        <input type="text" name="secret_answer" id="secret_answer" value="' . $secret_answer . '"  />
+    </div>
+        <div data-role="fieldcontain">
+        <label for="remember"> Remember these details? </label>
+        <input type="checkbox" name="remember" id="remember"  checked="yes"  />
+    </div>
+        <input type="submit" value="Go!"></form>';
+}
+include_footer();
+?>
 

file:a/owa/Callbacks.inc (deleted)
--- a/owa/Callbacks.inc
+++ /dev/null
@@ -1,10 +1,1 @@
-<?php
 
-
-/**
- * Gallery Template Callbacks class placeholder
- * Needed for fake out the require_once() in Gallery's template class callback method
- * See OWA Gallery module for the actual callback class
- */
-
-?>

file:a/owa/action.php (deleted)
--- a/owa/action.php
+++ /dev/null
@@ -1,48 +1,1 @@
-<?php
 
-//
-// Open Web Analytics - An Open Source Web Analytics Framework
-//
-// Copyright 2006 Peter Adams. All rights reserved.
-//
-// Licensed under GPL v2.0 http://www.gnu.org/copyleft/gpl.html
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// $Id$
-//
-
-include_once('owa_env.php');
-require_once(OWA_BASE_DIR.'/owa_php.php');
-
-/**
- * Special HTTP Requests Controler
- * 
- * @author      Peter Adams <peter@openwebanalytics.com>
- * @copyright   Copyright &copy; 2006 Peter Adams <peter@openwebanalytics.com>
- * @license     http://www.gnu.org/copyleft/gpl.html GPL v2.0
- * @category    owa
- * @package     owa
- * @version		$Revision$	      
- * @since		owa 1.0.0
- * @depricated
- */
-
-$owa = new owa_php;
-
-$owa->e->debug('Special action request received by action.php...');
-
-if ( $owa->isEndpointEnabled( basename( __FILE__ ) ) ) {
-
-	// run controller or view and echo page content
-	echo $owa->handleRequestFromURL();
-} else {
-	// unload owa
-	$owa->restInPeace();
-}
-
-?>

file:a/owa/api.php (deleted)
--- a/owa/api.php
+++ /dev/null
@@ -1,49 +1,1 @@
-<?php
 
-//
-// Open Web Analytics - An Open Source Web Analytics Framework
-//
-// Copyright 2006 Peter Adams. All rights reserved.
-//
-// Licensed under GPL v2.0 http://www.gnu.org/copyleft/gpl.html
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// $Id$
-//
-
-include_once('owa_env.php');
-require_once(OWA_BASE_DIR.'/owa_php.php');
-
-/**
- * REST API
- * 
- * @author      Peter Adams <peter@