Add geositemaps starting with route map
Add geositemaps starting with route map

# PostgreSQL Client Authentication Configuration File # PostgreSQL Client Authentication Configuration File
# =================================================== # ===================================================
# #
# Refer to the "Client Authentication" section in the # Refer to the "Client Authentication" section in the
# PostgreSQL documentation for a complete description # PostgreSQL documentation for a complete description
# of this file. A short synopsis follows. # of this file. A short synopsis follows.
# #
# This file controls: which hosts are allowed to connect, how clients # This file controls: which hosts are allowed to connect, how clients
# are authenticated, which PostgreSQL user names they can use, which # are authenticated, which PostgreSQL user names they can use, which
# databases they can access. Records take one of these forms: # databases they can access. Records take one of these forms:
# #
# local DATABASE USER METHOD [OPTIONS] # local DATABASE USER METHOD [OPTIONS]
# host DATABASE USER CIDR-ADDRESS METHOD [OPTIONS] # host DATABASE USER CIDR-ADDRESS METHOD [OPTIONS]
# hostssl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS] # hostssl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS]
# hostnossl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS] # hostnossl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS]
# #
# (The uppercase items must be replaced by actual values.) # (The uppercase items must be replaced by actual values.)
# #
# The first field is the connection type: "local" is a Unix-domain socket, # The first field is the connection type: "local" is a Unix-domain socket,
# "host" is either a plain or SSL-encrypted TCP/IP socket, "hostssl" is an # "host" is either a plain or SSL-encrypted TCP/IP socket, "hostssl" is an
# SSL-encrypted TCP/IP socket, and "hostnossl" is a plain TCP/IP socket. # SSL-encrypted TCP/IP socket, and "hostnossl" is a plain TCP/IP socket.
# #
# DATABASE can be "all", "sameuser", "samerole", a database name, or # DATABASE can be "all", "sameuser", "samerole", a database name, or
# a comma-separated list thereof. # a comma-separated list thereof.
# #
# USER can be "all", a user name, a group name prefixed with "+", or # USER can be "all", a user name, a group name prefixed with "+", or
# a comma-separated list thereof. In both the DATABASE and USER fields # a comma-separated list thereof. In both the DATABASE and USER fields
# you can also write a file name prefixed with "@" to include names from # you can also write a file name prefixed with "@" to include names from
# a separate file. # a separate file.
# #
# CIDR-ADDRESS specifies the set of hosts the record matches. # CIDR-ADDRESS specifies the set of hosts the record matches.
# It is made up of an IP address and a CIDR mask that is an integer # It is made up of an IP address and a CIDR mask that is an integer
# (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that specifies # (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that specifies
# the number of significant bits in the mask. Alternatively, you can write # the number of significant bits in the mask. Alternatively, you can write
# an IP address and netmask in separate columns to specify the set of hosts. # an IP address and netmask in separate columns to specify the set of hosts.
# #
# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi", "krb5", # METHOD can be "trust", "reject", "md5", "password", "gss", "sspi", "krb5",
# "ident", "pam", "ldap" or "cert". Note that "password" sends passwords # "ident", "pam", "ldap" or "cert". Note that "password" sends passwords
# in clear text; "md5" is preferred since it sends encrypted passwords. # in clear text; "md5" is preferred since it sends encrypted passwords.
# #
# OPTIONS are a set of options for the authentication in the format # OPTIONS are a set of options for the authentication in the format
# NAME=VALUE. The available options depend on the different authentication # NAME=VALUE. The available options depend on the different authentication
# methods - refer to the "Client Authentication" section in the documentation # methods - refer to the "Client Authentication" section in the documentation
# for a list of which options are available for which authentication methods. # for a list of which options are available for which authentication methods.
# #
# Database and user names containing spaces, commas, quotes and other special # Database and user names containing spaces, commas, quotes and other special
# characters must be quoted. Quoting one of the keywords "all", "sameuser" or # characters must be quoted. Quoting one of the keywords "all", "sameuser" or
# "samerole" makes the name lose its special character, and just match a # "samerole" makes the name lose its special character, and just match a
# database or username with that name. # database or username with that name.
# #
# This file is read on server startup and when the postmaster receives # This file is read on server startup and when the postmaster receives
# a SIGHUP signal. If you edit the file on a running system, you have # a SIGHUP signal. If you edit the file on a running system, you have
# to SIGHUP the postmaster for the changes to take effect. You can use # to SIGHUP the postmaster for the changes to take effect. You can use
# "pg_ctl reload" to do that. # "pg_ctl reload" to do that.
   
# Put your actual configuration here # Put your actual configuration here
# ---------------------------------- # ----------------------------------
# #
# If you want to allow non-local connections, you need to add more # If you want to allow non-local connections, you need to add more
# "host" records. In that case you will also need to make PostgreSQL listen # "host" records. In that case you will also need to make PostgreSQL listen
# on a non-local interface via the listen_addresses configuration parameter, # on a non-local interface via the listen_addresses configuration parameter,
# or via the -i or -h command line switches. # or via the -i or -h command line switches.
# #
   
   
   
# TYPE DATABASE USER CIDR-ADDRESS METHOD # TYPE DATABASE USER CIDR-ADDRESS METHOD
   
# "local" is for Unix domain socket connections only # "local" is for Unix domain socket connections only
local all all trust local all all trust
# IPv4 local connections: # IPv4 local connections:
host all all 127.0.0.1/32 trust host all all 127.0.0.1/32 trust
# IPv6 local connections: # IPv6 local connections:
host all all ::1/128 trust host all all ::1/128 trust
  #Allow any IP to connect, with a password:
  host all all 0.0.0.0 0.0.0.0 md5
   
  # -----------------------------
  # PostgreSQL configuration file
  # -----------------------------
  #
  # This file consists of lines of the form:
  #
  # name = value
  #
  # (The "=" is optional.) Whitespace may be used. Comments are introduced with
  # "#" anywhere on a line. The complete list of parameter names and allowed
  # values can be found in the PostgreSQL documentation.
  #
  # The commented-out settings shown in this file represent the default values.
  # Re-commenting a setting is NOT sufficient to revert it to the default value;
  # you need to reload the server.
  #
  # This file is read on server startup and when the server receives a SIGHUP
  # signal. If you edit the file on a running system, you have to SIGHUP the
  # server for the changes to take effect, or use "pg_ctl reload". Some
  # parameters, which are marked below, require a server shutdown and restart to
  # take effect.
  #
  # Any parameter can also be given as a command-line option to the server, e.g.,
  # "postgres -c log_connections=on". Some parameters can be changed at run time
  # with the "SET" SQL command.
  #
  # Memory units: kB = kilobytes Time units: ms = milliseconds
  # MB = megabytes s = seconds
  # GB = gigabytes min = minutes
  # h = hours
  # d = days
 
 
  #------------------------------------------------------------------------------
  # FILE LOCATIONS
  #------------------------------------------------------------------------------
 
  # The default values of these variables are driven from the -D command-line
  # option or PGDATA environment variable, represented here as ConfigDir.
 
  #data_directory = 'ConfigDir' # use data in another directory
  # (change requires restart)
  #hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file
  # (change requires restart)
  #ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file
  # (change requires restart)
 
  # If external_pid_file is not explicitly set, no extra PID file is written.
  #external_pid_file = '(none)' # write an extra PID file
  # (change requires restart)
 
 
  #------------------------------------------------------------------------------
  # CONNECTIONS AND AUTHENTICATION
  #------------------------------------------------------------------------------
 
  # - Connection Settings -
 
  listen_addresses = '*' # what IP address(es) to listen on;
  # comma-separated list of addresses;
  # defaults to 'localhost', '*' = all
  # (change requires restart)
  #port = 5432 # (change requires restart)
  max_connections = 100 # (change requires restart)
  # Note: Increasing max_connections costs ~400 bytes of shared memory per
  # connection slot, plus lock space (see max_locks_per_transaction).
  #superuser_reserved_connections = 3 # (change requires restart)
  #unix_socket_directory = '' # (change requires restart)
  #unix_socket_group = '' # (change requires restart)
  #unix_socket_permissions = 0777 # begin with 0 to use octal notation
  # (change requires restart)
  #bonjour_name = '' # defaults to the computer name
  # (change requires restart)
 
  # - Security and Authentication -
 
  #authentication_timeout = 1min # 1s-600s
  #ssl = off # (change requires restart)
  #ssl_ciphers = 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers
  # (change requires restart)
  #ssl_renegotiation_limit = 512MB # amount of data between renegotiations
  #password_encryption = on
  #db_user_namespace = off
 
  # Kerberos and GSSAPI
  #krb_server_keyfile = ''
  #krb_srvname = 'postgres' # (Kerberos only)
  #krb_caseins_users = off
 
  # - TCP Keepalives -
  # see "man 7 tcp" for details
 
  #tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds;
  # 0 selects the system default
  #tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds;
  # 0 selects the system default
  #tcp_keepalives_count = 0 # TCP_KEEPCNT;
  # 0 selects the system default
 
 
  #------------------------------------------------------------------------------
  # RESOURCE USAGE (except WAL)
  #------------------------------------------------------------------------------
 
  # - Memory -
 
  shared_buffers = 32MB # min 128kB
  # (change requires restart)
  #temp_buffers = 8MB # min 800kB
  #max_prepared_transactions = 0 # zero disables the feature
  # (change requires restart)
  # Note: Increasing max_prepared_transactions costs ~600 bytes of shared memory
  # per transaction slot, plus lock space (see max_locks_per_transaction).
  # It is not advisable to set max_prepared_transactions nonzero unless you
  # actively intend to use prepared transactions.
  #work_mem = 1MB # min 64kB
  #maintenance_work_mem = 16MB # min 1MB
  #max_stack_depth = 2MB # min 100kB
 
  # - Kernel Resource Usage -
 
  #max_files_per_process = 1000 # min 25
  # (change requires restart)
  #shared_preload_libraries = '' # (change requires restart)
 
  # - Cost-Based Vacuum Delay -
 
  #vacuum_cost_delay = 0ms # 0-100 milliseconds
  #vacuum_cost_page_hit = 1 # 0-10000 credits
  #vacuum_cost_page_miss = 10 # 0-10000 credits
  #vacuum_cost_page_dirty = 20 # 0-10000 credits
  #vacuum_cost_limit = 200 # 1-10000 credits
 
  # - Background Writer -
 
  #bgwriter_delay = 200ms # 10-10000ms between rounds
  #bgwriter_lru_maxpages = 100 # 0-1000 max buffers written/round
  #bgwriter_lru_multiplier = 2.0 # 0-10.0 multipler on buffers scanned/round
 
  # - Asynchronous Behavior -
 
  #effective_io_concurrency = 1 # 1-1000. 0 disables prefetching
 
 
  #------------------------------------------------------------------------------
  # WRITE AHEAD LOG
  #------------------------------------------------------------------------------
 
  # - Settings -
 
  #fsync = on # turns forced synchronization on or off
  #synchronous_commit = on # immediate fsync at commit
  #wal_sync_method = fsync # the default is the first option
  # supported by the operating system:
  # open_datasync
  # fdatasync
  # fsync
  # fsync_writethrough
  # open_sync
  #full_page_writes = on # recover from partial page writes
  #wal_buffers = 64kB # min 32kB
  # (change requires restart)
  #wal_writer_delay = 200ms # 1-10000 milliseconds
 
  #commit_delay = 0 # range 0-100000, in microseconds
  #commit_siblings = 5 # range 1-1000
 
  # - Checkpoints -
 
  #checkpoint_segments = 3 # in logfile segments, min 1, 16MB each
  #checkpoint_timeout = 5min # range 30s-1h
  #checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0
  #checkpoint_warning = 30s # 0 disables
 
  # - Archiving -
 
  #archive_mode = off # allows archiving to be done
  # (change requires restart)
  #archive_command = '' # command to use to archive a logfile segment
  #archive_timeout = 0 # force a logfile segment switch after this
  # number of seconds; 0 disables
 
 
  #------------------------------------------------------------------------------
  # QUERY TUNING
  #------------------------------------------------------------------------------
 
  # - Planner Method Configuration -
 
  #enable_bitmapscan = on
  #enable_hashagg = on
  #enable_hashjoin = on
  #enable_indexscan = on
  #enable_mergejoin = on
  #enable_nestloop = on
  #enable_seqscan = on
  #enable_sort = on
  #enable_tidscan = on
 
  # - Planner Cost Constants -
 
  #seq_page_cost = 1.0 # measured on an arbitrary scale
  #random_page_cost = 4.0 # same scale as above
  #cpu_tuple_cost = 0.01 # same scale as above
  #cpu_index_tuple_cost = 0.005 # same scale as above
  #cpu_operator_cost = 0.0025 # same scale as above
  #effective_cache_size = 128MB
 
  # - Genetic Query Optimizer -
 
  #geqo = on
  #geqo_threshold = 12
  #geqo_effort = 5 # range 1-10
  #geqo_pool_size = 0 # selects default based on effort
  #geqo_generations = 0 # selects default based on effort
  #geqo_selection_bias = 2.0 # range 1.5-2.0
 
  # - Other Planner Options -
 
  #default_statistics_target = 100 # range 1-10000
  #constraint_exclusion = partition # on, off, or partition
  #cursor_tuple_fraction = 0.1 # range 0.0-1.0
  #from_collapse_limit = 8
  #join_collapse_limit = 8 # 1 disables collapsing of explicit
  # JOIN clauses
 
 
  #------------------------------------------------------------------------------
  # ERROR REPORTING AND LOGGING
  #------------------------------------------------------------------------------
 
  # - Where to Log -
 
  #log_destination = 'stderr' # Valid values are combinations of
  # stderr, csvlog, syslog and eventlog,
  # depending on platform. csvlog
  # requires logging_collector to be on.
 
  # This is used when logging to stderr:
  logging_collector = on # Enable capturing of stderr and csvlog
  # into log files. Required to be on for
  # csvlogs.
  # (change requires restart)
 
  # These are only used if logging_collector is on:
  log_directory = 'pg_log' # directory where log files are written,
  # can be absolute or relative to PGDATA
  log_filename = 'postgresql-%a.log' # log file name pattern,
  # can include strftime() escapes
  log_truncate_on_rotation = on # If on, an existing log file of the
  # same name as the new log file will be
  # truncated rather than appended to.
  # But such truncation only occurs on
  # time-driven rotation, not on restarts
  # or size-driven rotation. Default is
  # off, meaning append to existing files
  # in all cases.
  log_rotation_age = 1d # Automatic rotation of logfiles will
  # happen after that time. 0 disables.
  log_rotation_size = 0 # Automatic rotation of logfiles will
  # happen after that much log output.
  # 0 disables.
 
  # These are relevant when logging to syslog:
  #syslog_facility = 'LOCAL0'
  #syslog_ident = 'postgres'
 
  #silent_mode = off # Run server silently.
  # DO NOT USE without syslog or
  # logging_collector
  # (change requires restart)
 
 
  # - When to Log -
 
  #client_min_messages = notice # values in order of decreasing detail:
  # debug5
  # debug4
  # debug3
  # debug2
  # debug1
  # log
  # notice
  # warning
  # error
 
  #log_min_messages = warning # values in order of decreasing detail:
  # debug5
  # debug4
  # debug3
  # debug2
  # debug1
  # info
  # notice
  # warning
  # error
  # log
  # fatal
  # panic
 
  #log_error_verbosity = default # terse, default, or verbose messages
 
  #log_min_error_statement = error # values in order of decreasing detail:
  # debug5
  # debug4
  # debug3
  # debug2
  # debug1
  # info
  # notice
  # warning
  # error
  # log
  # fatal
  # panic (effectively off)
 
  #log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements
  # and their durations, > 0 logs only
  # statements running at least this number
  # of milliseconds
 
 
  # - What to Log -
 
  #debug_print_parse = off
  #debug_print_rewritten = off
  #debug_print_plan = off
  #debug_pretty_print = on
  #log_checkpoints = off
  #log_connections = off
  #log_disconnections = off
  #log_duration = off
  #log_hostname = off
  #log_line_prefix = '' # special values:
  # %u = user name
  # %d = database name
  # %r = remote host and port
  # %h = remote host
  # %p = process ID
  # %t = timestamp without milliseconds
  # %m = timestamp with milliseconds
  # %i = command tag
  # %c = session ID
  # %l = session line number
  # %s = session start timestamp
  # %v = virtual transaction ID
  # %x = transaction ID (0 if none)
  # %q = stop here in non-session
  # processes
  # %% = '%'
  # e.g. '<%u%%%d> '
  #log_lock_waits = off # log lock waits >= deadlock_timeout
  #log_statement = 'none' # none, ddl, mod, all
  #log_temp_files = -1 # log temporary files equal or larger
  # than the specified size in kilobytes;
  # -1 disables, 0 logs all temp files
  #log_timezone = unknown # actually, defaults to TZ environment
  # setting
 
 
  #------------------------------------------------------------------------------
  # RUNTIME STATISTICS
  #------------------------------------------------------------------------------
 
  # - Query/Index Statistics Collector -
 
  #track_activities = on
  #track_counts = on
  #track_functions = none # none, pl, all
  #track_activity_query_size = 1024
  #update_process_title = on
  #stats_temp_directory = 'pg_stat_tmp'
 
 
  # - Statistics Monitoring -
 
  #log_parser_stats = off
  #log_planner_stats = off
  #log_executor_stats = off
  #log_statement_stats = off
 
 
  #------------------------------------------------------------------------------
  # AUTOVACUUM PARAMETERS
  #------------------------------------------------------------------------------
 
  #autovacuum = on # Enable autovacuum subprocess? 'on'
  # requires track_counts to also be on.
  #log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and
  # their durations, > 0 logs only
  # actions running at least this number
  # of milliseconds.
  #autovacuum_max_workers = 3 # max number of autovacuum subprocesses
  #autovacuum_naptime = 1min # time between autovacuum runs
  #autovacuum_vacuum_threshold = 50 # min number of row updates before
  # vacuum
  #autovacuum_analyze_threshold = 50 # min number of row updates before
  # analyze
  #autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
  #autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze
  #autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum
  # (change requires restart)
  #autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for
  # autovacuum, in milliseconds;
  # -1 means use vacuum_cost_delay
  #autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for
  # autovacuum, -1 means use
  # vacuum_cost_limit
 
 
  #------------------------------------------------------------------------------
  # CLIENT CONNECTION DEFAULTS
  #------------------------------------------------------------------------------
 
  # - Statement Behavior -
 
  #search_path = '"$user",public' # schema names
  #default_tablespace = '' # a tablespace name, '' uses the default
  #temp_tablespaces = '' # a list of tablespace names, '' uses
  # only default tablespace
  #check_function_bodies = on
  #default_transaction_isolation = 'read committed'
  #default_transaction_read_only = off
  #session_replication_role = 'origin'
  #statement_timeout = 0 # in milliseconds, 0 is disabled
  #vacuum_freeze_min_age = 50000000
  #vacuum_freeze_table_age = 150000000
  #xmlbinary = 'base64'
  #xmloption = 'content'
 
  # - Locale and Formatting -
 
  datestyle = 'iso, mdy'
  #intervalstyle = 'postgres'
  #timezone = unknown # actually, defaults to TZ environment
  # setting
  #timezone_abbreviations = 'Default' # Select the set of available time zone
  # abbreviations. Currently, there are
  # Default
  # Australia
  # India
  # You can create your own file in
  # share/timezonesets/.
  #extra_float_digits = 0 # min -15, max 2
  #client_encoding = sql_ascii # actually, defaults to database
  # encoding
 
  # These settings are initialized by initdb, but they can be changed.
  lc_messages = 'en_US.UTF-8' # locale for system error message
  # strings
  lc_monetary = 'en_US.UTF-8' # locale for monetary formatting
  lc_numeric = 'en_US.UTF-8' # locale for number formatting
  lc_time = 'en_US.UTF-8' # locale for time formatting
 
  # default configuration for text search
  default_text_search_config = 'pg_catalog.english'
 
  # - Other Defaults -
 
  #dynamic_library_path = '$libdir'
  #local_preload_libraries = ''
 
 
  #------------------------------------------------------------------------------
  # LOCK MANAGEMENT
  #------------------------------------------------------------------------------
 
  #deadlock_timeout = 1s
  #max_locks_per_transaction = 64 # min 10
  # (change requires restart)
  # Note: Each lock table slot uses ~270 bytes of shared memory, and there are
  # max_locks_per_transaction * (max_connections + max_prepared_transactions)
  # lock table slots.
 
 
  #------------------------------------------------------------------------------
  # VERSION/PLATFORM COMPATIBILITY
  #------------------------------------------------------------------------------
 
  # - Previous PostgreSQL Versions -
 
  #add_missing_from = off
  #array_nulls = on
  #backslash_quote = safe_encoding # on, off, or safe_encoding
  #default_with_oids = off
  #escape_string_warning = on
  #regex_flavor = advanced # advanced, extended, or basic
  #sql_inheritance = on
  #standard_conforming_strings = off
  #synchronize_seqscans = on
 
  # - Other Platforms and Clients -
 
  #transform_null_equals = off
 
 
  #------------------------------------------------------------------------------
  # CUSTOMIZED OPTIONS
  #------------------------------------------------------------------------------
 
  #custom_variable_classes = '' # list of custom variable class names
 
 Binary files /dev/null and b/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png differ
 Binary files /dev/null and b/css/images/ui-bg_diagonals-thick_20_666666_40x40.png differ
 Binary files /dev/null and b/css/images/ui-bg_flat_10_000000_40x100.png differ
 Binary files /dev/null and b/css/images/ui-bg_glass_100_f6f6f6_1x400.png differ
 Binary files /dev/null and b/css/images/ui-bg_glass_100_fdf5ce_1x400.png differ
 Binary files /dev/null and b/css/images/ui-bg_glass_65_ffffff_1x400.png differ
 Binary files /dev/null and b/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png differ
 Binary files /dev/null and b/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png differ
 Binary files /dev/null and b/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png differ
 Binary files /dev/null and b/css/images/ui-icons_222222_256x240.png differ
 Binary files /dev/null and b/css/images/ui-icons_228ef1_256x240.png differ
 Binary files /dev/null and b/css/images/ui-icons_ef8c08_256x240.png differ
 Binary files /dev/null and b/css/images/ui-icons_ffd27a_256x240.png differ
 Binary files /dev/null and b/css/images/ui-icons_ffffff_256x240.png differ
  /*
  * jQuery UI CSS Framework 1.8.12
  *
  * Copyright 2011, 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/Theming/API
  */
 
  /* Layout helpers
  ----------------------------------*/
  .ui-helper-hidden { display: none; }
  .ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
  .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
  .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
  .ui-helper-clearfix { display: inline-block; }
  /* required comment for clearfix to work in Opera \*/
  * html .ui-helper-clearfix { height:1%; }
  .ui-helper-clearfix { display:block; }
  /* end clearfix */
  .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
 
 
  /* Interaction Cues
  ----------------------------------*/
  .ui-state-disabled { cursor: default !important; }
 
 
  /* Icons
  ----------------------------------*/
 
  /* states and images */
  .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
 
 
  /* Misc visuals
  ----------------------------------*/
 
  /* Overlays */
  .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
 
 
  /*
  * jQuery UI CSS Framework 1.8.12
  *
  * Copyright 2011, 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/Theming/API
  *
  * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
  */
 
 
  /* Component containers
  ----------------------------------*/
  .ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
  .ui-widget .ui-widget { font-size: 1em; }
  .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
  .ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }
  .ui-widget-content a { color: #333333; }
  .ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
  .ui-widget-header a { color: #ffffff; }
 
  /* Interaction states
  ----------------------------------*/
  .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }
  .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }
  .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }
  .ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }
  .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }
  .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }
  .ui-widget :active { outline: none; }
 
  /* Interaction Cues
  ----------------------------------*/
  .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
  .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
  .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
  .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
  .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
  .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
  .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
  .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
 
  /* Icons
  ----------------------------------*/
 
  /* states and images */
  .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
  .ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
  .ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }
  .ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }
  .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
  .ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }
  .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }
  .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }
 
  /* positioning */
  .ui-icon-carat-1-n { background-position: 0 0; }
  .ui-icon-carat-1-ne { background-position: -16px 0; }
  .ui-icon-carat-1-e { background-position: -32px 0; }
  .ui-icon-carat-1-se { background-position: -48px 0; }
  .ui-icon-carat-1-s { background-position: -64px 0; }
  .ui-icon-carat-1-sw { background-position: -80px 0; }
  .ui-icon-carat-1-w { background-position: -96px 0; }
  .ui-icon-carat-1-nw { background-position: -112px 0; }
  .ui-icon-carat-2-n-s { background-position: -128px 0; }
  .ui-icon-carat-2-e-w { background-position: -144px 0; }
  .ui-icon-triangle-1-n { background-position: 0 -16px; }
  .ui-icon-triangle-1-ne { background-position: -16px -16px; }
  .ui-icon-triangle-1-e { background-position: -32px -16px; }
  .ui-icon-triangle-1-se { background-position: -48px -16px; }
  .ui-icon-triangle-1-s { background-position: -64px -16px; }
  .ui-icon-triangle-1-sw { background-position: -80px -16px; }
  .ui-icon-triangle-1-w { background-position: -96px -16px; }
  .ui-icon-triangle-1-nw { background-position: -112px -16px; }
  .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
  .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
  .ui-icon-arrow-1-n { background-position: 0 -32px; }
  .ui-icon-arrow-1-ne { background-position: -16px -32px; }
  .ui-icon-arrow-1-e { background-position: -32px -32px; }
  .ui-icon-arrow-1-se { background-position: -48px -32px; }
  .ui-icon-arrow-1-s { background-position: -64px -32px; }
  .ui-icon-arrow-1-sw { background-position: -80px -32px; }
  .ui-icon-arrow-1-w { background-position: -96px -32px; }
  .ui-icon-arrow-1-nw { background-position: -112px -32px; }
  .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
  .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
  .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
  .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
  .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
  .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
  .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
  .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
  .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
  .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
  .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
  .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
  .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
  .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
  .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
  .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
  .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
  .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
  .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
  .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
  .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
  .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
  .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
  .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
  .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
  .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
  .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
  .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
  .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
  .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
  .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
  .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
  .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
  .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
  .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
  .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
  .ui-icon-arrow-4 { background-position: 0 -80px; }
  .ui-icon-arrow-4-diag { background-position: -16px -80px; }
  .ui-icon-extlink { background-position: -32px -80px; }
  .ui-icon-newwin { background-position: -48px -80px; }
  .ui-icon-refresh { background-position: -64px -80px; }
  .ui-icon-shuffle { background-position: -80px -80px; }
  .ui-icon-transfer-e-w { background-position: -96px -80px; }
  .ui-icon-transferthick-e-w { background-position: -112px -80px; }
  .ui-icon-folder-collapsed { background-position: 0 -96px; }
  .ui-icon-folder-open { background-position: -16px -96px; }
  .ui-icon-document { background-position: -32px -96px; }
  .ui-icon-document-b { background-position: -48px -96px; }
  .ui-icon-note { background-position: -64px -96px; }
  .ui-icon-mail-closed { background-position: -80px -96px; }
  .ui-icon-mail-open { background-position: -96px -96px; }
  .ui-icon-suitcase { background-position: -112px -96px; }
  .ui-icon-comment { background-position: -128px -96px; }
  .ui-icon-person { background-position: -144px -96px; }
  .ui-icon-print { background-position: -160px -96px; }
  .ui-icon-trash { background-position: -176px -96px; }
  .ui-icon-locked { background-position: -192px -96px; }
  .ui-icon-unlocked { background-position: -208px -96px; }
  .ui-icon-bookmark { background-position: -224px -96px; }
  .ui-icon-tag { background-position: -240px -96px; }
  .ui-icon-home { background-position: 0 -112px; }
  .ui-icon-flag { background-position: -16px -112px; }
  .ui-icon-calendar { background-position: -32px -112px; }
  .ui-icon-cart { background-position: -48px -112px; }
  .ui-icon-pencil { background-position: -64px -112px; }
  .ui-icon-clock { background-position: -80px -112px; }
  .ui-icon-disk { background-position: -96px -112px; }
  .ui-icon-calculator { background-position: -112px -112px; }
  .ui-icon-zoomin { background-position: -128px -112px; }
  .ui-icon-zoomout { background-position: -144px -112px; }
  .ui-icon-search { background-position: -160px -112px; }
  .ui-icon-wrench { background-position: -176px -112px; }
  .ui-icon-gear { background-position: -192px -112px; }
  .ui-icon-heart { background-position: -208px -112px; }
  .ui-icon-star { background-position: -224px -112px; }
  .ui-icon-link { background-position: -240px -112px; }
  .ui-icon-cancel { background-position: 0 -128px; }
  .ui-icon-plus { background-position: -16px -128px; }
  .ui-icon-plusthick { background-position: -32px -128px; }
  .ui-icon-minus { background-position: -48px -128px; }
  .ui-icon-minusthick { background-position: -64px -128px; }
  .ui-icon-close { background-position: -80px -128px; }
  .ui-icon-closethick { background-position: -96px -128px; }
  .ui-icon-key { background-position: -112px -128px; }
  .ui-icon-lightbulb { background-position: -128px -128px; }
  .ui-icon-scissors { background-position: -144px -128px; }
  .ui-icon-clipboard { background-position: -160px -128px; }
  .ui-icon-copy { background-position: -176px -128px; }
  .ui-icon-contact { background-position: -192px -128px; }
  .ui-icon-image { background-position: -208px -128px; }
  .ui-icon-video { background-position: -224px -128px; }
  .ui-icon-script { background-position: -240px -128px; }
  .ui-icon-alert { background-position: 0 -144px; }
  .ui-icon-info { background-position: -16px -144px; }
  .ui-icon-notice { background-position: -32px -144px; }
  .ui-icon-help { background-position: -48px -144px; }
  .ui-icon-check { background-position: -64px -144px; }
  .ui-icon-bullet { background-position: -80px -144px; }
  .ui-icon-radio-off { background-position: -96px -144px; }
  .ui-icon-radio-on { background-position: -112px -144px; }
  .ui-icon-pin-w { background-position: -128px -144px; }
  .ui-icon-pin-s { background-position: -144px -144px; }
  .ui-icon-play { background-position: 0 -160px; }
  .ui-icon-pause { background-position: -16px -160px; }
  .ui-icon-seek-next { background-position: -32px -160px; }
  .ui-icon-seek-prev { background-position: -48px -160px; }
  .ui-icon-seek-end { background-position: -64px -160px; }
  .ui-icon-seek-start { background-position: -80px -160px; }
  /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
  .ui-icon-seek-first { background-position: -80px -160px; }
  .ui-icon-stop { background-position: -96px -160px; }
  .ui-icon-eject { background-position: -112px -160px; }
  .ui-icon-volume-off { background-position: -128px -160px; }
  .ui-icon-volume-on { background-position: -144px -160px; }
  .ui-icon-power { background-position: 0 -176px; }
  .ui-icon-signal-diag { background-position: -16px -176px; }
  .ui-icon-signal { background-position: -32px -176px; }
  .ui-icon-battery-0 { background-position: -48px -176px; }
  .ui-icon-battery-1 { background-position: -64px -176px; }
  .ui-icon-battery-2 { background-position: -80px -176px; }
  .ui-icon-battery-3 { background-position: -96px -176px; }
  .ui-icon-circle-plus { background-position: 0 -192px; }
  .ui-icon-circle-minus { background-position: -16px -192px; }
  .ui-icon-circle-close { background-position: -32px -192px; }
  .ui-icon-circle-triangle-e { background-position: -48px -192px; }
  .ui-icon-circle-triangle-s { background-position: -64px -192px; }
  .ui-icon-circle-triangle-w { background-position: -80px -192px; }
  .ui-icon-circle-triangle-n { background-position: -96px -192px; }
  .ui-icon-circle-arrow-e { background-position: -112px -192px; }
  .ui-icon-circle-arrow-s { background-position: -128px -192px; }
  .ui-icon-circle-arrow-w { background-position: -144px -192px; }
  .ui-icon-circle-arrow-n { background-position: -160px -192px; }
  .ui-icon-circle-zoomin { background-position: -176px -192px; }
  .ui-icon-circle-zoomout { background-position: -192px -192px; }
  .ui-icon-circle-check { background-position: -208px -192px; }
  .ui-icon-circlesmall-plus { background-position: 0 -208px; }
  .ui-icon-circlesmall-minus { background-position: -16px -208px; }
  .ui-icon-circlesmall-close { background-position: -32px -208px; }
  .ui-icon-squaresmall-plus { background-position: -48px -208px; }
  .ui-icon-squaresmall-minus { background-position: -64px -208px; }
  .ui-icon-squaresmall-close { background-position: -80px -208px; }
  .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
  .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
  .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
  .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
  .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
  .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
 
 
  /* Misc visuals
  ----------------------------------*/
 
  /* Corner radius */
  .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }
  .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
  .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
  .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
  .ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
  .ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
  .ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
  .ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
  .ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
 
  /* Overlays */
  .ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }
  .ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*
  * jQuery UI Autocomplete 1.8.12
  *
  * Copyright 2011, 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/Autocomplete#theming
  */
  .ui-autocomplete { position: absolute; cursor: default; }
 
  /* workarounds */
  * html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
 
  /*
  * jQuery UI Menu 1.8.12
  *
  * 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/Menu#theming
  */
  .ui-menu {
  list-style:none;
  padding: 2px;
  margin: 0;
  display:block;
  float: left;
  }
  .ui-menu .ui-menu {
  margin-top: -3px;
  }
  .ui-menu .ui-menu-item {
  margin:0;
  padding: 0;
  zoom: 1;
  float: left;
  clear: left;
  width: 100%;
  }
  .ui-menu .ui-menu-item a {
  text-decoration:none;
  display:block;
  padding:.2em .4em;
  line-height:1.5;
  zoom:1;
  }
  .ui-menu .ui-menu-item a.ui-state-hover,
  .ui-menu .ui-menu-item a.ui-state-active {
  font-weight: normal;
  margin: -1px;
  }
 
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;}  
 
  #!/bin/bash
  #dotcloud postinstall
 
  curl http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \
  -o /home/dotcloud/current/cbrfeed.zip
  wget http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \
  -O /tmp/Graph.obj
 
  #db setup
  #curl https://github.com/maxious/ACTBus-ui/raw/master/transitdata.cbrfeed.sql.gz -o transitdata.cbrfeed.sql.gz
  #curl https://github.com/maxious/ACTBus-ui/raw/master/lib/postgis.sql -o postgis.sql
  #createlang -d transitdata plpgsql
  #psql -d transitdata -f postgis.sql
  #gunzip /var/www/transitdata.cbrfeed.sql.gz
  #psql -d transitdata -f transitdata.cbrfeed.sql
  #createuser transitdata -SDRP
  #password transitdata
  #psql -c \"GRANT SELECT ON TABLE agency,calendar,calendar_dates,routes,stop_times,stops,trips TO transitdata;\"
 
file:b/dotcloud/push.sh (new)
  #wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-webapp.war
  cp ~/workspace/opentripplanner/maven.1277125291275/opentripplanner-webapp/target/opentripplanner-webapp.war ./
  #wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-api-webapp.war
  cp ~/workspace/opentripplanner/maven.1277125291275/opentripplanner-api-webapp/target/opentripplanner-api-webapp.war ./
 
  dotcloud push actbus.otp ./
 
file:b/geo/route.kml.php (new)
  <?php
  header('Content-Type: application/vnd.google-earth.kml+xml');
  include ('../include/common.inc.php');
  echo '<?xml version="1.0" encoding="UTF-8"?>
  <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"><Document>';
  echo '
  <Style id="yellowLineGreenPoly">
  <LineStyle>
  <color>7f00ff00</color>
  <width>4</width>
  </LineStyle>
  <PolyStyle>
  <color>7f00ffff</color>
  </PolyStyle>
  </Style>';
  $route = getRoute($routeid);
  echo "\n<Placemark>\n";
  $link = curPageURL()."/../trip.php?routeid=".htmlspecialchars ($route["route_id"]);
  echo "<name>".$route['route_short_name']."</name>";
  echo '<atom:link href="'.$link.'"/>';
  echo '<description><![CDATA[ <a href="'.$link.'">'.$route['route_short_name']." ".$route['route_long_name']."</a>]]> </description>";
  echo "<styleUrl>#yellowLineGreenPoly</styleUrl>";
 
  $trips = getRouteTrips($routeid);
  echo getTripShape($trips[0]['trip_id']);
 
  echo "</Placemark>\n</Document></kml>\n";
  ?>
 
 
