Upgrade origin-src to google transit feed 1.2.6
Upgrade origin-src to google transit feed 1.2.6

 Binary files a/origin-src/transitfeed-1.2.5.tar.gz and /dev/null differ
--- a/origin-src/transitfeed-1.2.5/COPYING
+++ /dev/null
@@ -1,203 +1,1 @@
 
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   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.
-

--- a/origin-src/transitfeed-1.2.5/INSTALL
+++ /dev/null
@@ -1,22 +1,1 @@
-INSTALL file for transitfeed distribution
 
-
-
-To download and install in one step make sure you have easy-install installed and run
-easy_install transitfeed
-
-
-
-Since you got this far chances are you have downloaded a copy of the source
-code. Install with the command
-
-python setup.py install
-
-
-
-If you don't want to install you may be able to run the scripts from this
-directory. For example, try running
-
-./feedvalidator.py -n test/data/good_feed.zip
-
-

--- a/origin-src/transitfeed-1.2.5/PKG-INFO
+++ /dev/null
@@ -1,21 +1,1 @@
-Metadata-Version: 1.0
-Name: transitfeed
-Version: 1.2.5
-Summary: Google Transit Feed Specification library and tools
-Home-page: http://code.google.com/p/googletransitdatafeed/
-Author: Tom Brown
-Author-email: tom.brown.code@gmail.com
-License: Apache License, Version 2.0
-Download-URL: http://googletransitdatafeed.googlecode.com/files/transitfeed-1.2.5.tar.gz
-Description: This module provides a library for reading, writing and validating Google Transit Feed Specification files. It includes some scripts that validate a feed, display it using the Google Maps API and the start of a KML importer and exporter.
-Platform: OS Independent
-Classifier: Development Status :: 4 - Beta
-Classifier: Intended Audience :: Developers
-Classifier: Intended Audience :: Information Technology
-Classifier: Intended Audience :: Other Audience
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Topic :: Scientific/Engineering :: GIS
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
 

--- a/origin-src/transitfeed-1.2.5/README
+++ /dev/null
@@ -1,19 +1,1 @@
-README file for transitfeed distribution
 
-
-
-This distribution contains a library to help you parse and generate Google
-Transit Feed files. It also contains some sample tools that demonstrate the
-library and are useful in their own right when maintaining Google
-Transit Feed files. You may fetch the specification from
-http://code.google.com/transit/spec/transit_feed_specification.htm
-
-
-See INSTALL for installation instructions
-
-The most recent source can be downloaded from our subversion repository at
-http://googletransitdatafeed.googlecode.com/svn/trunk/python/
-
-See http://code.google.com/p/googletransitdatafeed/wiki/TransitFeedDistribution
-for more information.
-

--- a/origin-src/transitfeed-1.2.5/build/lib/gtfsscheduleviewer/__init__.py
+++ /dev/null
@@ -1,9 +1,1 @@
-__doc__ = """
-Package holding files for Google Transit Feed Specification Schedule Viewer.
-"""
-# This package contains the data files for schedule_viewer.py, a script that
-# comes with the transitfeed distribution. According to the thread
-# "[Distutils] distutils data_files and setuptools.pkg_resources are driving
-# me crazy" this is the easiest way to include data files. My experience
-# agrees. - Tom 2007-05-29
 