<?php <?php
if (php_uname('n') == "actbus-www") { if (php_uname('n') == "actbus-www") {
$conn = pg_connect("dbname=transitdata user=transitdata password=transitdata host=db.actbus.dotcloud.com port=2242"); $conn = new PDO("pgsql:dbname=transitdata;user=transitdata;password=transitdata;host=bus-main.lambdacomplex.org");
} else if (isDebugServer()) { }
$conn = pg_connect("dbname=transitdata user=postgres password=snmc"); else if (isDebugServer()) {
} else { $conn = new PDO("pgsql:dbname=transitdata;user=postgres;password=snmc;host=localhost");
$conn = pg_connect("dbname=transitdata user=transitdata password=transitdata "); }
} else {
if (!$conn) { $conn = new PDO("pgsql:dbname=transitdata;user=transitdata;password=transitdata;host=localhost");
die("A database error occurred.\n"); }
} if (!$conn) {
  die("A database error occurred.\n");
function databaseError($errMsg) { }
die($errMsg); function databaseError($errMsg)
} {
  die($errMsg);
include('db/route-dao.inc.php'); }
include('db/trip-dao.inc.php'); include ('db/route-dao.inc.php');
include('db/stop-dao.inc.php'); include ('db/trip-dao.inc.php');
?> include ('db/stop-dao.inc.php');
  include ('db/servicealert-dao.inc.php');
  ?>
   
  <?php
  if (isset($_REQUEST['firstLetter'])) {
  $firstLetter = filter_var($_REQUEST['firstLetter'], FILTER_SANITIZE_STRING);
  }
  if (isset($_REQUEST['bysuburbs'])) {
  $bysuburbs = true;
  }
  if (isset($_REQUEST['bynumber'])) {
  $bynumber = true;
  }
  if (isset($_REQUEST['allstops'])) {
  $allstops = true;
  }
  if (isset($_REQUEST['nearby'])) {
  $nearby = true;
  }
  if (isset($_REQUEST['suburb'])) {
  $suburb = filter_var($_REQUEST['suburb'], FILTER_SANITIZE_STRING);
  }
  $pageKey = 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);
  $max_distance = filter_var($_REQUEST['radius'], FILTER_SANITIZE_NUMBER_INT);
  if (isset($_REQUEST['numberSeries'])) {
  $numberSeries = filter_var($_REQUEST['numberSeries'], FILTER_SANITIZE_NUMBER_INT);
  }
  if (isset($_REQUEST['routeDestination'])) {
  $routeDestination = urldecode(filter_var($_REQUEST['routeDestination'], FILTER_SANITIZE_ENCODED));
  }
  if (isset($_REQUEST['stopcode'])) {
  $stopcode = filter_var($_REQUEST['stopcode'], FILTER_SANITIZE_STRING);
  }
  if (isset($_REQUEST['stopids'])) {
  $stopids = explode(",", filter_var($_REQUEST['stopids'], FILTER_SANITIZE_STRING));
  }
  if (isset($_REQUEST['tripid'])) {
  $tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_NUMBER_INT);
  }
  if (isset($_REQUEST['stopid'])) {
  $stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT);
  }
  if (isset($_REQUEST['routeid'])) {
  $routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT);
  }
  if (isset($_REQUEST['geolocate'])) {
  $geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL);
  }
  ?>
<?php <?php
// you have to open the session to be able to modify or remove it // you have to open the session to be able to modify or remove it
session_start(); session_start();
if (isset($_REQUEST['service_period'])) { if (isset($_REQUEST['service_period'])) {
$_SESSION['service_period'] = filter_var($_REQUEST['service_period'], FILTER_SANITIZE_STRING); $_SESSION['service_period'] = filter_var($_REQUEST['service_period'], FILTER_SANITIZE_STRING);
sessionUpdated(); sessionUpdated();
} }
if (isset($_REQUEST['time'])) { if (isset($_REQUEST['time'])) {
$_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING); $_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING);
sessionUpdated(); sessionUpdated();
} }
if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") { if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") {
$geocoded = false; $geocoded = false;
if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) { if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) {
$_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], 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)); $_SESSION['lon'] = trim(filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
} }
else { else {
$geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL);  
if (startsWith($geolocate, "-")) { if (startsWith($geolocate, "-")) {
$locateparts = explode(",", $geolocate); $locateparts = explode(",", $geolocate);
  $_SESSION['lat'] = $locateparts[0];
  $_SESSION['lon'] = $locateparts[1];
  }
  else if (strpos($geolocate, "(") !== false) {
  $geoParts = explode("(", $geolocate);
  $locateparts = explode(",", str_replace(")", "",$geoParts[1]));
$_SESSION['lat'] = $locateparts[0]; $_SESSION['lat'] = $locateparts[0];
$_SESSION['lon'] = $locateparts[1]; $_SESSION['lon'] = $locateparts[1];
} }
else { else {
$contents = geocode($geolocate, true); $contents = geocode($geolocate, true);
print_r($contents); print_r($contents);
if (isset($contents[0]->centroid)) { if (isset($contents[0]->centroid)) {
$geocoded = true; $geocoded = true;
$_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; $_SESSION['lat'] = $contents[0]->centroid->coordinates[0];
$_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; $_SESSION['lon'] = $contents[0]->centroid->coordinates[1];
} }
else { else {
$_SESSION['lat'] = ""; $_SESSION['lat'] = "";
$_SESSION['lon'] = ""; $_SESSION['lon'] = "";
} }
} }
} }
if ($_SESSION['lat'] != "" && isAnalyticsOn()) { if ($_SESSION['lat'] != "" && isAnalyticsOn()) {
trackEvent("Geolocation","Updated Location", "Geocoded - ".($geocoded ? "Yes" : "No")); trackEvent("Geolocation", "Updated Location", "Geocoded - " . ($geocoded ? "Yes" : "No"));
} }
sessionUpdated(); sessionUpdated();
} }
function sessionUpdated() { function sessionUpdated()
  {
$_SESSION['lastUpdated'] = time(); $_SESSION['lastUpdated'] = time();
} }
// timeoutSession // timeoutSession
$TIMEOUT_LIMIT = 60*5; // 5 minutes $TIMEOUT_LIMIT = 60 * 5; // 5 minutes
if (isset($_SESSION['lastUpdated']) && $_SESSION['lastUpdated']+$TIMEOUT_LIMIT < time()) { if (isset($_SESSION['lastUpdated']) && $_SESSION['lastUpdated'] + $TIMEOUT_LIMIT < time()) {
debug ("Session timeout ".($_SESSION['lastUpdated']+$TIMEOUT_LIMIT).">".time(),"session"); debug("Session timeout " . ($_SESSION['lastUpdated'] + $TIMEOUT_LIMIT) . ">" . time() , "session");
session_destroy(); session_destroy();
session_start(); session_start();
} }
//debug(print_r($_SESSION, true) , "session"); //debug(print_r($_SESSION, true) , "session");
  function current_time()
function current_time() { {
return ($_SESSION['time']? $_SESSION['time'] : date("H:i:s")); return ($_SESSION['time'] ? $_SESSION['time'] : date("H:i:s"));
} }
?> ?>
<?php <?php
// Copyright 2009 Google Inc. All Rights Reserved. // Copyright 2009 Google Inc. All Rights Reserved.
$GA_ACCOUNT = "MO-22173039-1"; $GA_ACCOUNT = "MO-22173039-1";
$GA_PIXEL = "/lib/ga.php"; $GA_PIXEL = "/lib/ga.php";
function googleAnalyticsGetImageUrl() function googleAnalyticsGetImageUrl()
{ {
global $GA_ACCOUNT, $GA_PIXEL; global $GA_ACCOUNT, $GA_PIXEL;
  //if (stristr($_SERVER['HTTP_USER_AGENT'], 'Googlebot') return "";
$url = ""; $url = "";
$url.= $GA_PIXEL . "?"; $url.= $GA_PIXEL . "?";
$url.= "utmac=" . $GA_ACCOUNT; $url.= "utmac=" . $GA_ACCOUNT;
$url.= "&utmn=" . rand(0, 0x7fffffff); $url.= "&utmn=" . rand(0, 0x7fffffff);
$referer = $_SERVER["HTTP_REFERER"]; $referer = $_SERVER["HTTP_REFERER"];
$query = $_SERVER["QUERY_STRING"]; $query = $_SERVER["QUERY_STRING"];
$path = $_SERVER["REQUEST_URI"]; $path = $_SERVER["REQUEST_URI"];
if (empty($referer)) { if (empty($referer)) {
$referer = "-"; $referer = "-";
} }
$url.= "&utmr=" . urlencode($referer); $url.= "&utmr=" . urlencode($referer);
if (!empty($path)) { if (!empty($path)) {
$url.= "&utmp=" . urlencode($path); $url.= "&utmp=" . urlencode($path);
} }
$url.= "&guid=ON"; $url.= "&guid=ON";
return str_replace("&", "&amp;", $url); return str_replace("&", "&amp;", $url);
} }
function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false) function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false)
{ {
echo ' echo '
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>' . $pageTitle . '</title> <title>' . $pageTitle . '</title>
<meta name="google-site-verification" <meta name="google-site-verification"
content="-53T5Qn4TB_de1NyfR_ZZkEVdUNcNFSaYKSFkWKx-sY" />'; content="-53T5Qn4TB_de1NyfR_ZZkEVdUNcNFSaYKSFkWKx-sY" />
if ($datepicker) echo '<link rel="stylesheet" href="css/jquery.ui.datepicker.mobile.css" />'; <link rel="stylesheet" href="css/jquery-ui-1.8.12.custom.css" />';
if (isDebugServer()) { if (isDebugServer()) {
echo '<link rel="stylesheet" href="css/jquery.mobile-1.0a4.css" /> echo '<link rel="stylesheet" href="css/jquery.mobile-1.0a4.css" />
<script type="text/javascript" src="js/jquery-1.5.js"></script> <script type="text/javascript" src="js/jquery-1.5.js"></script>
<script>$(document).bind("mobileinit", function(){ <script>$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false; $.mobile.ajaxEnabled = false;
}); });
</script> </script>
<script type="text/javascript" src="js/jquery.mobile-1.0a4.js"></script>'; <script type="text/javascript" src="js/jquery.mobile-1.0a4.js"></script>';
} }
else { else {
echo '<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" /> echo '<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script>$(document).bind("mobileinit", function(){ <script>$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false; $.mobile.ajaxEnabled = false;
}); });
</script> </script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>'; <script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>';
} }
if ($datepicker) { echo '
echo '<script> <script src="js/jquery.ui.autocomplete.min.js"></script>
//reset type=date inputs to text <script src="js/jquery.ui.core.min.js"></script>
$( document ).bind( "mobileinit", function(){ <script src="js/jquery.ui.position.min.js"></script>
$.mobile.page.prototype.options.degradeInputs.date = true; <script src="js/jquery.ui.widget.min.js"></script>
}); <script>
</script> $(function() {
<script src="js/jQuery.ui.datepicker.js"></script>'; $( "#geolocate" ).autocomplete({
} source: "lib/autocomplete.php",
  minLength: 2
  });
  $( "#from" ).autocomplete({
  source: "lib/autocomplete.php",
  minLength: 2
  });
  $( "#to" ).autocomplete({
  source: "lib/autocomplete.php",
  minLength: 2
  });
  });
  </script>
  ';
echo '<style type="text/css"> echo '<style type="text/css">
.ui-navbar { .ui-navbar {
width: 100%; width: 100%;
} }
.ui-btn-inner { .ui-btn-inner {
white-space: normal !important; white-space: normal !important;
} }
.ui-li-heading { .ui-li-heading {
white-space: normal !important; white-space: normal !important;
} }
.ui-listview-filter { .ui-listview-filter {
margin: 0 !important; margin: 0 !important;
} }
.ui-icon-navigation { .ui-icon-navigation {
background-image: url(css/images/113-navigation.png); background-image: url(css/images/113-navigation.png);
background-position: 1px 0; background-position: 1px 0;
} }
.ui-icon-beaker { .ui-icon-beaker {
background-image: url(css/images/91-beaker-2.png); background-image: url(css/images/91-beaker-2.png);
background-position: 1px 0; background-position: 1px 0;
} }
#footer { #footer {
text-size: 0.75em; text-size: 0.75em;
text-align: center; text-align: center;
} }
body { body {
background-color: #F0F0F0; background-color: #F0F0F0;
} }
#jqm-homeheader { #jqm-homeheader {
text-align: center; text-align: center;
} }
.viaPoints { .viaPoints {
display: none; display: none;
text-size: 0.2em; text-size: 0.2em;
} }
.min-width-480px .viaPoints { .min-width-480px .viaPoints {
display: inline; display: inline;
} }
#extrainfo { #extrainfo {
visibility: hidden; visibility: hidden;
display: none; display: none;
} }
#servicewarning { #servicewarning {
padding: 1em; padding: 1em;
margin-bottom: 0.5em; margin-bottom: 0.5em;
text-size: 0.2em; text-size: 0.2em;
background-color: #FF9; background-color: #FF9;
-moz-border-radius: 15px; -moz-border-radius: 15px;
border-radius: 15px; border-radius: 15px;
} }
   
  /*#leftcolumn {
  float: none;
  }
  .min-width-768px #leftcolumn {
  float: left;
  width: 30%;
  }
  #rightcolumn {
  float: none;
  }
  .min-width-768px #rightcolumn {
  float: right;
  width: 68%;
  }*/
   
  #footer {
  clear:both;
  text-align:center;
  }
// source http://webaim.org/techniques/skipnav/ // source http://webaim.org/techniques/skipnav/
#skip a, #skip a:hover, #skip a:visited #skip a, #skip a:hover, #skip a:visited
{ {
position:absolute; position:absolute;
left:0px; left:0px;
top:-500px; top:-500px;
width:1px; width:1px;
height:1px; height:1px;
overflow:hidden; overflow:hidden;
} }
   
#skip a:active, #skip a:focus #skip a:active, #skip a:focus
{ {
position:static; position:static;
width:auto; width:auto;
height:auto; height:auto;
} }
</style>'; </style>';
if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod')) { if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad')) {
echo '<meta name="apple-mobile-web-app-capable" content="yes" /> echo '<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-startup-image" href="startup.png" /> <link rel="apple-touch-startup-image" href="startup.png" />
<link rel="apple-touch-icon" href="apple-touch-icon.png" />'; <link rel="apple-touch-icon" href="apple-touch-icon.png" />';
} }
if ($geolocate) { if ($geolocate) {
echo "<script> echo "<script>
   
function success(position) { function success(position) {
$('#error').val('Location now detected. Please wait for data to load.'); $('#error').val('Location now detected. Please wait for data to load.');
$('#geolocate').val(position.coords.latitude+','+position.coords.longitude); $('#geolocate').val(position.coords.latitude+','+position.coords.longitude);
$.ajax({ url: \"include/common.inc.php?geolocate=yes&lat=\"+position.coords.latitude+\"&lon=\"+position.coords.longitude }); $.ajax({ url: \"include/common.inc.php?geolocate=yes&lat=\"+position.coords.latitude+\"&lon=\"+position.coords.longitude });
location.reload(true); location.reload(true);
} }
function error(msg) { function error(msg) {
$('#error').val('Error: '+msg); $('#error').val('Error: '+msg);
} }
   
function geolocate() { function geolocate() {
if (navigator.geolocation) { if (navigator.geolocation) {
var options = { var options = {
enableHighAccuracy: true, enableHighAccuracy: true,
timeout: 60000, timeout: 60000,
maximumAge: 10000 maximumAge: 10000
} }
navigator.geolocation.getCurrentPosition(success, error, options); navigator.geolocation.getCurrentPosition(success, error, options);
} }
} }
$(document).ready(function() { $(document).ready(function() {
$('#here').click(function(event) { $('#geolocate').val(geolocate()); return false;}); $('#here').click(function(event) { $('#geolocate').val(geolocate()); return false;});
$('#here').show(); $('#here').show();
  /*if ($.mobile.media('screen and (min-width: 768px)')) {
  $('map a:first').click();
  $('#settings a:first').click();
  }*/
}); });
"; ";
if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") echo "geolocate();"; if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") echo "geolocate();";
echo "</script> "; echo "</script> ";
} }
if (isAnalyticsOn()) echo ' if (isAnalyticsOn()) echo '
<script type="text/javascript">' . " <script type="text/javascript">' . "
   
var _gaq = _gaq || []; var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-22173039-1']); _gaq.push(['_setAccount', 'UA-22173039-1']);
_gaq.push(['_trackPageview']); _gaq.push(['_trackPageview']);
  _gaq.push(['_trackPageLoadTime']);
</script>"; </script>";
echo '</head> echo '</head>
<body> <body>
<div id="skip"> <div id="skip">
<a href="#maincontent">Skip to content</a> <a href="#maincontent">Skip to content</a>
</div> </div>
'; ';
if ($opendiv) { if ($opendiv) {
echo '<div data-role="page"> echo '<div data-role="page">
<div data-role="header" data-position="inline"> <div data-role="header" data-position="inline">
<a href="' . $_SERVER["HTTP_REFERER"] . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a> <a href="' . (isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : "javascript:history.go(-1)") . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a>
<h1>' . $pageTitle . '</h1> <h1>' . $pageTitle . '</h1>
<a href="/index.php" data-icon="home" class="ui-btn-right">Home</a> <a href="/index.php" data-icon="home" class="ui-btn-right">Home</a>
</div><!-- /header --> </div><!-- /header -->
<a name="maincontent" id="maincontent"></a> <a name="maincontent" id="maincontent"></a>
<div data-role="content"> '; <div data-role="content"> ';
if (!$_SESSION['service_id']) { $overrides = getServiceOverride();
$overrides = getServiceOverride(); if ($overrides['service_id']) {
if ($overrides['service_id']) {  
if ($overrides['service_id'] == "noservice") { if ($overrides['service_id'] == "noservice") {
echo '<div id="servicewarning">Buses are <strong>not running today</strong> due to industrial action/public holiday. See <a echo '<div id="servicewarning">Buses are <strong>not running today</strong> due to industrial action/public holiday. See <a
href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>'; href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>';
} }
else { else {
echo '<div id="servicewarning">Buses are running on an altered timetable today due to industrial action/public holiday. See <a href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>'; echo '<div id="servicewarning">Buses are running on an altered timetable today due to industrial action/public holiday. See <a href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>';
} }
} }
} }
}  
} }
function include_footer() function include_footer()
{ {
echo '<div id="footer"><a href="about.php">About/Contact Us</a>&nbsp;<a href="feedback.php">Feedback/Bug Report</a>'; echo '<div id="footer"><a href="about.php">About/Contact Us</a>&nbsp;<a href="feedback.php">Feedback/Bug Report</a>';
echo '</div>'; echo '</div>';
if (isAnalyticsOn()) { if (isAnalyticsOn()) {
echo "<script> (function() { echo "<script> (function() {
var ga = document.createElement('script'); ga.type = var ga = document.createElement('script'); ga.type =
'text/javascript'; ga.async = true; 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? ga.src = ('https:' == document.location.protocol ?
'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s); s.parentNode.insertBefore(ga, s);
})();</script>"; })();</script>";
$googleAnalyticsImageUrl = googleAnalyticsGetImageUrl(); $googleAnalyticsImageUrl = googleAnalyticsGetImageUrl();
echo '<noscript><img src="' . $googleAnalyticsImageUrl . '" /></noscript>'; echo '<noscript><img src="' . $googleAnalyticsImageUrl . '" /></noscript>';
   
} }
echo "\n</div></div></body></html>"; echo "\n</div></div></body></html>";
} }
function timePlaceSettings($geolocate = false) function timePlaceSettings($geolocate = false)
{ {
global $service_periods; global $service_periods;
$geoerror = false; $geoerror = false;
if ($geolocate == true) { if ($geolocate == true) {
$geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == "";
} }
  echo '<div id="error">';
if ($geoerror) { if ($geoerror) {
echo '<div id="error">Sorry, but your location could not currently be detected. echo 'Sorry, but your location could not currently be detected.
Please allow location permission, wait for your location to be detected, Please allow location permission, wait for your location to be detected,
or enter an address/co-ordinates in the box below.</div>'; or enter an address/co-ordinates in the box below.';
} }
echo '<div data-role="collapsible" data-collapsed="' . !$geoerror . '"> echo '</div>';
  echo '<div id="settings" data-role="collapsible" data-collapsed="' . !$geoerror . '">
<h3>Change Time/Place (' . (isset($_SESSION['time']) ? $_SESSION['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...</h3> <h3>Change Time/Place (' . (isset($_SESSION['time']) ? $_SESSION['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...</h3>
<form action="' . basename($_SERVER['PHP_SELF']) . "?" . $_SERVER['QUERY_STRING'] . '" method="post"> <form action="' . basename($_SERVER['PHP_SELF']) . "?" . $_SERVER['QUERY_STRING'] . '" method="post">
<div class="ui-body"> <div class="ui-body">
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="geolocate"> Current Location: </label> <label for="geolocate"> Current Location: </label>
<input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here">Here?</a> <input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here">Here?</a>
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="time"> Time: </label> <label for="time"> Time: </label>
<input type="time" name="time" id="time" value="' . (isset($_SESSION['time']) ? $_SESSION['time'] : date("H:i")) . '"/> <input type="time" name="time" id="time" value="' . (isset($_SESSION['time']) ? $_SESSION['time'] : date("H:i")) . '"/>
<a href="#" name="currentTime" id="currentTime" onClick="var d = new Date();' . "$('#time').val(d.getHours() +':'+ (d.getMinutes().toString().length == 1 ? '0'+ d.getMinutes(): d.getMinutes()));" . '">Current Time?</a> <a href="#" name="currentTime" id="currentTime" onClick="var d = new Date();' . "$('#time').val(d.getHours() +':'+ (d.getMinutes().toString().length == 1 ? '0'+ d.getMinutes(): d.getMinutes()));" . '">Current Time?</a>
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="service_period"> Service Period: </label> <label for="service_period"> Service Period: </label>
<select name="service_period" id="service_period">'; <select name="service_period" id="service_period">';
foreach ($service_periods as $service_period) { foreach ($service_periods as $service_period) {
echo "<option value=\"$service_period\"" . (service_period() === $service_period ? " SELECTED" : "") . '>' . ucwords($service_period) . '</option>'; echo "<option value=\"$service_period\"" . (service_period() === $service_period ? " SELECTED" : "") . '>' . ucwords($service_period) . '</option>';
} }
echo '</select> echo '</select>
<a href="#" style="display:none" name="currentPeriod" id="currentPeriod">Current Period?</a> <a href="#" style="display:none" name="currentPeriod" id="currentPeriod">Current Period?</a>
</div> </div>
<input type="submit" value="Update"/> <input type="submit" value="Update"/>
</div></form> </div></form>
</div>'; </div>';
} }
function trackEvent($category, $action, $label = "", $value = - 1) function trackEvent($category, $action, $label = "", $value = - 1)
{ {
if (isAnalyticsOn()) { if (isAnalyticsOn()) {
echo "\n<script> _gaq.push(['_trackEvent', '$category', '$action'" . ($label != "" ? ", '$label'" : "") . ($value != - 1 ? ", $value" : "") . "]);</script>"; echo "\n<script> _gaq.push(['_trackEvent', '$category', '$action'" . ($label != "" ? ", '$label'" : "") . ($value != - 1 ? ", $value" : "") . "]);</script>";
} }
} }
?> ?>
   
<?php <?php
$service_periods = Array( $service_periods = Array(
'sunday', 'sunday',
'saturday', 'saturday',
'weekday' 'weekday'
); );
function getServiceOverride() {  
global $conn;  
$query = "Select * from calendar_dates where date = '".date("Ymd")."' and exception_type = '1'";  
debug($query,"database");  
$result = pg_query($conn, $query);  
if (!$result) {  
databaseError(pg_result_error($result));  
return Array();  
}  
return pg_fetch_assoc($result);  
}  
function service_period() function service_period()
{ {
if (isset($_SESSION['service_period'])) return $_SESSION['service_period']; if (isset($_SESSION['service_period'])) return $_SESSION['service_period'];
$override = getServiceOverride(); $override = getServiceOverride();
if ($override['service_id']){ if ($override['service_id']){
return $override['service_id']; return $override['service_id'];
} }
   
switch (date('w')) { switch (date('w')) {
case 0: case 0:
return 'sunday'; return 'sunday';
case 6: case 6:
return 'saturday'; return 'saturday';
default: default:
return 'weekday'; return 'weekday';
} }
} }
function midnight_seconds() function midnight_seconds()
{ {
// from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html // from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html
if (isset($_SESSION['time'])) { if (isset($_SESSION['time'])) {
$time = strtotime($_SESSION['time']); $time = strtotime($_SESSION['time']);
return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time);
} }
return (date("G") * 3600) + (date("i") * 60) + date("s"); return (date("G") * 3600) + (date("i") * 60) + date("s");
} }
function midnight_seconds_to_time($seconds) function midnight_seconds_to_time($seconds)
{ {
if ($seconds > 0) { if ($seconds > 0) {
$midnight = mktime(0, 0, 0, date("n") , date("j") , date("Y")); $midnight = mktime(0, 0, 0, date("n") , date("j") , date("Y"));
return date("h:ia", $midnight + $seconds); return date("h:ia", $midnight + $seconds);
} }
else { else {
return ""; return "";
} }
} }
?> ?>
   
<?php <?php
date_default_timezone_set('Australia/ACT'); date_default_timezone_set('Australia/ACT');
$debugOkay = Array( $debugOkay = Array(
"session", "session",
"json", "json",
"phperror", "phperror",
"awsotp", "awsotp",
//"squallotp", //"squallotp",
//"vanilleotp", "vanilleotp",
"database", "database",
"other" "other"
); );
$cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6"; $cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6";
$googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q"; $googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q";
$otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/'; $otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/';
if (isDebug("awsotp") || php_uname('n') == "maxious.xen.prgmr.com") { if (isDebug("awsotp") || php_uname('n') == "maxious.xen.prgmr.com") {
$otpAPIurl = 'http://bus-main.lambdacomplex.org:8080/opentripplanner-api-webapp/'; $otpAPIurl = 'http://bus-main.lambdacomplex.org:8080/opentripplanner-api-webapp/';
  }
  if (isDebug("dotcloudotp") || php_uname('n') == "actbus-www") {
  $otpAPIurl = 'http://otp.actbus.dotcloud.com/opentripplanner-api-webapp/';
} }
if (isDebug("squallotp")) { if (isDebug("squallotp")) {
$otpAPIurl = 'http://10.0.1.108:5080/opentripplanner-api-webapp/'; $otpAPIurl = 'http://10.0.1.108:5080/opentripplanner-api-webapp/';
} }
if (isDebug("vanilleotp")) { if (isDebug("vanilleotp")) {
$otpAPIurl = 'http://10.0.1.135:8080/opentripplanner-api-webapp/'; $otpAPIurl = 'http://10.0.1.135:8080/opentripplanner-api-webapp/';
} }
if (isDebug("phperror")) error_reporting(E_ALL ^ E_NOTICE); if (isDebug("phperror")) error_reporting(E_ALL ^ E_NOTICE);
   
include_once ("common-geo.inc.php"); include_once ("common-geo.inc.php");
include_once ("common-net.inc.php"); include_once ("common-net.inc.php");
include_once ("common-transit.inc.php"); include_once ("common-transit.inc.php");
  include_once ("common-db.inc.php");
   
  include_once ("common-request.inc.php");
include_once ("common-session.inc.php"); include_once ("common-session.inc.php");
include_once ("common-db.inc.php");  
include_once ("common-template.inc.php"); include_once ("common-template.inc.php");
   
function isDebugServer() function isDebugServer()
{ {
return $_SERVER['SERVER_NAME'] == "10.0.1.154" || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1" || !$_SERVER['SERVER_NAME']; return $_SERVER['SERVER_NAME'] == "10.0.1.154" || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1" || !$_SERVER['SERVER_NAME'];
} }
function isAnalyticsOn() function isAnalyticsOn()
{ {
return !isDebugServer(); return !isDebugServer();
} }
function isDebug($debugReason = "other") function isDebug($debugReason = "other")
{ {
global $debugOkay; global $debugOkay;
return in_array($debugReason, $debugOkay, false) && isDebugServer(); return in_array($debugReason, $debugOkay, false) && isDebugServer();
} }
function debug($msg, $debugReason = "other") function debug($msg, $debugReason = "other")
{ {
if (isDebug($debugReason)) echo "\n<!-- " . date(DATE_RFC822) . "\n $msg -->\n"; if (isDebug($debugReason)) echo "\n<!-- " . date(DATE_RFC822) . "\n $msg -->\n";
} }
function isJQueryMobileDevice() function isJQueryMobileDevice()
{ {
// http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897 // 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']; $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); 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() function isFastDevice()
{ {
$ua = $_SERVER['HTTP_USER_AGENT']; $ua = $_SERVER['HTTP_USER_AGENT'];
$fastDevices = Array( $fastDevices = Array(
"Mozilla/5.0 (X11;", "Mozilla/5.0 (X11;",
"Mozilla/5.0 (Windows;", "Mozilla/5.0 (Windows;",
"Mozilla/5.0 (iP", "Mozilla/5.0 (iP",
"Mozilla/5.0 (Linux; U; Android", "Mozilla/5.0 (Linux; U; Android",
"Mozilla/4.0 (compatible; MSIE" "Mozilla/4.0 (compatible; MSIE"
); );
$slowDevices = Array( $slowDevices = Array(
"J2ME", "J2ME",
"MIDP", "MIDP",
"Opera/", "Opera/",
"Mozilla/2.0 (compatible;", "Mozilla/2.0 (compatible;",
"Mozilla/3.0 (compatible;" "Mozilla/3.0 (compatible;"
); );
return true; return true;
} }
function array_flatten($a, $f = array()) function array_flatten($a, $f = array())
{ {
if (!$a || !is_array($a)) return ''; if (!$a || !is_array($a)) return '';
foreach ($a as $k => $v) { foreach ($a as $k => $v) {
if (is_array($v)) $f = array_flatten($v, $f); if (is_array($v)) $f = array_flatten($v, $f);
else $f[$k] = $v; else $f[$k] = $v;
} }
return $f; return $f;
} }
function remove_spaces($string) function remove_spaces($string)
{ {
return str_replace(' ', '', $string); return str_replace(' ', '', $string);
} }
function object2array($object) function object2array($object)
{ {
if (is_object($object)) { if (is_object($object)) {
foreach ($object as $key => $value) { foreach ($object as $key => $value) {
$array[$key] = $value; $array[$key] = $value;
} }
} }
else { else {
$array = $object; $array = $object;
} }
return $array; return $array;
} }
function startsWith($haystack, $needle, $case = true) function startsWith($haystack, $needle, $case = true)
{ {
if ($case) { if ($case) {
return (strcmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); return (strcmp(substr($haystack, 0, strlen($needle)) , $needle) === 0);
} }
return (strcasecmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); return (strcasecmp(substr($haystack, 0, strlen($needle)) , $needle) === 0);
} }
   
function endsWith($haystack, $needle, $case = true) function endsWith($haystack, $needle, $case = true)
{ {
if ($case) { if ($case) {
return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0);
} }
return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0);
} }
function bracketsMeanNewLine($input) function bracketsMeanNewLine($input)
{ {
return str_replace(")", "</small>", str_replace("(", "<br><small>", $input)); return str_replace(")", "</small>", str_replace("(", "<br><small>", $input));
} }
function sksort(&$array, $subkey = "id", $sort_ascending = false) function sksort(&$array, $subkey = "id", $sort_ascending = false)
{ {
if (count($array)) $temp_array[key($array) ] = array_shift($array); if (count($array)) $temp_array[key($array) ] = array_shift($array);
foreach ($array as $key => $val) { foreach ($array as $key => $val) {
$offset = 0; $offset = 0;
$found = false; $found = false;
foreach ($temp_array as $tmp_key => $tmp_val) { foreach ($temp_array as $tmp_key => $tmp_val) {
if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) {
$temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( $temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array(
$key => $val $key => $val
) , array_slice($temp_array, $offset)); ) , array_slice($temp_array, $offset));
$found = true; $found = true;
} }
$offset++; $offset++;
} }
if (!$found) $temp_array = array_merge($temp_array, array( if (!$found) $temp_array = array_merge($temp_array, array(
$key => $val $key => $val
)); ));
} }
if ($sort_ascending) $array = array_reverse($temp_array); if ($sort_ascending) $array = array_reverse($temp_array);
else $array = $temp_array; else $array = $temp_array;
} }
function sktimesort(&$array, $subkey = "id", $sort_ascending = false) function sktimesort(&$array, $subkey = "id", $sort_ascending = false)
{ {
if (count($array)) $temp_array[key($array) ] = array_shift($array); if (count($array)) $temp_array[key($array) ] = array_shift($array);
foreach ($array as $key => $val) { foreach ($array as $key => $val) {
$offset = 0; $offset = 0;
$found = false; $found = false;
foreach ($temp_array as $tmp_key => $tmp_val) { foreach ($temp_array as $tmp_key => $tmp_val) {
if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) { if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) {
$temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( $temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array(
$key => $val $key => $val
) , array_slice($temp_array, $offset)); ) , array_slice($temp_array, $offset));
$found = true; $found = true;
} }
$offset++; $offset++;
} }
if (!$found) $temp_array = array_merge($temp_array, array( if (!$found) $temp_array = array_merge($temp_array, array(
$key => $val $key => $val
)); ));
} }
if ($sort_ascending) $array = array_reverse($temp_array); if ($sort_ascending && isset($temp_array)) $array = array_reverse($temp_array);
else $array = $temp_array; else $array = $temp_array;
} }
function r_implode( $glue, $pieces ) function r_implode( $glue, $pieces )
{ {
foreach( $pieces as $r_pieces ) foreach( $pieces as $r_pieces )
{ {
if( is_array( $r_pieces ) ) if( is_array( $r_pieces ) )
{ {
$retVal[] = r_implode( $glue, $r_pieces ); $retVal[] = r_implode( $glue, $r_pieces );
} }
else else
{ {
$retVal[] = $r_pieces; $retVal[] = $r_pieces;
} }
} }
return implode( $glue, $retVal ); return implode( $glue, $retVal );
} }
?> ?>
   
<?php <?php
  function getRoute($routeID)
  {
  global $conn;
  $query = "Select * from routes where route_id = :routeID LIMIT 1";
  debug($query, "database");
  $query = $conn->prepare($query);
  $query->bindParam(":routeID", $routeID);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetch(PDO::FETCH_ASSOC);
  }
   
function getRoute($routeID) { function getRoutes()
global $conn; {
$query = "Select * from routes where route_id = '$routeID' LIMIT 1"; global $conn;
debug($query,"database");  
$result = pg_query($conn, $query);  
if (!$result) {  
databaseError(pg_result_error($result));  
return Array();  
}  
return pg_fetch_assoc($result);  
}  
function getRoutes() {  
global $conn;  
$query = "Select * from routes order by route_short_name;"; $query = "Select * from routes order by route_short_name;";
debug($query,"database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->execute();
databaseError(pg_result_error($result)); if (!$query) {
return Array(); databaseError($conn->errorInfo());
} return Array();
return pg_fetch_all($result); }
} return $query->fetchAll();
  }
  function getRoutesByNumber($routeNumber = "")
  {
  global $conn;
  if ($routeNumber != "") {
  $query = "Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id =
  routes.route_id join stop_times on stop_times.trip_id = trips.trip_id where route_short_name = :routeNumber order by route_short_name;";
  }
  else {
  $query = "SELECT DISTINCT route_short_name from routes order by route_short_name";
  }
  debug($query, "database");
  $query = $conn->prepare($query);
  if ($routeNumber != "") {
  $query->bindParam(":routeNumber", $routeNumber);
  }
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
  }
  function getRoutesByNumberSeries($routeNumberSeries = "")
  {
  global $conn;
  if (strlen($routeNumberSeries) == 1) {
  return getRoutesByNumber($routeNumberSeries);
  }
  $seriesMin = substr($routeNumberSeries, 0, -1) . "0";
  $seriesMax = substr($routeNumberSeries, 0, -1) . "9";
  $query = "Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id =
  routes.route_id join stop_times on stop_times.trip_id = trips.trip_id where to_number(route_short_name, 'FM999') between :seriesMin and :seriesMax OR route_short_name LIKE :routeNumberSeries order by route_short_name;";
  debug($query, "database");
  $query = $conn->prepare($query);
  $query->bindParam(":seriesMin", $seriesMin);
  $query->bindParam(":seriesMax", $seriesMax);
  $routeNumberSeries = "% ".substr($routeNumberSeries, 0, -1)."%";
  $query->bindParam(":routeNumberSeries", $routeNumberSeries);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
  }
  function getRouteNextTrip($routeID)
  {
  global $conn;
  $query = "select * from routes join trips on trips.route_id = routes.route_id
  join stop_times on stop_times.trip_id = trips.trip_id where
  arrival_time > :currentTime and routes.route_id = :routeID order by
  arrival_time limit 1";
  debug($query, "database");
  $query = $conn->prepare($query);
  $query->bindParam(":currentTime", current_time());
  $query->bindParam(":routeID", $routeID);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  $r = $query->fetch(PDO::FETCH_ASSOC);
   
function getRoutesByNumber($routeNumber = "") { // past last trip of the day special case
global $conn; if (sizeof($r) < 16) {
if ($routeNumber != "") { $query = "select * from routes join trips on trips.route_id = routes.route_id
$query = "Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id = join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID order by
routes.route_id join stop_times on stop_times.trip_id = trips.trip_id where route_short_name = '$routeNumber' order by route_short_name;";  
} else {  
$query = "SELECT DISTINCT route_short_name from routes order by route_short_name";  
}  
debug($query,"database");  
$result = pg_query($conn, $query);  
if (!$result) {  
databaseError(pg_result_error($result));  
return Array();  
}  
return pg_fetch_all($result);  
}  
   
function getRouteNextTrip($routeID) {  
global $conn;  
$query = "select * from routes join trips on trips.route_id = routes.route_id  
join stop_times on stop_times.trip_id = trips.trip_id where  
arrival_time > '".current_time()."' and routes.route_id = '$routeID' order by  
arrival_time limit 1";  
debug($query,"database");  
$result = pg_query($conn, $query);  
if (!$result) {  
databaseError(pg_result_error($result));  
return Array();  
}  
$r = pg_fetch_assoc($result);  
// past last trip of the day special case  
if (sizeof($r) == 0) {  
$query = "select * from routes join trips on trips.route_id = routes.route_id  
join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = '$routeID' order by  
arrival_time DESC limit 1"; arrival_time DESC limit 1";
debug($query,"database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":routeID", $routeID);
databaseError(pg_result_error($result)); $query->execute();
return Array(); if (!$query) {
} databaseError($conn->errorInfo());
$r = pg_fetch_assoc($result); return Array();
} }
return $r;  
} $r = $query->fetch(PDO::FETCH_ASSOC);
  }
function getTimeInterpolatedRouteAtStop($routeID, $stop_id) return $r;
{ }
$nextTrip = getRouteNextTrip($routeID); function getTimeInterpolatedRouteAtStop($routeID, $stop_id)
if ($nextTrip['trip_id']){ {
foreach (getTimeInterpolatedTrip($nextTrip['trip_id']) as $tripStop) { $nextTrip = getRouteNextTrip($routeID);
if ($tripStop['stop_id'] == $stop_id) return $tripStop; if ($nextTrip['trip_id']) {
} foreach (getTimeInterpolatedTrip($nextTrip['trip_id']) as $tripStop) {
} if ($tripStop['stop_id'] == $stop_id) return $tripStop;
  }
  }
return Array(); return Array();
} }
  function getRouteTrips($routeID)
function getRouteTrips($routeID) { {
global $conn; global $conn;
$query = "select routes.route_id,trips.trip_id,service_id,arrival_time, stop_id, stop_sequence from routes join trips on trips.route_id = routes.route_id $query = "select routes.route_id,trips.trip_id,service_id,arrival_time, stop_id, stop_sequence from routes join trips on trips.route_id = routes.route_id
join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = '$routeID' and stop_sequence = '1' order by join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID and stop_sequence = '1' order by
arrival_time "; arrival_time ";
debug($query,"database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":routeID", $routeID);
databaseError(pg_result_error($result)); $query->execute();
return Array(); if (!$query) {
} databaseError($conn->errorInfo());
return pg_fetch_all($result); return Array();
} }
function getRoutesByDestination($destination = "", $service_period = "") { return $query->fetchAll();
global $conn; }
if ($service_period == "") $service_period = service_period(); function getRoutesByDestination($destination = "", $service_period = "")
if ($destination != "") { {
$query = "SELECT DISTINCT trips.route_id,route_short_name,route_long_name, service_id global $conn;
  if ($service_period == "") $service_period = service_period();
  if ($destination != "") {
  $query = "SELECT DISTINCT trips.route_id,route_short_name,route_long_name, service_id
FROM stop_times join trips on trips.trip_id = FROM stop_times join trips on trips.trip_id =
stop_times.trip_id join routes on trips.route_id = routes.route_id stop_times.trip_id join routes on trips.route_id = routes.route_id
WHERE route_long_name = '$destination' AND service_id='$service_period' order by route_short_name"; WHERE route_long_name = :destination AND service_id=:service_period order by route_short_name";
} else { }
$query = "SELECT DISTINCT route_long_name else {
  $query = "SELECT DISTINCT route_long_name
FROM stop_times join trips on trips.trip_id = FROM stop_times join trips on trips.trip_id =
stop_times.trip_id join routes on trips.route_id = routes.route_id stop_times.trip_id join routes on trips.route_id = routes.route_id
WHERE service_id='$service_period' order by route_long_name"; WHERE service_id= :service_period order by route_long_name";
} }
debug($query,"database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":service_period", $service_period);
databaseError(pg_result_error($result)); if ($destination != "") $query->bindParam(":destination", $destination);
return Array(); $query->execute();
} if (!$query) {
return pg_fetch_all($result); databaseError($conn->errorInfo());
} return Array();
  }
function getRoutesBySuburb($suburb, $service_period = "") { return $query->fetchAll();
if ($service_period == "") $service_period = service_period(); }
global $conn; function getRoutesBySuburb($suburb, $service_period = "")
$query = "SELECT DISTINCT service_id,trips.route_id,route_short_name,route_long_name {
  if ($service_period == "") $service_period = service_period();
  global $conn;
  $query = "SELECT DISTINCT service_id,trips.route_id,route_short_name,route_long_name
FROM stop_times join trips on trips.trip_id = stop_times.trip_id FROM stop_times join trips on trips.trip_id = stop_times.trip_id
join routes on trips.route_id = routes.route_id join routes on trips.route_id = routes.route_id
join stops on stops.stop_id = stop_times.stop_id join stops on stops.stop_id = stop_times.stop_id
WHERE zone_id LIKE '%$suburb;%' AND service_id='$service_period' ORDER BY route_short_name"; WHERE zone_id LIKE ':suburb AND service_id=:service_period ORDER BY route_short_name";
debug($query,"database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":service_period", $service_period);
databaseError(pg_result_error($result)); $suburb = "%" . $suburb . ";%";
return Array(); $query->bindParam(":suburb", $suburb);
} $query->execute();
return pg_fetch_all($result); if (!$query) {
} databaseError($conn->errorInfo());
  return Array();
function getRoutesNearby($lat, $lng, $limit = "", $distance = 500) { }
  return $query->fetchAll();
  }
if ($service_period == "") $service_period = service_period(); function getRoutesNearby($lat, $lng, $limit = "", $distance = 500)
if ($limit != "") $limit = " LIMIT $limit "; {
global $conn; if ($service_period == "") $service_period = service_period();
$query = "SELECT service_id,trips.route_id,route_short_name,route_long_name,min(stops.stop_id) as stop_id, if ($limit != "") $limitSQL = " LIMIT :limit ";
  global $conn;
  $query = "SELECT service_id,trips.route_id,route_short_name,route_long_name,min(stops.stop_id) as stop_id,
min(ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE)) as distance min(ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE)) as distance
FROM stop_times FROM stop_times
join trips on trips.trip_id = stop_times.trip_id join trips on trips.trip_id = stop_times.trip_id
join routes on trips.route_id = routes.route_id join routes on trips.route_id = routes.route_id
join stops on stops.stop_id = stop_times.stop_id join stops on stops.stop_id = stop_times.stop_id
WHERE service_id='$service_period' WHERE service_id=:service_period
AND ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), $distance, FALSE) AND ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), :distance, FALSE)
group by service_id,trips.route_id,route_short_name,route_long_name group by service_id,trips.route_id,route_short_name,route_long_name
order by distance $limit"; order by distance $limitSQL";
debug($query,"database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":service_period", $service_period);
databaseError(pg_result_error($result)); $query->bindParam(":distance", $distance);
return Array(); if ($limit != "") $query->bindParam(":limit", $limit);
} $query->execute();
return pg_fetch_all($result); if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetchAll();
} }
?> ?>
  <?php
  function getServiceOverride() {
  global $conn;
  $query = "Select * from calendar_dates where date = :date and exception_type = '1' LIMIT 1";
  debug($query,"database");
  $query = $conn->prepare($query); // Create a prepared statement
  $query->bindParam(":date", date("Ymd"));
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetch(PDO::FETCH_ASSOC);
  }
  ?>
<?php <?php
function getStop($stopID) function getStop($stopID)
{ {
global $conn; global $conn;
$query = "Select * from stops where stop_id = '$stopID' LIMIT 1"; $query = "Select * from stops where stop_id = :stopID LIMIT 1";
debug($query, "database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":stopID", $stopID);
databaseError(pg_result_error($result)); $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
return Array(); return Array();
} }
return pg_fetch_assoc($result); return $query->fetch(PDO::FETCH_ASSOC);
} }
function getStops($timingPointsOnly = false, $firstLetter = "") function getStops($timingPointsOnly = false, $firstLetter = "")
{ {
global $conn; global $conn;
$conditions = Array(); $conditions = Array();
if ($timingPointsOnly) $conditions[] = "substr(stop_code,1,2) != 'Wj'"; if ($timingPointsOnly) $conditions[] = "substr(stop_code,1,2) != 'Wj'";
if ($firstLetter != "") $conditions[] = "substr(stop_name,1,1) = '$firstLetter'"; if ($firstLetter != "") $conditions[] = "substr(stop_name,1,1) = :firstLetter";
$query = "Select * from stops"; $query = "Select * from stops";
if (sizeof($conditions) > 0) { if (sizeof($conditions) > 0) {
if (sizeof($conditions) > 1) { if (sizeof($conditions) > 1) {
$query.= " Where " . implode(" AND ", $conditions) . " "; $query.= " Where " . implode(" AND ", $conditions) . " ";
} }
else { else {
$query.= " Where " . $conditions[0] . " "; $query.= " Where " . $conditions[0] . " ";
} }
} }
$query.= " order by stop_name;"; $query.= " order by stop_name;";
debug($query, "database"); $query = $conn->prepare($query);
$result = pg_query($conn, $query); $query->bindParam(":firstLetter", $firstLetter);
if (!$result) { $query->execute();
databaseError(pg_result_error($result)); if (!$query) {
  databaseError($conn->errorInfo());
return Array(); return Array();
} }
return pg_fetch_all($result); return $query->fetchAll();
} }
function getNearbyStops($lat, $lng, $limit = "", $distance = 1000) function getNearbyStops($lat, $lng, $limit = "", $distance = 1000)
{ {
if ($lat == null || $lng == null) return Array(); if ($lat == null || $lng == null) return Array();
if ($limit != "") $limit = " LIMIT $limit "; if ($limit != "") $limitSQL = " LIMIT :limit ";
global $conn; global $conn;
$query = "Select *, ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE) as distance $query = "Select *, ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE) as distance
from stops WHERE ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), $distance, FALSE) from stops WHERE ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), :distance, FALSE)
order by distance $limit;"; order by distance $limitSQL;";
debug($query, "database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":distance", $distance);
databaseError(pg_result_error($result)); $query->bindParam(":limit", $limit);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
return Array(); return Array();
} }
return pg_fetch_all($result); return $query->fetchAll();
} }
function getStopsBySuburb($suburb) function getStopsBySuburb($suburb)
{ {
global $conn; global $conn;
$query = "Select * from stops where zone_id LIKE '%$suburb;%' order by stop_name;"; $query = "Select * from stops where zone_id LIKE :suburb order by stop_name;";
debug($query, "database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $suburb = "%" . $suburb . ";%";
databaseError(pg_result_error($result)); $query->bindParam(":suburb", $suburb);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
return Array(); return Array();
} }
return pg_fetch_all($result); return $query->fetchAll();
} }
function getStopRoutes($stopID, $service_period) function getStopRoutes($stopID, $service_period)
{ {
if ($service_period == "") $service_period = service_period(); if ($service_period == "") $service_period = service_period();
global $conn; global $conn;
$query = "SELECT service_id,trips.route_id,route_short_name,route_long_name $query = "SELECT service_id,trips.route_id,route_short_name,route_long_name
FROM stop_times join trips on trips.trip_id = FROM stop_times join trips on trips.trip_id =
stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_id = '$stopID' AND service_id='$service_period'"; stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_id = :stopID AND service_id=:service_period";
debug($query, "database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":service_period", $service_period);
databaseError(pg_result_error($result)); $query->bindParam(":stopID", $stopID);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
return Array(); return Array();
} }
return pg_fetch_all($result); return $query->fetchAll();
} }
function getStopTrips($stopID, $service_period = "", $afterTime = "") function getStopTrips($stopID, $service_period = "", $afterTime = "")
{ {
if ($service_period == "") $service_period = service_period(); if ($service_period == "") $service_period = service_period();
$afterCondition = "AND arrival_time > '$afterTime'";  
global $conn; global $conn;
if ($afterTime != "") { if ($afterTime != "") {
$query = " SELECT stop_times.trip_id,stop_times.arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name, end_times.arrival_time as end_time $query = " SELECT stop_times.trip_id,stop_times.arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name, end_times.arrival_time as end_time
FROM stop_times FROM stop_times
join trips on trips.trip_id = join trips on trips.trip_id =
stop_times.trip_id stop_times.trip_id
join routes on trips.route_id = routes.route_id , (SELECT trip_id,max(arrival_time) as arrival_time from stop_times join routes on trips.route_id = routes.route_id , (SELECT trip_id,max(arrival_time) as arrival_time from stop_times
WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times
WHERE stop_times.stop_id = '$stopID' WHERE stop_times.stop_id = :stopID
AND stop_times.trip_id = end_times.trip_id AND stop_times.trip_id = end_times.trip_id
AND service_id='$service_period' AND service_id=:service_period
AND end_times.arrival_time > '$afterTime' AND end_times.arrival_time > :afterTime
ORDER BY end_time"; ORDER BY end_time";
} }
else { else {
$query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name $query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name
FROM stop_times FROM stop_times
join trips on trips.trip_id = join trips on trips.trip_id =
stop_times.trip_id stop_times.trip_id
join routes on trips.route_id = routes.route_id join routes on trips.route_id = routes.route_id
WHERE stop_times.stop_id = '$stopID' WHERE stop_times.stop_id = :stopID
AND service_id='$service_period' AND service_id=:service_period
ORDER BY arrival_time"; ORDER BY arrival_time";
} }
debug($query, "database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":service_period", $service_period);
databaseError(pg_result_error($result)); $query->bindParam(":stopID", $stopID);
  if ($afterTime != "") $query->bindParam(":afterTime", $afterTime);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
return Array(); return Array();
} }
return pg_fetch_all($result); return $query->fetchAll();
} }
function getStopTripsWithTimes($stopID, $time = "", $service_period = "", $time_range = "", $limit = "") function getStopTripsWithTimes($stopID, $time = "", $service_period = "", $time_range = "", $limit = "")
{ {
if ($service_period == "") $service_period = service_period(); if ($service_period == "") $service_period = service_period();
if ($time_range == "") $time_range = (24 * 60 * 60); if ($time_range == "") $time_range = (24 * 60 * 60);
if ($time == "") $time = current_time(); if ($time == "") $time = current_time();
if ($limit == "") $limit = 10; if ($limit == "") $limit = 10;
$trips = getStopTrips($stopID, $service_period, $time); $trips = getStopTrips($stopID, $service_period, $time);
$timedTrips = Array(); $timedTrips = Array();
if ($trips && sizeof($trips) > 0) { if ($trips && sizeof($trips) > 0) {
foreach ($trips as $trip) { foreach ($trips as $trip) {
if ($trip['arrival_time'] != "") { if ($trip['arrival_time'] != "") {
if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) { if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) {
$timedTrips[] = $trip; $timedTrips[] = $trip;
} }
} }
else { else {
$timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']); $timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']);
if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) { if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) {
$timedTrips[] = $timedTrip; $timedTrips[] = $timedTrip;
} }
} }
if (sizeof($timedTrips) > $limit) break; if (sizeof($timedTrips) > $limit) break;
} }
sktimesort($timedTrips, "arrival_time", true); sktimesort($timedTrips, "arrival_time", true);
} }
return $timedTrips; return $timedTrips;
} }
?> ?>
<?php <?php
function getTrip($tripID) function getTrip($tripID)
{ {
global $conn; global $conn;
$query = "Select * from trips $query = "Select * from trips
join routes on trips.route_id = routes.route_id join routes on trips.route_id = routes.route_id
where trip_id = '$tripID' where trip_id = :tripID
LIMIT 1"; LIMIT 1";
debug($query, "database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":tripID", $tripID);
databaseError(pg_result_error($result)); $query->execute();
return Array(); if (!$query) {
} databaseError($conn->errorInfo());
return pg_fetch_assoc($result); return Array();
} }
function getTripShape() return $query->fetch(PDO::FETCH_ASSOC);
{ }
/* def handle_json_GET_tripstopTimes(self, params): function getTripShape($tripID)
schedule = self.server.schedule {
try: global $conn;
trip = schedule.GetTrip(params.get('trip')) $query = "SELECT ST_AsKML(ST_MakeLine(geometry(a.position))) as the_route
except KeyError: FROM (SELECT position,
# if a non-existent trip is searched for, the return nothing stop_sequence, trips.trip_id
return FROM stop_times
time_stops = trip.GetTimeInterpolatedStops() join trips on trips.trip_id = stop_times.trip_id
stops = [] join stops on stops.stop_id = stop_times.stop_id
times = [] WHERE trips.trip_id = :tripID ORDER BY stop_sequence) as a group by a.trip_id";
for arr,ts,is_timingpoint in time_stops: debug($query, "database");
stops.append(StopToTuple(ts.stop)) $query = $conn->prepare($query);
times.append(arr) $query->bindParam(":tripID", $tripID);
return [stops, times] $query->execute();
  if (!$query) {
def handle_json_GET_tripshape(self, params): databaseError($conn->errorInfo());
schedule = self.server.schedule return Array();
try: }
trip = schedule.GetTrip(params.get('trip')) return $query->fetchColumn(0);
except KeyError:  
# if a non-existent trip is searched for, the return nothing  
return  
points = []  
if trip.shape_id:  
shape = schedule.GetShape(trip.shape_id)  
for (lat, lon, dist) in shape.points:  
points.append((lat, lon))  
else:  
time_stops = trip.GetTimeStops()  
for arr,dep,stop in time_stops:  
points.append((stop.stop_lat, stop.stop_lon))  
return points*/  
} }
function getTimeInterpolatedTrip($tripID, $range = "") function getTimeInterpolatedTrip($tripID, $range = "")
{ {
global $conn; global $conn;
$query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_lat,stop_lon,stop_name,stop_code, $query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_lat,stop_lon,stop_name,stop_code,
stop_sequence,service_id,trips.route_id,route_short_name,route_long_name stop_sequence,service_id,trips.route_id,route_short_name,route_long_name
FROM stop_times FROM stop_times
join trips on trips.trip_id = stop_times.trip_id join trips on trips.trip_id = stop_times.trip_id
join routes on trips.route_id = routes.route_id join routes on trips.route_id = routes.route_id
join stops on stops.stop_id = stop_times.stop_id join stops on stops.stop_id = stop_times.stop_id
WHERE trips.trip_id = '$tripID' $range ORDER BY stop_sequence"; WHERE trips.trip_id = :tripID $range ORDER BY stop_sequence";
debug($query, "database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":tripID", $tripID);
databaseError(pg_result_error($result)); $query->execute();
return Array(); if (!$query) {
} databaseError($conn->errorInfo());
$stopTimes = pg_fetch_all($result); return Array();
  }
  $stopTimes = $query->fetchAll();
$cur_timepoint = Array(); $cur_timepoint = Array();
$next_timepoint = Array(); $next_timepoint = Array();
$distance_between_timepoints = 0.0; $distance_between_timepoints = 0.0;
$distance_traveled_between_timepoints = 0.0; $distance_traveled_between_timepoints = 0.0;
$rv = Array(); $rv = Array();
foreach ($stopTimes as $i => $stopTime) { foreach ($stopTimes as $i => $stopTime) {
if ($stopTime['arrival_time'] != "") { if ($stopTime['arrival_time'] != "") {
// is timepoint // is timepoint
$cur_timepoint = $stopTime; $cur_timepoint = $stopTime;
$distance_between_timepoints = 0.0; $distance_between_timepoints = 0.0;
$distance_traveled_between_timepoints = 0.0; $distance_traveled_between_timepoints = 0.0;
if ($i + 1 < sizeof($stopTimes)) { if ($i + 1 < sizeof($stopTimes)) {
$k = $i + 1; $k = $i + 1;
$distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); $distance_between_timepoints+= distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]);
while ($stopTimes[$k]["arrival_time"] == "" && $k + 1 < sizeof($stopTimes)) { while ($stopTimes[$k]["arrival_time"] == "" && $k + 1 < sizeof($stopTimes)) {
$k += 1; $k+= 1;
//echo "k".$k; //echo "k".$k;
$distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); $distance_between_timepoints+= distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]);
} }
$next_timepoint = $stopTimes[$k]; $next_timepoint = $stopTimes[$k];
$rv[] = $stopTime; $rv[] = $stopTime;
} }
} }
else { else {
// is untimed point // is untimed point
//echo "i".$i; //echo "i".$i;
$distance_traveled_between_timepoints += distance($stopTimes[$i - 1]["stop_lat"], $stopTimes[$i - 1]["stop_lon"], $stopTimes[$i]["stop_lat"], $stopTimes[$i]["stop_lon"]); $distance_traveled_between_timepoints+= distance($stopTimes[$i - 1]["stop_lat"], $stopTimes[$i - 1]["stop_lon"], $stopTimes[$i]["stop_lat"], $stopTimes[$i]["stop_lon"]);
//echo "$distance_traveled_between_timepoints / $distance_between_timepoints<br>"; //echo "$distance_traveled_between_timepoints / $distance_between_timepoints<br>";
$distance_percent = $distance_traveled_between_timepoints / $distance_between_timepoints; $distance_percent = $distance_traveled_between_timepoints / $distance_between_timepoints;
if ($next_timepoint["arrival_time"] != "") { if ($next_timepoint["arrival_time"] != "") {
$total_time = strtotime($next_timepoint["arrival_time"]) - strtotime($cur_timepoint["arrival_time"]); $total_time = strtotime($next_timepoint["arrival_time"]) - strtotime($cur_timepoint["arrival_time"]);
//echo strtotime($next_timepoint["arrival_time"])." - ".strtotime($cur_timepoint["arrival_time"])."<br>"; //echo strtotime($next_timepoint["arrival_time"])." - ".strtotime($cur_timepoint["arrival_time"])."<br>";
$time_estimate = ($distance_percent * $total_time) + strtotime($cur_timepoint["arrival_time"]); $time_estimate = ($distance_percent * $total_time) + strtotime($cur_timepoint["arrival_time"]);
$stopTime["arrival_time"] = date("H:i:s", $time_estimate); $stopTime["arrival_time"] = date("H:i:s", $time_estimate);
} else { }
$stopTime["arrival_time"] = $cur_timepoint["arrival_time"]; else {
  $stopTime["arrival_time"] = $cur_timepoint["arrival_time"];
} }
$rv[] = $stopTime; $rv[] = $stopTime;
//var_dump($rv); //var_dump($rv);
   
} }
} }
return $rv; return $rv;
} }
  function getTripPreviousTimePoint($tripID, $stop_sequence)
  {
  global $conn;
  $query = " SELECT trip_id,stop_id,
  stop_sequence
  FROM stop_times
  WHERE trip_id = :tripID and stop_sequence < :stop_sequence
  and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence DESC LIMIT 1";
  debug($query, "database");
  $query = $conn->prepare($query);
  $query->bindParam(":tripID", $tripID);
  $query->bindParam(":stop_sequence", $stop_sequence);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetch(PDO::FETCH_ASSOC);
  }
  function getTripNextTimePoint($tripID, $stop_sequence)
  {
  global $conn;
  $query = " SELECT trip_id,stop_id,
  stop_sequence
  FROM stop_times
  WHERE trip_id = :tripID and stop_sequence > :stop_sequence
  and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence LIMIT 1";
  debug($query, "database");
  $query = $conn->prepare($query);
  $query->bindParam(":tripID", $tripID);
  $query->bindParam(":stop_sequence", $stop_sequence);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  return $query->fetch(PDO::FETCH_ASSOC);
  }