--- a/origin-src/transitfeed-1.2.5/build/lib/gtfsscheduleviewer/files/index.html
+++ /dev/null
@@ -1,706 +1,1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
-  <head>
-    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
-    <title>[agency]</title>
-    <link href="file/style.css" rel="stylesheet" type="text/css" />
-    <style type="text/css">
-    v\:* {
-      behavior:url(#default#VML);
-    }
-    </style>
-    <script src="http://[host]/maps?file=api&amp;v=2&amp;key=[key]" type="text/javascript"></script>
-    <script src="/file/labeled_marker.js" type="text/javascript"></script>
-    <script language="VBScript" src="/file/svgcheck.vbs"></script>
-    <script type="text/javascript">
-    //<![CDATA[
-    var map;
-    // Set to true when debugging for log statements about HTTP requests.
-    var log = false;
-    var twelveHourTime = false;  // set to true to see AM/PM
-    var selectedRoute = null;
-    var forbid_editing = [forbid_editing];
 
-    function load() {
-      if (GBrowserIsCompatible()) {
-        sizeRouteList();
-        var map_dom = document.getElementById("map");
-        map = new GMap2(map_dom);
-        map.addControl(new GLargeMapControl());
-        map.addControl(new GMapTypeControl());
-        map.addControl(new GOverviewMapControl());
-        map.enableScrollWheelZoom();
-        var bb = new GLatLngBounds(new GLatLng([min_lat], [min_lon]),new GLatLng([max_lat], [max_lon]));
-        map.setCenter(bb.getCenter(), map.getBoundsZoomLevel(bb));
-        map.enableDoubleClickZoom();
-        initIcons();
-        GEvent.addListener(map, "moveend", callbackMoveEnd);
-        GEvent.addListener(map, "zoomend", callbackZoomEnd);
-        callbackMoveEnd();  // Pretend we just moved to current center
-        fetchRoutes();
-      }
-    }
-
-    function callbackZoomEnd() {
-    }
-
-    function callbackMoveEnd() {
-      // Map moved, search for stops near the center
-      fetchStopsInBounds(map.getBounds());
-    }
-
-    /**
-     * Fetch a sample of stops in the bounding box.
-     */
-    function fetchStopsInBounds(bounds) {
-      url = "/json/boundboxstops?n=" + bounds.getNorthEast().lat()
-                             + "&e=" + bounds.getNorthEast().lng()
-                             + "&s=" + bounds.getSouthWest().lat()
-                             + "&w=" + bounds.getSouthWest().lng()
-                             + "&limit=50";
-      if (log)
-        GLog.writeUrl(url);
-      GDownloadUrl(url, callbackDisplayStopsBackground);
-    }
-
-    /**
-     * Displays stops returned by the server on the map. Expected to be called
-     * when GDownloadUrl finishes.
-     *
-     * @param {String} data JSON encoded list of list, each
-     *     containing a row of stops.txt
-     * @param {Number} responseCode Response code from server
-     */
-    function callbackDisplayStops(data, responseCode) {
-      if (responseCode != 200) {
-        return;
-      }
-      clearMap();
-      var stops = eval(data);
-      if (stops.length == 1) {
-        var marker = addStopMarkerFromList(stops[0], true);
-        fetchStopInfoWindow(marker);
-      } else {
-        for (var i=0; i<stops.length; ++i) {
-          addStopMarkerFromList(stops[i], true);
-        }
-      }
-    }
-
-    function stopTextSearchSubmit() {
-      var text = document.getElementById("stopTextSearchInput").value;
-      var url = "/json/stopsearch?q=" + text;  // TODO URI escape
-      if (log)
-        GLog.writeUrl(url);
-      GDownloadUrl(url, callbackDisplayStops);
-    }
-
-    function tripTextSearchSubmit() {
-      var text = document.getElementById("tripTextSearchInput").value;
-      selectTrip(text);
-    }
-
-    /**
-     * Add stops markers to the map and remove stops no longer in the
-     * background.
-     */
-    function callbackDisplayStopsBackground(data, responseCode) {
-      if (responseCode != 200) {
-        return;
-      }
-      var stops = eval(data);
-      // Make a list of all background markers
-      var oldStopMarkers = {};
-      for (var stopId in stopMarkersBackground) {
-        oldStopMarkers[stopId] = 1;
-      }
-      // Add new markers to the map and remove from oldStopMarkers
-      for (var i=0; i<stops.length; ++i) {
-        var marker = addStopMarkerFromList(stops[i], false);
-        if (oldStopMarkers[marker.stopId]) {
-          delete oldStopMarkers[marker.stopId];
-        }
-      }
-      // Delete all markers that remain in oldStopMarkers
-      for (var stopId in oldStopMarkers) {
-        GEvent.removeListener(stopMarkersBackground[stopId].clickListener);
-        map.removeOverlay(stopMarkersBackground[stopId]);
-        delete stopMarkersBackground[stopId]
-      }
-    }
-
-    /**
-     * Remove all overlays from the map
-     */
-    function clearMap() {
-      boundsOfPolyLine = null;
-      for (var stopId in stopMarkersSelected) {
-        GEvent.removeListener(stopMarkersSelected[stopId].clickListener);
-      }
-      for (var stopId in stopMarkersBackground) {
-        GEvent.removeListener(stopMarkersBackground[stopId].clickListener);
-      }
-      stopMarkersSelected = {};
-      stopMarkersBackground = {};
-      map.clearOverlays();
-    }
-
-    /**
-     * Return a new GIcon used for stops
-     */
-    function makeStopIcon() {
-      var icon = new GIcon();
-      icon.iconSize = new GSize(12, 20);
-      icon.shadowSize = new GSize(22, 20);
-      icon.iconAnchor = new GPoint(6, 20);
-      icon.infoWindowAnchor = new GPoint(5, 1);
-      return icon;
-    }
-
-    /**
-     * Initialize icons. Call once during load.
-     */
-    function initIcons() {
-      iconSelected = makeStopIcon();
-      iconSelected.image = "/file/mm_20_yellow.png";
-      iconSelected.shadow = "/file/mm_20_shadow.png";
-      iconBackground = makeStopIcon();
-      iconBackground.image = "/file/mm_20_blue_trans.png";
-      iconBackground.shadow = "/file/mm_20_shadow_trans.png";
-      iconBackgroundStation = makeStopIcon();
-      iconBackgroundStation.image = "/file/mm_20_red_trans.png";
-      iconBackgroundStation.shadow = "/file/mm_20_shadow_trans.png";
-    }
-
-    var iconSelected;
-    var iconBackground;
-    var iconBackgroundStation;
-    // Map from stopId to GMarker object for stops selected because they are
-    // part of a trip, etc
-    var stopMarkersSelected = {};
-    // Map from stopId to GMarker object for stops found by the background
-    // passive search
-    var stopMarkersBackground = {};
-    /**
-     * Add a stop to the map, given a row from stops.txt.
-     */
-    function addStopMarkerFromList(list, selected, text) {
-      return addStopMarker(list[0], list[1], list[2], list[3], list[4], selected, text);
-    }
-
-    /**
-     * Add a stop to the map, returning the new marker
-     */
-    function addStopMarker(stopId, stopName, stopLat, stopLon, locationType, selected, text) {
-      if (stopMarkersSelected[stopId]) {
-        // stop was selected
-	var marker = stopMarkersSelected[stopId];
-	if (text) {
-          oldText = marker.getText();
-          if (oldText) {
-            oldText = oldText + "<br>";
-          }
-          marker.setText(oldText + text);
-	}
-        return marker;
-      }
-      if (stopMarkersBackground[stopId]) {
-        // Stop was in the background. Either delete it from the background or
-        // leave it where it is.
-        if (selected) {
-          map.removeOverlay(stopMarkersBackground[stopId]);
-          delete stopMarkersBackground[stopId];
-        } else {
-          return stopMarkersBackground[stopId];
-        }
-      }
-
-      var icon;
-      if (selected) {
-        icon = iconSelected;
-      } else if (locationType == 1)  {
-        icon = iconBackgroundStation
-      } else {
-        icon = iconBackground;
-      }
-      var ll = new GLatLng(stopLat,stopLon);
-      var marker;
-      if (selected || text) {
-        if (!text) {
-          text = "";  // Make sure every selected icon has a text box, even if empty
-        }
-        var markerOpts = new Object();
-        markerOpts.icon = icon;
-        markerOpts.labelText = text;
-        markerOpts.labelClass = "tooltip";
-        markerOpts.labelOffset = new GSize(6, -20);
-        marker = new LabeledMarker(ll, markerOpts);
-      } else {
-        marker = new GMarker(ll, {icon: icon, draggable: !forbid_editing});
-      }
-      marker.stopName = stopName;
-      marker.stopId = stopId;
-      if (selected) {
-        stopMarkersSelected[stopId] = marker;
-      } else {
-        stopMarkersBackground[stopId] = marker;
-      }
-      map.addOverlay(marker);
-      marker.clickListener = GEvent.addListener(marker, "click", function() {fetchStopInfoWindow(marker);});
-      GEvent.addListener(marker, "dragend", function() {
-        
-        document.getElementById("edit").style.visibility = "visible";
-        document.getElementById("edit_status").innerHTML = "updating..."
-        changeStopLocation(marker);
-      });
-      return marker;
-    }
-    
-    /**
-     * Sends new location of a stop to server.
-     */
-    function changeStopLocation(marker) {
-      var url = "/json/setstoplocation?id=" +
-      			encodeURIComponent(marker.stopId) +
-                "&lat=" + encodeURIComponent(marker.getLatLng().lat()) + 
-                "&lng=" + encodeURIComponent(marker.getLatLng().lng());
-      GDownloadUrl(url, function(data, responseCode) {
-          document.getElementById("edit_status").innerHTML = unescape(data);
-          } );
-      if (log)
-        GLog.writeUrl(url);
-    }
-
-    /**
-     * Saves the current state of the data file opened at server side to file.
-     */
-    function saveData() {
-      var url = "/json/savedata";
-      GDownloadUrl(url, function(data, responseCode) {
-          document.getElementById("edit_status").innerHTML = data;} );
-      if (log)
-        GLog.writeUrl(url);
-    }
-
-    /**
-     * Fetch the next departing trips from the stop for display in an info
-     * window.
-     */
-    function fetchStopInfoWindow(marker) {
-      var url = "/json/stoptrips?stop=" + encodeURIComponent(marker.stopId) + "&time=" + parseTimeInput();
-      GDownloadUrl(url, function(data, responseCode) {
-          callbackDisplayStopInfoWindow(marker, data, responseCode); } );
-      if (log)
-        GLog.writeUrl(url);
-    }
-
-    function callbackDisplayStopInfoWindow(marker, data, responseCode) {
-      if (responseCode != 200) {
-        return;
-      }
-      var timeTrips = eval(data);
-      var html = "<b>" + marker.stopName + "</b> (" + marker.stopId + ")<br>";
-      var latLng = marker.getLatLng();
-      html = html + "(" + latLng.lat() + ", " + latLng.lng() + ")<br>";
-      html = html + "<table><tr><th>service_id<th>time<th>name</tr>";
-      for (var i=0; i < timeTrips.length; ++i) {
-        var time = timeTrips[i][0];
-        var tripid = timeTrips[i][1][0];
-        var tripname = timeTrips[i][1][1];
-        var service_id = timeTrips[i][1][2];
-        var timepoint = timeTrips[i][2];
-        html = html + "<tr onClick='map.closeInfoWindow();selectTrip(\"" +
-          tripid + "\")'>" +
-          "<td>" + service_id +
-          "<td align='right'>" + (timepoint ? "" : "~") +
-          formatTime(time) + "<td>" + tripname + "</tr>";
-      }
-      html = html + "</table>";
-      marker.openInfoWindowHtml(html);
-    }
-
-    function leadingZero(digit) {
-      if (digit < 10)
-        return "0" + digit;
-      else
-        return "" + digit;
-    }
-
-    function formatTime(secSinceMidnight) {
-      var hours = Math.floor(secSinceMidnight / 3600);
-      var suffix = "";
-
-      if (twelveHourTime) {
-        suffix = (hours >= 12) ? "p" : "a";
-        suffix += (hours >= 24) ? " next day" : "";
-        hours = hours % 12;
-        if (hours == 0)
-          hours = 12;
-      }
-      var minutes = Math.floor(secSinceMidnight / 60) % 60;
-      var seconds = secSinceMidnight % 60;
-      if (seconds == 0) {
-        return hours + ":" + leadingZero(minutes) + suffix;
-      } else {
-        return hours + ":" + leadingZero(minutes) + ":" + leadingZero(seconds) + suffix;
-      }
-    }
-
-    function parseTimeInput() {
-      var text = document.getElementById("timeInput").value;
-      var m = text.match(/([012]?\d):([012345]?\d)(:([012345]?\d))?/);
-      if (m) {
-        var seconds = parseInt(m[1], 10) * 3600;
-        seconds += parseInt(m[2], 10) * 60;
-        if (m[4]) {
-          second += parseInt(m[4], 10);
-        }
-        return seconds;
-      } else {
-        if (log)
-          GLog.write("Couldn't match " + text);
-      }
-    }
-
-    /**
-     * Create a string of dots that gets longer with the log of count.
-     */
-    function countToRepeatedDots(count) {
-      // Find ln_2(count) + 1
-      var logCount = Math.ceil(Math.log(count) / 0.693148) + 1;
-      return new Array(logCount + 1).join(".");
-    }
-
-    function fetchRoutes() {
-      url = "/json/routes";
-      if (log)
-        GLog.writeUrl(url);
-      GDownloadUrl(url, callbackDisplayRoutes);
-    }
-
-    function callbackDisplayRoutes(data, responseCode) {
-      if (responseCode != 200) {
-        patternDiv.appendChild(div);
-      }
-      var routes = eval(data);
-      var routesList = document.getElementById("routeList");
-      while (routesList.hasChildNodes()) {
-        routesList.removeChild(routesList.firstChild);
-      }
-      for (i = 0; i < routes.length; ++i) {
-        var routeId = routes[i][0];
-        var shortName = document.createElement("span");
-        shortName.className = "shortName";
-        shortName.appendChild(document.createTextNode(routes[i][1] + " "));
-        var routeName = routes[i][2];
-        var elem = document.createElement("div");
-        elem.appendChild(shortName);
-        elem.appendChild(document.createTextNode(routeName));
-        elem.id = "route_" + routeId;
-        elem.className = "routeChoice";
-        elem.title = routeName;
-        GEvent.addDomListener(elem, "click", makeClosure(selectRoute, routeId));
-
-        var routeContainer = document.createElement("div");
-        routeContainer.id = "route_container_" + routeId;
-        routeContainer.className = "routeContainer";
-        routeContainer.appendChild(elem);
-        routesList.appendChild(routeContainer);
-      }
-    }
-
-    function selectRoute(routeId) {
-      var routesList = document.getElementById("routeList");
-      routeSpans = routesList.getElementsByTagName("div");
-      for (var i = 0; i < routeSpans.length; ++i) {
-        if (routeSpans[i].className == "routeChoiceSelected") {
-          routeSpans[i].className = "routeChoice";
-        }
-      }
-
-      // remove any previously-expanded route
-      var tripInfo = document.getElementById("tripInfo");
-      if (tripInfo)
-        tripInfo.parentNode.removeChild(tripInfo);
-
-      selectedRoute = routeId;
-      var span = document.getElementById("route_" + routeId);
-      span.className = "routeChoiceSelected";
-      fetchPatterns(routeId);
-    }
-
-    function fetchPatterns(routeId) {
-      url = "/json/routepatterns?route=" + encodeURIComponent(routeId) + "&time=" + parseTimeInput();
-      if (log)
-        GLog.writeUrl(url);
-      GDownloadUrl(url, callbackDisplayPatterns);
-    }
-
-    function callbackDisplayPatterns(data, responseCode) {
-      if (responseCode != 200) {
-        return;
-      }
-      var div = document.createElement("div");
-      div.className = "tripSection";
-      div.id = "tripInfo";
-      var firstTrip = null;
-      var patterns = eval(data);
-      clearMap();
-      for (i = 0; i < patterns.length; ++i) {
-        patternDiv = document.createElement("div")
-        patternDiv.className = 'patternSection';
-        div.appendChild(patternDiv)
-        var pat = patterns[i];  // [patName, patId, len(early trips), trips, len(later trips), has_non_zero_trip_type]
-        if (pat[5] == '1') {
-          patternDiv.className += " unusualPattern"
-        }
-        patternDiv.appendChild(document.createTextNode(pat[0]));
-        patternDiv.appendChild(document.createTextNode(", " + (pat[2] + pat[3].length + pat[4]) + " trips: "));
-        if (pat[2] > 0) {
-          patternDiv.appendChild(document.createTextNode(countToRepeatedDots(pat[2]) + " "));
-        }
-        for (j = 0; j < pat[3].length; ++j) {
-          var trip = pat[3][j];
-          var tripId = trip[1];
-          if ((i == 0) && (j == 0))
-            firstTrip = tripId;
-          patternDiv.appendChild(document.createTextNode(" "));
-          var sp