function getTimeInterpolatedTripAtStop($tripID, $stop_sequence) function getTimeInterpolatedTripAtStop($tripID, $stop_sequence)
{ {
global $conn; global $conn;
// limit interpolation to between nearest actual points. // limit interpolation to between nearest actual points.
$prevTimePoint = pg_fetch_assoc(pg_query($conn," SELECT trip_id,stop_id, $prevTimePoint = getTripPreviousTimePoint($tripID, $stop_sequence);
stop_sequence $nextTimePoint = getTripNextTimePoint($tripID, $stop_sequence);
FROM stop_times $range = "AND stop_sequence >= '{$prevTimePoint['stop_sequence']}' AND stop_sequence <= '{$nextTimePoint['stop_sequence']}'";
WHERE trip_id = '$tripID' and stop_sequence < $stop_sequence and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence DESC LIMIT 1")); foreach (getTimeInterpolatedTrip($tripID, $range) as $tripStop) {
$nextTimePoint = pg_fetch_assoc(pg_query($conn," SELECT trip_id,stop_id,  
stop_sequence  
FROM stop_times  
WHERE trip_id = '$tripID' and stop_sequence > $stop_sequence and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence LIMIT 1"));  
$range = "AND stop_sequence >= '{$prevTimePoint['stop_sequence']}' AND stop_sequence <= '{$nextTimePoint['stop_sequence']}'";  
foreach (getTimeInterpolatedTrip($tripID,$range) as $tripStop) {  
if ($tripStop['stop_sequence'] == $stop_sequence) return $tripStop; if ($tripStop['stop_sequence'] == $stop_sequence) return $tripStop;
} }
return Array(); return Array();
} }
function getTripStartTime($tripID) function getTripStartTime($tripID)
{ {
global $conn; global $conn;
$query = "Select * from stop_times $query = "Select * from stop_times
where trip_id = '$tripID' where trip_id = :tripID
AND arrival_time IS NOT NULL AND arrival_time IS NOT NULL
AND stop_sequence = '1'"; AND stop_sequence = '1'";
debug($query, "database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":tripID", $tripID);
databaseError(pg_result_error($result)); $query->execute();
return Array(); if (!$query) {
} databaseError($conn->errorInfo());
$r = pg_fetch_assoc($result); return Array();
  }
  $r = $query->fetch(PDO::FETCH_ASSOC);
return $r['arrival_time']; return $r['arrival_time'];
} }
function getActiveTrips($time) function getActiveTrips($time)
{ {
global $conn; global $conn;
if ($time == "") $time = current_time(); if ($time == "") $time = current_time();
$query = "Select distinct stop_times.trip_id, start_times.arrival_time as start_time, end_times.arrival_time as end_time from stop_times, (SELECT trip_id,arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL $query = "Select distinct stop_times.trip_id, start_times.arrival_time as start_time, end_times.arrival_time as end_time from stop_times, (SELECT trip_id,arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL
AND stop_sequence = '1') as start_times, (SELECT trip_id,max(arrival_time) as arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times AND stop_sequence = '1') as start_times, (SELECT trip_id,max(arrival_time) as arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times
WHERE start_times.trip_id = end_times.trip_id AND stop_times.trip_id = end_times.trip_id AND $time > start_times.arrival_time AND $time < end_times.arrival_time"; WHERE start_times.trip_id = end_times.trip_id AND stop_times.trip_id = end_times.trip_id AND :time > start_times.arrival_time AND :time < end_times.arrival_time";
debug($query, "database"); debug($query, "database");
$result = pg_query($conn, $query); $query = $conn->prepare($query);
if (!$result) { $query->bindParam(":time", $time);
databaseError(pg_result_error($result)); $query->execute();
return Array(); if (!$query) {
} databaseError($conn->errorInfo());
return pg_fetch_all($result); return Array();
} }
  return $query->fetchAll();
function viaPoints($tripid, $stop_sequence = "") }
  function viaPoints($tripID, $stop_sequence = "")
{ {
global $conn; global $conn;
$query = "SELECT stops.stop_id, stop_name, arrival_time $query = "SELECT stops.stop_id, stop_name, arrival_time
FROM stop_times join stops on stops.stop_id = stop_times.stop_id FROM stop_times join stops on stops.stop_id = stop_times.stop_id
WHERE stop_times.trip_id = '$tripid' WHERE stop_times.trip_id = :tripID
".($stop_sequence != "" ? "AND stop_sequence > '$stop_sequence'" : ""). " . ($stop_sequence != "" ? " AND stop_sequence > :stop_sequence " : "") . "AND substr(stop_code,1,2) != 'Wj' ORDER BY stop_sequence";
"AND substr(stop_code,1,2) != 'Wj' ORDER BY stop_sequence"; debug($query, "database");
debug($query, "database"); $query = $conn->prepare($query);
$result = pg_query($conn, $query); if ($stop_sequence != "") $query->bindParam(":stop_sequence", $stop_sequence);
if (!$result) { $query->bindParam(":tripID", $tripID);
databaseError(pg_result_error($result)); $query->execute();
return Array(); if (!$query) {
} databaseError($conn->errorInfo());
return pg_fetch_all($result); return Array();
  }
  return $query->fetchAll();
} }
function viaPointNames($tripid, $stop_sequence = "") function viaPointNames($tripid, $stop_sequence = "")
{ {
$viaPointNames = Array(); $viaPointNames = Array();
foreach(viaPoints($tripid, $stop_sequence) as $point) { foreach (viaPoints($tripid, $stop_sequence) as $point) {
$viaPointNames[] = $point['stop_name']; $viaPointNames[] = $point['stop_name'];
} }
return r_implode(", ", $viaPointNames); if (sizeof($viaPointNames) > 0) {
  return r_implode(", ", $viaPointNames);
  }
  else {
  return "";
  }
} }
?> ?>
file:a/index.php -> file:b/index.php
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
include_header("bus.lambdacomplex.org", "index", false) include_header("bus.lambdacomplex.org", "index", false)
?> ?>
<div data-role="page"> <div data-role="page">
<div data-role="content"> <div data-role="content">
<div id="jqm-homeheader"> <div id="jqm-homeheader">
<h1>busness time</h1><br><small>Canberra Bus Timetables and Trip Planner</small> <h1>busness time</h1><br><small>Canberra Bus Timetables and Trip Planner</small>
</div> </div>
<a name="maincontent" id="maincontent"></a> <a name="maincontent" id="maincontent"></a>
<a href="tripPlanner.php" data-role="button" data-icon="navigation">Launch Trip Planner...</a> <a href="tripPlanner.php" data-role="button" data-icon="navigation">Launch Trip Planner...</a>
<ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b"> <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
<li data-role="list-divider">Timetables - Stops</li> <li data-role="list-divider">Timetables - Stops</li>
<li><a href="stopList.php">Major (Timing Point) Stops</a></li> <li><a href="stopList.php">Major (Timing Point) Stops</a></li>
<li><a href="stopList.php?allstops=yes">All Stops</a></li> <li><a href="stopList.php?allstops=yes">All Stops</a></li>
<li><a href="stopList.php?suburbs=yes">Stops By Suburb</a></li> <li><a href="stopList.php?bysuburbs=yes">Stops By Suburb</a></li>
<li><a class="nearby" href="stopList.php?nearby=yes">Nearby Stops</a></li> <li><a class="nearby" href="stopList.php?nearby=yes">Nearby Stops</a></li>
</ul> </ul>
<ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b"> <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
<li data-role="list-divider">Timetables - Routes</li> <li data-role="list-divider">Timetables - Routes</li>
<li><a href="routeList.php">Routes By Final Destination</a></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?bynumber=yes">Routes By Number</a></li>
<li><a href="routeList.php?bysuburb=yes">Routes By Suburb</a></li> <li><a href="routeList.php?bysuburbs=yes">Routes By Suburb</a></li>
<li><a class="nearby" href="routeList.php?nearby=yes">Nearby Routes</a></li> <li><a class="nearby" href="routeList.php?nearby=yes">Nearby Routes</a></li>
</ul> </ul>
<?php <?php
echo timePlaceSettings(); echo timePlaceSettings();
echo ' <a href="labs/index.php" data-role="button" data-icon="beaker">Busness R&amp;D</a>'; echo ' <a href="labs/index.php" data-role="button" data-icon="beaker">Busness R&amp;D</a>';
include_footer(true) include_footer(true)
?> ?>
   
   
/*!  
* jQuery UI 1.8.5  
*  
* 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  
*/  
(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.5",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,  
NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,  
"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");  
if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"));if(!isNaN(b)&&b!=0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind("mousedown.ui-disableSelection selectstart.ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,  
"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c.style(this,h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c.style(this,  
h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});  
c(function(){var a=document.createElement("div"),b=document.body;c.extend(a.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.appendChild(a).offsetHeight===100;b.removeChild(a).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,  
d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);  
;/*  
* jQuery UI Datepicker 1.8.5  
*  
* 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  
*  
* Depends:  
* jquery.ui.core.js  
*/  
(function(d,G){function L(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=  
"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su",  
"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",  
minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false};d.extend(this._defaults,this.regional[""]);this.dpDiv=d('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>')}function E(a,b){d.extend(a,  
b);for(var c in b)if(b[c]==null||b[c]==G)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.5"}});var y=(new Date).getTime();d.extend(L.prototype,{markerClassName:"hasDatepicker",log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){E(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=  
f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_])/g,"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:d('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')}},  
_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&  
b.append.remove();if(c){b.append=d('<span class="'+this._appendClass+'">'+c+"</span>");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c=="focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("<img/>").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('<button type="button"></button>').addClass(this._triggerClass).html(f==  
""?c:d("<img/>").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;g<f.length;g++)if(f[g].length>h){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,  
c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),  
true);this._updateDatepicker(b);this._updateAlternate(b)}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=1;this._dialogInput=d('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}E(a.settings,e||{});b=b&&b.constructor==  
Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);  
d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},  
_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().removeClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=  
d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().addClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;  
for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return true;return false},_getInst:function(a){try{return d.data(a,"datepicker")}catch(b){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(a,b,c){var e=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?d.extend({},d.datepicker._defaults):e?b=="all"?d.extend({},e.settings):this._get(e,b):null;var f=b||{};if(typeof b=="string"){f={};f[b]=c}if(e){this._curInst==e&&  
this._hideDatepicker();var h=this._getDateDatepicker(a,true);E(e.settings,f);this._attachments(d(a),e);this._autoSize(e);this._setDateDatepicker(a,h);this._updateDatepicker(e)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){(a=this._getInst(a))&&this._updateDatepicker(a)},_setDateDatepicker:function(a,b){if(a=this._getInst(a)){this._setDate(a,b);this._updateDatepicker(a);this._updateAlternate(a)}},_getDateDatepicker:function(a,b){(a=this._getInst(a))&&  
!a.inline&&this._setDateFromField(a,b);return a?this._getDate(a):null},_doKeyDown:function(a){var b=d.datepicker._getInst(a.target),c=true,e=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=true;if(d.datepicker._datepickerShowing)switch(a.keyCode){case 9:d.datepicker._hideDatepicker();c=false;break;case 13:c=d("td."+d.datepicker._dayOverClass,b.dpDiv).add(d("td."+d.datepicker._currentClass,b.dpDiv));c[0]?d.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,c[0]):d.datepicker._hideDatepicker();  
return false;case 27:d.datepicker._hideDatepicker();break;case 33:d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 34:d.datepicker._adjustDate(a.target,a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 35:if(a.ctrlKey||a.metaKey)d.datepicker._clearDate(a.target);c=a.ctrlKey||a.metaKey;break;case 36:if(a.ctrlKey||a.metaKey)d.datepicker._gotoToday(a.target);c=a.ctrlKey||  
a.metaKey;break;case 37:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?+1:-1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,a.ctrlKey?-d.datepicker._get(b,"stepBigMonths"):-d.datepicker._get(b,"stepMonths"),"M");break;case 38:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,-7,"D");c=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,e?-1:+1,"D");c=a.ctrlKey||a.metaKey;if(a.originalEvent.altKey)d.datepicker._adjustDate(a.target,  
a.ctrlKey?+d.datepicker._get(b,"stepBigMonths"):+d.datepicker._get(b,"stepMonths"),"M");break;case 40:if(a.ctrlKey||a.metaKey)d.datepicker._adjustDate(a.target,+7,"D");c=a.ctrlKey||a.metaKey;break;default:c=false}else if(a.keyCode==36&&a.ctrlKey)d.datepicker._showDatepicker(this);else c=false;if(c){a.preventDefault();a.stopPropagation()}},_doKeyPress:function(a){var b=d.datepicker._getInst(a.target);if(d.datepicker._get(b,"constrainInput")){b=d.datepicker._possibleChars(d.datepicker._get(b,"dateFormat"));  
var c=String.fromCharCode(a.charCode==G?a.keyCode:a.charCode);return a.ctrlKey||c<" "||!b||b.indexOf(c)>-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||  
a;if(a.nodeName.toLowerCase()!="input")a=d("input",a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);d.datepicker._curInst&&d.datepicker._curInst!=b&&d.datepicker._curInst.dpDiv.stop(true,true);var c=d.datepicker._get(b,"beforeShow");E(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);  
d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&  
d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){d.datepicker._datepickerShowing=true;var i=d.datepicker._getBorders(b.dpDiv);b.dpDiv.find("iframe.ui-datepicker-cover").css({left:-i[0],top:-i[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})};b.dpDiv.zIndex(d(a).zIndex()+1);d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,  
h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this,c=d.datepicker._getBorders(a.dpDiv);a.dpDiv.empty().append(this._generateHTML(a)).find("iframe.ui-datepicker-cover").css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}).end().find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){d(this).removeClass("ui-state-hover");  
this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).removeClass("ui-datepicker-prev-hover");this.className.indexOf("ui-datepicker-next")!=-1&&d(this).removeClass("ui-datepicker-next-hover")}).bind("mouseover",function(){if(!b._isDisabledDatepicker(a.inline?a.dpDiv.parent()[0]:a.input[0])){d(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");d(this).addClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).addClass("ui-datepicker-prev-hover");  
this.className.indexOf("ui-datepicker-next")!=-1&&d(this).addClass("ui-datepicker-next-hover")}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();c=this._getNumberOfMonths(a);var e=c[1];e>1?a.dpDiv.addClass("ui-datepicker-multi-"+e).css("width",17*e+"em"):a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");a.dpDiv[(c[0]!=1||c[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");  
a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input.focus()},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),  
k=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>k&&k>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1);)a=a[b?"previousSibling":"nextSibling"];  
a=d(a).offset();return[a.left,a.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();if(a=this._get(b,"onClose"))a.apply(b.input?b.input[0]:null,[b.input?b.input.val():  
"",b]);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&  
!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;  
b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e._selectingMonthYear=false;e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var b=  
this._getInst(d(a)[0]);b.input&&b._selectingMonthYear&&setTimeout(function(){b.input.focus()},0);b._selectingMonthYear=!b._selectingMonthYear},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=  
d(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,  
"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b==  
"object"?b.toString():b+"";if(b=="")return null;for(var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff,f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,k=c=-1,l=-1,u=-1,j=false,o=function(p){(p=z+1<a.length&&a.charAt(z+1)==p)&&z++;return p},m=function(p){o(p);p=new RegExp("^\\d{1,"+(p=="@"?14:p=="!"?20:p=="y"?4:p=="o"?  
3:2)+"}");p=b.substring(s).match(p);if(!p)throw"Missing number at position "+s;s+=p[0].length;return parseInt(p[0],10)},n=function(p,w,H){p=o(p)?H:w;for(w=0;w<p.length;w++)if(b.substr(s,p[w].length).toLowerCase()==p[w].toLowerCase()){s+=p[w].length;return w+1}throw"Unknown name at position "+s;},r=function(){if(b.charAt(s)!=a.charAt(z))throw"Unexpected literal at position "+s;s++},s=0,z=0;z<a.length;z++)if(j)if(a.charAt(z)=="'"&&!o("'"))j=false;else r();else switch(a.charAt(z)){case "d":l=m("d");  
break;case "D":n("D",f,h);break;case "o":u=m("o");break;case "m":k=m("m");break;case "M":k=n("M",i,g);break;case "y":c=m("y");break;case "@":var v=new Date(m("@"));c=v.getFullYear();k=v.getMonth()+1;l=v.getDate();break;case "!":v=new Date((m("!")-this._ticksTo1970)/1E4);c=v.getFullYear();k=v.getMonth()+1;l=v.getDate();break;case "'":if(o("'"))r();else j=true;break;default:r()}if(c==-1)c=(new Date).getFullYear();else if(c<100)c+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c<=e?0:-100);if(u>  
-1){k=1;l=u;do{e=this._getDaysInMonth(c,k-1);if(l<=e)break;k++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,k-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=k||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*  
60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=j+1<a.length&&a.charAt(j+1)==o)&&j++;return o},g=function(o,m,n){m=""+m;if(i(o))for(;m.length<n;)m="0"+m;return m},k=function(o,m,n,r){return i(o)?r[m]:n[m]},l="",u=false;if(b)for(var j=0;j<a.length;j++)if(u)if(a.charAt(j)==  
"'"&&!i("'"))u=false;else l+=a.charAt(j);else switch(a.charAt(j)){case "d":l+=g("d",b.getDate(),2);break;case "D":l+=k("D",b.getDay(),e,f);break;case "o":l+=g("o",(b.getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864E5,3);break;case "m":l+=g("m",b.getMonth()+1,2);break;case "M":l+=k("M",b.getMonth(),h,c);break;case "y":l+=i("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case "@":l+=b.getTime();break;case "!":l+=b.getTime()*1E4+this._ticksTo1970;break;case "'":if(i("'"))l+=  
"'";else u=true;break;default:l+=a.charAt(j)}return l},_possibleChars:function(a){for(var b="",c=false,e=function(h){(h=f+1<a.length&&a.charAt(f+1)==h)&&f++;return h},f=0;f<a.length;f++)if(c)if(a.charAt(f)=="'"&&!e("'"))c=false;else b+=a.charAt(f);else switch(a.charAt(f)){case "d":case "m":case "y":case "@":b+="0123456789";break;case "D":case "M":return null;case "'":if(e("'"))b+="'";else c=true;break;default:b+=a.charAt(f)}return b},_get:function(a,b){return a.settings[b]!==G?a.settings[b]:this._defaults[b]},  
_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),e=a.lastVal=a.input?a.input.val():null,f,h;f=h=this._getDefaultDate(a);var i=this._getFormatConfig(a);try{f=this.parseDate(c,e,i)||h}catch(g){this.log(g);e=b?"":e}a.selectedDay=f.getDate();a.drawMonth=a.selectedMonth=f.getMonth();a.drawYear=a.selectedYear=f.getFullYear();a.currentDay=e?f.getDate():0;a.currentMonth=e?f.getMonth():0;a.currentYear=e?f.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,  
this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var e=function(h){var i=new Date;i.setDate(i.getDate()+h);return i},f=function(h){try{return d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),h,d.datepicker._getFormatConfig(a))}catch(i){}var g=(h.toLowerCase().match(/^c/)?d.datepicker._getDate(a):null)||new Date,k=g.getFullYear(),l=g.getMonth();g=g.getDate();for(var u=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,j=u.exec(h);j;){switch(j[2]||"d"){case "d":case "D":g+=  
parseInt(j[1],10);break;case "w":case "W":g+=parseInt(j[1],10)*7;break;case "m":case "M":l+=parseInt(j[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(k,l));break;case "y":case "Y":k+=parseInt(j[1],10);g=Math.min(g,d.datepicker._getDaysInMonth(k,l));break}j=u.exec(h)}return new Date(k,l,g)};if(b=(b=b==null?c:typeof b=="string"?f(b):typeof b=="number"?isNaN(b)?c:e(b):b)&&b.toString()=="Invalid Date"?c:b){b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0)}return this._daylightSavingAdjust(b)},  
_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?  
"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),k=  
this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay?new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),j=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=j&&n<j?j:n;this._daylightSavingAdjust(new Date(m,g,1))>n;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,  
"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-k,1)),this._getFormatConfig(a));n=this._canAdjustMonth(a,-1,m,g)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', -"+k+", 'M');\" title=\""+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+n+"</span></a>":f?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+n+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+  
n+"</span></a>";var r=this._get(a,"nextText");r=!h?r:this.formatDate(r,this._daylightSavingAdjust(new Date(m,g+k,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+y+".datepicker._adjustDate('#"+a.id+"', +"+k+", 'M');\" title=\""+r+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+r+"</span></a>":f?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+r+'"><span class="ui-icon ui-icon-circle-triangle-'+  
(c?"w":"e")+'">'+r+"</span></a>";k=this._get(a,"currentText");r=this._get(a,"gotoCurrent")&&a.currentDay?u:b;k=!h?k:this.formatDate(k,r,this._getFormatConfig(a));h=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+y+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>":"";e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?h:"")+(this._isInRange(a,r)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+  
y+".datepicker._gotoToday('#"+a.id+"');\">"+k+"</button>":"")+(c?"":h)+"</div>":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;k=this._get(a,"showWeek");r=this._get(a,"dayNames");this._get(a,"dayNamesShort");var s=this._get(a,"dayNamesMin"),z=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),w=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var M=this._getDefaultDate(a),I="",C=0;C<i[0];C++){for(var N=  
"",D=0;D<i[1];D++){var J=this._daylightSavingAdjust(new Date(m,g,a.selectedDay)),t=" ui-corner-all",x="";if(l){x+='<div class="ui-datepicker-group';if(i[1]>1)switch(D){case 0:x+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:x+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:x+=" ui-datepicker-group-middle";t="";break}x+='">'}x+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&C==0?c?  
f:n:"")+(/all|right/.test(t)&&C==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,j,o,C>0||D>0,z,v)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var A=k?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(t=0;t<7;t++){var q=(t+h)%7;A+="<th"+((t+h+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+r[q]+'">'+s[q]+"</span></th>"}x+=A+"</tr></thead><tbody>";A=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay,  
A);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;A=l?6:Math.ceil((t+A)/7);q=this._daylightSavingAdjust(new Date(m,g,1-t));for(var O=0;O<A;O++){x+="<tr>";var P=!k?"":'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(q)+"</td>";for(t=0;t<7;t++){var F=p?p.apply(a.input?a.input[0]:null,[q]):[true,""],B=q.getMonth()!=g,K=B&&!H||!F[0]||j&&q<j||o&&q>o;P+='<td class="'+((t+h+6)%7>=5?" ui-datepicker-week-end":"")+(B?" ui-datepicker-other-month":"")+(q.getTime()==J.getTime()&&g==a.selectedMonth&&  
a._keyEvent||M.getTime()==q.getTime()&&M.getTime()==J.getTime()?" "+this._dayOverClass:"")+(K?" "+this._unselectableClass+" ui-state-disabled":"")+(B&&!w?"":" "+F[1]+(q.getTime()==u.getTime()?" "+this._currentClass:"")+(q.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!B||w)&&F[2]?' title="'+F[2]+'"':"")+(K?"":' onclick="DP_jQuery_'+y+".datepicker._selectDay('#"+a.id+"',"+q.getMonth()+","+q.getFullYear()+', this);return false;"')+">"+(B&&!w?"&#xa0;":K?'<span class="ui-state-default">'+q.getDate()+  
"</span>":'<a class="ui-state-default'+(q.getTime()==b.getTime()?" ui-state-highlight":"")+(q.getTime()==J.getTime()?" ui-state-active":"")+(B?" ui-priority-secondary":"")+'" href="#">'+q.getDate()+"</a>")+"</td>";q.setDate(q.getDate()+1);q=this._daylightSavingAdjust(q)}x+=P+"</tr>"}g++;if(g>11){g=0;m++}x+="</tbody></table>"+(l?"</div>"+(i[0]>0&&D==i[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");N+=x}I+=N}I+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':  
"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var k=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),j='<div class="ui-datepicker-title">',o="";if(h||!k)o+='<span class="ui-datepicker-month">'+i[b]+"</span>";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+  
a.id+"');\">";for(var n=0;n<12;n++)if((!i||n>=e.getMonth())&&(!m||n<=f.getMonth()))o+='<option value="'+n+'"'+(n==b?' selected="selected"':"")+">"+g[n]+"</option>";o+="</select>"}u||(j+=o+(h||!(k&&l)?"&#xa0;":""));if(h||!l)j+='<span class="ui-datepicker-year">'+c+"</span>";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,  
i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(j+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+y+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" onclick=\"DP_jQuery_"+y+".datepicker._clickMonthYear('#"+a.id+"');\">";b<=g;b++)j+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";j+="</select>"}j+=this._get(a,"yearSuffix");if(u)j+=(h||!(k&&l)?"&#xa0;":"")+o;j+="</div>";return j},_adjustInstDate:function(a,b,c){var e=  
a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&b<c?c:b;return b=a&&b>a?a:b},_notifyChange:function(a){var b=this._get(a,  
"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);  
c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,  
"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 );  
 
/*  
* jQuery UI Effects @VERSION  
*  
* Copyright 2011, 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/Effects/  
*/  
;jQuery.effects || (function($, undefined) {  
 
$.effects = {};  
 
 
 
/******************************************************************************/  
/****************************** COLOR ANIMATIONS ******************************/  
/******************************************************************************/  
 
// override the animation for color styles  
$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',  
'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],  
function(i, attr) {  
$.fx.step[attr] = function(fx) {  
if (!fx.colorInit) {  
fx.start = getColor(fx.elem, attr);  
fx.end = getRGB(fx.end);  
fx.colorInit = true;  
}  
 
fx.elem.style[attr] = 'rgb(' +  
Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +  
Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +  
Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';  
};  
});  
 
// Color Conversion functions from highlightFade  
// By Blair Mitchelmore  
// http://jquery.offput.ca/highlightFade/  
 
// Parse strings looking for color tuples [255,255,255]  
function getRGB(color) {  
var result;  
 
// Check if we're already dealing with an array of colors  
if ( color && color.constructor == Array && color.length == 3 )  
return color;  
 
// Look for rgb(num,num,num)  
if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))  
return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];  
 
// Look for rgb(num%,num%,num%)  
if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))  
return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];  
 
// Look for #a0b1c2  
if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))  
return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];  
 
// Look for #fff  
if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))  
return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];  
 
// Look for rgba(0, 0, 0, 0) == transparent in Safari 3  
if (result = /rgba\(0, 0, 0, 0\)/.exec(color))  
return colors['transparent'];  
 
// Otherwise, we're most likely dealing with a named color  
return colors[$.trim(color).toLowerCase()];  
}  
 
function getColor(elem, attr) {  
var color;  
 
do {  
color = $.curCSS(elem, attr);  
 
// Keep going until we find an element that has color, or we hit the body  
if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )  
break;  
 
attr = "backgroundColor";  
} while ( elem = elem.parentNode );  
 
return getRGB(color);  
};  
 
// Some named colors to work with  
// From Interface by Stefan Petre  
// http://interface.eyecon.ro/  
 
var colors = {  
aqua:[0,255,255],  
azure:[240,255,255],  
beige:[245,245,220],  
black:[0,0,0],  
blue:[0,0,255],  
brown:[165,42,42],  
cyan:[0,255,255],  
darkblue:[0,0,139],  
darkcyan:[0,139,139],  
darkgrey:[169,169,169],  
darkgreen:[0,100,0],  
darkkhaki:[189,183,107],  
darkmagenta:[139,0,139],  
darkolivegreen:[85,107,47],  
darkorange:[255,140,0],  
darkorchid:[153,50,204],  
darkred:[139,0,0],  
darksalmon:[233,150,122],  
darkviolet:[148,0,211],  
fuchsia:[255,0,255],  
gold:[255,215,0],  
green:[0,128,0],  
indigo:[75,0,130],  
khaki:[240,230,140],  
lightblue:[173,216,230],  
lightcyan:[224,255,255],  
lightgreen:[144,238,144],  
lightgrey:[211,211,211],  
lightpink:[255,182,193],  
lightyellow:[255,255,224],  
lime:[0,255,0],  
magenta:[255,0,255],  
maroon:[128,0,0],  
navy:[0,0,128],  
olive:[128,128,0],  
orange:[255,165,0],  
pink:[255,192,203],  
purple:[128,0,128],  
violet:[128,0,128],  
red:[255,0,0],  
silver:[192,192,192],  
white:[255,255,255],  
yellow:[255,255,0],  
transparent: [255,255,255]  
};  
 
 
 
/******************************************************************************/  
/****************************** CLASS ANIMATIONS ******************************/  
/******************************************************************************/  
 
var classAnimationActions = ['add', 'remove', 'toggle'],  
shorthandStyles = {  
border: 1,  
borderBottom: 1,  
borderColor: 1,  
borderLeft: 1,  
borderRight: 1,  
borderTop: 1,  
borderWidth: 1,  
margin: 1,  
padding: 1  
};  
 
function getElementStyles() {  
var style = document.defaultView  
? document.defaultView.getComputedStyle(this, null)  
: this.currentStyle,  
newStyle = {},  
key,  
camelCase;  
 
// webkit enumerates style porperties  
if (style && style.length && style[0] && style[style[0]]) {  
var len = style.length;  
while (len--) {  
key = style[len];  
if (typeof style[key] == 'string') {  
camelCase = key.replace(/\-(\w)/g, function(all, letter){  
return letter.toUpperCase();  
});  
newStyle[camelCase] = style[key];  
}  
}  
} else {  
for (key in style) {  
if (typeof style[key] === 'string') {  
newStyle[key] = style[key];  
}  
}  
}  
 
return newStyle;  
}  
 
function filterStyles(styles) {  
var name, value;  
for (name in styles) {  
value = styles[name];  
if (  
// ignore null and undefined values  
value == null ||  
// ignore functions (when does this occur?)  
$.isFunction(value) ||  
// shorthand styles that need to be expanded  
name in shorthandStyles ||  
// ignore scrollbars (break in IE)  
(/scrollbar/).test(name) ||  
 
// only colors or values that can be converted to numbers  
(!(/color/i).test(name) && isNaN(parseFloat(value)))  
) {  
delete styles[name];  
}  
}  
 
return styles;  
}  
 
function styleDifference(oldStyle, newStyle) {  
var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459  
name;  
 
for (name in newStyle) {  
if (oldStyle[name] != newStyle[name]) {  
diff[name] = newStyle[name];  
}  
}  
 
return diff;  
}  
 
$.effects.animateClass = function(value, duration, easing, callback) {  
if ($.isFunction(easing)) {  
callback = easing;  
easing = null;  
}  
 
return this.queue('fx', function() {  
var that = $(this),  
originalStyleAttr = that.attr('style') || ' ',  
originalStyle = filterStyles(getElementStyles.call(this)),  
newStyle,  
className = that.attr('className');  
 
$.each(classAnimationActions, function(i, action) {  
if (value[action]) {  
that[action + 'Class'](value[action]);  
}  
});  
newStyle = filterStyles(getElementStyles.call(this));  
that.attr('className', className);  
 
that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() {  
$.each(classAnimationActions, function(i, action) {  
if (value[action]) { that[action + 'Class'](value[action]); }  
});  
// work around bug in IE by clearing the cssText before setting it  
if (typeof that.attr('style') == 'object') {  
that.attr('style').cssText = '';  
that.attr('style').cssText = originalStyleAttr;  
} else {  
that.attr('style', originalStyleAttr);  
}  
if (callback) { callback.apply(this, arguments); }  
});  
 
// $.animate adds a function to the end of the queue  
// but we want it at the front  
var queue = $.queue(this),  
anim = queue.splice(queue.length - 1, 1)[0];  
queue.splice(1, 0, anim);  
$.dequeue(this);  
});  
};  
 
$.fn.extend({  
_addClass: $.fn.addClass,  
addClass: function(classNames, speed, easing, callback) {  
return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);  
},  
 
_removeClass: $.fn.removeClass,  
removeClass: function(classNames,speed,easing,callback) {  
return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);  
},  
 
_toggleClass: $.fn.toggleClass,  
toggleClass: function(classNames, force, speed, easing, callback) {  
if ( typeof force == "boolean" || force === undefined ) {  
if ( !speed ) {  
// without speed parameter;  
return this._toggleClass(classNames, force);  
} else {  
return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);  
}  
} else {  
// without switch parameter;  
return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);  
}  
},  
 
switchClass: function(remove,add,speed,easing,callback) {  
return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);  
}  
});  
 
 
 
/******************************************************************************/  
/*********************************** EFFECTS **********************************/  
/******************************************************************************/  
 
$.extend($.effects, {  
version: "@VERSION",  
 
// Saves a set of properties in a data storage  
save: function(element, set) {  
for(var i=0; i < set.length; i++) {  
if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);  
}  
},  
 
// Restores a set of previously saved properties from a data storage  
restore: function(element, set) {  
for(var i=0; i < set.length; i++) {  
if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));  
}  
},  
 
setMode: function(el, mode) {  
if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle  
return mode;  
},  
 
getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value  
// this should be a little more flexible in the future to handle a string & hash  
var y, x;  
switch (origin[0]) {  
case 'top': y = 0; break;  
case 'middle': y = 0.5; break;  
case 'bottom': y = 1; break;  
default: y = origin[0] / original.height;  
};  
switch (origin[1]) {  
case 'left': x = 0; break;  
case 'center': x = 0.5; break;  
case 'right': x = 1; break;  
default: x = origin[1] / original.width;  
};  
return {x: x, y: y};  
},  
 
// Wraps the element around a wrapper that copies position properties  
createWrapper: function(element) {  
 
// if the element is already wrapped, return it  
if (element.parent().is('.ui-effects-wrapper')) {  
return element.parent();  
}  
 
// wrap the element  
var props = {  
width: element.outerWidth(true),  
height: element.outerHeight(true),  
'float': element.css('float')  
},  
wrapper = $('<div></div>')  
.addClass('ui-effects-wrapper')  
.css({  
fontSize: '100%',  
background: 'transparent',  
border: 'none',  
margin: 0,  
padding: 0  
});  
 
element.wrap(wrapper);  
wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element  
 
// transfer positioning properties to the wrapper  
if (element.css('position') == 'static') {  
wrapper.css({ position: 'relative' });  
element.css({ position: 'relative' });  
} else {  
$.extend(props, {  
position: element.css('position'),  
zIndex: element.css('z-index')  
});  
$.each(['top', 'left', 'bottom', 'right'], function(i, pos) {  
props[pos] = element.css(pos);  
if (isNaN(parseInt(props[pos], 10))) {  
props[pos] = 'auto';  
}  
});  
element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });  
}  
 
return wrapper.css(props).show();  
},  
 
removeWrapper: function(element) {  
if (element.parent().is('.ui-effects-wrapper'))  
return element.parent().replaceWith(element);  
return element;  
},  
 
setTransition: function(element, list, factor, value) {  
value = value || {};  
$.each(list, function(i, x){  
unit = element.cssUnit(x);  
if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];  
});  
return value;  
}  
});  
 
 
function _normalizeArguments(effect, options, speed, callback) {  
// shift params for method overloading  
if (typeof effect == 'object') {  
callback = options;  
speed = null;  
options = effect;  
effect = options.effect;  
}  
if ($.isFunction(options)) {  
callback = options;  
speed = null;  
options = {};  
}  
if (typeof options == 'number' || $.fx.speeds[options]) {  
callback = speed;  
speed = options;  
options = {};  
}  
if ($.isFunction(speed)) {  
callback = speed;  
speed = null;  
}  
 
options = options || {};  
 
speed = speed || options.duration;  
speed = $.fx.off ? 0 : typeof speed == 'number'  
? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;  
 
callback = callback || options.complete;  
 
return [effect, options, speed, callback];  
}  
 
function standardSpeed( speed ) {  
// valid standard speeds  
if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {  
return true;  
}  
 
// invalid strings - treat as "normal" speed  
if ( typeof speed === "string" && !$.effects[ speed ] ) {  
return true;  
}  
 
return false;  
}  
 
$.fn.extend({  
effect: function(effect, options, speed, callback) {  
var args = _normalizeArguments.apply(this, arguments),  
// TODO: make effects take actual parameters instead of a hash  
args2 = {  
options: args[1],  
duration: args[2],  
callback: args[3]  
},  
mode = args2.options.mode,  
effectMethod = $.effects[effect];  
 
if ( $.fx.off || !effectMethod ) {  
// delegate to the original method (e.g., .show()) if possible  
if ( mode ) {  
return this[ mode ]( args2.duration, args2.callback );  
} else {  
return this.each(function() {  
if ( args2.callback ) {  
args2.callback.call( this );  
}  
});  
}  
}  
 
return effectMethod.call(this, args2);  
},  
 
_show: $.fn.show,  
show: function(speed) {  
if ( standardSpeed( speed ) ) {  
return this._show.apply(this, arguments);  
} else {  
var args = _normalizeArguments.apply(this, arguments);  
args[1].mode = 'show';  
return this.effect.apply(this, args);  
}  
},  
 
_hide: $.fn.hide,  
hide: function(speed) {  
if ( standardSpeed( speed ) ) {  
return this._hide.apply(this, arguments);  
} else {  
var args = _normalizeArguments.apply(this, arguments);  
args[1].mode = 'hide';  
return this.effect.apply(this, args);  
}  
},  
 
// jQuery core overloads toggle and creates _toggle  
__toggle: $.fn.toggle,  
toggle: function(speed) {  
if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {  
return this.__toggle.apply(this, arguments);  
} else {  
var args = _normalizeArguments.apply(this, arguments);  
args[1].mode = 'toggle';  
return this.effect.apply(this, args);  
}  
},  
 
// helper functions  
cssUnit: function(key) {  
var style = this.css(key), val = [];  
$.each( ['em','px','%','pt'], function(i, unit){  
if(style.indexOf(unit) > 0)  
val = [parseFloat(style), unit];  
});  
return val;  
}  
});  
 
 
 
/******************************************************************************/  
/*********************************** EASING ***********************************/  
/******************************************************************************/  
 
/*  
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/  
*  
* Uses the built in easing capabilities added In jQuery 1.1  
* to offer multiple easing options  
*  
* TERMS OF USE - jQuery Easing  
*  
* Open source under the BSD License.  
*  
* Copyright 2008 George McGinley Smith  
* All rights reserved.  
*  
* Redistribution and use in source and binary forms, with or without modification,  
* are permitted provided that the following conditions are met:  
*  
* Redistributions of source code must retain the above copyright notice, this list of  
* conditions and the following disclaimer.  
* Redistributions in binary form must reproduce the above copyright notice, this list  
* of conditions and the following disclaimer in the documentation and/or other materials  
* provided with the distribution.  
*  
* Neither the name of the author nor the names of contributors may be used to endorse  
* or promote products derived from this software without specific prior written permission.  
*  
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY  
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE  
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE  
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  
* OF THE POSSIBILITY OF SUCH DAMAGE.  
*  
*/  
 
// t: current time, b: begInnIng value, c: change In value, d: duration  
$.easing.jswing = $.easing.swing;  
 
$.extend($.easing,  
{  
def: 'easeOutQuad',  
swing: function (x, t, b, c, d) {  
//alert($.easing.default);  
return $.easing[$.easing.def](x, t, b, c, d);  
},  
easeInQuad: function (x, t, b, c, d) {  
return c*(t/=d)*t + b;  
},  
easeOutQuad: function (x, t, b, c, d) {  
return -c *(t/=d)*(t-2) + b;  
},  
easeInOutQuad: function (x, t, b, c, d) {  
if ((t/=d/2) < 1) return c/2*t*t + b;  
return -c/2 * ((--t)*(t-2) - 1) + b;  
},  
easeInCubic: function (x, t, b, c, d) {  
return c*(t/=d)*t*t + b;  
},  
easeOutCubic: function (x, t, b, c, d) {  
return c*((t=t/d-1)*t*t + 1) + b;  
},  
easeInOutCubic: function (x, t, b, c, d) {  
if ((t/=d/2) < 1) return c/2*t*t*t + b;  
return c/2*((t-=2)*t*t + 2) + b;  
},  
easeInQuart: function (x, t, b, c, d) {  
return c*(t/=d)*t*t*t + b;  
},  
easeOutQuart: function (x, t, b, c, d) {  
return -c * ((t=t/d-1)*t*t*t - 1) + b;  
},  
easeInOutQuart: function (x, t, b, c, d) {  
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;  
return -c/2 * ((t-=2)*t*t*t - 2) + b;  
},  
easeInQuint: function (x, t, b, c, d) {  
return c*(t/=d)*t*t*t*t + b;  
},  
easeOutQuint: function (x, t, b, c, d) {  
return c*((t=t/d-1)*t*t*t*t + 1) + b;  
},  
easeInOutQuint: function (x, t, b, c, d) {  
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;  
return c/2*((t-=2)*t*t*t*t + 2) + b;  
},  
easeInSine: function (x, t, b, c, d) {  
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;  
},  
easeOutSine: function (x, t, b, c, d) {  
return c * Math.sin(t/d * (Math.PI/2)) + b;  
},  
easeInOutSine: function (x, t, b, c, d) {  
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;  
},  
easeInExpo: function (x, t, b, c, d) {  
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;  
},  
easeOutExpo: function (x, t, b, c, d) {  
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;  
},  
easeInOutExpo: function (x, t, b, c, d) {  
if (t==0) return b;  
if (t==d) return b+c;  
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;  
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;  
},  
easeInCirc: function (x, t, b, c, d) {  
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;  
},  
easeOutCirc: function (x, t, b, c, d) {  
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;  
},  
easeInOutCirc: function (x, t, b, c, d) {  
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;  
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;  
},  
easeInElastic: function (x, t, b, c, d) {  
var s=1.70158;var p=0;var a=c;  
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;  
if (a < Math.abs(c)) { a=c; var s=p/4; }  
else var s = p/(2*Math.PI) * Math.asin (c/a);  
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;  
},  
easeOutElastic: function (x, t, b, c, d) {  
var s=1.70158;var p=0;var a=c;  
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;  
if (a < Math.abs(c)) { a=c; var s=p/4; }  
else var s = p/(2*Math.PI) * Math.asin (c/a);  
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;  
},  
easeInOutElastic: function (x, t, b, c, d) {  
var s=1.70158;var p=0;var a=c;  
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);  
if (a < Math.abs(c)) { a=c; var s=p/4; }  
else var s = p/(2*Math.PI) * Math.asin (c/a);  
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;  
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;  
},  
easeInBack: function (x, t, b, c, d, s) {  
if (s == undefined) s = 1.70158;  
return c*(t/=d)*t*((s+1)*t - s) + b;  
},  
easeOutBack: function (x, t, b, c, d, s) {  
if (s == undefined) s = 1.70158;  
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;  
},  
easeInOutBack: function (x, t, b, c, d, s) {  
if (s == undefined) s = 1.70158;  
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;  
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;  
},  
easeInBounce: function (x, t, b, c, d) {  
return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;  
},  
easeOutBounce: function (x, t, b, c, d) {  
if ((t/=d) < (1/2.75)) {  
return c*(7.5625*t*t) + b;  
} else if (t < (2/2.75)) {  
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;  
} else if (t < (2.5/2.75)) {  
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;  
} else {  
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;  
}  
},  
easeInOutBounce: function (x, t, b, c, d) {  
if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;  
return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;  
}  
});  
 
/*  
*  
* TERMS OF USE - EASING EQUATIONS  
*  
* Open source under the BSD License.  
*  
* Copyright 2001 Robert Penner  
* All rights reserved.  
*  
* Redistribution and use in source and binary forms, with or without modification,  
* are permitted provided that the following conditions are met:  
*  
* Redistributions of source code must retain the above copyright notice, this list of  
* conditions and the following disclaimer.  
* Redistributions in binary form must reproduce the above copyright notice, this list  
* of conditions and the following disclaimer in the documentation and/or other materials  
* provided with the distribution.  
*  
* Neither the name of the author nor the names of contributors may be used to endorse  
* or promote products derived from this software without specific prior written permission.  
*  
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY  
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF  
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE  
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE  
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING  
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  
* OF THE POSSIBILITY OF SUCH DAMAGE.  
*  
*/  
 
})(jQuery);  
 
/*  
* jQuery UI Autocomplete @VERSION  
*  
* Copyright 2011, 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/Autocomplete  
*  
* Depends:  
* jquery.ui.core.js  
* jquery.ui.widget.js  
* jquery.ui.position.js  
* jquery.ui.menu.js  
*/  
(function( $, undefined ) {  
 
// used to prevent race conditions with remote data sources  
var requestIndex = 0;  
 
$.widget( "ui.autocomplete", {  
defaultElement: "<input>",  
options: {  
appendTo: "body",  
delay: 300,  
minLength: 1,  
position: {  
my: "left top",  
at: "left bottom",  
collision: "none"  
},  
source: null  
},  
 
pending: 0,  
 
_create: function() {  
var self = this,  
doc = this.element[ 0 ].ownerDocument,  
suppressKeyPress;  
 
this.element  
.addClass( "ui-autocomplete-input" )  
.attr( "autocomplete", "off" )  
// TODO verify these actually work as intended  
.attr({  
role: "textbox",  
"aria-autocomplete": "list",  
"aria-haspopup": "true"  
})  
.bind( "keydown.autocomplete", function( event ) {  
if ( self.options.disabled || self.element.attr( "readonly" ) ) {  
return;  
}  
 
suppressKeyPress = false;  
var keyCode = $.ui.keyCode;  
switch( event.keyCode ) {  
case keyCode.PAGE_UP:  
self._move( "previousPage", event );  
break;  
case keyCode.PAGE_DOWN:  
self._move( "nextPage", event );  
break;  
case keyCode.UP:  
self._move( "previous", event );  
// prevent moving cursor to beginning of text field in some browsers  
event.preventDefault();  
break;  
case keyCode.DOWN:  
self._move( "next", event );  
// prevent moving cursor to end of text field in some browsers  
event.preventDefault();  
break;  
case keyCode.ENTER:  
case keyCode.NUMPAD_ENTER:  
// when menu is open and has focus  
if ( self.menu.active ) {  
// #6055 - Opera still allows the keypress to occur  
// which causes forms to submit  
suppressKeyPress = true;  
event.preventDefault();  
}  
//passthrough - ENTER and TAB both select the current element  
case keyCode.TAB:  
if ( !self.menu.active ) {  
return;  
}  
self.menu.select( event );  
break;  
case keyCode.ESCAPE:  
self.element.val( self.term );  
self.close( event );  
break;  
default:  
// keypress is triggered before the input value is changed  
clearTimeout( self.searching );  
self.searching = setTimeout(function() {  
// only search if the value has changed  
if ( self.term != self.element.val() ) {  
self.selectedItem = null;  
self.search( null, event );  
}  
}, self.options.delay );  
break;  
}  
})  
.bind( "keypress.autocomplete", function( event ) {  
if ( suppressKeyPress ) {  
suppressKeyPress = false;  
event.preventDefault();  
}  
})  
.bind( "focus.autocomplete", function() {  
if ( self.options.disabled ) {  
return;  
}  
 
self.selectedItem = null;  
self.previous = self.element.val();  
})  
.bind( "blur.autocomplete", function( event ) {  
if ( self.options.disabled ) {  
return;  
}  
 
clearTimeout( self.searching );  
// clicks on the menu (or a button to trigger a search) will cause a blur event  
self.closing = setTimeout(function() {  
self.close( event );  
self._change( event );  
}, 150 );  
});  
this._initSource();  
this.response = function() {  
return self._response.apply( self, arguments );  
};  
this.menu = $( "<ul></ul>" )  
.addClass( "ui-autocomplete" )  
.appendTo( $( this.options.appendTo || "body", doc )[0] )  
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)  
.mousedown(function( event ) {  
// clicking on the scrollbar causes focus to shift to the body  
// but we can't detect a mouseup or a click immediately afterward  
// so we have to track the next mousedown and close the menu if  
// the user clicks somewhere outside of the autocomplete  
var menuElement = self.menu.element[ 0 ];  
if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {  
setTimeout(function() {  
$( document ).one( 'mousedown', function( event ) {  
if ( event.target !== self.element[ 0 ] &&  
event.target !== menuElement &&  
!$.contains( menuElement, event.target ) ) {  
self.close();  
}  
});  
}, 1 );  
}  
 
// use another timeout to make sure the blur-event-handler on the input was already triggered  
setTimeout(function() {  
clearTimeout( self.closing );  
}, 13);  
})  
.menu({  
// custom key handling for now  
input: $(),  
focus: function( event, ui ) {  
var item = ui.item.data( "item.autocomplete" );  
if ( false !== self._trigger( "focus", event, { item: item } ) ) {  
// use value to match what will end up in the input, if it was a key event  
if ( /^key/.test(event.originalEvent.type) ) {  
self.element.val( item.value );  
}  
}  
},  
select: function( event, ui ) {  
var item = ui.item.data( "item.autocomplete" ),  
previous = self.previous;  
 
// only trigger when focus was lost (click on menu)  
if ( self.element[0] !== doc.activeElement ) {  
self.element.focus();  
self.previous = previous;  
// #6109 - IE triggers two focus events and the second  
// is asynchronous, so we need to reset the previous  
// term synchronously and asynchronously :-(  
setTimeout(function() {  
self.previous = previous;  
self.selectedItem = item;  
}, 1);  
}  
 
if ( false !== self._trigger( "select", event, { item: item } ) ) {  
self.element.val( item.value );  
}  
// reset the term after the select event  
// this allows custom select handling to work properly  
self.term = self.element.val();  
 
self.close( event );  
self.selectedItem = item;  
},  
blur: function( event, ui ) {  
// don't set the value of the text field if it's already correct  
// this prevents moving the cursor unnecessarily  
if ( self.menu.element.is(":visible") &&  
( self.element.val() !== self.term ) ) {  
self.element.val( self.term );  
}  
}  
})  
.zIndex( this.element.zIndex() + 1 )  
.hide()  
.data( "menu" );  
if ( $.fn.bgiframe ) {  
this.menu.element.bgiframe();  
}  
},  
 
_destroy: function() {  
this.element  
.removeClass( "ui-autocomplete-input" )  
.removeAttr( "autocomplete" )  
.removeAttr( "role" )  
.removeAttr( "aria-autocomplete" )  
.removeAttr( "aria-haspopup" );  
this.menu.element.remove();  
},  
 
_setOption: function( key, value ) {  
this._super( "_setOption", key, value );  
if ( key === "source" ) {  
this._initSource();  
}  
if ( key === "appendTo" ) {  
this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )  
}  
if ( key === "disabled" && value && this.xhr ) {  
this.xhr.abort();  
}  
},  
 
_initSource: function() {  
var self = this,  
array,  
url;  
if ( $.isArray(this.options.source) ) {  
array = this.options.source;  
this.source = function( request, response ) {  
response( $.ui.autocomplete.filter(array, request.term) );  
};  
} else if ( typeof this.options.source === "string" ) {  
url = this.options.source;  
this.source = function( request, response ) {  
if ( self.xhr ) {  
self.xhr.abort();  
}  
self.xhr = $.ajax({  
url: url,  
data: request,  
dataType: "json",  
autocompleteRequest: ++requestIndex,  
success: function( data, status ) {  
if ( this.autocompleteRequest === requestIndex ) {  
response( data );  
}  
},  
error: function() {  
if ( this.autocompleteRequest === requestIndex ) {  
response( [] );  
}  
}  
});  
};  
} else {  
this.source = this.options.source;  
}  
},  
 
search: function( value, event ) {  
value = value != null ? value : this.element.val();  
 
// always save the actual value, not the one passed as an argument  
this.term = this.element.val();  
 
if ( value.length < this.options.minLength ) {  
return this.close( event );  
}  
 
clearTimeout( this.closing );  
if ( this._trigger( "search", event ) === false ) {  
return;  
}  
 
return this._search( value );  
},  
 
_search: function( value ) {  
this.pending++;  
this.element.addClass( "ui-autocomplete-loading" );  
 
this.source( { term: value }, this.response );  
},  
 
_response: function( content ) {  
if ( !this.options.disabled && content && content.length ) {  
content = this._normalize( content );  
this._suggest( content );  
this._trigger( "open" );  
} else {  
this.close();  
}  
this.pending--;  
if ( !this.pending ) {  
this.element.removeClass( "ui-autocomplete-loading" );  
}  
},  
 
close: function( event ) {  
clearTimeout( this.closing );  
if ( this.menu.element.is(":visible") ) {  
this.menu.element.hide();  
this.menu.deactivate();  
this._trigger( "close", event );  
}  
},  
 
_change: function( event ) {  
if ( this.previous !== this.element.val() ) {  
this._trigger( "change", event, { item: this.selectedItem } );  
}  
},  
 
_normalize: function( items ) {  
// assume all items have the right format when the first item is complete  
if ( items.length && items[0].label && items[0].value ) {  
return items;  
}  
return $.map( items, function(item) {  
if ( typeof item === "string" ) {  
return {  
label: item,  
value: item  
};  
}  
return $.extend({  
label: item.label || item.value,  
value: item.value || item.label  
}, item );  
});  
},  
 
_suggest: function( items ) {  
var ul = this.menu.element  
.empty()  
.zIndex( this.element.zIndex() + 1 );  
this._renderMenu( ul, items );  
// TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate  
this.menu.deactivate();  
this.menu.refresh();  
 
// size and position menu  
ul.show();  
this._resizeMenu();  
ul.position( $.extend({  
of: this.element  
}, this.options.position ));  
},  
 
_resizeMenu: function() {  
var ul = this.menu.element;  
ul.outerWidth( Math.max(  
ul.width( "" ).outerWidth(),  
this.element.outerWidth()  
) );  
},  
 
_renderMenu: function( ul, items ) {  
var self = this;  
$.each( items, function( index, item ) {  
self._renderItem( ul, item );  
});  
},  
 
_renderItem: function( ul, item) {  
return $( "<li></li>" )  
.data( "item.autocomplete", item )  
.append( $( "<a></a>" ).text( item.label ) )  
.appendTo( ul );  
},  
 
_move: function( direction, event ) {  
if ( !this.menu.element.is(":visible") ) {  
this.search( null, event );  
return;  
}  
if ( this.menu.first() && /^previous/.test(direction) ||  
this.menu.last() && /^next/.test(direction) ) {  
this.element.val( this.term );  
this.menu.deactivate();  
return;  
}  
this.menu[ direction ]( event );  
},  
 
widget: function() {  
return this.menu.element;  
}  
});  
 
$.extend( $.ui.autocomplete, {  
version: "@VERSION",  
escapeRegex: function( value ) {  
return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");  
},  
filter: function(array, term) {  
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );  
return $.grep( array, function(value) {  
return matcher.test( value.label || value.value || value );  
});  
}  
});  
 
}( jQuery ));  
 
  /*
  * jQuery UI Autocomplete 1.8.12
  *
  * Copyright 2011, 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/Autocomplete
  *
  * Depends:
  * jquery.ui.core.js
  * jquery.ui.widget.js
  * jquery.ui.position.js
  */
  (function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.attr("readonly"))){g=
  false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!=
  a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)};
  this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&&
  a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");
  d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&&
  b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source=
  this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==false)return this._search(a)},_search:function(a){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:a},this.response)},_response:function(a){if(!this.options.disabled&&a&&a.length){a=this._normalize(a);this._suggest(a);this._trigger("open")}else this.close();
  this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",a)}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return d.map(a,function(b){if(typeof b==="string")return{label:b,value:b};return d.extend({label:b.label||
  b.value,value:b.value||b.label},b)})},_suggest:function(a){var b=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(b,a);this.menu.deactivate();this.menu.refresh();b.show();this._resizeMenu();b.position(d.extend({of:this.element},this.options.position));this.options.autoFocus&&this.menu.next(new d.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(a,b){var g=this;
  d.each(b,function(c,f){g._renderItem(a,f)})},_renderItem:function(a,b){return d("<li></li>").data("item.autocomplete",b).append(d("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,
  "\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery);
  (function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
  -1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.attr("scrollTop"),c=this.element.height();if(b<0)this.element.attr("scrollTop",g+b);else b>=c&&this.element.attr("scrollTop",g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})},
  deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0);
  e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b,this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e,
  g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first"));
  this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element.attr("scrollHeight")},select:function(e){this._trigger("selected",e,{item:this.active})}})})(jQuery);
 
  /*!
  * jQuery UI 1.8.12
  *
  * Copyright 2011, 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
  */
  (function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.12",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,
  NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,
  "position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");
  if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,
  "border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,
  d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});
  c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&
  b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);
 
/*  
* jQuery UI Position @VERSION  
*  
* Copyright 2011, 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/Position  
*/  
(function( $, undefined ) {  
 
$.ui = $.ui || {};  
 
var horizontalPositions = /left|center|right/,  
verticalPositions = /top|center|bottom/,  
center = "center",  
_position = $.fn.position,  
_offset = $.fn.offset;  
 
$.fn.position = function( options ) {  
if ( !options || !options.of ) {  
return _position.apply( this, arguments );  
}  
 
// make a copy, we don't want to modify arguments  
options = $.extend( {}, options );  
 
var target = $( options.of ),  
targetElem = target[0],  
collision = ( options.collision || "flip" ).split( " " ),  
offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],  
targetWidth,  
targetHeight,  
basePosition;  
 
if ( targetElem.nodeType === 9 ) {  
targetWidth = target.width();  
targetHeight = target.height();  
basePosition = { top: 0, left: 0 };  
} else if ( $.isWindow( targetElem ) ) {  
targetWidth = target.width();  
targetHeight = target.height();  
basePosition = { top: target.scrollTop(), left: target.scrollLeft() };  
} else if ( targetElem.preventDefault ) {  
// force left top to allow flipping  
options.at = "left top";  
targetWidth = targetHeight = 0;  
basePosition = { top: options.of.pageY, left: options.of.pageX };  
} else {  
targetWidth = target.outerWidth();  
targetHeight = target.outerHeight();  
basePosition = target.offset();  
}  
 
// force my and at to have valid horizontal and veritcal positions  
// if a value is missing or invalid, it will be converted to center  
$.each( [ "my", "at" ], function() {  
var pos = ( options[this] || "" ).split( " " );  
if ( pos.length === 1) {  
pos = horizontalPositions.test( pos[0] ) ?  
pos.concat( [center] ) :  
verticalPositions.test( pos[0] ) ?  
[ center ].concat( pos ) :  
[ center, center ];  
}  
pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;  
pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;  
options[ this ] = pos;  
});  
 
// normalize collision option  
if ( collision.length === 1 ) {  
collision[ 1 ] = collision[ 0 ];  
}  
 
// normalize offset option  
offset[ 0 ] = parseInt( offset[0], 10 ) || 0;  
if ( offset.length === 1 ) {  
offset[ 1 ] = offset[ 0 ];  
}  
offset[ 1 ] = parseInt( offset[1], 10 ) || 0;  
 
if ( options.at[0] === "right" ) {  
basePosition.left += targetWidth;  
} else if ( options.at[0] === center ) {  
basePosition.left += targetWidth / 2;  
}  
 
if ( options.at[1] === "bottom" ) {  
basePosition.top += targetHeight;  
} else if ( options.at[1] === center ) {  
basePosition.top += targetHeight / 2;  
}  
 
basePosition.left += offset[ 0 ];  
basePosition.top += offset[ 1 ];  
 
return this.each(function() {  
var elem = $( this ),  
elemWidth = elem.outerWidth(),  
elemHeight = elem.outerHeight(),  
marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,  
marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,  
collisionWidth = elemWidth + marginLeft +  
( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),  
collisionHeight = elemHeight + marginTop +  
( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),  
position = $.extend( {}, basePosition ),  
collisionPosition;  
 
if ( options.my[0] === "right" ) {  
position.left -= elemWidth;  
} else if ( options.my[0] === center ) {  
position.left -= elemWidth / 2;  
}  
 
if ( options.my[1] === "bottom" ) {  
position.top -= elemHeight;  
} else if ( options.my[1] === center ) {  
position.top -= elemHeight / 2;  
}  
 
// prevent fractions (see #5280)  
position.left = Math.round( position.left );  
position.top = Math.round( position.top );  
 
collisionPosition = {  
left: position.left - marginLeft,  
top: position.top - marginTop  
};  
 
$.each( [ "left", "top" ], function( i, dir ) {  
if ( $.ui.position[ collision[i] ] ) {  
$.ui.position[ collision[i] ][ dir ]( position, {  
targetWidth: targetWidth,  
targetHeight: targetHeight,  
elemWidth: elemWidth,  
elemHeight: elemHeight,  
collisionPosition: collisionPosition,  
collisionWidth: collisionWidth,  
collisionHeight: collisionHeight,  
offset: offset,  
my: options.my,  
at: options.at  
});  
}  
});  
 
if ( $.fn.bgiframe ) {  
elem.bgiframe();  
}  
elem.offset( $.extend( position, { using: options.using } ) );  
});  
};  
 
$.ui.position = {  
fit: {  
left: function( position, data ) {  
var win = $( window ),  
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();  
position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );  
},  
top: function( position, data ) {  
var win = $( window ),  
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();  
position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );  
}  
},  
 
flip: {  
left: function( position, data ) {  
if ( data.at[0] === center ) {  
return;  
}  
var win = $( window ),  
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),  
myOffset = data.my[ 0 ] === "left" ?  
-data.elemWidth :  
data.my[ 0 ] === "right" ?  
data.elemWidth :  
0,  
atOffset = data.at[ 0 ] === "left" ?  
data.targetWidth :  
-data.targetWidth,  
offset = -2 * data.offset[ 0 ];  
position.left += data.collisionPosition.left < 0 ?  
myOffset + atOffset + offset :  
over > 0 ?  
myOffset + atOffset + offset :  
0;  
},  
top: function( position, data ) {  
if ( data.at[1] === center ) {  
return;  
}  
var win = $( window ),  
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),  
myOffset = data.my[ 1 ] === "top" ?  
-data.elemHeight :  
data.my[ 1 ] === "bottom" ?  
data.elemHeight :  
0,  
atOffset = data.at[ 1 ] === "top" ?  
data.targetHeight :  
-data.targetHeight,  
offset = -2 * data.offset[ 1 ];  
position.top += data.collisionPosition.top < 0 ?  
myOffset + atOffset + offset :  
over > 0 ?  
myOffset + atOffset + offset :  
0;  
}  
}  
};  
 
// offset setter from jQuery 1.4  
if ( !$.offset.setOffset ) {  
$.offset.setOffset = function( elem, options ) {  
// set position first, in-case top/left are set even on static elem  
if ( /static/.test( $.curCSS( elem, "position" ) ) ) {  
elem.style.position = "relative";  
}  
var curElem = $( elem ),  
curOffset = curElem.offset(),  
curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,  
curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,  
props = {  
top: (options.top - curOffset.top) + curTop,  
left: (options.left - curOffset.left) + curLeft  
};  
 
if ( 'using' in options ) {  
options.using.call( elem, props );  
} else {  
curElem.css( props );  
}  
};  
 
$.fn.offset = function( options ) {  
var elem = this[ 0 ];  
if ( !elem || !elem.ownerDocument ) { return null; }  
if ( options ) {  
return this.each(function() {  
$.offset.setOffset( this, options );  
});  
}  
return _offset.call( this );  
};  
}  
 
}( jQuery ));  
 
  /*
  * jQuery UI Position 1.8.12
  *
  * Copyright 2011, 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/Position
  */
  (function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY,
  left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+=
  k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-=
  m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left=
  d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+=
  a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b),
  g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
 
file:a/js/jquery.ui.widget.js (deleted)
/*!  
* jQuery UI Widget @VERSION  
*  
* Copyright 2011, 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/Widget  
*/  
(function( $, undefined ) {  
 
var slice = Array.prototype.slice;  
 
var _cleanData = $.cleanData;  
$.cleanData = function( elems ) {  
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {  
$( elem ).triggerHandler( "remove" );  
}  
_cleanData( elems );  
};  
 
$.widget = function( name, base, prototype ) {  
var namespace = name.split( "." )[ 0 ],  
fullName;  
name = name.split( "." )[ 1 ];  
fullName = namespace + "-" + name;  
 
if ( !prototype ) {  
prototype = base;  
base = $.Widget;  
}  
 
// create selector for plugin  
$.expr[ ":" ][ fullName ] = function( elem ) {  
return !!$.data( elem, name );  
};  
 
$[ namespace ] = $[ namespace ] || {};  
$[ namespace ][ name ] = $[ namespace ][ name ] || function( options, element ) {  
// allow instantiation without "new" keyword  
if ( !this._createWidget ) {  
return new $[ namespace ][ name ]( options, element );  
}  
 
// allow instantiation without initializing for simple inheritance  
// must use "new" keyword (the code above always passes args)  
if ( arguments.length ) {  
this._createWidget( options, element );  
}  
};  
 
var basePrototype = new base();  
// we need to make the options hash a property directly on the new instance  
// otherwise we'll modify the options hash on the prototype that we're  
// inheriting from  
basePrototype.options = $.extend( true, {}, basePrototype.options );  
$[ namespace ][ name ].prototype = $.extend( true, basePrototype, {  
namespace: namespace,  
widgetName: name,  
widgetEventPrefix: name,  
widgetBaseClass: fullName,  
base: base.prototype  
}, prototype );  
 
$.widget.bridge( name, $[ namespace ][ name ] );  
};  
 
$.widget.bridge = function( name, object ) {  
$.fn[ name ] = function( options ) {  
var isMethodCall = typeof options === "string",  
args = slice.call( arguments, 1 ),  
returnValue = this;  
 
// allow multiple hashes to be passed on init  
options = !isMethodCall && args.length ?  
$.extend.apply( null, [ true, options ].concat(args) ) :  
options;  
 
// prevent calls to internal methods  
if ( isMethodCall && options.charAt( 0 ) === "_" ) {  
return returnValue;  
}  
 
if ( isMethodCall ) {  
this.each(function() {  
var instance = $.data( this, name );  
if ( !instance ) {  
return $.error( "cannot call methods on " + name + " prior to initialization; " +  
"attempted to call method '" + options + "'" );  
}  
if ( !$.isFunction( instance[options] ) ) {  
return $.error( "no such method '" + options + "' for " + name + " widget instance" );  
}  
var methodValue = instance[ options ].apply( instance, args );  
if ( methodValue !== instance && methodValue !== undefined ) {  
returnValue = methodValue;  
return false;  
}  
});  
} else {  
this.each(function() {  
var instance = $.data( this, name );  
if ( instance ) {  
instance.option( options || {} )._init();  
} else {  
object( options, this );  
}  
});  
}  
 
return returnValue;  
};  
};  
 
$.Widget = function( options, element ) {  
// allow instantiation without "new" keyword  
if ( !this._createWidget ) {  
return new $[ namespace ][ name ]( options, element );  
}  
 
// allow instantiation without initializing for simple inheritance  
// must use "new" keyword (the code above always passes args)  
if ( arguments.length ) {  
this._createWidget( options, element );  
}  
};  
 
$.Widget.prototype = {  
widgetName: "widget",  
widgetEventPrefix: "",  
defaultElement: "<div>",  
options: {  
disabled: false  
},  
_createWidget: function( options, element ) {  
element = $( element || this.defaultElement || this )[ 0 ];  
this.element = $( element );  
this.options = $.extend( true, {},  
this.options,  
this._getCreateOptions(),  
options );  
 
this.bindings = $();  
this.hoverable = $();  
this.focusable = $();  
 
if ( element !== this ) {  
$.data( element, this.widgetName, this );  
this._bind({ remove: "destroy" });  
}  
 
this._create();  
this._trigger( "create" );  
this._init();  
},  
_getCreateOptions: function() {  
return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];  
},  
_create: $.noop,  
_init: $.noop,  
 
_super: function( method ) {  
return this.base[ method ].apply( this, slice.call( arguments, 1 ) );  
},  
_superApply: function( method, args ) {  
return this.base[ method ].apply( this, args );  
},  
 
destroy: function() {  
this._destroy();  
// we can probably remove the unbind calls in 2.0  
// all event bindings should go through this._bind()  
this.element  
.unbind( "." + this.widgetName )  
.removeData( this.widgetName );  
this.widget()  
.unbind( "." + this.widgetName )  
.removeAttr( "aria-disabled" )  
.removeClass(  
this.widgetBaseClass + "-disabled " +  
"ui-state-disabled" );  
 
// clean up events and states  
this.bindings.unbind( "." + this.widgetName );  
this.hoverable.removeClass( "ui-state-hover" );  
this.focusable.removeClass( "ui-state-focus" );  
},  
_destroy: $.noop,  
 
widget: function() {  
return this.element;  
},  
 
option: function( key, value ) {  
var options = key;  
 
if ( arguments.length === 0 ) {  
// don't return a reference to the internal hash  
return $.extend( {}, this.options );  
}  
 
if (typeof key === "string" ) {  
if ( value === undefined ) {  
return this.options[ key ];  
}  
options = {};  
options[ key ] = value;  
}  
 
this._setOptions( options );  
 
return this;  
},  
_setOptions: function( options ) {  
var self = this;  
$.each( options, function( key, value ) {  
self._setOption( key, value );  
});  
 
return this;  
},  
_setOption: function( key, value ) {  
this.options[ key ] = value;  
 
if ( key === "disabled" ) {  
this.widget()  
.toggleClass( this.widgetBaseClass + "-disabled ui-state-disabled", !!value )  
.attr( "aria-disabled", value );  
this.hoverable.removeClass( "ui-state-hover" );  
this.focusable.removeClass( "ui-state-focus" );  
}  
 
return this;  
},  
 
enable: function() {  
return this._setOption( "disabled", false );  
},  
disable: function() {  
return this._setOption( "disabled", true );  
},  
 
_bind: function( element, handlers ) {  
// no element argument, shuffle and use this.element  
if ( !handlers ) {  
handlers = element;  
element = this.element;  
} else {  
this.bindings = this.bindings.add( element );  
}  
var instance = this;  
$.each( handlers, function( event, handler ) {  
element.bind( event + "." + instance.widgetName, function() {  
// allow widgets to customize the disabled handling  
// - disabled as an array instead of boolean  
// - disabled class as method for disabling individual parts  
if ( instance.options.disabled === true ||  
$( this ).hasClass( "ui-state-disabled" ) ) {  
return;  
}  
return ( typeof handler === "string" ? instance[ handler ] : handler )  
.apply( instance, arguments );  
});  
});  
},  
 
_hoverable: function( element ) {  
this.hoverable = this.hoverable.add( element );  
this._bind( element, {  
mouseenter: function( event ) {  
$( event.currentTarget ).addClass( "ui-state-hover" );  
},  
mouseleave: function( event ) {  
$( event.currentTarget ).removeClass( "ui-state-hover" );  
}  
});  
},  
 
_focusable: function( element ) {  
this.focusable = this.focusable.add( element );  
this._bind( element, {  
focusin: function( event ) {  
$( event.currentTarget ).addClass( "ui-state-focus" );  
},  
focusout: function( event ) {  
$( event.currentTarget ).removeClass( "ui-state-focus" );  
}  
});  
},  
 
_trigger: function( type, event, data ) {  
var callback = this.options[ type ],  
args;  
 
event = $.Event( event );  
event.type = ( type === this.widgetEventPrefix ?  
type :  
this.widgetEventPrefix + type ).toLowerCase();  
data = data || {};  
 
// copy original event properties over to the new event  
// this would happen if we could call $.event.fix instead of $.Event  
// but we don't have a way to force an event to be fixed multiple times  
if ( event.originalEvent ) {  
for ( var i = $.event.props.length, prop; i; ) {  
prop = $.event.props[ --i ];  
event[ prop ] = event.originalEvent[ prop ];  
}  
}  
 
this.element.trigger( event, data );  
 
args = $.isArray( data ) ?  
[ event ].concat( data ) :  
[ event, data ];  
 
return !( $.isFunction( callback ) &&  
callback.apply( this.element[0], args ) === false ||  
event.isDefaultPrevented() );  
}  
};  
 
})( jQuery );  
 
  /*!
  * jQuery UI Widget 1.8.12
  *
  * Copyright 2011, 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/Widget
  */
  (function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)b(d).triggerHandler("remove");k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,
  a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.charAt(0)==="_")return h;
  e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,
  this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},
  widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},
  enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
 
<?php <?php
include ('../include/common.inc.php'); include ('../include/common.inc.php');
//include_header("Bus Stop Density", "busstopdensity") //include_header("Bus Stop Density", "busstopdensity")
?> ?>
   
<style type="text/css"> <style type="text/css">
   
#map_container{ #map_container{
width:100%; width:100%;
height:100%; height:100%;
} }
#status, #legend { #status, #legend {
background-color: #eeeeee; background-color: #eeeeee;
padding: 3px 5px 3px 5px; padding: 3px 5px 3px 5px;
opacity: .9; opacity: .9;
} }
</style> </style>
<div id="map_container"></div> <div id="map_container"></div>
<div id="status"> <div id="status">
Status:&nbsp; <span id="log"> <img alt="progess bar" src="progress_bar.gif" width="150" height="16"/></span> Status:&nbsp; <span id="log"> <img alt="progess bar" src="progress_bar.gif" width="150" height="16"/></span>
</div> </div>
<script type="text/javascript" src="http://www.google.com/jsapi?autoload={%22modules%22:[{%22name%22:%22maps%22,version:3,other_params:%22sensor=false%22},{%22name%22:%22jquery%22,%22version%22:%221.4.2%22}]}"></script> <script type="text/javascript" src="http://www.google.com/jsapi?autoload={%22modules%22:[{%22name%22:%22maps%22,version:3,other_params:%22sensor=false%22},{%22name%22:%22jquery%22,%22version%22:%221.4.2%22}]}"></script>
<script type="text/javascript"> <script type="text/javascript">
//<![CDATA[ //<![CDATA[
//Google Map API v3 //Google Map API v3
var googleMap = null; var googleMap = null;
var previousPos = null; var previousPos = null;
   
$(function($){//Called when page is loaded $(function($){//Called when page is loaded
googleMap = new google.maps.Map(document.getElementById("map_container"), { googleMap = new google.maps.Map(document.getElementById("map_container"), {
zoom: 17, zoom: 17,
  minZoom: 12,
center: new google.maps.LatLng(-35.25,149.125), center: new google.maps.LatLng(-35.25,149.125),
mapTypeId: google.maps.MapTypeId.SATELLITE}); mapTypeId: google.maps.MapTypeId.SATELLITE});
//Set status bar //Set status bar
googleMap.controls[google.maps.ControlPosition.TOP_LEFT].push($("#status").get(0)); googleMap.controls[google.maps.ControlPosition.TOP_LEFT].push($("#status").get(0));
//Set legend //Set legend
googleMap.controls[google.maps.ControlPosition.BOTTOM_LEFT].push($("#legend").get(0)); googleMap.controls[google.maps.ControlPosition.BOTTOM_LEFT].push($("#legend").get(0));
   
google.maps.event.addListener(googleMap, "zoom_changed", function(){ google.maps.event.addListener(googleMap, "zoom_changed", function(){
google.maps.event.trigger(googleMap, "mousemove", previousPos); google.maps.event.trigger(googleMap, "mousemove", previousPos);
});//onzoomend });//onzoomend
//Add a listener when mouse moves //Add a listener when mouse moves
google.maps.event.addListener(googleMap, "mousemove", function(event){ google.maps.event.addListener(googleMap, "mousemove", function(event){
var latLng = event.latLng; var latLng = event.latLng;
var xy = googleMap.getProjection().fromLatLngToPoint(latLng); var xy = googleMap.getProjection().fromLatLngToPoint(latLng);
var ratio = Math.pow(2,googleMap.getZoom()); var ratio = Math.pow(2,googleMap.getZoom());
$("#log").html("Zoom:" + googleMap.getZoom() + " WGS84:(" + latLng.lat().toFixed(5) + ", " + latLng.lng().toFixed(5) + ") Px:(" + Math.floor(xy.x * ratio) + "," + Math.floor(xy.y *ratio) + ")"); $("#log").html("Zoom:" + googleMap.getZoom() + " WGS84:(" + latLng.lat().toFixed(5) + ", " + latLng.lng().toFixed(5) + ") Px:(" + Math.floor(xy.x * ratio) + "," + Math.floor(xy.y *ratio) + ")");
previousPos = event; previousPos = event;
});//onmouseover });//onmouseover
   
//Add a listener when mouse leaves the map area //Add a listener when mouse leaves the map area
google.maps.event.addListener(googleMap, "mouseout", function(event){ google.maps.event.addListener(googleMap, "mouseout", function(event){
$("#log").html(""); $("#log").html("");
});//onmouseout });//onmouseout
   
//Add tile overlay //Add tile overlay
var myOverlay = new google.maps.ImageMapType({ var myOverlay = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) { getTileUrl: function(coord, zoom) {
return 'busstopdensity.tile.php?x=' + coord.x + '&y=' + coord.y + '&zoom=' +zoom; return 'busstopdensity.tile.php?x=' + coord.x + '&y=' + coord.y + '&zoom=' +zoom;
}, },
tileSize: new google.maps.Size(256, 256), tileSize: new google.maps.Size(256, 256),
isPng: true, isPng: true,
opacity:1.0 opacity:1.0
}); });
googleMap.overlayMapTypes.insertAt(0, myOverlay); googleMap.overlayMapTypes.insertAt(0, myOverlay);
$("#log").html("Map loaded!"); $("#log").html("Map loaded!");
});//onload });//onload
//]]> //]]>
</script> </script>
<?php <?php
include_footer() include_footer()
?> ?>
   
<?php <?php
include ('../include/common.inc.php'); include ('../include/common.inc.php');
$debugOkay = Array(); $debugOkay = Array();
   
/* /*
*DISCLAIMER *DISCLAIMER
* http://blog.gmapify.fr/create-beautiful-tiled-heat-maps-with-php-and-gd * http://blog.gmapify.fr/create-beautiful-tiled-heat-maps-with-php-and-gd
*THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* @author: Olivier G. <olbibigo_AT_gmail_DOT_com> * @author: Olivier G. <olbibigo_AT_gmail_DOT_com>
* @version: 1.0 * @version: 1.0
* @history: * @history:
* 1.0 creation * 1.0 creation
*/ */
set_time_limit(120);//2mn set_time_limit(120);//2mn
ini_set('memory_limit', '256M'); ini_set('memory_limit', '256M');
error_reporting(E_ALL ^ E_DEPRECATED); error_reporting(E_ALL ^ E_DEPRECATED);
require_once ('lib/GoogleMapUtility.php'); require_once ('lib/GoogleMapUtility.php');
require_once ('lib/HeatMap.php'); require_once ('lib/HeatMap.php');
   
//Root folder to store generated tiles //Root folder to store generated tiles
define('TILE_DIR', 'tiles/'); define('TILE_DIR', 'tiles/');
//Covered geographic areas //Covered geographic areas
define('MIN_LAT', -35.48); define('MIN_LAT', -35.48);
define('MAX_LAT', -35.15); define('MAX_LAT', -35.15);
define('MIN_LNG', 148.98); define('MIN_LNG', 148.98);
define('MAX_LNG', 149.25); define('MAX_LNG', 149.25);
define('TILE_SIZE_FACTOR', 0.5); define('TILE_SIZE_FACTOR', 0.5);
define('SPOT_RADIUS', 30); define('SPOT_RADIUS', 30);
define('SPOT_DIMMING_LEVEL', 50); define('SPOT_DIMMING_LEVEL', 50);
//Input parameters //Input parameters
if(isset($_GET['x'])) if(isset($_GET['x']))
$X = (int)$_GET['x']; $X = (int)$_GET['x'];
else else
exit("x missing"); exit("x missing");
if(isset($_GET['y'])) if(isset($_GET['y']))
$Y = (int)$_GET['y']; $Y = (int)$_GET['y'];
else else
exit("y missing"); exit("y missing");
if(isset($_GET['zoom'])) if(isset($_GET['zoom']))
$zoom = (int)$_GET['zoom']; $zoom = (int)$_GET['zoom'];
else else
exit("zoom missing"); exit("zoom missing");
  if ($zoom < 12) { //enforce minimum zoom
  header('Content-type: image/png');
  echo file_get_contents(TILE_DIR.'empty.png');
  }
$dir = TILE_DIR.$zoom; $dir = TILE_DIR.$zoom;
$tilename = $dir.'/'.$X.'_'.$Y.'.png'; $tilename = $dir.'/'.$X.'_'.$Y.'.png';
//HTTP headers (data type and caching rule) //HTTP headers (data type and caching rule)
header("Cache-Control: must-revalidate"); header("Cache-Control: must-revalidate");
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 86400) . " GMT"); header("Expires: " . gmdate("D, d M Y H:i:s", time() + 86400) . " GMT");
if(!file_exists($tilename)){ if(!file_exists($tilename)){
$rect = GoogleMapUtility::getTileRect($X, $Y, $zoom); $rect = GoogleMapUtility::getTileRect($X, $Y, $zoom);
//A tile can contain part of a spot with center in an adjacent tile (overlaps). //A tile can contain part of a spot with center in an adjacent tile (overlaps).
//Knowing the spot radius (in pixels) and zoom level, a smart way to process tiles would be to compute the box (in decimal degrees) containing only spots that can be drawn on current tile. We choose a simpler solution by increeasing geo bounds by 2*TILE_SIZE_FACTOR whatever the zoom level and spot radius. //Knowing the spot radius (in pixels) and zoom level, a smart way to process tiles would be to compute the box (in decimal degrees) containing only spots that can be drawn on current tile. We choose a simpler solution by increeasing geo bounds by 2*TILE_SIZE_FACTOR whatever the zoom level and spot radius.
$extend_X = $rect->width * TILE_SIZE_FACTOR;//in decimal degrees $extend_X = $rect->width * TILE_SIZE_FACTOR;//in decimal degrees
$extend_Y = $rect->height * TILE_SIZE_FACTOR;//in decimal degrees $extend_Y = $rect->height * TILE_SIZE_FACTOR;//in decimal degrees
$swlat = $rect->y - $extend_Y; $swlat = $rect->y - $extend_Y;
$swlng = $rect->x - $extend_X; $swlng = $rect->x - $extend_X;
$nelat = $swlat + $rect->height + 2 * $extend_Y; $nelat = $swlat + $rect->height + 2 * $extend_Y;
$nelng = $swlng + $rect->width + 2 * $extend_X; $nelng = $swlng + $rect->width + 2 * $extend_X;
   
if( ($nelat <= MIN_LAT) || ($swlat >= MAX_LAT) || ($nelng <= MIN_LNG) || ($swlng >= MAX_LNG)){ if( ($nelat <= MIN_LAT) || ($swlat >= MAX_LAT) || ($nelng <= MIN_LNG) || ($swlng >= MAX_LNG)){
//No geodata so return generic empty tile //No geodata so return generic empty tile
echo file_get_contents(TILE_DIR.'empty.png'); echo file_get_contents(TILE_DIR.'empty.png');
exit(); exit();
} }
   
//Get McDonald's spots //Get McDonald's spots
$spots = fGetPOI('Select * from stops where $spots = fGetPOI('Select * from stops where
(stop_lon > '.$swlng.' AND stop_lon < '.$nelng.') (stop_lon > '.$swlng.' AND stop_lon < '.$nelng.')
AND (stop_lat < '.$nelat.' AND stop_lat > '.$swlat.')', $im, $X, $Y, $zoom, SPOT_RADIUS); AND (stop_lat < '.$nelat.' AND stop_lat > '.$swlat.')', $im, $X, $Y, $zoom, SPOT_RADIUS);
   
if(empty($spots)){ if(empty($spots)){
//No geodata so return generic empty tile //No geodata so return generic empty tile
header('Content-type: image/png'); header('Content-type: image/png');
echo file_get_contents(TILE_DIR.'empty.png'); echo file_get_contents(TILE_DIR.'empty.png');
}else{ }else{
if(!file_exists($dir)){ if(!file_exists($dir)){
mkdir($dir, 0705); mkdir($dir, 0705);
} }
//All the magics is in HeatMap class :) //All the magics is in HeatMap class :)
$im = HeatMap::createImage($spots, GoogleMapUtility::TILE_SIZE, GoogleMapUtility::TILE_SIZE, heatMap::$WITH_ALPHA, SPOT_RADIUS, SPOT_DIMMING_LEVEL, HeatMap::$GRADIENT_FIRE); $im = HeatMap::createImage($spots, GoogleMapUtility::TILE_SIZE, GoogleMapUtility::TILE_SIZE, heatMap::$WITH_ALPHA, SPOT_RADIUS, SPOT_DIMMING_LEVEL, HeatMap::$GRADIENT_FIRE);
//Store tile for reuse and output it //Store tile for reuse and output it
header('content-type:image/png;'); header('content-type:image/png;');
imagepng($im, $tilename); imagepng($im, $tilename);
echo file_get_contents($tilename); echo file_get_contents($tilename);
imagedestroy($im); imagedestroy($im);
unset($im); unset($im);
} }
}else{ }else{
//Output stored tile //Output stored tile
header('content-type:image/png;'); header('content-type:image/png;');
echo file_get_contents($tilename); echo file_get_contents($tilename);
} }
///////////// /////////////
//Functions// //Functions//
///////////// /////////////
function fGetPOI($query, &$im, $X, $Y, $zoom, $offset){ function fGetPOI($query, &$im, $X, $Y, $zoom, $offset){
global $conn; global $conn;
$nbPOIInsideTile = 0; $nbPOIInsideTile = 0;
   
$result = pg_query($conn, $query); $result = pg_query($conn, $query);
$spots = Array(); $spots = Array();
if (!$result) { if (!$result) {
databaseError(pg_result_error($result)); databaseError(pg_result_error($result));
return Array(); return Array();
} }
foreach( pg_fetch_all($result) as $row){ foreach( pg_fetch_all($result) as $row){
$point = GoogleMapUtility::getOffsetPixelCoords($row['stop_lat'], $row['stop_lon'], $zoom, $X, $Y); $point = GoogleMapUtility::getOffsetPixelCoords($row['stop_lat'], $row['stop_lon'], $zoom, $X, $Y);
//Count result only in the tile //Count result only in the tile
if( ($point->x > -$offset) && ($point->x < (GoogleMapUtility::TILE_SIZE+$offset)) && ($point->y > -$offset) && ($point->y < (GoogleMapUtility::TILE_SIZE+$offset))){ if( ($point->x > -$offset) && ($point->x < (GoogleMapUtility::TILE_SIZE+$offset)) && ($point->y > -$offset) && ($point->y < (GoogleMapUtility::TILE_SIZE+$offset))){
$spots[] = new HeatMapPoint($point->x, $point->y); $spots[] = new HeatMapPoint($point->x, $point->y);
} }
}//while }//while
return $spots; return $spots;
}//fAddPOI }//fAddPOI
?> ?>
   
   
<?php <?php
include ('../include/common.inc.php'); include ('../include/common.inc.php');
include_header("Busness R&amp;D", "index") include_header("Busness R&amp;D", "index")
?> ?>
<ul data-role="listview" data-theme="e" data-groupingtheme="e"> <ul data-role="listview" data-theme="e" data-groupingtheme="e">
<li data-role="list-divider" > Experimental Features </li> <li data-role="list-divider" > Experimental Features </li>
<li><a href="mywaybalance.php"><h3>MyWay Balance for mobile</h3> <li><a href="mywaybalance.php"><h3>MyWay Balance for mobile</h3>
<p>Mobile viewer for MyWay balance. Warning! No HTTPS security.</p></a></li> <p>Mobile viewer for MyWay balance. Warning! No HTTPS security.</p></a></li>
<li><a href="networkstats.php"><h3>Route Statistics</h3> <li><a href="networkstats.php"><h3>Route Statistics</h3>
<p>Analysis of route timing points</p></a></li> <p>Analysis of route timing points</p></a></li>
<li><a href="busstopdensity.php"><h3>Bus Stop Density Map</h3> <li><a href="busstopdensity.php"><h3>Bus Stop Density Map</h3>
<p>Analysis of bus stop coverage</p></a></li> <p>Analysis of bus stop coverage</p></a></li>
  <li><a href="stopBrowser.php"><h3>Bus Stop Browser Map</h3>
  <p>Bus stop location/route browser</p></a></li>
<li>More coming soon!</li> <li>More coming soon!</li>
</ul> </ul>
</div> </div>
<?php <?php
include_footer() include_footer()
?> ?>
   
<?php <?php
function cleanString($subject) function cleanString($subject)
{ {
$subject = str_replace("&nbsp;", " ", $subject); $subject = str_replace("&nbsp;", " ", $subject);
$subject = str_replace("&", "&amp;", $subject); $subject = str_replace("&", "&amp;", $subject);
$subject = preg_replace('/[^\r\n\t\x20-\x7E\xA0-\xFF]/', '', $subject); $subject = preg_replace('/[^\r\n\t\x20-\x7E\xA0-\xFF]/', '', $subject);
$subject = str_replace(" ", " ", $subject); $subject = str_replace(" ", " ", $subject);
return trim($subject); return trim($subject);
} }
$return = Array(); $return = Array();
/*if (file_exists("mywayresponse.txt")) { /*if (file_exists("mywayresponse.txt")) {
@$fh = fopen("mywayresponse.txt", 'r'); @$fh = fopen("mywayresponse.txt", 'r');
if ($fh) { if ($fh) {
$pageHTML = fread($fh, filesize("mywayresponse.txt")); $pageHTML = fread($fh, filesize("mywayresponse.txt"));
fclose($fh); fclose($fh);
} }
}*/ }*/
//set POST variables //set POST variables
$url = 'https://www.action.act.gov.au/ARTS/use_Funcs.asp'; $url = 'https://www.action.act.gov.au/ARTS/use_Funcs.asp';
$field_mapping = Array( $field_mapping = Array(
"card_number" => "SRNO", "card_number" => "SRNO",
"DOBmonth" => "month", "DOBmonth" => "month",
"DOBday" => "day", "DOBday" => "day",
"DOByear" => "year", "DOByear" => "year",
"secret_answer" => "pwrd", "secret_answer" => "pwrd",
"button" => "button" "button" => "Submit"
); );
foreach (Array( foreach (Array(
"card_number", "card_number",
"DOBday", "DOBday",
"DOBmonth", "DOBmonth",
"DOByear" "DOByear"
) as $field_name) { ) as $field_name) {
if (isset($_REQUEST[$field_name])) { if (isset($_REQUEST[$field_name])) {
$fields[$field_name] = filter_var($_REQUEST[$field_name], FILTER_SANITIZE_NUMBER_INT); $fields[$field_name] = filter_var($_REQUEST[$field_name], FILTER_SANITIZE_NUMBER_INT);
} }
else { else {
$return["error"][] = $field_name. " parameter invalid or unspecified"; $return["error"][] = $field_name. " parameter invalid or unspecified";
} }
} }
if (isset($_REQUEST['secret_answer'])) { if (isset($_REQUEST['secret_answer'])) {
$fields['secret_answer'] = filter_var($_REQUEST['secret_answer'], FILTER_SANITIZE_STRING, Array( $fields['secret_answer'] = filter_var($_REQUEST['secret_answer'], FILTER_SANITIZE_STRING, Array(
FILTER_FLAG_NO_ENCODE_QUOTES, FILTER_FLAG_NO_ENCODE_QUOTES,
FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_HIGH,
FILTER_FLAG_STRIP_LOW FILTER_FLAG_STRIP_LOW
)); ));
} }
else { else {
$return["error"][] = "secret_answer parameter invalid or unspecified"; $return["error"][] = "secret_answer parameter invalid or unspecified";
} }
$fields['button'] = 'Submit'; $fields['button'] = 'Submit';
$fields_string = ""; $fields_string = "";
//url-ify the data for the POST //url-ify the data for the POST
foreach ($fields as $key => $value) { foreach ($fields as $key => $value) {
if (sizeof($value) === 0) $return['error'][] = $key . " parameter invalid or unspecified"; if (sizeof($value) === 0) $return['error'][] = $key . " parameter invalid or unspecified";
$fields_string.= $field_mapping[$key] . '=' . $value . '&'; $fields_string.= $field_mapping[$key] . '=' . $value . '&';
} }
$fields_string = rtrim($fields_string, '&'); $fields_string = rtrim($fields_string, '&');
if (!isset($return['error'])) { if (!isset($return['error'])) {
//open connection //open connection
$ch = curl_init(); $ch = curl_init();
//set the url, number of POST vars, POST data //set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields)); curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_REFERER, "https://www.action.act.gov.au/ARTS/getbalance.asp");
curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_TIMEOUT, 30);
//execute post //execute post
$pageHTML = curl_exec($ch); $pageHTML = curl_exec($ch);
if (curl_errno($ch)) $return["error"][] = "Network error " . curl_errno($ch) . " " . curl_error($ch) . " " . $url . $fields_string; if (curl_errno($ch)) $return["error"][] = "Network error " . curl_errno($ch) . " " . curl_error($ch) . " " . $url . $fields_string;
//close connection //close connection
curl_close($ch); curl_close($ch);
} }
   
if (!isset($return['error'])) { if (!isset($return['error'])) {
include_once ('lib/simple_html_dom.php'); include_once ('lib/simple_html_dom.php');
  //print_r($pageHTML);
$page = str_get_html($pageHTML); $page = str_get_html($pageHTML);
$pageAlerts = $page->find(".smartCardAlert"); $pageAlerts = $page->find(".smartCardAlert");
if (sizeof($pageAlerts) > 0) { if (sizeof($pageAlerts) > 0) {
$return['error'][] = $pageAlerts[0]->plaintext; $return['error'][] = $pageAlerts[0]->plaintext;
} }
if (!isset($return['error'])) { if (!isset($return['error'])) {
$tableNum = 0; $tableNum = 0;
$tableName = Array( $tableName = Array(
1 => "myway_carddetails", 1 => "myway_carddetails",
2 => "myway_transactions" 2 => "myway_transactions"
); );
foreach ($page->find("table") as $table) { foreach ($page->find("table") as $table) {
$tableNum++; $tableNum++;
$tableColumns = Array(); $tableColumns = Array();
$tableColumnNum = 0; $tableColumnNum = 0;
foreach ($table->find("th") as $th) { foreach ($table->find("th") as $th) {
$tableColumns[$tableColumnNum] = cleanString($th->plaintext); $tableColumns[$tableColumnNum] = cleanString($th->plaintext);
$tableColumnNum++; $tableColumnNum++;
} }
  //print_r($tableColumns);
$tableRowNum = 0; $tableRowNum = 0;
foreach ($table->find("tr") as $tr) { foreach ($table->find("tr") as $tr) {
$tableColumnNum = 0; $tableColumnNum = 0;
foreach ($tr->find("td") as $td) { foreach ($tr->find("td") as $td) {
if ($tableNum == 1) $return[$tableName[$tableNum]][$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); else $return[$tableName[$tableNum]][$tableRowNum][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext);
  //print_r($return);
$tableColumnNum++; $tableColumnNum++;
} }
$tableRowNum++; $tableRowNum++;
} }
} }
} }
} }
if (sizeof($return) == 0) { if (sizeof($return) == 0) {
$return['error'][] = "No data extracted from MyWay website - API may be out of date"; $return['error'][] = "No data extracted from MyWay website - API may be out of date";
} }
   
header('Content-Type: text/javascript; charset=utf8'); header('Content-Type: text/javascript; charset=utf8');
// header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/'); // header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/');
header('Access-Control-Max-Age: 3628800'); header('Access-Control-Max-Age: 3628800');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
if (isset($_GET['callback'])) { if (isset($_GET['callback'])) {
$json = '(' . json_encode($return) . ');'; //must wrap in parens and end with semicolon $json = '(' . json_encode($return) . ');'; //must wrap in parens and end with semicolon
print_r($_GET['callback'] . $json); //callback is prepended for json-p print_r($_GET['callback'] . $json); //callback is prepended for json-p
} }
else echo json_encode($return); else echo json_encode($return);
?> ?>
   
<?php <?php
include ('../include/common.inc.php'); include ('../include/common.inc.php');
include_header("MyWay Balance", "mywayBalance", false, false, true); include_header("MyWay Balance", "mywayBalance", false, false, true);
echo '<div data-role="page"> echo '<div data-role="page">
<div data-role="header" data-position="inline"> <div data-role="header" data-position="inline">
<a href="' . $_SERVER["HTTP_REFERER"] . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a> <a href="' . $_SERVER["HTTP_REFERER"] . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a>
<h1>MyWay Balance</h1> <h1>MyWay Balance</h1>
<a href="mywaybalance.php?logout=yes" data-icon="delete" class="ui-btn-right">Logout</a> <a href="mywaybalance.php?logout=yes" data-icon="delete" class="ui-btn-right">Logout</a>
</div><!-- /header --> </div><!-- /header -->
<a name="maincontent" id="maincontent"></a> <a name="maincontent" id="maincontent"></a>
<div data-role="content"> '; <div data-role="content"> ';
$return = Array(); $return = Array();
function logout() { function logout() {
setcookie("card_number", "", time() - 60 * 60 * 24 * 100, "/"); setcookie("card_number", "", time() - 60 * 60 * 24 * 100, "/");
setcookie("date", "", time() - 60 * 60 * 24 * 100, "/"); setcookie("date", "", time() - 60 * 60 * 24 * 100, "/");
setcookie("secret_answer", "", time() - 60 * 60 * 24 * 100, "/"); setcookie("secret_answer", "", time() - 60 * 60 * 24 * 100, "/");
} }
function printBalance($cardNumber, $date, $pwrd) function printBalance($cardNumber, $date, $pwrd)
{ {
global $return; 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); $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'])) { if (isset($return['error'])) {
logout(); logout();
echo '<h3><font color="red">' . $return['error'][0] . "</font></h3>"; echo '<h3><font color="red">' . $return['error'][0] . "</font></h3>";
} }
else { else {
echo "<h2>Balance: " . $return['myway_carddetails']['Card Balance'] . "</h2>"; 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>'; echo '<ul data-role="listview" data-inset="true"><li data-role="list-divider"> Recent Transactions </li>';
  $txCount=0;
foreach ($return['myway_transactions'] as $transaction) { foreach ($return['myway_transactions'] as $transaction) {
echo "<li><b>" . $transaction["Date / Time"] . "</b>"; echo "<li>";
echo "<br><small>" . $transaction["TX Reference No / Type"] . "</small>"; if ($transaction["Deduction Type"] == "DEFAULT") echo '<img src="css/images/warning.png" alt="Failed to tap off: " class="ui-li-icon">';
  echo"<b>" . $transaction["Date / Time"] . "</b>";
  echo "<br><small>" .$transaction["Route"] ." at " . $transaction["Stop Name"]. "<br>". $transaction["TX Reference No / Type"] . "</small>";
echo '<p class="ui-li-aside">' . $transaction["TX Amount"] . '</p>'; echo '<p class="ui-li-aside">' . $transaction["TX Amount"] . '</p>';
echo "</li>"; echo "</li>";
  $txCount++;
  if ($txCount > 10) break;
} }
echo "</ul>"; echo "</ul>";
} }
} }
if (isset($_REQUEST['card_number']) && isset($_REQUEST['date']) && isset($_REQUEST['secret_answer'])) { if (isset($_REQUEST['card_number']) && isset($_REQUEST['date']) && isset($_REQUEST['secret_answer'])) {
$cardNumber = $_REQUEST['card_number']; $cardNumber = $_REQUEST['card_number'];
$date = explode("/", $_REQUEST['date']); $date = explode("/", $_REQUEST['date']);
$pwrd = $_REQUEST['secret_answer']; $pwrd = $_REQUEST['secret_answer'];
if ($_REQUEST['remember'] == "on") { if ($_REQUEST['remember'] == "on") {
setcookie("card_number", $cardNumber, time() + 60 * 60 * 24 * 100, "/"); setcookie("card_number", $cardNumber, time() + 60 * 60 * 24 * 100, "/");
setcookie("date", $_REQUEST['date'], time() + 60 * 60 * 24 * 100, "/"); setcookie("date", $_REQUEST['date'], time() + 60 * 60 * 24 * 100, "/");
setcookie("secret_answer", $pwrd, time() + 60 * 60 * 24 * 100, "/"); setcookie("secret_answer", $pwrd, time() + 60 * 60 * 24 * 100, "/");
} }
printBalance($cardNumber, $date, $pwrd); printBalance($cardNumber, $date, $pwrd);
} }
else if (isset($_REQUEST['logout'])) { else if (isset($_REQUEST['logout'])) {
echo '<center><h3> Logged out of MyWay balance </h3><a href="/index.php">Back to main menu...</a><center>'; echo '<center><h3> Logged out of MyWay balance </h3><a href="/index.php">Back to main menu...</a><center>';
} }
else if (isset($_COOKIE['card_number']) && isset($_COOKIE['date']) && isset($_COOKIE['secret_answer'])) { else if (isset($_COOKIE['card_number']) && isset($_COOKIE['date']) && isset($_COOKIE['secret_answer'])) {
$cardNumber = $_COOKIE['card_number']; $cardNumber = $_COOKIE['card_number'];
$date = explode("/", $_COOKIE['date']); $date = explode("/", $_COOKIE['date']);
$pwrd = $_COOKIE['secret_answer']; $pwrd = $_COOKIE['secret_answer'];
printBalance($cardNumber, $date, $pwrd); printBalance($cardNumber, $date, $pwrd);
} }
else { else {
$date = (isset($_REQUEST['date']) ? filter_var($_REQUEST['date'], FILTER_SANITIZE_STRING) : date("m/d/Y")); $date = (isset($_REQUEST['date']) ? filter_var($_REQUEST['date'], FILTER_SANITIZE_STRING) : date("m/d/Y"));
echo '<form action="" method="post"> echo '<form action="" method="post">
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="card_number">Card number</label> <label for="card_number">Card number</label>
<input type="text" name="card_number" id="card_number" value="' . $card_number . '" /> <input type="text" name="card_number" id="card_number" value="' . $card_number . '" />
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="date"> Date of birth </label> <label for="date"> Date of birth </label>
<input type="text" name="date" id="date" value="' . $date . '" /> <input type="text" name="date" id="date" value="' . $date . '" />
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="secret_answer"> Secret question answer </label> <label for="secret_answer"> Secret question answer </label>
<input type="text" name="secret_answer" id="secret_answer" value="' . $secret_answer . '" /> <input type="text" name="secret_answer" id="secret_answer" value="' . $secret_answer . '" />
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="remember"> Remember these details? </label> <label for="remember"> Remember these details? </label>
<input type="checkbox" name="remember" id="remember" checked="yes" /> <input type="checkbox" name="remember" id="remember" checked="yes" />
</div> </div>
<input type="submit" value="Go!"></form>'; <input type="submit" value="Go!"></form>';
} }
include_footer(); include_footer();
?> ?>
   
<?php <?php
include ('../include/common.inc.php'); include ('../include/common.inc.php');
include_header("Route Statistics", "networkstats") include_header("Route Statistics", "networkstats")
?> ?>
<script type="text/javascript" src="js/flotr/lib/prototype-1.6.0.2.js"></script> <script type="text/javascript" src="js/flotr/lib/prototype-1.6.0.2.js"></script>
   
<!--[if IE]> <!--[if IE]>
   
<script type="text/javascript" src="js/flotr/lib/excanvas.js"></script> <script type="text/javascript" src="js/flotr/lib/excanvas.js"></script>
   
<script type="text/javascript" src="js/flotr/lib/base64.js"></script> <script type="text/javascript" src="js/flotr/lib/base64.js"></script>
   
<![endif]--> <![endif]-->
   
<script type="text/javascript" src="js/flotr/lib/canvas2image.js"></script> <script type="text/javascript" src="js/flotr/lib/canvas2image.js"></script>
   
<script type="text/javascript" src="js/flotr/lib/canvastext.js"></script> <script type="text/javascript" src="js/flotr/lib/canvastext.js"></script>
   
<script type="text/javascript" src="js/flotr/flotr.debug-0.2.0-alpha_radar1.js"></script> <script type="text/javascript" src="js/flotr/flotr.debug-0.2.0-alpha_radar1.js"></script>
<form method="get" action="networkstats.php"> <form method="get" action="networkstats.php">
<select id="routeid" name="routeid"> <select id="routeid" name="routeid">
<?php <?php
foreach (getRoutes() as $route) { foreach (getRoutes() as $route) {
echo "<option value=\"{$route['route_id']}\">{$route['route_short_name']} {$route['route_long_name']}</option>"; echo "<option value=\"{$route['route_id']}\">{$route['route_short_name']} {$route['route_long_name']}</option>";
} }
?> ?>
</select> </select>
<input type="submit" value="View"/> <input type="submit" value="View"/>
</form> </form>
   
<?php <?php
// middle of graph = 6am // middle of graph = 6am
$adjustFactor = 0; $adjustFactor = 0;
$routeid = ($_REQUEST['routeid'] ? filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT) : 0);  
$route = getRoute($routeid); $route = getRoute($routeid);
echo "<h1>{$route['route_short_name']} {$route['route_long_name']}</h1>"; echo "<h1>{$route['route_short_name']} {$route['route_long_name']}</h1>";
foreach (getRouteTrips($routeid) as $key => $trip) { foreach (getRouteTrips($routeid) as $key => $trip) {
$dLabel[$key] = $trip['arrival_time']; $dLabel[$key] = $trip['arrival_time'];
if ($key == 0) { if ($key == 0) {
$time = strtotime($trip['arrival_time']); $time = strtotime($trip['arrival_time']);
$adjustFactor = (date("G", $time) * 3600); $adjustFactor = (date("G", $time) * 3600);
} }
$tripStops = viaPoints($trip['trip_id']); $tripStops = viaPoints($trip['trip_id']);
foreach ($tripStops as $i => $stop) { foreach ($tripStops as $i => $stop) {
if ($key == 0) { if ($key == 0) {
$dTicks[$i] = $stop['stop_name']; $dTicks[$i] = $stop['stop_name'];
} }
$time = strtotime($stop['arrival_time']); $time = strtotime($stop['arrival_time']);
$d[$key][$i] = (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time) - $adjustFactor; $d[$key][$i] = (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time) - $adjustFactor;
   
} }
} }
   
?> ?>
<div id="container" style="width:100%;height:900px;"></div> <div id="container" style="width:100%;height:900px;"></div>
<script type="text/javascript"> <script type="text/javascript">
   
/** /**
   
* Wait till dom's finished loading. * Wait till dom's finished loading.
   
*/ */
   
document.observe('dom:loaded', function(){ document.observe('dom:loaded', function(){
   
/** /**
   
* Fill series d1 and d2. * Fill series d1 and d2.
   
*/ */
<?php <?php
foreach ($d as $key => $dataseries) { foreach ($d as $key => $dataseries) {
echo "var d$key =["; echo "var d$key =[";
foreach ($dataseries as $i => $datapoint) { foreach ($dataseries as $i => $datapoint) {
echo "[$i, $datapoint],"; echo "[$i, $datapoint],";
} }
echo "];\n"; echo "];\n";
} }
   
?> ?>
   
   
var f = Flotr.draw($('container'), var f = Flotr.draw($('container'),
   
[ [
<?php <?php
foreach ($d as $key => $dataseries) { foreach ($d as $key => $dataseries) {
echo '{data:d'.$key.", label:'{$dLabel[$key]}'".', radar:{fill:false}},'."\n"; echo '{data:d'.$key.", label:'{$dLabel[$key]}'".', radar:{fill:false}},'."\n";
} }
   
?> ?>
], ],
   
{defaultType: 'radar', {defaultType: 'radar',
   
radarChartMode: true, radarChartMode: true,
   
HtmlText: false, HtmlText: false,
   
fontSize: 9, fontSize: 9,
   
xaxis:{ xaxis:{
   
ticks: [ ticks: [
<?php <?php
foreach ($dTicks as $key => $tickName) { foreach ($dTicks as $key => $tickName) {
echo '['.$key.', "'.$tickName.'"],'; echo '['.$key.', "'.$tickName.'"],';
} }
   
?> ?>
]}, ]},
   
mouse:{ // Setup point tracking mouse:{ // Setup point tracking
   
track: true, track: true,
   
lineColor: 'black', lineColor: 'black',
   
relative: true, relative: true,
   
sensibility: 70, sensibility: 70,
   
trackFormatter: function(obj){ trackFormatter: function(obj){
var d = new Date(); var d = new Date();
d.setMinutes(0); d.setMinutes(0);
d.setHours(0); d.setHours(0);
d.setTime(d.getTime() + Math.floor(obj.radarData*1000) + <?php echo $adjustFactor*1000 ?>); d.setTime(d.getTime() + Math.floor(obj.radarData*1000) + <?php echo $adjustFactor*1000 ?>);
return d.getHours() +':'+ (d.getMinutes().toString().length == 1 ? '0'+ d.getMinutes(): d.getMinutes()); return d.getHours() +':'+ (d.getMinutes().toString().length == 1 ? '0'+ d.getMinutes(): d.getMinutes());
}}}); }}});
   
}); });
   
</script> </script>
   
</div> </div>
   
   
<?php <?php
include_footer() include_footer()
?> ?>
   
  <?php
  header('Content-type: application/vnd.google-earth.kml+xml');
  //http://wiki.openstreetmap.org/wiki/OpenLayers_Dynamic_KML
 
  // Creates the KML/XML Document.
  $dom = new DOMDocument('1.0', 'UTF-8');
 
  // Creates the root KML element and appends it to the root document.
  $node = $dom->createElementNS('http://earth.google.com/kml/2.1', 'kml');
  $parNode = $dom->appendChild($node);
 
  // Creates a KML Document element and append it to the KML element.
  $dnode = $dom->createElement('Document');
  $docNode = $parNode->appendChild($dnode);
 
 
  $bbox = $_GET['bbox']; // get the bbox param from google earth
  list($bbox_south, $bbox_west, $bbox_north,$bbox_east) = explode(",", $bbox); // west, south, east, north
 
  include ('../include/common.inc.php');
  $debugOkay = Array();
  $contents = getNearbyStops( (($bbox_west+ $bbox_east) /2), ($bbox_south + $bbox_north)/2 ,50, 3000);
  foreach ($contents as $stop) {
  $description = 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] ." <br>";
  $trips = getStopTripsWithTimes($stop['stop_id'], "", "", "", 3);
  if ($trips) {
  foreach ($trips as $key => $row) {
  if ($key < 3) {
  $description .= $row['route_short_name'] . ' ' . $row['route_long_name'] . ' @ ' . $row['arrival_time'] . "<br>";
  }
  }
  } else {
  $description .= "No more trips today";
  }
  // Creates a Placemark and append it to the Document.
  $node = $dom->createElement('Placemark');
  $placeNode = $docNode->appendChild($node);
 
  // Creates an id attribute and assign it the value of id column.
  $placeNode->setAttribute('id', 'placemark' . $stop['stop_id']);
 
  // Create name, and description elements and assigns them the values of the name and address columns from the results.
  $nameNode = $dom->createElement('name',htmlentities($stop['stop_name']));
  $descriptionNode = $dom->createElement('description',$description);
  $placeNode->appendChild($nameNode);
  $placeNode->appendChild($descriptionNode);
 
  // Creates a Point element.
  $pointNode = $dom->createElement('Point');
  $placeNode->appendChild($pointNode);
 
  // Creates a coordinates element and gives it the value of the lng and lat columns from the results.
  $coorStr = $stop['stop_lon'] . ',' . $stop['stop_lat'];
  $coorNode = $dom->createElement('coordinates', $coorStr);
  $pointNode->appendChild($coorNode);
  }
 
 
  $kmlOutput = $dom->saveXML();
  echo $kmlOutput;
  ?>
 
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  <script src="openlayers/OpenLayers.js"></script>
  <SCRIPT TYPE="text/javascript" SRC="OpenStreetMap.js"></SCRIPT>
  <script type="text/javascript">
  var map,select;
 
 
  function init()
  {
  var extent = new OpenLayers.Bounds(148.98, -35.48, 149.25, -35.15);
 
  // set up the map options
  var options =
  {
  maxExtent: extent,
  numZoomLevels: 20,
  };
 
  // create the ol map object
  map = new OpenLayers.Map('map', options);
 
  var osmtiles = new OpenLayers.Layer.OSM("OSM");
 
  var nearmap = new OpenLayers.Layer.OSM.NearMap("NearMap");
 
  var stopbrowser = new OpenLayers.Layer.Vector("POI", {
  projection: new OpenLayers.Projection("EPSG:4326"),
  strategies: [
  new OpenLayers.Strategy.BBOX(),
  ],
  protocol: new OpenLayers.Protocol.HTTP({
  url: "stopBrowser.kml.php", //Note that it is probably worth adding a Math.random() on the end of the URL to stop caching.
  format: new OpenLayers.Format.KML({
  extractStyles: true,
  extractAttributes: true
  }),
  })
  });
 
  map.addLayers([osmtiles,stopbrowser,nearmap]);
 
  var lonLat = new OpenLayers.LonLat(149.11, -35.28).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
  map.setCenter(lonLat, 15);
  map.addControl( new OpenLayers.Control.LayerSwitcher({'ascending':false}));
  map.addControl(new OpenLayers.Control.MousePosition(
  {
  displayProjection: new OpenLayers.Projection("EPSG:4326"),
  suffix: "__________________________________"
  }));
  map.addControl(new OpenLayers.Control.MousePosition(
  {
  displayProjection: new OpenLayers.Projection("EPSG:900913")
  }));
 
  select = new OpenLayers.Control.SelectFeature(stopbrowser);
 
  stopbrowser.events.on({
  "featureselected": onFeatureSelect,
  "featureunselected": onFeatureUnselect
  });
 
  map.addControl(select);
  select.activate();
 
  }
  function onPopupClose(evt) {
  select.unselectAll();
  }
  function onFeatureSelect(event) {
  var feature = event.feature;
  // Since KML is user-generated, do naive protection against
  // Javascript.
  var content = "<h2>"+feature.attributes.name + "</h2>" + feature.attributes.description;
  if (content.search("<script") != -1) {
  content = "Content contained Javascript! Escaped content below.<br />" + content.replace(/</g, "&lt;");
  }
  popup = new OpenLayers.Popup.FramedCloud("chicken",
  feature.geometry.getBounds().getCenterLonLat(),
  new OpenLayers.Size(100,100),
  content,
  null, true, onPopupClose);
  feature.popup = popup;
  map.addPopup(popup);
  }
  function onFeatureUnselect(event) {
  var feature = event.feature;
  if(feature.popup) {
  map.removePopup(feature.popup);
  feature.popup.destroy();
  delete feature.popup;
  }
  }
  </script>
 
  </head>
  <body onload="init()">
  <div id="map" width="100%" height="100%" class="smallmap"></div>
  </body>
  </html>
 
 
<?php <?php
// http://www.herethere.net/~samson/php/color_gradient/color_gradient_generator.php.txt // http://www.herethere.net/~samson/php/color_gradient/color_gradient_generator.php.txt
// return the interpolated value between pBegin and pEnd // return the interpolated value between pBegin and pEnd
function interpolate($pBegin, $pEnd, $pStep, $pMax) function interpolate($pBegin, $pEnd, $pStep, $pMax)
{ {
if ($pBegin < $pEnd) { if ($pBegin < $pEnd) {
return (($pEnd - $pBegin) * ($pStep / $pMax)) + $pBegin; return (($pEnd - $pBegin) * ($pStep / $pMax)) + $pBegin;
} }
else { else {
return (($pBegin - $pEnd) * (1 - ($pStep / $pMax))) + $pEnd; return (($pBegin - $pEnd) * (1 - ($pStep / $pMax))) + $pEnd;
} }
} }
require ("../lib/rolling-curl/RollingCurl.php"); require ("../lib/rolling-curl/RollingCurl.php");
function processResult_cb($response, $info, $request) function processResult_cb($response, $info, $request)
{ {
global $testRegions, $regionTimes,$csv,$kml, $latdeltasize,$londeltasize; global $testRegions, $regionTimes,$csv,$kml, $latdeltasize,$londeltasize;
$md = $request->metadata; $md = $request->metadata;
$tripplan = json_decode($response); $tripplan = json_decode($response);
$plans = Array(); $plans = Array();
//var_dump(Array($info, $request)); //var_dump(Array($info, $request));
if (is_array($tripplan->plan->itineraries->itinerary)) { if (is_array($tripplan->plan->itineraries->itinerary)) {
foreach ($tripplan->plan->itineraries->itinerary as $itineraryNumber => $itinerary) { foreach ($tripplan->plan->itineraries->itinerary as $itineraryNumber => $itinerary) {
$plans[floor($itinerary->duration / 60000) ] = $itinerary; $plans[floor($itinerary->duration / 60000) ] = $itinerary;
} }
} }
else { else {
$plans[floor($tripplan->plan->itineraries->itinerary->duration / 60000) ] = $tripplan->plan->itineraries->itinerary; $plans[floor($tripplan->plan->itineraries->itinerary->duration / 60000) ] = $tripplan->plan->itineraries->itinerary;
} }
if ($csv) echo "{$md['i']},{$md['j']}," . min(array_keys($plans)) . ",$latdeltasize, $londeltasize,{$md['key']}\n"; if ($csv) echo "{$md['i']},{$md['j']}," . min(array_keys($plans)) . ",$latdeltasize, $londeltasize,{$md['key']}\n";
if ($kml) { if ($kml) {
$time = min(array_keys($plans)); $time = min(array_keys($plans));
$plan = ""; $plan = "";
if (is_array($plans[min(array_keys($plans)) ]->legs->leg)) { if (is_array($plans[min(array_keys($plans)) ]->legs->leg)) {
foreach ($plans[min(array_keys($plans)) ]->legs->leg as $legNumber => $leg) { foreach ($plans[min(array_keys($plans)) ]->legs->leg as $legNumber => $leg) {
$plan.= processLeg($legNumber, $leg) . ","; $plan.= processLeg($legNumber, $leg) . ",";
} }
} }
else { else {
$plan.= processLeg(0, $plans[min(array_keys($plans)) ]->legs->leg); $plan.= processLeg(0, $plans[min(array_keys($plans)) ]->legs->leg);
} }
if (isset($tripplan->error) && $tripplan->error->id == 404) { if (isset($tripplan->error) && $tripplan->error->id == 404) {
$time = 999; $time = 999;
$plan = "Trip not possible without excessive walking from nearest bus stop"; $plan = "Trip not possible without excessive walking from nearest bus stop";
} }
$testRegions[] = Array( $testRegions[] = Array(
"lat" => $md['i'], "lat" => $md['i'],
"lon" => $md['j'], "lon" => $md['j'],
"time" => $time, "time" => $time,
"latdeltasize" => $latdeltasize, "latdeltasize" => $latdeltasize,
"londeltasize" => $londeltasize, "londeltasize" => $londeltasize,
"regionname" => $md['key'], "regionname" => $md['key'],
"plan" => $plan . "<br/><a href='" . htmlspecialchars($url) . "'>original plan</a>" "plan" => $plan . '<br/><a href="' . htmlspecialchars($md['url']) . '">original plan</a>'
); );
$regionTimes[] = $time; $regionTimes[] = $time;
} }
} }
function Gradient($HexFrom, $HexTo, $ColorSteps) function Gradient($HexFrom, $HexTo, $ColorSteps)
{ {
$theColorBegin = hexdec($HexFrom); $theColorBegin = hexdec($HexFrom);
$theColorEnd = hexdec($HexTo); $theColorEnd = hexdec($HexTo);
$theNumSteps = intval($ColorSteps); $theNumSteps = intval($ColorSteps);
$theR0 = ($theColorBegin & 0xff0000) >> 16; $theR0 = ($theColorBegin & 0xff0000) >> 16;
$theG0 = ($theColorBegin & 0x00ff00) >> 8; $theG0 = ($theColorBegin & 0x00ff00) >> 8;
$theB0 = ($theColorBegin & 0x0000ff) >> 0; $theB0 = ($theColorBegin & 0x0000ff) >> 0;
$theR1 = ($theColorEnd & 0xff0000) >> 16; $theR1 = ($theColorEnd & 0xff0000) >> 16;
$theG1 = ($theColorEnd & 0x00ff00) >> 8; $theG1 = ($theColorEnd & 0x00ff00) >> 8;
$theB1 = ($theColorEnd & 0x0000ff) >> 0; $theB1 = ($theColorEnd & 0x0000ff) >> 0;
$GradientColors = array(); $GradientColors = array();
// generate gradient swathe now // generate gradient swathe now
for ($i = 0; $i <= $theNumSteps; $i++) { for ($i = 0; $i <= $theNumSteps; $i++) {
$theR = interpolate($theR0, $theR1, $i, $theNumSteps); $theR = interpolate($theR0, $theR1, $i, $theNumSteps);
$theG = interpolate($theG0, $theG1, $i, $theNumSteps); $theG = interpolate($theG0, $theG1, $i, $theNumSteps);
$theB = interpolate($theB0, $theB1, $i, $theNumSteps); $theB = interpolate($theB0, $theB1, $i, $theNumSteps);
$theVal = ((($theR << 8) | $theG) << 8) | $theB; $theVal = ((($theR << 8) | $theG) << 8) | $theB;
$GradientColors[] = sprintf("%06X", $theVal); $GradientColors[] = sprintf("%06X", $theVal);
} }
return $GradientColors; return $GradientColors;
} }
function processLeg($legNumber, $leg) function processLeg($legNumber, $leg)
{ {
$legArray = object2array($leg); $legArray = object2array($leg);
if ($legArray["@mode"] === "BUS") { if ($legArray["@mode"] === "BUS") {
return "bus {$legArray['@route']} " . str_replace("To", "towards", $legArray['@headsign']); return "bus {$legArray['@route']} " . str_replace("To", "towards", $legArray['@headsign']);
} }
else { else {
return "walk"; return "walk";
//$walkingstep = "walk "; //$walkingstep = "walk ";
//if (strpos($step->streetName, "from") !== false && strpos($step->streetName, "way") !== false) { //if (strpos($step->streetName, "from") !== false && strpos($step->streetName, "way") !== false) {
// $walkingstep.= "footpath"; // $walkingstep.= "footpath";
//} //}
//else { //else {
// $walkingstep.= $step->streetName; // $walkingstep.= $step->streetName;
//} //}
//$walkingstep.= floor($step->distance) . "m"; //$walkingstep.= floor($step->distance) . "m";
//return $walkingstep; //return $walkingstep;
} }
} }
$csv = false; $csv = false;
$kml = true; $kml = true;
  $gearthcolors = false;
if ($kml) { if ($kml) {
header('Content-Type: application/vnd.google-earth.kml+xml'); header('Content-Type: application/vnd.google-earth.kml+xml');
echo '<?xml version="1.0" encoding="UTF-8"?> echo '<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"><Document>'; <kml xmlns="http://www.opengis.net/kml/2.2"><Document>';
} }
include ('../include/common.inc.php'); include ('../include/common.inc.php');
$boundingBoxes = Array( $boundingBoxes = Array(
"belconnen" => Array( "belconnen" => Array(
"startlat" => - 35.1928, "startlat" => - 35.1928,
"startlon" => 149.006, "startlon" => 149.006,
"finishlat" => - 35.2630, "finishlat" => - 35.2630,
"finishlon" => 149.1045, "finishlon" => 149.1045,
) , ) ,
"north gungahlin civic" => Array( "north gungahlin civic" => Array(
"startlat" => - 35.1828, "startlat" => - 35.1828,
"startlon" => 149.1045, "startlon" => 149.1045,
"finishlat" => - 35.2955, "finishlat" => - 35.2955,
"finishlon" => 149.1559, "finishlon" => 149.1559,
) , ) ,
"west duffy" => Array( "west duffy" => Array(
"startlat" => - 35.3252, "startlat" => - 35.3252,
"startlon" => 149.0240, "startlon" => 149.0240,
"finishlat" => - 35.3997, "finishlat" => - 35.3997,
"finishlon" => 149.0676, "finishlon" => 149.0676,
) , ) ,
"central south" => Array( "central south" => Array(
"startlat" => - 35.3042, "startlat" => - 35.3042,
"startlon" => 149.0762, "startlon" => 149.0762,
"finishlat" => - 35.3370, "finishlat" => - 35.3370,
"finishlon" => 149.1806, "finishlon" => 149.1806,
) , ) ,
"south" => Array( "south" => Array(
"startlat" => - 35.3403, "startlat" => - 35.3403,
"startlon" => 149.0714, "startlon" => 149.0714,
"finishlat" => - 35.4607, "finishlat" => - 35.4607,
"finishlon" => 149.1243, "finishlon" => 149.1243,
) )
); );
$latdeltasize = 0.01; $latdeltasize = 0.005;
$londeltasize = 0.01; $londeltasize = 0.005;
$from = "Wattle Street"; $from = "Wattle Street";
$fromPlace = (startsWith($from, "-") ? $from : geocode($from, false)); $fromPlace = (startsWith($from, "-") ? $from : geocode($from, false));
$startTime = "9:00 am"; $startTime = "9:00 am";
$startDate = "03/21/2011"; // american dates, OTP does not validate! $startDate = "03/21/2011"; // american dates, OTP does not validate!
$counter = 0; $counter = 0;
$regionTimes = Array(); $regionTimes = Array();
$testRegions = Array(); $testRegions = Array();
$useragent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"; $useragent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1";
  if ($kml) echo "<name> $from at $startTime on $startDate </name>";
if ($csv) echo "<pre>"; if ($csv) echo "<pre>";
if ($csv) echo "lat,lon,time,latdeltasize, londeltasize, region key name\n"; if ($csv) echo "lat,lon,time,latdeltasize, londeltasize, region key name\n";
$rc = new RollingCurl("processResult_cb"); $rc = new RollingCurl("processResult_cb");
$rc->window_size = 3; $rc->window_size = 2;
foreach ($boundingBoxes as $key => $boundingBox) { foreach ($boundingBoxes as $key => $boundingBox) {
for ($i = $boundingBox['startlat']; $i >= $boundingBox['finishlat']; $i-= $latdeltasize) { for ($i = $boundingBox['startlat']; $i >= $boundingBox['finishlat']; $i-= $latdeltasize) {
for ($j = $boundingBox['startlon']; $j <= $boundingBox['finishlon']; $j+= $londeltasize) { for ($j = $boundingBox['startlon']; $j <= $boundingBox['finishlon']; $j+= $londeltasize) {
$url = $otpAPIurl . "ws/plan?date=" . urlencode($startDate) . "&time=" . urlencode($startTime) . "&mode=TRANSIT%2CWALK&optimize=QUICK&maxWalkDistance=440&wheelchair=false&toPlace=" . $i . "," . $j . "&fromPlace=$fromPlace"; $url = $otpAPIurl . "ws/plan?date=" . urlencode($startDate) . "&time=" . urlencode($startTime) . "&mode=TRANSIT%2CWALK&optimize=QUICK&maxWalkDistance=440&wheelchair=false&toPlace=" . $i . "," . $j . "&fromPlace=$fromPlace";
  //debug($url);
$request = new RollingCurlRequest($url); $request = new RollingCurlRequest($url);
$request->headers = Array( $request->headers = Array(
"Accept: application/json" "Accept: application/json"
); );
$request->metadata = Array( "i" => $i, "j" => $j, "key" => $key); $request->metadata = Array( "i" => $i, "j" => $j, "key" => $key, "url" => $url);
$rc->add($request); $rc->add($request);
} }
} }
} }
$rc->execute(); $rc->execute();
if ($kml) { if ($kml) {
$colorSteps = 9; $colorSteps = 9;
//$minTime = min($regionTimes); //$minTime = min($regionTimes);
//$maxTime = max($regionTimes); //$maxTime = max($regionTimes);
//$rangeTime = $maxTime - $minTime; //$rangeTime = $maxTime - $minTime;
//$deltaTime = $rangeTime / $colorSteps; //$deltaTime = $rangeTime / $colorSteps;
$Gradients = Gradient(strrev("66FF00") , strrev("FF0000") , $colorSteps); // KML is BGR not RGB so strrev $Gradients = Gradient(strrev("66FF00") , strrev("FF0000") , $colorSteps); // KML is BGR not RGB so strrev
foreach ($testRegions as $testRegion) { foreach ($testRegions as $testRegion) {
//$band = (floor(($testRegion[time] - $minTime) / $deltaTime)); //$band = (floor(($testRegion[time] - $minTime) / $deltaTime));
$band = (floor($testRegion[time] / 10)); $band = (floor($testRegion[time] / 10));
if ($band > $colorSteps) $band = $colorSteps; if ($band > $colorSteps) $band = $colorSteps;
echo "<Placemark> echo "<Placemark>
<name>" . $testRegion['regionname'] . " time {$testRegion['time']} band $band</name> <name>" . $testRegion['regionname'] . " time {$testRegion['time']} band $band</name>
<description> {$testRegion['plan']} </description> <description> <![CDATA[ {$testRegion['plan']} ]]> </description>
<Style> <Style>
<PolyStyle> <PolyStyle>
<color>c7" . $Gradients[$band] . "</color>" . // 7f = 50% alpha, c7=78% <color>c7" . $Gradients[$band] . "</color>" . // 7f = 50% alpha, c7=78%
"</PolyStyle> "</PolyStyle>
<LineStyle> <LineStyle>
<color>c7" . $Gradients[$band] . "</color>" . "</LineStyle> <color>c7" . $Gradients[$band] . "</color>" . "</LineStyle>
</Style> </Style>
<Polygon> <Polygon>
<altitudeMode>relativeToGround</altitudeMode> <altitudeMode>relativeToGround</altitudeMode>
<outerBoundaryIs> <outerBoundaryIs>
<LinearRing> <LinearRing>
<coordinates> <coordinates>
" . ($testRegion['lon'] - ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] - ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] - ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] + ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] + ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] + ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] + ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] - ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] - ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] - ($testRegion['latdeltasize'] / 2)) . ",500\n" . " " . ($testRegion['lon'] - ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] - ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] - ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] + ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] + ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] + ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] + ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] - ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] - ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] - ($testRegion['latdeltasize'] / 2)) . ",500\n" . "
</coordinates> </coordinates>
</LinearRing> </LinearRing>
</outerBoundaryIs> </outerBoundaryIs>
</Polygon> </Polygon>
</Placemark>"; </Placemark>";
} }
echo "\n</Document></kml>\n"; echo "\n</Document></kml>\n";
} }
if ($csv) echo "</pre>"; if ($csv) echo "</pre>";
?> ?>
   
<html xmlns="http://www.w3.org/1999/xhtml"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<script src="openlayers/OpenLayers.js"></script> <script src="openlayers/OpenLayers.js"></script>
<SCRIPT TYPE="text/javascript" SRC="OpenStreetMap.js"></SCRIPT> <SCRIPT TYPE="text/javascript" SRC="OpenStreetMap.js"></SCRIPT>
<script type="text/javascript"> <script type="text/javascript">
  var map,select;
   
   
function init() function init()
{ {
var extent = new OpenLayers.Bounds(148.98, -35.48, 149.25, -35.15); var extent = new OpenLayers.Bounds(148.98, -35.48, 149.25, -35.15);
// set up the map options // set up the map options
var options = var options =
{ {
maxExtent: extent, maxExtent: extent,
numZoomLevels: 20, numZoomLevels: 20,
}; };
// create the ol map object // create the ol map object
var map = new OpenLayers.Map('map', options); map = new OpenLayers.Map('map', options);
var osmtiles = new OpenLayers.Layer.OSM("OSM"); var osmtiles = new OpenLayers.Layer.OSM("OSM");
   
var nearmap = new OpenLayers.Layer.OSM.NearMap("NearMap"); var nearmap = new OpenLayers.Layer.OSM.NearMap("NearMap");
   
var tripplantest = new OpenLayers.Layer.GML("tripplantest", "tripPlannerTester.kml.php", { var tripplantest = new OpenLayers.Layer.GML("tripplantest", "tripPlannerTester.kml", {
format: OpenLayers.Format.KML, format: OpenLayers.Format.KML,
formatOptions: { formatOptions: {
extractStyles: true, extractStyles: true,
extractAttributes: true, extractAttributes: true,
maxDepth: 2 maxDepth: 2
} }
}); });
map.addLayers([osmtiles,tripplantest,nearmap]); map.addLayers([osmtiles,tripplantest,nearmap]);
   
var lonLat = new OpenLayers.LonLat(149.11, -35.28).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()); var lonLat = new OpenLayers.LonLat(149.11, -35.28).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
map.setCenter(lonLat, 11); map.setCenter(lonLat, 11);
map.addControl( new OpenLayers.Control.LayerSwitcher({'ascending':false})); map.addControl( new OpenLayers.Control.LayerSwitcher({'ascending':false}));
map.addControl(new OpenLayers.Control.MousePosition( map.addControl(new OpenLayers.Control.MousePosition(
{ {
displayProjection: new OpenLayers.Projection("EPSG:4326"), displayProjection: new OpenLayers.Projection("EPSG:4326"),
suffix: "__________________________________" suffix: "__________________________________"
})); }));
map.addControl(new OpenLayers.Control.MousePosition( map.addControl(new OpenLayers.Control.MousePosition(
{ {
displayProjection: new OpenLayers.Projection("EPSG:900913") displayProjection: new OpenLayers.Projection("EPSG:900913")
})); }));
   
  select = new OpenLayers.Control.SelectFeature(tripplantest);
   
  tripplantest.events.on({
  "featureselected": onFeatureSelect,
  "featureunselected": onFeatureUnselect
  });
   
  map.addControl(select);
  select.activate();
   
} }
  function onPopupClose(evt) {
  select.unselectAll();
  }
  function onFeatureSelect(event) {
  var feature = event.feature;
  // Since KML is user-generated, do naive protection against
  // Javascript.
  var content = "<h2>"+feature.attributes.name + "</h2>" + feature.attributes.description;
  if (content.search("<script") != -1) {
  content = "Content contained Javascript! Escaped content below.<br />" + content.replace(/</g, "&lt;");
  }
  popup = new OpenLayers.Popup.FramedCloud("chicken",
  feature.geometry.getBounds().getCenterLonLat(),
  new OpenLayers.Size(100,100),
  content,
  null, true, onPopupClose);
  feature.popup = popup;
  map.addPopup(popup);
  }
  function onFeatureUnselect(event) {
  var feature = event.feature;
  if(feature.popup) {
  map.removePopup(feature.popup);
  feature.popup.destroy();
  delete feature.popup;
  }
  }
</script> </script>
   
</head> </head>
<body onload="init()"> <body onload="init()">
<div id="map" width="100%" height="100%" class="smallmap"></div> <div id="map" width="100%" height="100%" class="smallmap"></div>
</body> </body>
</html> </html>
   
   
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
$output = Array(); $output = Array();
$output['hotspots'] = Array(); $output['hotspots'] = Array();
$output['layer'] = "canberrabusstops"; $output['layer'] = "canberrabusstops";
$max_page = 10; $max_page = 10;
$max_results = 50; $max_results = 50;
$page_start = 0 + filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); $page_start = 0 + $pageKey;
$page_end = $max_page + filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); $page_end = $max_page + $pageKey;
$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);  
$max_distance = filter_var($_REQUEST['radius'], FILTER_SANITIZE_NUMBER_INT);  
$contents = getNearbyStops($lat, $lon, 50, $max_distance); $contents = getNearbyStops($lat, $lon, 50, $max_distance);
$stopNum = 0; $stopNum = 0;
foreach ($contents as $stop) { foreach ($contents as $stop) {
$stopNum++; $stopNum++;
if ($stopNum > $page_start && $stopNum <= $page_end) { if ($stopNum > $page_start && $stopNum <= $page_end) {
$hotspot = Array(); $hotspot = Array();
$hotspot['id'] = $stop['stop_id']; $hotspot['id'] = $stop['stop_id'];
$hotspot['title'] = $stop['stop_name']; $hotspot['title'] = $stop['stop_name'];
$hotspot['type'] = 0; $hotspot['type'] = 0;
$hotspot['lat'] = floor($stop['stop_lat'] * 1000000); $hotspot['lat'] = floor($stop['stop_lat'] * 1000000);
$hotspot['lon'] = floor($stop['stop_lon'] * 1000000); $hotspot['lon'] = floor($stop['stop_lon'] * 1000000);
$hotspot['distance'] = floor($stop['distance']); $hotspot['distance'] = floor($stop['distance']);
$hotspot['attribution'] = "ACTION Buses"; $hotspot['attribution'] = "ACTION Buses";
$hotspot['actions'] = Array( $hotspot['actions'] = Array(
Array( Array(
"label" => 'View more trips/information', "label" => 'View more trips/information',
'uri' => 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] 'uri' => 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id']
) )
); );
$trips = getStopTripsWithTimes($stop['stop_id'], "", "", "", 3); $trips = getStopTripsWithTimes($stop['stop_id'], "", "", "", 3);
foreach ($trips as $key => $row) { foreach ($trips as $key => $row) {
if ($key < 3) { if ($key < 3) {
$hotspot['line' . strval($key + 2) ] = $row['route_short_name'] . ' ' . $row['route_long_name'] . ' @ ' . $row['arrival_time']; $hotspot['line' . strval($key + 2) ] = $row['route_short_name'] . ' ' . $row['route_long_name'] . ' @ ' . $row['arrival_time'];
} }
} }
if (sizeof($trips) == 0) $hotspot['line2'] = 'No trips in the near future.'; if (sizeof($trips) == 0) $hotspot['line2'] = 'No trips in the near future.';
$output['hotspots'][] = $hotspot; $output['hotspots'][] = $hotspot;
} }
} }
if (sizeof($hotspot) > 0) { if (sizeof($hotspot) > 0) {
$output['errorString'] = 'ok'; $output['errorString'] = 'ok';
$output['errorCode'] = 0; $output['errorCode'] = 0;
} }
else { else {
$output['errorString'] = 'no results, try increasing range'; $output['errorString'] = 'no results, try increasing range';
$output['errorCode'] = 21; $output['errorCode'] = 21;
} }
if ($page_end >= $max_results || sizeof($contents) < $page_start+$max_page) { if ($page_end >= $max_results || sizeof($contents) < $page_start+$max_page) {
$output["morePages"] = false; $output["morePages"] = false;
$output["nextPageKey"] = null; $output["nextPageKey"] = null;
} }
else { else {
$output["morePages"] = true; $output["morePages"] = true;
$output["nextPageKey"] = $page_end; $output["nextPageKey"] = $page_end;
} }
echo json_encode($output); echo json_encode($output);
?> ?>
   
  <?php
  include ("../include/common.inc.php");
  $result = Array();
  if (isset($_REQUEST['term'])) {
  $term = filter_var($_REQUEST['term'], FILTER_SANITIZE_STRING);
  $query = "Select stop_name,min(stop_lat) as stop_lat,min(stop_lon) as stop_lon from stops where stop_name LIKE :term group by stop_name";
  $query = $conn->prepare($query);
  $term = "$term%";
  $query->bindParam(":term", $term);
  $query->execute();
  if (!$query) {
  databaseError($conn->errorInfo());
  return Array();
  }
  foreach ($query->fetchAll() as $row) {
  $name = $row['stop_name'] . " (" . $row['stop_lat'] . "," . $row['stop_lon'] . ")";
  $result[] = Array(
  "id" => $name,
  "label" => $name,
  "value" => $name
  );
  }
  }
  echo json_encode($result);
  ?>
file:a/postinstall (deleted)
#!/bin/bash  
#dotcloud postinstall  
 
curl http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \  
-o /home/dotcloud/current/cbrfeed.zip  
 
#db setup  
#curl https://github.com/maxious/ACTBus-ui/raw/master/transitdata.cbrfeed.sql.gz -o transitdata.cbrfeed.sql.gz  
#curl https://github.com/maxious/ACTBus-ui/raw/master/lib/postgis.sql -o postgis.sql  
#createlang -d transitdata plpgsql  
#psql -d transitdata -f postgis.sql  
#gunzip /var/www/transitdata.cbrfeed.sql.gz  
#psql -d transitdata -f transitdata.cbrfeed.sql  
#createuser transitdata -SDRP  
#password transitdata  
#psql -c \"GRANT SELECT ON TABLE agency,calendar,calendar_dates,routes,stop_times,stops,trips TO transitdata;\"  
 
file:a/robots.txt -> file:b/robots.txt
User-agent: * User-agent: *
Allow: / Allow: /
  User-agent: *
  Disallow: /lib/ga.php
sitemap: http://bus.lambdacomplex.org/sitemap.xml.php sitemap: http://bus.lambdacomplex.org/sitemap.xml.php
   
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
function navbar() function navbar()
{ {
echo ' echo '
<div data-role="navbar"> <div data-role="navbar">
<ul> <ul>
<li><a href="routeList.php">By Final Destination...</a></li> <li><a href="routeList.php">By Final Destination...</a></li>
<li><a href="routeList.php?bynumber=yes">By Number... </a></li> <li><a href="routeList.php?bynumber=yes">By Number... </a></li>
<li><a href="routeList.php?bysuburb=yes">By Suburb... </a></li> <li><a href="routeList.php?bysuburbs=yes">By Suburb... </a></li>
<li><a href="routeList.php?nearby=yes">Nearby... </a></li> <li><a href="routeList.php?nearby=yes">Nearby... </a></li>
</ul> </ul>
</div> </div>
'; ';
} }
if ($_REQUEST['bysuburb']) { if (isset($bysuburbs)) {
include_header("Routes by Suburb", "routeList"); include_header("Routes by Suburb", "routeList");
navbar(); navbar();
echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; echo ' <ul data-role="listview" data-filter="true" data-inset="true" >';
if (!isset($_REQUEST['firstLetter'])) { if (!isset($firstLetter)) {
foreach (range('A', 'Z') as $letter) { foreach (range('A', 'Z') as $letter) {
echo "<li><a href=\"routeList.php?firstLetter=$letter&amp;bysuburb=yes\">$letter...</a></li>\n"; echo "<li><a href=\"routeList.php?firstLetter=$letter&amp;bysuburbs=yes\">$letter...</a></li>\n";
} }
} }
else { else {
foreach ($suburbs as $suburb) { foreach ($suburbs as $suburb) {
if (startsWith($suburb, $_REQUEST['firstLetter'])) { if (startsWith($suburb, $firstLetter)) {
echo '<li><a href="routeList.php?suburb=' . urlencode($suburb) . '">' . $suburb . '</a></li>'; echo '<li><a href="routeList.php?suburb=' . urlencode($suburb) . '">' . $suburb . '</a></li>';
} }
} }
} }
echo '</ul>'; echo '</ul>';
} }
else if ($_REQUEST['nearby'] || $_REQUEST['suburb']) { else if (isset($nearby) || isset($suburb)) {
$routes = Array(); $routes = Array();
if ($_REQUEST['suburb']) { if ($suburb) {
$suburb = filter_var($_REQUEST['suburb'], FILTER_SANITIZE_STRING); include_header($suburb . " - " . ucwords(service_period()) , "routeList");
include_header($suburb ." - ".ucwords(service_period()), "routeList"); navbar();
navbar(); timePlaceSettings();
timePlaceSettings(); trackEvent("Route Lists", "Routes By Suburb", $suburb);
trackEvent("Route Lists", "Routes By Suburb", $suburb); $routes = getRoutesbysuburbs($suburb);
$routes = getRoutesBySuburb($suburb);  
   
} }
if ($_REQUEST['nearby']) { if (isset($nearby)) {
include_header("Routes Nearby", "routeList", true, true); include_header("Routes Nearby", "routeList", true, true);
trackEvent("Route Lists", "Routes Nearby", $_SESSION['lat'].",".$_SESSION['lon']); trackEvent("Route Lists", "Routes Nearby", $_SESSION['lat'] . "," . $_SESSION['lon']);
navbar(); navbar();
timePlaceSettings(true); timePlaceSettings(true);
if (!isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == "") { if (!isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == "") {
include_footer(); include_footer();
die(); die();
} }
$routes = getRoutesNearby($_SESSION['lat'],$_SESSION['lon']); $routes = getRoutesNearby($_SESSION['lat'], $_SESSION['lon']);
} }
   
echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; echo ' <ul data-role="listview" data-filter="true" data-inset="true" >';
if ($routes) { if ($routes) {
foreach ($routes as $route) { foreach ($routes as $route) {
echo '<li><a href="trip.php?routeid=' . $route['route_id'] . '"><h3>' . $route['route_short_name'] . "</h3><p>" . $route['route_long_name'] . " (" . ucwords($route['service_id']) . ")</p>"; echo '<li><a href="trip.php?routeid=' . $route['route_id'] . '"><h3>' . $route['route_short_name'] . "</h3><p>" . $route['route_long_name'] . " (" . ucwords($route['service_id']) . ")</p>";
if ($_REQUEST['nearby']) { if (isset($nearby)) {
$time = getTimeInterpolatedRouteAtStop($route['route_id'], $route['stop_id']); $time = getTimeInterpolatedRouteAtStop($route['route_id'], $route['stop_id']);
echo '<span class="ui-li-count">'.($time['arrival_time']?$time['arrival_time']:"No more trips today")."<br>" .floor($route['distance']) . 'm away</span>'; echo '<span class="ui-li-count">' . ($time['arrival_time'] ? $time['arrival_time'] : "No more trips today") . "<br>" . floor($route['distance']) . 'm away</span>';
  }
  echo "</a></li>\n";
} }
echo "</a></li>\n";  
} }
} else { else {
echo "<li style='text-align: center;'> No routes nearby.</li>"; echo "<li style='text-align: center;'> No routes nearby.</li>";
} }
} }
else if ($_REQUEST['bynumber'] || $_REQUEST['numberSeries']) { else if (isset($bynumber) || isset($numberSeries)) {
include_header("Routes by Number", "routeList"); include_header("Routes by Number", "routeList");
navbar(); navbar();
echo ' <ul data-role="listview" data-inset="true">'; echo ' <ul data-role="listview" data-inset="true">';
if ($_REQUEST['bynumber']) { if (isset($bynumber)) {
$routes = getRoutesByNumber(); $routes = getRoutesByNumber();
$routeSeries = Array(); $routeSeries = Array();
$seriesRange = Array(); $seriesRange = Array();
foreach ($routes as $key => $routeNumber) { foreach ($routes as $key => $routeNumber) {
foreach (explode(" ", $routeNumber['route_short_name']) as $routeNumber) { foreach (explode(" ", $routeNumber['route_short_name']) as $routeNumber) {
$seriesNum = substr($routeNumber, 0, -1) . "0"; $seriesNum = substr($routeNumber, 0, -1) . "0";
if ($seriesNum == "0") $seriesNum = $routeNumber; if ($seriesNum == "0") $seriesNum = $routeNumber;
$finalDigit = substr($routeNumber, sizeof($routeNumber) - 1, 1); $finalDigit = substr($routeNumber, sizeof($routeNumber) - 1, 1);
if (isset($seriesRange[$seriesNum])) { if (isset($seriesRange[$seriesNum])) {
if ($finalDigit < $seriesRange[$seriesNum]['max']) $seriesRange[$seriesNum]['max'] = $routeNumber; if ($finalDigit < $seriesRange[$seriesNum]['max']) $seriesRange[$seriesNum]['max'] = $routeNumber;
if ($finalDigit > $seriesRange[$seriesNum]['min']) $seriesRange[$seriesNum]['min'] = $routeNumber; if ($finalDigit > $seriesRange[$seriesNum]['min']) $seriesRange[$seriesNum]['min'] = $routeNumber;
} }
else { else {
$seriesRange[$seriesNum]['max'] = $routeNumber; $seriesRange[$seriesNum]['max'] = $routeNumber;
$seriesRange[$seriesNum]['min'] = $routeNumber; $seriesRange[$seriesNum]['min'] = $routeNumber;
} }
$routeSeries[$seriesNum][$seriesNum . "-" . $row[1] . "-" . $row[0]] = $row; $routeSeries[$seriesNum][$seriesNum . "-" . $row[1] . "-" . $row[0]] = $row;
} }
} }
ksort($routeSeries); ksort($routeSeries);
ksort($seriesRange); ksort($seriesRange);
foreach ($routeSeries as $series => $routes) { foreach ($routeSeries as $series => $routes) {
echo '<li><a href="' . curPageURL() . '/routeList.php?numberSeries=' . $series . '">'; echo '<li><a href="' . curPageURL() . '/routeList.php?numberSeries=' . $series . '">';
if ($series <= 9) echo $series; if ($series <= 9) echo $series;
else echo "{$seriesRange[$series]['min']}-{$seriesRange[$series]['max']}"; else echo "{$seriesRange[$series]['min']}-{$seriesRange[$series]['max']}";
echo "</a></li>\n"; echo "</a></li>\n";
} }
} }
else if ($_REQUEST['numberSeries']) { else if ($numberSeries) {
$routes = getRoutesByNumber($_REQUEST['numberSeries']); $routes = getRoutesByNumberSeries($numberSeries);
foreach ($routes as $route) { foreach ($routes as $route) {
echo '<li> <a href="trip.php?routeid=' . $route['route_id'] . '"><h3>' . $route['route_short_name'] . "</h3><p>" . $route['route_long_name'] . " (" . ucwords($route['service_id']) . ")</p></a></li>\n"; echo '<li> <a href="trip.php?routeid=' . $route['route_id'] . '"><h3>' . $route['route_short_name'] . "</h3><p>" . $route['route_long_name'] . " (" . ucwords($route['service_id']) . ")</p></a></li>\n";
} }
} }
} }
else { else {
include_header("Routes by Destination", "routeList"); include_header("Routes by Destination", "routeList");
navbar(); navbar();
echo ' <ul data-role="listview" data-inset="true">'; echo ' <ul data-role="listview" data-inset="true">';
if ($_REQUEST['routeDestination']) { if (isset($routeDestination)) {
foreach (getRoutesByDestination(urldecode($_REQUEST['routeDestination'])) as $route) { foreach (getRoutesByDestination($routeDestination) as $route) {
echo '<li><a href="trip.php?routeid=' . $route["route_id"] . '"><h3>' . $route["route_short_name"] . '</h3><p>' . $route["route_long_name"] . " (" . ucwords($route['service_id']) . ")</p></a></li>\n"; echo '<li><a href="trip.php?routeid=' . $route["route_id"] . '"><h3>' . $route["route_short_name"] . '</h3><p>' . $route["route_long_name"] . " (" . ucwords($route['service_id']) . ")</p></a></li>\n";
} }
} }
else { else {
foreach (getRoutesByDestination() as $destination) { foreach (getRoutesByDestination() as $destination) {
echo '<li><a href="' . curPageURL() . '/routeList.php?routeDestination=' . urlencode($destination['route_long_name']) . '">' . $destination['route_long_name'] . "... </a></li>\n"; echo '<li><a href="' . curPageURL() . '/routeList.php?routeDestination=' . urlencode($destination['route_long_name']) . '">' . $destination['route_long_name'] . "... </a></li>\n";
} }
} }
} }
echo "</ul>\n"; echo "</ul>\n";
include_footer(); include_footer();
?> ?>
   
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
$last_updated = date('Y-m-d',@filemtime('cbrfeed.zip')); $last_updated = date('Y-m-d',@filemtime('cbrfeed.zip'));
header("Content-Type: text/xml"); header("Content-Type: text/xml");
echo "<?xml version='1.0' encoding='UTF-8'?>"; echo "<?xml version='1.0' encoding='UTF-8'?>";
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n"; echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
echo " <url><loc>".curPageURL()."index.php</loc><priority>1.0</priority></url>\n"; echo " <url><loc>".curPageURL()."index.php</loc><priority>1.0</priority></url>\n";
foreach (scandir("./") as $file) { foreach (scandir("./") as $file) {
if (strpos($file,".php") !== false && $file != "index.php" && $file != "sitemap.xml.php") echo " <url><loc>".curPageURL()."$file</loc><priority>0.3</priority></url>\n"; if (strpos($file,".php") !== false && $file != "index.php" && $file != "sitemap.xml.php") echo " <url><loc>".curPageURL()."$file</loc><priority>0.3</priority></url>\n";
} }
$url = $APIurl . "/json/stops"; foreach (getStops() as $stop) {
$stops = json_decode(getPage($url)); echo " <url><loc>".curPageURL()."stop.php?stopid=".htmlspecialchars ($stop["stop_id"])."</loc>";
foreach ($stops as $stop) {  
echo " <url><loc>".curPageURL()."stop.php?stopid=".htmlspecialchars ($stop[0])."</loc>";  
echo "<lastmod>" . $last_updated . "</lastmod>"; echo "<lastmod>" . $last_updated . "</lastmod>";
echo "<changefreq>monthly</changefreq>"; echo "<changefreq>monthly</changefreq>";
echo "<priority>0.9</priority>"; echo "<priority>0.9</priority>";
echo "</url>\n"; echo "</url>\n";
} }
$url = $APIurl . "/json/routes"; foreach (getRoutes() as $route) {
$routes = json_decode(getPage($url)); echo " <url><loc>".curPageURL()."trip.php?routeid=".htmlspecialchars ($route["route_id"])."</loc>";
foreach ($routes as $route) {  
echo " <url><loc>".curPageURL()."trip.php?routeid=".htmlspecialchars ($route[0])."</loc>";  
echo "<lastmod>" . $last_updated . "</lastmod>"; echo "<lastmod>" . $last_updated . "</lastmod>";
echo "<changefreq>monthly</changefreq>"; echo "<changefreq>monthly</changefreq>";
echo "<priority>0.9</priority>"; echo "<priority>0.9</priority>";
echo "</url>\n"; echo "</url>\n";
} }
   
  // geosite map
  foreach (getRoutes() as $route) {
  echo " <url><loc>".curPageURL()."geo/route.kml.php?routeid=".htmlspecialchars ($route["route_id"])."</loc>";
  echo "<lastmod>" . $last_updated . "</lastmod>";
  echo "<geo:geo>
  <geo:format>kml</geo:format>
  </geo:geo>";
  echo "</url>\n";
  }
   
echo '</urlset>'; echo '</urlset>';
   
?> ?>
   
file:a/stop.php -> file:b/stop.php
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
$stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT);  
$stopcode = filter_var($_REQUEST['stopcode'], FILTER_SANITIZE_STRING);  
if ($stopid) $stop = getStop($stopid); if ($stopid) $stop = getStop($stopid);
/*if ($stopcode != "" && $stop[5] != $stopcode) { /*if ($stopcode != "" && $stop[5] != $stopcode) {
$url = $APIurl . "/json/stopcodesearch?q=" . $stopcode; $url = $APIurl . "/json/stopcodesearch?q=" . $stopcode;
$stopsearch = json_decode(getPage($url)); $stopsearch = json_decode(getPage($url));
$stopid = $stopsearch[0][0]; $stopid = $stopsearch[0][0];
$url = $APIurl . "/json/stop?stop_id=" . $stopid; $url = $APIurl . "/json/stop?stop_id=" . $stopid;
$stop = json_decode(getPage($url)); $stop = json_decode(getPage($url));
} }
if (!startsWith($stop[5], "Wj") && strpos($stop[1], "Platform") === false) { if (!startsWith($stop[5], "Wj") && strpos($stop[1], "Platform") === false) {
// expand out to all platforms // expand out to all platforms
}*/ }*/
$stops = Array(); $stops = Array();
$stopPositions = Array(); $stopPositions = Array();
$stopNames = Array(); $stopNames = Array();
$tripStopNumbers = Array(); $tripStopNumbers = Array();
$allStopsTrips = Array(); $allStopsTrips = Array();
$fetchedTripSequences = Array(); $fetchedTripSequences = Array();
$stopLinks = ""; $stopLinks = "";
if (isset($_REQUEST['stopids'])) { if (isset($stopids)) {
$stopids = explode(",", filter_var($_REQUEST['stopids'], FILTER_SANITIZE_STRING));  
foreach ($stopids as $sub_stopid) { foreach ($stopids as $sub_stopid) {
$stops[] = getStop($sub_stopid); $stops[] = getStop($sub_stopid);
} }
$stop = $stops[0]; $stop = $stops[0];
$stopid = $stops[0]["stop_id"]; $stopid = $stops[0]["stop_id"];
$stopLinks.= "Individual stop pages: "; $stopLinks.= "Individual stop pages: ";
foreach ($stops as $key => $sub_stop) { foreach ($stops as $key => $sub_stop) {
// $stopNames[$key] = $sub_stop[1] . ' Stop #' . ($key + 1); // $stopNames[$key] = $sub_stop[1] . ' Stop #' . ($key + 1);
if (strpos($stop["stop_name"], "Station")) { if (strpos($stop["stop_name"], "Station")) {
$stopNames[$key] = 'Platform ' . ($key + 1); $stopNames[$key] = 'Platform ' . ($key + 1);
$stopLinks.= '<a href="stop.php?stopid=' . $sub_stop["stop_id"] . '&amp;stopcode=' . $sub_stop["stop_code"] . '">' . $sub_stop["stop_name"] . '</a> '; $stopLinks.= '<a href="stop.php?stopid=' . $sub_stop["stop_id"] . '&amp;stopcode=' . $sub_stop["stop_code"] . '">' . $sub_stop["stop_name"] . '</a> ';
} }
else { else {
$stopNames[$key] = '#' . ($key + 1); $stopNames[$key] = '#' . ($key + 1);
$stopLinks.= '<a href="stop.php?stopid=' . $sub_stop["stop_id"] . '&amp;stopcode=' . $sub_stop["stop_code"] . '">' . $sub_stop["stop_name"] . ' Stop #' . ($key + 1) . '</a> '; $stopLinks.= '<a href="stop.php?stopid=' . $sub_stop["stop_id"] . '&amp;stopcode=' . $sub_stop["stop_code"] . '">' . $sub_stop["stop_name"] . ' Stop #' . ($key + 1) . '</a> ';
} }
$stopPositions[$key] = Array( $stopPositions[$key] = Array(
$sub_stop["stop_lat"], $sub_stop["stop_lat"],
$sub_stop["stop_lon"] $sub_stop["stop_lon"]
); );
$trips = getStopTrips($sub_stop["stop_id"]); $trips = getStopTrips($sub_stop["stop_id"]);
$tripSequence = ""; $tripSequence = "";
foreach ($trips as $trip) { foreach ($trips as $trip) {
$tripSequence.= "{$trip['trip_id']},"; $tripSequence.= "{$trip['trip_id']},";
$tripStopNumbers[$trip['trip_id']][] = $key; $tripStopNumbers[$trip['trip_id']][] = $key;
} }
if (!in_array($tripSequence, $fetchedTripSequences)) { if (!in_array($tripSequence, $fetchedTripSequences)) {
// only fetch new trip sequences // only fetch new trip sequences
$fetchedTripSequences[] = $tripSequence; $fetchedTripSequences[] = $tripSequence;
$trips = getStopTripsWithTimes($sub_stop["stop_id"]); $trips = getStopTripsWithTimes($sub_stop["stop_id"]);
foreach ($trips as $trip) { foreach ($trips as $trip) {
if (!isset($allStopsTrips[$trip["trip_id"]])) $allStopsTrips[$trip["trip_id"]] = $trip; if (!isset($allStopsTrips[$trip["trip_id"]])) $allStopsTrips[$trip["trip_id"]] = $trip;
} }
} }
//else { //else {
// echo "skipped sequence $tripSequence"; // echo "skipped sequence $tripSequence";
//} //}
} }
} }
include_header($stop['stop_name'], "stop"); include_header($stop['stop_name'], "stop");
  echo '<span id="leftcolumn">';
timePlaceSettings(); timePlaceSettings();
echo $stopLinks; echo $stopLinks;
if (sizeof($stops) > 0) { if (sizeof($stops) > 0) {
trackEvent("View Stops", "View Combined Stops", $stop["stop_name"], $stop["stop_id"]); trackEvent("View Stops", "View Combined Stops", $stop["stop_name"], $stop["stop_id"]);
echo staticmap($stopPositions); echo staticmap($stopPositions);
} }
else { else {
trackEvent("View Stops", "View Single Stop", $stop["stop_name"], $stop["stop_id"]); trackEvent("View Stops", "View Single Stop", $stop["stop_name"], $stop["stop_id"]);
echo staticmap(Array( echo staticmap(Array(
0 => Array( 0 => Array(
$stop["stop_lat"], $stop["stop_lat"],
$stop["stop_lon"] $stop["stop_lon"]
) )
)) ; )) ;
} }
  echo '</span><span id="rightcolumn">';
echo ' <ul data-role="listview" data-inset="true">'; echo ' <ul data-role="listview" data-inset="true">';
if (sizeof($allStopsTrips) > 0) { if (sizeof($allStopsTrips) > 0) {
sktimesort($allStopsTrips,"arrival_time", true); sktimesort($allStopsTrips,"arrival_time", true);
$trips = $allStopsTrips; $trips = $allStopsTrips;
} }
else { else {
$trips = getStopTripsWithTimes($stopid); $trips = getStopTripsWithTimes($stopid);
} }
if (sizeof($trips) == 0) { if (sizeof($trips) == 0) {
echo "<li style='text-align: center;'>No trips in the near future.</li>"; echo "<li style='text-align: center;'>No trips in the near future.</li>";
} }
else { else {
foreach ($trips as $trip) { foreach ($trips as $trip) {
echo '<li>'; echo '<li>';
echo '<a href="trip.php?stopid=' . $stopid . '&amp;tripid=' . $trip['trip_id'] . '"><h3>' . $trip['route_short_name'] . " " . $trip['route_long_name'] . "</h3><p>"; echo '<a href="trip.php?stopid=' . $stopid . '&amp;tripid=' . $trip['trip_id'] . '"><h3>' . $trip['route_short_name'] . " " . $trip['route_long_name'] . "</h3><p>";
$viaPoints = viaPointNames($trip['trip_id'], $trip['stop_sequence']); $viaPoints = viaPointNames($trip['trip_id'], $trip['stop_sequence']);
if ($viaPoints != "") echo '<br><span class="viaPoints">Via: ' . $viaPoints . '</span>'; if ($viaPoints != "") echo '<br><span class="viaPoints">Via: ' . $viaPoints . '</span>';
if (sizeof($tripStopNumbers) > 0) { if (sizeof($tripStopNumbers) > 0) {
echo '<br><small>Boarding At: '; echo '<br><small>Boarding At: ';
foreach ($tripStopNumbers[$trip['trip_id']] as $key) { foreach ($tripStopNumbers[$trip['trip_id']] as $key) {
echo $stopNames[$key] . ' '; echo $stopNames[$key] . ' ';
} }
echo '</small>'; echo '</small>';
} }
echo '</p>'; echo '</p>';
echo '<p class="ui-li-aside"><strong>' . $trip['arrival_time'] . '</strong></p>'; echo '<p class="ui-li-aside"><strong>' . $trip['arrival_time'] . '</strong></p>';
echo '</a></li>'; echo '</a></li>';
flush(); flush();
@ob_flush(); @ob_flush();
} }
} }
echo '</ul>'; echo '</ul>';
  echo '</span>';
include_footer(); include_footer();
?> ?>
   
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
$stops = Array(); $stops = Array();
function filterByFirstLetter($var)  
{  
return $var[1][0] == $_REQUEST['firstLetter'];  
}  
function navbar() function navbar()
{ {
echo ' echo '
<div data-role="navbar"> <div data-role="navbar">
<ul> <ul>
<li><a href="stopList.php">Timing Points</a></li> <li><a href="stopList.php">Timing Points</a></li>
<li><a href="stopList.php?suburbs=yes">By Suburb</a></li> <li><a href="stopList.php?bysuburbs=yes">By Suburb</a></li>
<li><a href="stopList.php?nearby=yes">Nearby Stops</a></li> <li><a href="stopList.php?nearby=yes">Nearby Stops</a></li>
<li><a href="stopList.php?allstops=yes">All Stops</a></li> <li><a href="stopList.php?allstops=yes">All Stops</a></li>
</ul> </ul>
</div> </div>
'; ';
} }
// By suburb // By suburb
if (isset($_REQUEST['suburbs'])) { if (isset($bysuburbs)) {
include_header("Stops by Suburb", "stopList"); include_header("Stops by Suburb", "stopList");
navbar(); navbar();
echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; echo ' <ul data-role="listview" data-filter="true" data-inset="true" >';
if (!isset($_REQUEST['firstLetter'])) { if (!isset($firstLetter)) {
foreach (range('A', 'Z') as $letter) { foreach (range('A', 'Z') as $letter) {
echo "<li><a href=\"stopList.php?firstLetter=$letter&amp;suburbs=yes\">$letter...</a></li>\n"; echo "<li><a href=\"stopList.php?firstLetter=$letter&amp;bysuburbs=yes\">$letter...</a></li>\n";
} }
} }
else { else {
foreach ($suburbs as $suburb) { foreach ($suburbs as $suburb) {
if (startsWith($suburb, $_REQUEST['firstLetter'])) { if (startsWith($suburb, $firstLetter)) {
echo '<li><a href="stopList.php?suburb=' . urlencode($suburb) . '">' . $suburb . '</a></li>'; echo '<li><a href="stopList.php?suburb=' . urlencode($suburb) . '">' . $suburb . '</a></li>';
} }
} }
} }
echo '</ul>'; echo '</ul>';
} }
else { else {
// Timing Points / All stops // Timing Points / All stops
if ($_REQUEST['allstops']) { if (isset($allstops)) {
$listType = 'allstops=yes'; $listType = 'allstops=yes';
$stops = getStops(); $stops = getStops();
include_header("All Stops", "stopList"); include_header("All Stops", "stopList");
navbar(); navbar();
timePlaceSettings(); timePlaceSettings();
} }
else if ($_REQUEST['nearby']) { else if (isset($nearby)) {
$listType = 'nearby=yes'; $listType = 'nearby=yes';
include_header("Nearby Stops", "stopList", true, true); include_header("Nearby Stops", "stopList", true, true);
trackEvent("Stop Lists","Stops Nearby", $_SESSION['lat'].",".$_SESSION['lon']); trackEvent("Stop Lists", "Stops Nearby", $_SESSION['lat'] . "," . $_SESSION['lon']);
navbar(); navbar();
timePlaceSettings(true); timePlaceSettings(true);
if (!isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == "") { if (!isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == "") {
include_footer(); include_footer();
die(); die();
} }
  $stops = getNearbyStops($_SESSION['lat'], $_SESSION['lon'], 15);
$stops = getNearbyStops($_SESSION['lat'],$_SESSION['lon'],15);  
} }
else if ($_REQUEST['suburb']) { else if (isset($suburb)) {
$suburb = filter_var($_REQUEST['suburb'], FILTER_SANITIZE_STRING);  
$stops = getStopsBySuburb($suburb); $stops = getStopsBySuburb($suburb);
include_header("Stops in " . ucwords($suburb) , "stopList"); include_header("Stops in " . ucwords($suburb) , "stopList");
navbar(); navbar();
trackEvent("Stop Lists","Stops By Suburb", $suburb); trackEvent("Stop Lists", "Stops By Suburb", $suburb);
} }
else { else {
$stops = getStops(true,$_REQUEST['firstLetter']); $stops = getStops(true, $firstLetter);
include_header("Timing Points / Major Stops", "stopList"); include_header("Timing Points / Major Stops", "stopList");
navbar(); navbar();
timePlaceSettings(); timePlaceSettings();
} }
echo ' <ul data-role="listview" data-filter="true" data-inset="true" >'; echo ' <ul data-role="listview" data-filter="true" data-inset="true" >';
if (!isset($_REQUEST['firstLetter']) && !$_REQUEST['suburb'] && !$_REQUEST['nearby']) { if (!isset($firstLetter) && !isset($suburb) && !isset($nearby)) {
foreach (range('A', 'Z') as $letter) { foreach (range('A', 'Z') as $letter) {
echo "<li><a href=\"stopList.php?firstLetter=$letter&amp;$listType\">$letter...</a></li>\n"; echo "<li><a href=\"stopList.php?firstLetter=$letter&amp;$listType\">$letter...</a></li>\n";
} }
} }
else { else {
//var_dump($stops); //var_dump($stops);
$stopsGrouped = Array(); $stopsGrouped = Array();
foreach ($stops as $key => $stop) { foreach ($stops as $key => $stop) {
if ((trim(preg_replace("/\(Platform.*/", "", $stops[$key]["stop_name"])) != trim(preg_replace("/\(Platform.*/", "", $stops[$key + 1]["stop_name"]))) || $key + 1 >= sizeof($stops)) { if ((trim(preg_replace("/\(Platform.*/", "", $stops[$key]["stop_name"])) != trim(preg_replace("/\(Platform.*/", "", $stops[$key + 1]["stop_name"]))) || $key + 1 >= sizeof($stops)) {
if (sizeof($stopsGrouped) > 0) { if (sizeof($stopsGrouped) > 0) {
// print and empty grouped stops // print and empty grouped stops
// subsequent duplicates // subsequent duplicates
$stopsGrouped["stop_ids"][] = $stop['stop_id']; $stopsGrouped["stop_ids"][] = $stop['stop_id'];
echo '<li>'; echo '<li>';
if (!startsWith($stopsGrouped['stop_codes'][0], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point: " class="ui-li-icon">'; if (!startsWith($stopsGrouped['stop_codes'][0], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point: " class="ui-li-icon">';
echo '<a href="stop.php?stopids=' . implode(",", $stopsGrouped['stop_ids']) . '">'; echo '<a href="stop.php?stopids=' . implode(",", $stopsGrouped['stop_ids']) . '">';
if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) { if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) {
echo '<span class="ui-li-count">' . distance($stop['stop_lat'],$stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away</span>'; echo '<span class="ui-li-count">' . distance($stop['stop_lat'], $stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away</span>';
} }
echo bracketsMeanNewLine(trim(preg_replace("/\(Platform.*/", "", $stop['stop_name'])) . '(' . sizeof($stopsGrouped["stop_ids"]) . ' stops)'); echo bracketsMeanNewLine(trim(preg_replace("/\(Platform.*/", "", $stop['stop_name'])) . '(' . sizeof($stopsGrouped["stop_ids"]) . ' stops)');
echo "</a></li>\n"; echo "</a></li>\n";
flush(); @ob_flush(); flush();
  @ob_flush();
$stopsGrouped = Array(); $stopsGrouped = Array();
} }
else { else {
// just a normal stop // just a normal stop
echo '<li>'; echo '<li>';
if (!startsWith($stop['stop_code'], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point" class="ui-li-icon">'; if (!startsWith($stop['stop_code'], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point" class="ui-li-icon">';
echo '<a href="stop.php?stopid=' . $stop['stop_id'] . (startsWith($stop['stop_code'], "Wj") ? '&amp;stopcode=' . $stop['stop_code'] : "") . '">'; echo '<a href="stop.php?stopid=' . $stop['stop_id'] . (startsWith($stop['stop_code'], "Wj") ? '&amp;stopcode=' . $stop['stop_code'] : "") . '">';
if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) { if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) {
echo '<span class="ui-li-count">' . distance($stop['stop_lat'],$stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away</span>'; echo '<span class="ui-li-count">' . distance($stop['stop_lat'], $stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away</span>';
} }
echo bracketsMeanNewLine($stop['stop_name']); echo bracketsMeanNewLine($stop['stop_name']);
echo "</a></li>\n"; echo "</a></li>\n";
flush(); @ob_flush(); flush();
  @ob_flush();
} }
} }
else { else {
// this is a duplicated line item // this is a duplicated line item
if ($key - 1 <= 0 || (trim(preg_replace("/\(Platform.*/", "", $stops[$key]['stop_name'])) != trim(preg_replace("/\(Platform.*/", "", $stops[$key - 1]['stop_name'])))) { if ($key - 1 <= 0 || (trim(preg_replace("/\(Platform.*/", "", $stops[$key]['stop_name'])) != trim(preg_replace("/\(Platform.*/", "", $stops[$key - 1]['stop_name'])))) {
// first duplicate // first duplicate
$stopsGrouped = Array( $stopsGrouped = Array(
"name" => trim(preg_replace("/\(Platform.*/", "", $stop['stop_name'])) , "name" => trim(preg_replace("/\(Platform.*/", "", $stop['stop_name'])) ,
"stop_ids" => Array( "stop_ids" => Array(
$stop['stop_id'] $stop['stop_id']
) , ) ,
"stop_codes" => Array( "stop_codes" => Array(
$stop['stop_code'] $stop['stop_code']
) )
); );
} }
else { else {
// subsequent duplicates // subsequent duplicates
$stopsGrouped["stop_ids"][] = $stop['stop_id'];; $stopsGrouped["stop_ids"][] = $stop['stop_id'];;
} }
} }
} }
} }
echo '</ul>'; echo '</ul>';
} }
include_footer(); include_footer();
?> ?>
   
file:a/trip.php -> file:b/trip.php
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
$tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_NUMBER_INT);  
$stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT);  
$routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT);  
   
$routetrips = Array(); $routetrips = Array();
   
if ($_REQUEST['routeid'] && !$_REQUEST['tripid']) { if (isset($routeid) && !isset($tripid)) {
$trip = getRouteNextTrip($routeid); $trip = getRouteNextTrip($routeid);
$tripid = $trip['trip_id']; $tripid = $trip['trip_id'];
} else { } else {
$trip = getTrip($tripid); $trip = getTrip($tripid);
$routeid = $trip["route_id"]; $routeid = $trip["route_id"];
} }
   
$routetrips = getRouteTrips($routeid); $routetrips = getRouteTrips($routeid);
include_header("Stops on " . $trip['route_short_name'] . ' ' . $trip['route_long_name'], "trip"); include_header("Stops on " . $trip['route_short_name'] . ' ' . $trip['route_long_name'], "trip");
trackEvent("Route/Trip View","View Route", $trip['route_short_name'] . ' ' . $trip['route_long_name'], $routeid); trackEvent("Route/Trip View","View Route", $trip['route_short_name'] . ' ' . $trip['route_long_name'], $routeid);
   
  echo '<span id="leftcolumn">';
echo '<h2>Via:</h2> <small>' . viaPointNames($tripid) . '</small>'; echo '<h2>Via:</h2> <small>' . viaPointNames($tripid) . '</small>';
echo '<h2>Other Trips:</h2> '; echo '<h2>Other Trips:</h2> ';
foreach (getRouteTrips($routeid) as $othertrip) { foreach (getRouteTrips($routeid) as $othertrip) {
echo '<a href="trip.php?tripid=' . $othertrip['trip_id'] . "&amp;routeid=" . $routeid . '">' . str_replace(" ",":00",str_replace(":00"," ",$othertrip['arrival_time'])). '</a> '; echo '<a href="trip.php?tripid=' . $othertrip['trip_id'] . "&amp;routeid=" . $routeid . '">' . str_replace(" ",":00",str_replace(":00"," ",$othertrip['arrival_time'])). '</a> ';
} }
flush(); @ob_flush(); flush(); @ob_flush();
echo '<h2>Other directions/timing periods:</h2> '; echo '<h2>Other directions/timing periods:</h2> ';
foreach (getRoutesByNumber($trip['route_short_name']) as $row) { foreach (getRoutesByNumber($trip['route_short_name']) as $row) {
if ($row['route_id'] != $routeid) echo '<a href="trip.php?routeid=' . $row['route_id'] . '">' . $row['route_long_name'] . ' (' . ucwords($row['service_id']) . ')</a> '; if ($row['route_id'] != $routeid) echo '<a href="trip.php?routeid=' . $row['route_id'] . '">' . $row['route_long_name'] . ' (' . ucwords($row['service_id']) . ')</a> ';
} }
  echo '</span><span id="rightcolumn">';
flush(); @ob_flush(); flush(); @ob_flush();
echo ' <ul data-role="listview" data-inset="true">'; echo ' <ul data-role="listview" data-inset="true">';
$stopsGrouped = Array(); $stopsGrouped = Array();
$tripStopTimes = getTimeInterpolatedTrip($tripid); $tripStopTimes = getTimeInterpolatedTrip($tripid);
echo '<li data-role="list-divider">' . $tripStopTimes[0]['arrival_time'] . ' to ' . $tripStopTimes[sizeof($tripStopTimes) - 1]['arrival_time'] . ' ' . $trips[1]->route_long_name . '</li>'; echo '<li data-role="list-divider">' . $tripStopTimes[0]['arrival_time'] . ' to ' . $tripStopTimes[sizeof($tripStopTimes) - 1]['arrival_time'] . ' ' . $trip['route_long_name'] . ' (' . ucwords($tripStopTimes[0]['service_id']).')</li>';
   
foreach ($tripStopTimes as $key => $tripStopTime) { foreach ($tripStopTimes as $key => $tripStopTime) {
if (($tripStopTimes[$key]["stop_name"] != $tripStopTimes[$key + 1]["stop_name"]) || $key + 1 >= sizeof($tripStopTimes)) { if (($tripStopTimes[$key]["stop_name"] != $tripStopTimes[$key + 1]["stop_name"]) || $key + 1 >= sizeof($tripStopTimes)) {
echo '<li>'; echo '<li>';
if (!startsWith($tripStopTime['stop_code'], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point" class="ui-li-icon">'; if (!startsWith($tripStopTime['stop_code'], "Wj")) echo '<img src="css/images/time.png" alt="Timing Point" class="ui-li-icon">';
if (sizeof($stopsGrouped) > 0) { if (sizeof($stopsGrouped) > 0) {
// print and empty grouped stops // print and empty grouped stops
// subsequent duplicates // subsequent duplicates
$stopsGrouped["stop_ids"][] = $tripStopTime['stop_id']; $stopsGrouped["stop_ids"][] = $tripStopTime['stop_id'];
$stopsGrouped["endTime"] = $tripStopTime['arrival_time']; $stopsGrouped["endTime"] = $tripStopTime['arrival_time'];
echo '<a href="stop.php?stopids=' . implode(",", $stopsGrouped['stop_ids']) . '">'; echo '<a href="stop.php?stopids=' . implode(",", $stopsGrouped['stop_ids']) . '">';
echo '<p class="ui-li-aside">' . $stopsGrouped['startTime'] . ' to ' . $stopsGrouped['endTime']; echo '<p class="ui-li-aside">' . $stopsGrouped['startTime'] . ' to ' . $stopsGrouped['endTime'];
echo '</p>';  
if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) { if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) {
echo '<span class="ui-li-count">' . distance($stop['stop_lat'],$stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away</span>'; echo '<br>' . distance($tripStopTime['stop_lat'],$tripStopTime['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away';
} }
  echo '</p>';
echo bracketsMeanNewLine($tripStopTime["stop_name"]); echo bracketsMeanNewLine($tripStopTime["stop_name"]);
echo '</a></li>'; echo '</a></li>';
flush(); @ob_flush(); flush(); @ob_flush();
$stopsGrouped = Array(); $stopsGrouped = Array();
} }
else { else {
// just a normal stop // just a normal stop
echo '<a href="stop.php?stopid=' . $tripStopTime['stop_id'] . (startsWith($tripStopTime['stop_code'], "Wj") ? '&amp;stopcode=' . $tripStopTime['stop_code'] : "") . '">'; echo '<a href="stop.php?stopid=' . $tripStopTime['stop_id'] . (startsWith($tripStopTime['stop_code'], "Wj") ? '&amp;stopcode=' . $tripStopTime['stop_code'] : "") . '">';
echo '<p class="ui-li-aside">' . $tripStopTime['arrival_time'] . '</p>'; echo '<p class="ui-li-aside">' . $tripStopTime['arrival_time'];
if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) { if (isset($_SESSION['lat']) && isset($_SESSION['lon'])) {
echo '<span class="ui-li-count">' . distance($stop['stop_lat'],$stop['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away</span>'; echo '<br>' . distance($tripStopTime['stop_lat'],$tripStopTime['stop_lon'], $_SESSION['lat'], $_SESSION['lon'], true) . 'm away';
} }
  echo '</p>';
echo bracketsMeanNewLine($tripStopTime['stop_name']); echo bracketsMeanNewLine($tripStopTime['stop_name']);
echo '</a></li>'; echo '</a></li>';
flush(); @ob_flush(); flush(); @ob_flush();
} }
} }
else { else {
// this is a duplicated line item // this is a duplicated line item
if ($key - 1 <= 0 || ($tripStopTimes[$key]['stop_name'] != $tripStopTimes[$key - 1]['stop_name'])) { if ($key - 1 <= 0 || ($tripStopTimes[$key]['stop_name'] != $tripStopTimes[$key - 1]['stop_name'])) {
// first duplicate // first duplicate
$stopsGrouped = Array( $stopsGrouped = Array(
"name" => $tripStopTime['stop_name'], "name" => $tripStopTime['stop_name'],
"startTime" => $tripStopTime['arrival_time'], "startTime" => $tripStopTime['arrival_time'],
"stop_ids" => Array( "stop_ids" => Array(
$tripStopTime['stop_id'] $tripStopTime['stop_id']
) )
); );
} }
else { else {
// subsequent duplicates // subsequent duplicates
$stopsGrouped["stop_ids"][] = $tripStopTime['stop_id']; $stopsGrouped["stop_ids"][] = $tripStopTime['stop_id'];
$stopsGrouped["endTime"] = $tripStopTime['arrival_time']; $stopsGrouped["endTime"] = $tripStopTime['arrival_time'];
} }
} }
} }
echo '</ul>'; echo '</ul>';
   
  echo '</span>';
include_footer(); include_footer();
?> ?>
   
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
include_header("Trip Planner", "tripPlanner", true, true, true); include_header("Trip Planner", "tripPlanner", true, true, true);
$from = (isset($_REQUEST['from']) ? filter_var($_REQUEST['from'], FILTER_SANITIZE_STRING) : ""); $from = (isset($_REQUEST['from']) ? filter_var($_REQUEST['from'], FILTER_SANITIZE_STRING) : "");
$to = (isset($_REQUEST['to']) ? filter_var($_REQUEST['to'], FILTER_SANITIZE_STRING) : ""); $to = (isset($_REQUEST['to']) ? filter_var($_REQUEST['to'], FILTER_SANITIZE_STRING) : "");
$date = (isset($_REQUEST['date']) ? filter_var($_REQUEST['date'], FILTER_SANITIZE_STRING) : date("m/d/Y")); $date = (isset($_REQUEST['date']) ? filter_var($_REQUEST['date'], FILTER_SANITIZE_STRING) : date("m/d/Y"));
$time = (isset($_REQUEST['time']) ? filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING) : date("H:i")); $time = (isset($_REQUEST['time']) ? filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING) : date("H:i"));
function formatTime($timeString) { function formatTime($timeString)
$timeParts = explode("T",$timeString); {
return str_replace("Z","",$timeParts[1]); $timeParts = explode("T", $timeString);
  return str_replace("Z", "", $timeParts[1]);
} }
function tripPlanForm($errorMessage = "") function tripPlanForm($errorMessage = "")
{ {
   
global $date, $time, $from, $to; global $date, $time, $from, $to;
echo "<font color=red>$errorMessage</font>"; echo "<font color=red>$errorMessage</font>";
echo '<form action="tripPlanner.php" method="post"> echo '<form action="tripPlanner.php" method="post">
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="from">I would like to go from</label> <label for="from">I would like to go from</label>
<input type="text" name="from" id="from" value="' . $from . '" /> <input type="text" name="from" id="from" value="' . $from . '" />
<a href="#" style="display:none" name="fromHere" id="fromHere"/>Here?</a> <a href="#" style="display:none" name="fromHere" id="fromHere"/>Here?</a>
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="to"> to </label> <label for="to"> to </label>
<input type="text" name="to" id="to" value="' . $to . '" /> <input type="text" name="to" id="to" value="' . $to . '" />
<a href="#" style="display:none" name="toHere" id="toHere"/>Here?</a> <a href="#" style="display:none" name="toHere" id="toHere"/>Here?</a>
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="date"> on </label> <label for="date"> on </label>
<input type="text" name="date" id="date" value="' . $date . '" /> <input type="text" name="date" id="date" value="' . $date . '" />
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="time"> at </label> <label for="time"> at </label>
<input type="time" name="time" id="time" value="' . $time . '" /> <input type="time" name="time" id="time" value="' . $time . '" />
</div> </div>
<input type="submit" value="Go!"></form>'; <input type="submit" value="Go!"></form>';
echo "<script> echo "<script>
$('#toHere').click(function(event) { $('#to').val(getCookie('geolocate')); return false;}); $('#toHere').click(function(event) { $('#to').val(getCookie('geolocate')); return false;});
$('#toHere').show(); $('#toHere').show();
$('#fromHere').click(function(event) { $('#from').val(getCookie('geolocate')); return false;}); $('#fromHere').click(function(event) { $('#from').val(getCookie('geolocate')); return false;});
$('#fromHere').show(); $('#fromHere').show();
   
</script>"; </script>";
} }
function processItinerary($itineraryNumber, $itinerary) function processItinerary($itineraryNumber, $itinerary)
{ {
echo '<div data-role="collapsible" ' . ($itineraryNumber > 0 ? 'data-collapsed="true"' : "") . '> <h3> Option #' . ($itineraryNumber + 1) . ": " . floor($itinerary->duration / 60000) . " minutes (".formatTime($itinerary->startTime)." to ".formatTime($itinerary->endTime).")</h3><p>"; echo '<div data-role="collapsible" ' . ($itineraryNumber > 0 ? 'data-collapsed="true"' : "") . '> <h3> Option #' . ($itineraryNumber + 1) . ": " . floor($itinerary->duration / 60000) . " minutes (" . formatTime($itinerary->startTime) . " to " . formatTime($itinerary->endTime) . ")</h3><p>";
echo "Walking time: " . floor($itinerary->walkTime / 60000) . " minutes (" . floor($itinerary->walkDistance) . " meters)<br>\n"; echo "Walking time: " . floor($itinerary->walkTime / 60000) . " minutes (" . floor($itinerary->walkDistance) . " meters)<br>\n";
echo "Transit time: " . floor($itinerary->transitTime / 60000) . " minutes<br>\n"; echo "Transit time: " . floor($itinerary->transitTime / 60000) . " minutes<br>\n";
echo "Waiting time: " . floor($itinerary->waitingTime / 60000) . " minutes<br>\n"; echo "Waiting time: " . floor($itinerary->waitingTime / 60000) . " minutes<br>\n";
if (is_array($itinerary->legs->leg)) { if (is_array($itinerary->legs->leg)) {
$legMarkers = array(); $legMarkers = array();
foreach ($itinerary->legs->leg as $legNumber => $leg) { foreach ($itinerary->legs->leg as $legNumber => $leg) {
$legMarkers[] = array( $legMarkers[] = array(
$leg->from->lat, $leg->from->lat,
$leg->from->lon $leg->from->lon
); );
} }
echo '' . staticmap($legMarkers, 0, "iconb", false) . "<br>\n"; echo '' . staticmap($legMarkers, 0, "iconb", false) . "<br>\n";
echo '<ul>'; echo '<ul>';
foreach ($itinerary->legs->leg as $legNumber => $leg) { foreach ($itinerary->legs->leg as $legNumber => $leg) {
echo '<li>'; echo '<li>';
processLeg($legNumber, $leg); processLeg($legNumber, $leg);
echo "</li>"; echo "</li>";
flush(); @ob_flush(); flush();
  @ob_flush();
} }
echo "</ul>"; echo "</ul>";
} }
else { else {
echo '' . staticmap(array( echo '' . staticmap(array(
array( array(
$itinerary->legs->leg->from->lat, $itinerary->legs->leg->from->lat,
$itinerary->legs->leg->from->lon $itinerary->legs->leg->from->lon
) )
) , 0, "iconb", false) . "<br>\n"; ) , 0, "iconb", false) . "<br>\n";
processLeg(0, $itinerary->legs->leg); processLeg(0, $itinerary->legs->leg);
} }
echo "</p></div>"; echo "</p></div>";
} }
function processLeg($legNumber, $leg) function processLeg($legNumber, $leg)
{ {
$legArray = object2array($leg); $legArray = object2array($leg);
echo '<h3>Leg #' . ($legNumber + 1) . " ( {$legArray['@mode']} from: {$leg->from->name} to {$leg->to->name}, " . floor($leg->duration / 60000) . " minutes) </h3>\n"; echo '<h3>Leg #' . ($legNumber + 1) . " ( {$legArray['@mode']} from: {$leg->from->name} to {$leg->to->name}, " . floor($leg->duration / 60000) . " minutes) </h3>\n";
if ($legArray["@mode"] === "BUS") { if ($legArray["@mode"] === "BUS") {
echo "Take bus {$legArray['@route']} " . str_replace("To", "towards", $legArray['@headsign']) . "<br>"; echo "Take bus {$legArray['@route']} " . str_replace("To", "towards", $legArray['@headsign']) . "<br>";
} }
else { else {
$walkStepMarkers = array(); $walkStepMarkers = array();
foreach ($leg->steps->walkSteps as $stepNumber => $step) { foreach ($leg->steps->walkSteps as $stepNumber => $step) {
$walkStepMarkers[] = array( $walkStepMarkers[] = array(
$step->lat, $step->lat,
$step->lon $step->lon
); );
} }
echo "" . staticmap($walkStepMarkers, 0, "icong", false) . "<br>\n"; echo "" . staticmap($walkStepMarkers, 0, "icong", false) . "<br>\n";
foreach ($leg->steps->walkSteps as $stepNumber => $step) { foreach ($leg->steps->walkSteps as $stepNumber => $step) {
echo "Walking step " . ($stepNumber + 1) . ": "; echo "Walking step " . ($stepNumber + 1) . ": ";
if ($step->relativeDirection == "CONTINUE") { if ($step->relativeDirection == "CONTINUE") {
echo "Continue, "; echo "Continue, ";
} else if ($step->relativeDirection) echo "Turn ".ucwords(strtolower(str_replace("_"," ",$step->relativeDirection))).", "; }
echo "Go ".ucwords(strtolower($step->absoluteDirection))." on "; else if ($step->relativeDirection) echo "Turn " . ucwords(strtolower(str_replace("_", " ", $step->relativeDirection))) . ", ";
if (strpos($step->streetName,"from") !== false && strpos($step->streetName,"way") !== false) { echo "Go " . ucwords(strtolower($step->absoluteDirection)) . " on ";
echo "footpath"; if (strpos($step->streetName, "from") !== false && strpos($step->streetName, "way") !== false) {
} else { echo "footpath";
echo $step->streetName; }
} else {
echo " for " . floor($step->distance) . " meters<br>\n"; echo $step->streetName;
  }
  echo " for " . floor($step->distance) . " meters<br>\n";
} }
} }
} }
if ($_REQUEST['time']) { if ($_REQUEST['time']) {
$toPlace = (startsWith($to, "-") ? $to : geocode($to, false)); if (startsWith($to, "-")) {
$fromPlace = (startsWith($from, "-") ? $from : geocode($from, false)); $toPlace = $to;
  }
  else if (strpos($to, "(") !== false) {
  $toParts = explode("(", $to);
  print_r($toParts);
  $toPlace = str_replace( ")", "", $toParts[1]);
  }
  else {
  $toPlace = geocode($to, false);
  }
   
  if (startsWith($from, "-")) {
  $fromPlace = $from;
  }
  else if (strpos($from, "(") !== false) {
  $fromParts = explode("(", urldecode($from));
  $fromPlace = str_replace(")", "", $fromParts[1]);
  }
  else {
  $fromPlace = geocode($from, false);
  }
   
if ($toPlace == "" || $fromPlace == "") { if ($toPlace == "" || $fromPlace == "") {
$errorMessage = ""; $errorMessage = "";
if ($toPlace === "") { if ($toPlace == "") {
$errorMessage.= urlencode($to) . " not found.<br>\n"; $errorMessage.= urlencode($to) . " not found.<br>\n";
trackEvent("Trip Planner","Geocoder Failed", $to); trackEvent("Trip Planner", "Geocoder Failed", $to);
} }
if ($fromPlace === "") { if ($fromPlace == "") {
$errorMessage.= urlencode($from) . " not found.<br>\n"; $errorMessage.= urlencode($from) . " not found.<br>\n";
trackEvent("Trip Planner","Geocoder Failed", $from); trackEvent("Trip Planner", "Geocoder Failed", $from);
} }
tripPlanForm($errorMessage); tripPlanForm($errorMessage);
} }
else { else {
$url = $otpAPIurl . "ws/plan?date=" . urlencode($_REQUEST['date']) . "&time=" . urlencode($_REQUEST['time']) . "&mode=TRANSIT%2CWALK&optimize=QUICK&maxWalkDistance=840&wheelchair=false&toPlace=$toPlace&fromPlace=$fromPlace&intermediatePlaces="; $url = $otpAPIurl . "ws/plan?date=" . urlencode($_REQUEST['date']) . "&time=" . urlencode($_REQUEST['time']) . "&mode=TRANSIT%2CWALK&optimize=QUICK&maxWalkDistance=840&wheelchair=false&toPlace=$toPlace&fromPlace=$fromPlace&intermediatePlaces=";
debug($url); debug($url);
$ch = curl_init($url); $ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array( curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Accept: application/json" "Accept: application/json"
)); ));
curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$page = curl_exec($ch); $page = curl_exec($ch);
if (curl_errno($ch) || curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200) { if (curl_errno($ch) || curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200) {
tripPlanForm("Trip planner temporarily unavailable: " . curl_errno($ch) . " " . curl_error($ch) . " ". curl_getinfo($ch, CURLINFO_HTTP_CODE) .(isDebug() ? "<br>".$url : "")); tripPlanForm("Trip planner temporarily unavailable: " . curl_errno($ch) . " " . curl_error($ch) . " " . curl_getinfo($ch, CURLINFO_HTTP_CODE) . (isDebug() ? "<br>" . $url : ""));
trackEvent("Trip Planner","Trip Planner Failed", $url); trackEvent("Trip Planner", "Trip Planner Failed", $url);
} }
else { else {
trackEvent("Trip Planner","Plan Trip From", $from); trackEvent("Trip Planner", "Plan Trip From", $from);
trackEvent("Trip Planner","Plan Trip To", $to); trackEvent("Trip Planner", "Plan Trip To", $to);
$tripplan = json_decode($page); $tripplan = json_decode($page);
debug(print_r($tripplan, true)); debug(print_r($tripplan, true));
echo "<h1> From: {$tripplan->plan->from->name} To: {$tripplan->plan->to->name} </h1>"; echo "<h1> From: {$tripplan->plan->from->name} To: {$tripplan->plan->to->name} </h1>";
echo "<h1> At: ".formatTime($tripplan->plan->date)." </h1>"; echo "<h1> At: " . formatTime($tripplan->plan->date) . " </h1>";
if (is_array($tripplan->plan->itineraries->itinerary)) { if (is_array($tripplan->plan->itineraries->itinerary)) {
echo '<div data-role="collapsible-set">'; echo '<div data-role="collapsible-set">';
foreach ($tripplan->plan->itineraries->itinerary as $itineraryNumber => $itinerary) { foreach ($tripplan->plan->itineraries->itinerary as $itineraryNumber => $itinerary) {
processItinerary($itineraryNumber, $itinerary); processItinerary($itineraryNumber, $itinerary);
} }
echo "</div>"; echo "</div>";
} }
else { else {
processItinerary(0, $tripplan->plan->itineraries->itinerary); processItinerary(0, $tripplan->plan->itineraries->itinerary);
} }
} }
curl_close($ch); curl_close($ch);
} }
} }
else { else {
tripPlanForm(); tripPlanForm();
} }
include_footer(); include_footer();
?> ?>