From: Alexander Sadleir Date: Sat, 10 Mar 2012 08:02:21 +0000 Subject: Merge branch 'master' of https://github.com/maxious/ACTBus-ui X-Git-Url: https://maxious.lambdacomplex.org/git/?p=busui.git&a=commitdiff&h=4aab11cb185fdfa17409d8512b881d5d6e9c9093 --- Merge branch 'master' of https://github.com/maxious/ACTBus-ui Conflicts: .gitmodules myway/myway_timeliness_route.json.php myway/myway_timeliness_stop.php --- --- /dev/null +++ b/.gitignore @@ -1,1 +1,9 @@ +/labs/tiles/12 +/labs/tiles/13 +/labs/tiles/14 +/labs/tiles/15 +/labs/tiles/16 +/labs/tiles/17 +/labs/tiles/19 +/nbproject/private/ --- /dev/null +++ b/.gitmodules @@ -1,1 +1,16 @@ +<<<<<<< HEAD +[submodule "js/flotr2"] + path = js/flotr2 + url = https://github.com/HumbleSoftware/Flotr2.git +[submodule "js/FlashCanvas"] + path = js/FlashCanvas + url = https://github.com/timcameronryan/FlashCanvas +======= +[submodule "lib/amon-php"] + path = lib/amon-php + url = https://github.com/martinrusev/amon-php.git +[submodule "js/yepnope"] + path = js/yepnope + url = https://github.com/SlexAxton/yepnope.js.git +>>>>>>> 9714b3c938ad66f914c8d22144b8883e40f2ef09 --- /dev/null +++ b/Boxfile @@ -1,1 +1,7 @@ +web1: + php_extensions: + - pgsql + - pdo + - pdo_pgsql + - curl --- a/about.php +++ b/about.php @@ -1,31 +1,57 @@

-Busness Time - An ACT bus timetable webapp
-Based on the maxious-canberra-transit-feed (download, -last updated )
-Source code for the transit -feed and this -site available from github.
-Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service
-
-Feedback encouraged; contact maxious@lambdacomplex.org
+ Busness Time - An ACT bus timetable webapp
+ Based on the maxious-canberra-transit-feed (download, + last updated )
+ Source code for the transit + feed and this + site available from github.
+ Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service
+ Suburb Geocoding Based on Australian Bureau of Statistics data.
+ Street geocoding based on work by OpenStreetMap contributors

-Some icons by Joseph Wain / glyphish.com
-
-Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip. -Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, -express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided -"as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability. -All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, -change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site -without prior notice. - + Feedback encouraged; contact maxious@lambdacomplex.org
+
+ Some icons by Joseph Wain / glyphish.com
+ Native clients also available for iPhone(cbrTimetable by Sandor Kolotenko + , ACT Buses by David Sullivan, Bus Trips ACT by Molson Chengalath) + , Android (MyBus 2.0 by Imagine Team, GetMe2 Canberra by +Colin Thompson , TransitTimes+ by Zervaas Enterprises) + and Windows Phone 7 (TransHub Canberra by Soul Solutions) Other web clients include iTranzit. +
+ GTFS-realtime API: + Alerts and Trip Updates (but only Cancelled or Stop Skipped) + Default format binary Protocol Buffer but can get JSON by adding ?ascii=yes +
+
+ Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip. + Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, + express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided + "as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability. + All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, + change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site + without prior notice. + --- a/aws/awsStartup.sh +++ /dev/null @@ -1,39 +1,1 @@ -#!/bin/bash -#this script should be run from a fresh git checkout from github -#ami base must have yum install lighttpd-fastcgi, git, tomcat6 -#php-cli php-gd tomcat6-webapps tomcat6-admin-webapps svn maven2 -#postgres postgres-server php-pg -#http://www.how2forge.org/installing-lighttpd-with-php5-and-mysql-support-on-fedora-12 -cp /root/aws.php /tmp/ -mkdir /var/www/lib/staticmaplite/cache -chcon -h system_u:object_r:httpd_sys_content_t /var/www -chcon -R -h root:object_r:httpd_sys_content_t /var/www/* -chcon -R -t httpd_sys_content_rw_t /var/www/lib/staticmaplite/cache -chmod -R 777 /var/www/lib/staticmaplite/cache -chcon -R -t httpd_sys_content_rw_t /var/www/labs/tiles -chmod -R 777 /var/www/labs/tiles -wget http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \ --O /var/www/cbrfeed.zip - -createdb transitdata -createlang -d transitdata plpgsql -psql -d transitdata -f /var/www/lib/postgis.sql -# curl https://github.com/maxious/ACTBus-ui/raw/master/transitdata.cbrfeed.sql.gz -o transitdata.cbrfeed.sql.gz -#made with pg_dump transitdata | gzip -c > transitdata.cbrfeed.sql.gz -gunzip /var/www/transitdata.cbrfeed.sql.gz -psql -d transitdata -f /var/www/transitdata.cbrfeed.sql -#createuser transitdata -SDRP -#password transitdata -#psql -d transitdata -c \"GRANT SELECT ON TABLE agency,calendar,calendar_dates,routes,stop_times,stops,trips TO transitdata;\" -php /var/www/updatedb.php - -wget http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \ --O /tmp/Graph.obj -rm -rfv /usr/share/tomcat6/webapps/opentripplanner* -wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-webapp.war \ --O /usr/share/tomcat6/webapps/opentripplanner-webapp.war -wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-api-webapp.war \ --O /usr/share/tomcat6/webapps/opentripplanner-api-webapp.war -/etc/init.d/tomcat6 restart - --- a/aws/compress.conf +++ /dev/null @@ -1,33 +1,1 @@ -####################################################################### -## -## Output Compression -## -------------------- -## -## see http://www.lighttpd.net/documentation/compress.html -## -server.modules += ( "mod_compress" ) -## -## where should the compressed files be cached? -## see the base config for the declaration of the variable. -## -## This directory should be changed per vhost otherwise you can -## run into trouble with overlapping filenames -## -compress.cache-dir = cache_dir + "/compress" - -## -## FileTypes to compress. -## -#compress.filetype = ("text/plain", "text/html") -compress.filetype = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml") - -## -## Maximum filesize that will be compressed. -## Default is 0, which means unlimited file size. -## -#compress.max-filesize = 0 - -## -####################################################################### - --- a/aws/expire.conf +++ /dev/null @@ -1,29 +1,1 @@ -####################################################################### -## -## Expire Module -## --------------- -## -## See http://www.lighttpd.net/documentation/expire.html -## -server.modules += ( "mod_expire" ) -## -## assignes a expiration to all files below the specified path. The -## specification of the time is made up of: -## -## -## -#expire.url = ( -# "/buggy/" => "access 2 hours", -# "/images/" => "access plus 1 seconds 2 minutes" -#) -etag.use-mtime = "enable" -etag.use-inode = "disable" -static-file.etags = "enable" -$HTTP["url"] =~ "\.(css|js|png|jpg|ico|gif)$" { - expire.url = ( "" => "access 7 days" ) -} - -## -####################################################################### - --- a/aws/fastcgi.conf +++ /dev/null @@ -1,144 +1,1 @@ -####################################################################### -## -## FastCGI Module -## --------------- -## -## http://www.lighttpd.net/documentation/fastcgi.html -## -server.modules += ( "mod_fastcgi" ) -fastcgi.server = ( ".php" => - ( "localhost" => - ( - "socket" => -"/var/run/lighttpd/php-fastcgi.socket", - "bin-path" => "/usr/bin/php-cgi" - ) - ) - ) -## -## PHP Example -## For PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini. -## -## The number of php processes you will get can be easily calculated: -## -## num-procs = max-procs * ( 1 + PHP_FCGI_CHILDREN ) -## -## for the php-num-procs example it means you will get 17*5 = 85 php -## processes. you always should need this high number for your very -## busy sites. And if you have a lot of RAM. :) -## -#fastcgi.server = ( ".php" => -# ( "php-local" => -# ( -# "socket" => socket_dir + "/php-fastcgi-1.socket", -# "bin-path" => server_root + "/php-cgi", -# "max-procs" => 1, -# "broken-scriptfilename" => "enable", -# ) -# ), -# ( "php-tcp" => -# ( -# "host" => "127.0.0.1", -# "port" => 9999, -# "check-local" => "disable", -# "broken-scriptfilename" => "enable", -# ) -# ), -# -# ( "php-num-procs" => -# ( -# "socket" => socket_dir + "/php-fastcgi-2.socket", -# "bin-path" => server_root + "/php-cgi", -# "bin-environment" => ( -# "PHP_FCGI_CHILDREN" => "16", -# "PHP_FCGI_MAX_REQUESTS" => "10000", -# ), -# "max-procs" => 5, -# "broken-scriptfilename" => "enable", -# ) -# ), -# ) -## -## Ruby on Rails Example -## -## Normally you only run one Rails application on one vhost. -## -#$HTTP["host"] == "rails1.example.com" { -# server.document-root = server_root + "/rails/someapp/public" -# server.error-handler-404 = "/dispatch.fcgi" -# fastcgi.server = ( ".fcgi" => -# ("someapp" => -# ( "socket" => socket_dir + "/someapp-fcgi.socket", -# "bin-path" => server_root + "/rails/someapp/public/dispatch.fcgi", -# "bin-environment" => ( -# "RAILS_ENV" => "production", -# "TMP" => home_dir + "/rails/someapp", -# ), -# ) -# ) -# ) -#} - -## -## Another example with multiple rails applications on one vhost. -## -## http://blog.lighttpd.net/articles/2005/11/23/lighttpd-1-4-8-and-multiple-rails-apps -## -#$HTTP["host"] == "rails2.example.com" { -# $HTTP["url"] =~ "^/someapp1" { -# server.document-root = server_root + "/rails/someapp1/public" -# server.error-handler-404 = "/dispatch.fcgi" -# fastcgi.server = ( ".fcgi" => -# ("someapp1" => -# ( "socket" => socket_dir + "/someapp1-fcgi.socket", -# "bin-path" => server_root + "/rails/someapp1/public/dispatch.fcgi", -# "bin-environment" => ( -# "RAILS_ENV" => "production", -# "TMP" => home_dir + "/rails/someapp1", -# ), -# "strip-request-uri" => "/someapp1/" -# ) -# ) -# ) -# } -# -# $HTTP["url"] =~ "^/someapp2" { -# server.document-root = server_root + "/rails/someapp2/public" -# server.error-handler-404 = "/dispatch.fcgi" -# fastcgi.server = ( ".fcgi" => -# ("someapp2" => -# ( "socket" => socket_dir + "/someapp2-fcgi.socket", -# "bin-path" => server_root + "/rails/someapp2/public/dispatch.fcgi", -# "bin-environment" => ( -# "RAILS_ENV" => "production", -# "TMP" => home_dir + "/rails/someapp2", -# ), -# "strip-request-uri" => "/someapp2/" -# ) -# ) -# ) -# } -#} - -## chrooted webserver + external PHP -## -## $ spawn-fcgi -f /usr/bin/php-cgi -p 2000 -a 127.0.0.1 -C 8 -## -## webserver chrooted to /srv/www/ -## php running outside the chroot -# -#fastcgi.server = ( -# ".php" => (( -# "host" => "127.0.0.1", -# "port" => "2000", -# "docroot" => "/srv/www/servers/www.example.org/htdocs/" -# ))) -# -#server.chroot = "/srv/www" -#server.document-root = "/servers/wwww.example.org/htdocs/" -# - -## -####################################################################### - --- a/aws/modules.conf +++ /dev/null @@ -1,173 +1,1 @@ -####################################################################### -## -## Modules to load -## ----------------- -## -## at least mod_access and mod_accesslog should be loaded -## all other module should only be loaded if really neccesary -## -## - saves some time -## - saves memory -## -## the default module set contains: -## -## "mod_indexfile", "mod_dirlisting", "mod_staticfile" -## -## you dont have to include those modules in your list -## -## Modules, which are pulled in via conf.d/*.conf -## -## NOTE: the order of modules is important. -## -## - mod_accesslog -> conf.d/access_log.conf -## - mod_compress -> conf.d/compress.conf -## - mod_status -> conf.d/status.conf -## - mod_webdav -> conf.d/webdav.conf -## - mod_cml -> conf.d/cml.conf -## - mod_evhost -> conf.d/evhost.conf -## - mod_simple_vhost -> conf.d/simple_vhost.conf -## - mod_mysql_vhost -> conf.d/mysql_vhost.conf -## - mod_trigger_b4_dl -> conf.d/trigger_b4_dl.conf -## - mod_userdir -> conf.d/userdir.conf -## - mod_rrdtool -> conf.d/rrdtool.conf -## - mod_ssi -> conf.d/ssi.conf -## - mod_cgi -> conf.d/cgi.conf -## - mod_scgi -> conf.d/scgi.conf -## - mod_fastcgi -> conf.d/fastcgi.conf -## - mod_proxy -> conf.d/proxy.conf -## - mod_secdownload -> conf.d/secdownload.conf -## - mod_expire -> conf.d/expire.conf -## -server.modules = ( - "mod_access", -# "mod_alias", -# "mod_auth", -# "mod_evasive", -# "mod_redirect", -# "mod_rewrite", -# "mod_setenv", -# "mod_usertrack", -) - -## -####################################################################### - -####################################################################### -## -## Config for various Modules -## - -## -## mod_ssi -## -#include "conf.d/ssi.conf" - -## -## mod_status -## -#include "conf.d/status.conf" - -## -## mod_webdav -## -#include "conf.d/webdav.conf" - -## -## mod_compress -## -include "conf.d/compress.conf" - -## -## mod_userdir -## -#include "conf.d/userdir.conf" - -## -## mod_magnet -## -#include "conf.d/magnet.conf" - -## -## mod_cml -## -#include "conf.d/cml.conf" - -## -## mod_rrdtool -## -#include "conf.d/rrdtool.conf" - -## -## mod_proxy -## -#include "conf.d/proxy.conf" - -## -## mod_expire -## -include "conf.d/expire.conf" - -## -## mod_secdownload -## -#include "conf.d/secdownload.conf" - -## -####################################################################### - -####################################################################### -## -## CGI modules -## - -## -## SCGI (mod_scgi) -## -#include "conf.d/scgi.conf" - -## -## FastCGI (mod_fastcgi) -## -include "conf.d/fastcgi.conf" - -## -## plain old CGI (mod_cgi) -## -#include "conf.d/cgi.conf" - -## -####################################################################### - -####################################################################### -## -## VHost Modules -## -## Only load ONE of them! -## ======================== -## - -## -## You can use conditionals for vhosts aswell. -## -## see http://www.lighttpd.net/documentation/configuration.html -## - -## -## mod_evhost -## -#include "conf.d/evhost.conf" - -## -## mod_simple_vhost -## -#include "conf.d/simple_vhost.conf" - -## -## mod_mysql_vhost -## -#include "conf.d/mysql_vhost.conf" - -## -####################################################################### - --- a/aws/pg_hba.conf +++ /dev/null @@ -1,77 +1,1 @@ -# PostgreSQL Client Authentication Configuration File -# =================================================== -# -# Refer to the "Client Authentication" section in the -# PostgreSQL documentation for a complete description -# of this file. A short synopsis follows. -# -# This file controls: which hosts are allowed to connect, how clients -# are authenticated, which PostgreSQL user names they can use, which -# databases they can access. Records take one of these forms: -# -# local DATABASE USER METHOD [OPTIONS] -# host DATABASE USER CIDR-ADDRESS METHOD [OPTIONS] -# hostssl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS] -# hostnossl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS] -# -# (The uppercase items must be replaced by actual values.) -# -# 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 -# SSL-encrypted TCP/IP socket, and "hostnossl" is a plain TCP/IP socket. -# -# DATABASE can be "all", "sameuser", "samerole", a database name, or -# a comma-separated list thereof. -# -# 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 -# you can also write a file name prefixed with "@" to include names from -# a separate file. -# -# 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 -# (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that specifies -# 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. -# -# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi", "krb5", -# "ident", "pam", "ldap" or "cert". Note that "password" sends passwords -# in clear text; "md5" is preferred since it sends encrypted passwords. -# -# OPTIONS are a set of options for the authentication in the format -# NAME=VALUE. The available options depend on the different authentication -# methods - refer to the "Client Authentication" section in the documentation -# for a list of which options are available for which authentication methods. -# -# Database and user names containing spaces, commas, quotes and other special -# characters must be quoted. Quoting one of the keywords "all", "sameuser" or -# "samerole" makes the name lose its special character, and just match a -# database or username with that name. -# -# 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 -# to SIGHUP the postmaster for the changes to take effect. You can use -# "pg_ctl reload" to do that. -# Put your actual configuration here -# ---------------------------------- -# -# 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 -# on a non-local interface via the listen_addresses configuration parameter, -# or via the -i or -h command line switches. -# - - - -# TYPE DATABASE USER CIDR-ADDRESS METHOD - -# "local" is for Unix domain socket connections only -local all all trust -# IPv4 local connections: -host all all 127.0.0.1/32 trust -# IPv6 local connections: -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 - --- a/aws/php.ini +++ /dev/null @@ -1,1662 +1,1 @@ -[PHP] -date.timezone = "Australia/Sydney" - -;;;;;;;;;;;;;;;;;;; -; About php.ini ; -;;;;;;;;;;;;;;;;;;; -; PHP's initialization file, generally called php.ini, is responsible for -; configuring many of the aspects of PHP's behavior. - -; PHP attempts to find and load this configuration from a number of locations. -; The following is a summary of its search order: -; 1. SAPI module specific location. -; 2. The PHPRC environment variable. (As of PHP 5.2.0) -; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0) -; 4. Current working directory (except CLI) -; 5. The web server's directory (for SAPI modules), or directory of PHP -; (otherwise in Windows) -; 6. The directory from the --with-config-file-path compile time option, or the -; Windows directory (C:\windows or C:\winnt) -; See the PHP docs for more specific information. -; http://www.php.net/manual/en/configuration.file.php - -; The syntax of the file is extremely simple. Whitespace and Lines -; beginning with a semicolon are silently ignored (as you probably guessed). -; Section headers (e.g. [Foo]) are also silently ignored, even though -; they might mean something in the future. - -; Directives following the section heading [PATH=/www/mysite] only -; apply to PHP files in the /www/mysite directory. Directives -; following the section heading [HOST=www.example.com] only apply to -; PHP files served from www.example.com. Directives set in these -; special sections cannot be overridden by user-defined INI files or -; at runtime. Currently, [PATH=] and [HOST=] sections only work under -; CGI/FastCGI. -; http://www.php.net/manual/en/ini.sections.php - -; Directives are specified using the following syntax: -; directive = value -; Directive names are *case sensitive* - foo=bar is different from FOO=bar. -; Directives are variables used to configure PHP or PHP extensions. -; There is no name validation. If PHP can't find an expected -; directive because it is not set or is mistyped, a default value will be used. - -; The value can be a string, a number, a PHP constant (e.g. E_ALL or M_PI), one -; of the INI constants (On, Off, True, False, Yes, No and None) or an expression -; (e.g. E_ALL & ~E_NOTICE), a quoted string ("bar"), or a reference to a -; previously set variable or directive (e.g. ${foo}) - -; Expressions in the INI file are limited to bitwise operators and parentheses: -; | bitwise OR -; ^ bitwise XOR -; & bitwise AND -; ~ bitwise NOT -; ! boolean NOT - -; Boolean flags can be turned on using the values 1, On, True or Yes. -; They can be turned off using the values 0, Off, False or No. - -; An empty string can be denoted by simply not writing anything after the equal -; sign, or by using the None keyword: - -; foo = ; sets foo to an empty string -; foo = None ; sets foo to an empty string -; foo = "None" ; sets foo to the string 'None' - -; If you use constants in your value, and these constants belong to a -; dynamically loaded extension (either a PHP extension or a Zend extension), -; you may only use these constants *after* the line that loads the extension. - -;;;;;;;;;;;;;;;;;;; -; About this file ; -;;;;;;;;;;;;;;;;;;; -; PHP comes packaged with two INI files. One that is recommended to be used -; in production environments and one that is recommended to be used in -; development environments. - -; php.ini-production contains settings which hold security, performance and -; best practices at its core. But please be aware, these settings may break -; compatibility with older or less security conscience applications. We -; recommending using the production ini in production and testing environments. - -; php.ini-development is very similar to its production variant, except it's -; much more verbose when it comes to errors. We recommending using the -; development version only in development environments as errors shown to -; application users can inadvertently leak otherwise secure information. - -; This 2 files are provided, by RPM, in /usr/share/doc/php-common-*/ -; File used by RPM (the /etc/php.ini) is mainly the php.ini-production - -;;;;;;;;;;;;;;;;;;; -; Quick Reference ; -;;;;;;;;;;;;;;;;;;; -; The following are all the settings which are different in either the production -; or development versions of the INIs with respect to PHP's default behavior. -; Please see the actual settings later in the document for more details as to why -; we recommend these changes in PHP's behavior. - -; allow_call_time_pass_reference -; Default Value: On -; Development Value: Off -; Production Value: Off - -; display_errors -; Default Value: On -; Development Value: On -; Production Value: Off - -; display_startup_errors -; Default Value: Off -; Development Value: On -; Production Value: Off - -; error_reporting -; Default Value: E_ALL & ~E_NOTICE -; Development Value: E_ALL | E_STRICT -; Production Value: E_ALL & ~E_DEPRECATED - -; html_errors -; Default Value: On -; Development Value: On -; Production value: Off - -; log_errors -; Default Value: Off -; Development Value: On -; Production Value: On - -; magic_quotes_gpc -; Default Value: On -; Development Value: Off -; Production Value: Off - -; max_input_time -; Default Value: -1 (Unlimited) -; Development Value: 60 (60 seconds) -; Production Value: 60 (60 seconds) - -; output_buffering -; Default Value: Off -; Development Value: 4096 -; Production Value: 4096 - -; register_argc_argv -; Default Value: On -; Development Value: Off -; Production Value: Off - -; register_long_arrays -; Default Value: On -; Development Value: Off -; Production Value: Off - -; request_order -; Default Value: None -; Development Value: "GP" -; Production Value: "GP" - -; session.bug_compat_42 -; Default Value: On -; Development Value: On -; Production Value: Off - -; session.bug_compat_warn -; Default Value: On -; Development Value: On -; Production Value: Off - -; session.gc_divisor -; Default Value: 100 -; Development Value: 1000 -; Production Value: 1000 - -; session.hash_bits_per_character -; Default Value: 4 -; Development Value: 5 -; Production Value: 5 - -; short_open_tag -; Default Value: On -; Development Value: Off -; Production Value: Off - -; track_errors -; Default Value: Off -; Development Value: On -; Production Value: Off - -; url_rewriter.tags -; Default Value: "a=href,area=href,frame=src,form=,fieldset=" -; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry" -; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry" - -; variables_order -; Default Value: "EGPCS" -; Development Value: "GPCS" -; Production Value: "GPCS" - -;;;;;;;;;;;;;;;;;;;; -; php.ini Options ; -;;;;;;;;;;;;;;;;;;;; -; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini" -;user_ini.filename = ".user.ini" - -; To disable this feature set this option to empty value -;user_ini.filename = - -; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes) -;user_ini.cache_ttl = 300 - -;;;;;;;;;;;;;;;;;;;; -; Language Options ; -;;;;;;;;;;;;;;;;;;;; - -; Enable the PHP scripting language engine under Apache. -; http://www.php.net/manual/en/apache.configuration.php#ini.engine -engine = On - -; This directive determines whether or not PHP will recognize code between -; tags as PHP source which should be processed as such. It's been -; recommended for several years that you not use the short tag "short cut" and -; instead to use the full tag combination. With the wide spread use -; of XML and use of these tags by other languages, the server can become easily -; confused and end up parsing the wrong code in the wrong context. But because -; this short cut has been a feature for such a long time, it's currently still -; supported for backwards compatibility, but we recommend you don't use them. -; Default Value: On -; Development Value: Off -; Production Value: Off -; http://www.php.net/manual/en/ini.core.php#ini.short-open-tag -short_open_tag = Off - -; Allow ASP-style <% %> tags. -; http://www.php.net/manual/en/ini.core.php#ini.asp-tags -asp_tags = Off - -; The number of significant digits displayed in floating point numbers. -; http://www.php.net/manual/en/ini.core.php#ini.precision -precision = 14 - -; Enforce year 2000 compliance (will cause problems with non-compliant browsers) -; http://www.php.net/manual/en/ini.core.php#ini.y2k-compliance -y2k_compliance = On - -; Output buffering is a mechanism for controlling how much output data -; (excluding headers and cookies) PHP should keep internally before pushing that -; data to the client. If your application's output exceeds this setting, PHP -; will send that data in chunks of roughly the size you specify. -; Turning on this setting and managing its maximum buffer size can yield some -; interesting side-effects depending on your application and web server. -; You may be able to send headers and cookies after you've already sent output -; through print or echo. You also may see performance benefits if your server is -; emitting less packets due to buffered output versus PHP streaming the output -; as it gets it. On production servers, 4096 bytes is a good setting for performance -; reasons. -; Note: Output buffering can also be controlled via Output Buffering Control -; functions. -; Possible Values: -; On = Enabled and buffer is unlimited. (Use with caution) -; Off = Disabled -; Integer = Enables the buffer and sets its maximum size in bytes. -; Default Value: Off -; Development Value: 4096 -; Production Value: 4096 -; http://www.php.net/manual/en/outcontrol.configuration.php#ini.output-buffering -output_buffering = 4096 - -; You can redirect all of the output of your scripts to a function. For -; example, if you set output_handler to "mb_output_handler", character -; encoding will be transparently converted to the specified encoding. -; Setting any output handler automatically turns on output buffering. -; Note: People who wrote portable scripts should not depend on this ini -; directive. Instead, explicitly set the output handler using ob_start(). -; Using this ini directive may cause problems unless you know what script -; is doing. -; Note: You cannot use both "mb_output_handler" with "ob_iconv_handler" -; and you cannot use both "ob_gzhandler" and "zlib.output_compression". -; Note: output_handler must be empty if this is set 'On' !!!! -; Instead you must use zlib.output_handler. -; http://www.php.net/manual/en/outcontrol.configuration.php#ini.output-handler -;output_handler = - -; Transparent output compression using the zlib library -; Valid values for this option are 'off', 'on', or a specific buffer size -; to be used for compression (default is 4KB) -; Note: Resulting chunk size may vary due to nature of compression. PHP -; outputs chunks that are few hundreds bytes each as a result of -; compression. If you prefer a larger chunk size for better -; performance, enable output_buffering in addition. -; Note: You need to use zlib.output_handler instead of the standard -; output_handler, or otherwise the output will be corrupted. -; http://www.php.net/manual/en/zlib.configuration.php#ini.zlib.output-compression -zlib.output_compression = on - -; http://www.php.net/manual/en/zlib.configuration.php#ini.zlib.output-compression-level -;zlib.output_compression_level = -1 - -; You cannot specify additional output handlers if zlib.output_compression -; is activated here. This setting does the same as output_handler but in -; a different order. -; http://www.php.net/manual/en/zlib.configuration.php#ini.zlib.output-handler -;zlib.output_handler = - -; Implicit flush tells PHP to tell the output layer to flush itself -; automatically after every output block. This is equivalent to calling the -; PHP function flush() after each and every call to print() or echo() and each -; and every HTML block. Turning this option on has serious performance -; implications and is generally recommended for debugging purposes only. -; http://www.php.net/manual/en/outcontrol.configuration.php#ini.implicit-flush -implicit_flush = Off - -; The unserialize callback function will be called (with the undefined class' -; name as parameter), if the unserializer finds an undefined class -; which should be instantiated. A warning appears if the specified function is -; not defined, or if the function doesn't include/implement the missing class. -; So only set this entry, if you really want to implement such a -; callback-function. -unserialize_callback_func = - -; When floats & doubles are serialized store serialize_precision significant -; digits after the floating point. The default value ensures that when floats -; are decoded with unserialize, the data will remain the same. -serialize_precision = 100 - -; This directive allows you to enable and disable warnings which PHP will issue -; if you pass a value by reference at function call time. Passing values by -; reference at function call time is a deprecated feature which will be removed -; from PHP at some point in the near future. The acceptable method for passing a -; value by reference to a function is by declaring the reference in the functions -; definition, not at call time. This directive does not disable this feature, it -; only determines whether PHP will warn you about it or not. These warnings -; should enabled in development environments only. -; Default Value: On (Suppress warnings) -; Development Value: Off (Issue warnings) -; Production Value: Off (Issue warnings) -; http://www.php.net/manual/en/ini.core.php#ini.allow-call-time-pass-reference -allow_call_time_pass_reference = Off - -; Safe Mode -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode -safe_mode = Off - -; By default, Safe Mode does a UID compare check when -; opening files. If you want to relax this to a GID compare, -; then turn on safe_mode_gid. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-gid -safe_mode_gid = Off - -; When safe_mode is on, UID/GID checks are bypassed when -; including files from this directory and its subdirectories. -; (directory must also be in include_path or full path must -; be used when including) -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-include-dir -safe_mode_include_dir = - -; When safe_mode is on, only executables located in the safe_mode_exec_dir -; will be allowed to be executed via the exec family of functions. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-exec-dir -safe_mode_exec_dir = - -; Setting certain environment variables may be a potential security breach. -; This directive contains a comma-delimited list of prefixes. In Safe Mode, -; the user may only alter environment variables whose names begin with the -; prefixes supplied here. By default, users will only be able to set -; environment variables that begin with PHP_ (e.g. PHP_FOO=BAR). -; Note: If this directive is empty, PHP will let the user modify ANY -; environment variable! -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-allowed-env-vars -safe_mode_allowed_env_vars = PHP_ - -; This directive contains a comma-delimited list of environment variables that -; the end user won't be able to change using putenv(). These variables will be -; protected even if safe_mode_allowed_env_vars is set to allow to change them. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-protected-env-vars -safe_mode_protected_env_vars = LD_LIBRARY_PATH - -; open_basedir, if set, limits all file operations to the defined directory -; and below. This directive makes most sense if used in a per-directory -; or per-virtualhost web server configuration file. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.open-basedir -;open_basedir = - -; This directive allows you to disable certain functions for security reasons. -; It receives a comma-delimited list of function names. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.disable-functions -disable_functions = - -; This directive allows you to disable certain classes for security reasons. -; It receives a comma-delimited list of class names. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.disable-classes -disable_classes = - -; Colors for Syntax Highlighting mode. Anything that's acceptable in -; would work. -; http://www.php.net/manual/en/misc.configuration.php#ini.syntax-highlighting -;highlight.string = #DD0000 -;highlight.comment = #FF9900 -;highlight.keyword = #007700 -;highlight.bg = #FFFFFF -;highlight.default = #0000BB -;highlight.html = #000000 - -; If enabled, the request will be allowed to complete even if the user aborts -; the request. Consider enabling it if executing long requests, which may end up -; being interrupted by the user or a browser timing out. PHP's default behavior -; is to disable this feature. -; http://www.php.net/manual/en/misc.configuration.php#ini.ignore-user-abort -;ignore_user_abort = On - -; Determines the size of the realpath cache to be used by PHP. This value should -; be increased on systems where PHP opens many files to reflect the quantity of -; the file operations performed. -; http://www.php.net/manual/en/ini.core.php#ini.realpath-cache-size -;realpath_cache_size = 16k - -; Duration of time, in seconds for which to cache realpath information for a given -; file or directory. For systems with rarely changing files, consider increasing this -; value. -; http://www.php.net/manual/en/ini.core.php#ini.realpath-cache-ttl -;realpath_cache_ttl = 120 - -;;;;;;;;;;;;;;;;; -; Miscellaneous ; -;;;;;;;;;;;;;;;;; - -; Decides whether PHP may expose the fact that it is installed on the server -; (e.g. by adding its signature to the Web server header). It is no security -; threat in any way, but it makes it possible to determine whether you use PHP -; on your server or not. -; http://www.php.net/manual/en/ini.core.php#ini.expose-php -expose_php = On - -;;;;;;;;;;;;;;;;;;; -; Resource Limits ; -;;;;;;;;;;;;;;;;;;; - -; Maximum execution time of each script, in seconds -; http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time -max_execution_time = 30 - -; Maximum amount of time each script may spend parsing request data. It's a good -; idea to limit this time on productions servers in order to eliminate unexpectedly -; long running scripts. -; Default Value: -1 (Unlimited) -; Development Value: 60 (60 seconds) -; Production Value: 60 (60 seconds) -; http://www.php.net/manual/en/info.configuration.php#ini.max-input-time -max_input_time = 60 - -; Maximum input variable nesting level -; http://www.php.net/manual/en/info.configuration.php#ini.max-input-nesting-level -;max_input_nesting_level = 64 - -; Maximum amount of memory a script may consume (128MB) -; http://www.php.net/manual/en/ini.core.php#ini.memory-limit -memory_limit = 128M - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Error handling and logging ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; This directive informs PHP of which errors, warnings and notices you would like -; it to take action for. The recommended way of setting values for this -; directive is through the use of the error level constants and bitwise -; operators. The error level constants are below here for convenience as well as -; some common settings and their meanings. -; By default, PHP is set to take action on all errors, notices and warnings EXCEPT -; those related to E_NOTICE and E_STRICT, which together cover best practices and -; recommended coding standards in PHP. For performance reasons, this is the -; recommend error reporting setting. Your production server shouldn't be wasting -; resources complaining about best practices and coding standards. That's what -; development servers and development settings are for. -; Note: The php.ini-development file has this setting as E_ALL | E_STRICT. This -; means it pretty much reports everything which is exactly what you want during -; development and early testing. -; -; Error Level Constants: -; E_ALL - All errors and warnings (includes E_STRICT as of PHP 6.0.0) -; E_ERROR - fatal run-time errors -; E_RECOVERABLE_ERROR - almost fatal run-time errors -; E_WARNING - run-time warnings (non-fatal errors) -; E_PARSE - compile-time parse errors -; E_NOTICE - run-time notices (these are warnings which often result -; from a bug in your code, but it's possible that it was -; intentional (e.g., using an uninitialized variable and -; relying on the fact it's automatically initialized to an -; empty string) -; E_STRICT - run-time notices, enable to have PHP suggest changes -; to your code which will ensure the best interoperability -; and forward compatibility of your code -; E_CORE_ERROR - fatal errors that occur during PHP's initial startup -; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP's -; initial startup -; E_COMPILE_ERROR - fatal compile-time errors -; E_COMPILE_WARNING - compile-time warnings (non-fatal errors) -; E_USER_ERROR - user-generated error message -; E_USER_WARNING - user-generated warning message -; E_USER_NOTICE - user-generated notice message -; E_DEPRECATED - warn about code that will not work in future versions -; of PHP -; E_USER_DEPRECATED - user-generated deprecation warnings -; -; Common Values: -; E_ALL & ~E_NOTICE (Show all errors, except for notices and coding standards warnings.) -; E_ALL & ~E_NOTICE | E_STRICT (Show all errors, except for notices) -; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors) -; E_ALL | E_STRICT (Show all errors, warnings and notices including coding standards.) -; Default Value: E_ALL & ~E_NOTICE -; Development Value: E_ALL | E_STRICT -; Production Value: E_ALL & ~E_DEPRECATED -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-reporting -error_reporting = E_ALL & ~E_DEPRECATED - -; This directive controls whether or not and where PHP will output errors, -; notices and warnings too. Error output is very useful during development, but -; it could be very dangerous in production environments. Depending on the code -; which is triggering the error, sensitive information could potentially leak -; out of your application such as database usernames and passwords or worse. -; It's recommended that errors be logged on production servers rather than -; having the errors sent to STDOUT. -; Possible Values: -; Off = Do not display any errors -; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) -; On or stdout = Display errors to STDOUT -; Default Value: On -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors -display_errors = Off - -; The display of errors which occur during PHP's startup sequence are handled -; separately from display_errors. PHP's default behavior is to suppress those -; errors from clients. Turning the display of startup errors on can be useful in -; debugging configuration problems. But, it's strongly recommended that you -; leave this setting off on production servers. -; Default Value: Off -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-startup-errors -display_startup_errors = Off - -; Besides displaying errors, PHP can also log errors to locations such as a -; server-specific log, STDERR, or a location specified by the error_log -; directive found below. While errors should not be displayed on productions -; servers they should still be monitored and logging is a great way to do that. -; Default Value: Off -; Development Value: On -; Production Value: On -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.log-errors -log_errors = On - -; Set maximum length of log_errors. In error_log information about the source is -; added. The default is 1024 and 0 allows to not apply any maximum length at all. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.log-errors-max-len -log_errors_max_len = 1024 - -; Do not log repeated messages. Repeated errors must occur in same file on same -; line unless ignore_repeated_source is set true. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.ignore-repeated-errors -ignore_repeated_errors = Off - -; Ignore source of message when ignoring repeated messages. When this setting -; is On you will not log errors with repeated messages from different files or -; source lines. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.ignore-repeated-source -ignore_repeated_source = Off - -; If this parameter is set to Off, then memory leaks will not be shown (on -; stdout or in the log). This has only effect in a debug compile, and if -; error reporting includes E_WARNING in the allowed list -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.report-memleaks -report_memleaks = On - -; This setting is on by default. -;report_zend_debug = 0 - -; Store the last error/warning message in $php_errormsg (boolean). Setting this value -; to On can assist in debugging and is appropriate for development servers. It should -; however be disabled on production servers. -; Default Value: Off -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.track-errors -track_errors = Off - -; Turn off normal error reporting and emit XML-RPC error XML -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.xmlrpc-errors -;xmlrpc_errors = 0 - -; An XML-RPC faultCode -;xmlrpc_error_number = 0 - -; When PHP displays or logs an error, it has the capability of inserting html -; links to documentation related to that error. This directive controls whether -; those HTML links appear in error messages or not. For performance and security -; reasons, it's recommended you disable this on production servers. -; Default Value: On -; Development Value: On -; Production value: Off -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.html-errors -html_errors = Off - -; If html_errors is set On PHP produces clickable error messages that direct -; to a page describing the error or function causing the error in detail. -; You can download a copy of the PHP manual from http://www.php.net/docs.php -; and change docref_root to the base URL of your local copy including the -; leading '/'. You must also specify the file extension being used including -; the dot. PHP's default behavior is to leave these settings empty. -; Note: Never use this feature for production boxes. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.docref-root -; Examples -;docref_root = "/phpmanual/" - -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.docref-ext -;docref_ext = .html - -; String to output before an error message. PHP's default behavior is to leave -; this setting blank. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-prepend-string -; Example: -;error_prepend_string = "" - -; String to output after an error message. PHP's default behavior is to leave -; this setting blank. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-append-string -; Example: -;error_append_string = "" - -; Log errors to specified file. PHP's default behavior is to leave this value -; empty. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-log -; Example: -;error_log = php_errors.log -; Log errors to syslog (Event Log on NT, not valid in Windows 95). -;error_log = syslog - -;;;;;;;;;;;;;;;;; -; Data Handling ; -;;;;;;;;;;;;;;;;; - -; Note - track_vars is ALWAYS enabled as of PHP 4.0.3 - -; The separator used in PHP generated URLs to separate arguments. -; PHP's default setting is "&". -; http://www.php.net/manual/en/ini.core.php#ini.arg-separator.output -; Example: -;arg_separator.output = "&" - -; List of separator(s) used by PHP to parse input URLs into variables. -; PHP's default setting is "&". -; NOTE: Every character in this directive is considered as separator! -; http://www.php.net/manual/en/ini.core.php#ini.arg-separator.input -; Example: -;arg_separator.input = ";&" - -; This directive determines which super global arrays are registered when PHP -; starts up. If the register_globals directive is enabled, it also determines -; what order variables are populated into the global space. G,P,C,E & S are -; abbreviations for the following respective super globals: GET, POST, COOKIE, -; ENV and SERVER. There is a performance penalty paid for the registration of -; these arrays and because ENV is not as commonly used as the others, ENV is -; is not recommended on productions servers. You can still get access to -; the environment variables through getenv() should you need to. -; Default Value: "EGPCS" -; Development Value: "GPCS" -; Production Value: "GPCS"; -; http://www.php.net/manual/en/ini.core.php#ini.variables-order -variables_order = "GPCS" - -; This directive determines which super global data (G,P,C,E & S) should -; be registered into the super global array REQUEST. If so, it also determines -; the order in which that data is registered. The values for this directive are -; specified in the same manner as the variables_order directive, EXCEPT one. -; Leaving this value empty will cause PHP to use the value set in the -; variables_order directive. It does not mean it will leave the super globals -; array REQUEST empty. -; Default Value: None -; Development Value: "GP" -; Production Value: "GP" -; http://www.php.net/manual/en/ini.core.php#ini.request-order -request_order = "GP" - -; Whether or not to register the EGPCS variables as global variables. You may -; want to turn this off if you don't want to clutter your scripts' global scope -; with user data. This makes most sense when coupled with track_vars - in which -; case you can access all of the GPC variables through the $HTTP_*_VARS[], -; variables. -; You should do your best to write your scripts so that they do not require -; register_globals to be on; Using form variables as globals can easily lead -; to possible security problems, if the code is not very well thought of. -; http://www.php.net/manual/en/ini.core.php#ini.register-globals -register_globals = Off - -; Determines whether the deprecated long $HTTP_*_VARS type predefined variables -; are registered by PHP or not. As they are deprecated, we obviously don't -; recommend you use them. They are on by default for compatibility reasons but -; they are not recommended on production servers. -; Default Value: On -; Development Value: Off -; Production Value: Off -; http://www.php.net/manual/en/ini.core.php#ini.register-long-arrays -register_long_arrays = Off - -; This directive determines whether PHP registers $argv & $argc each time it -; runs. $argv contains an array of all the arguments passed to PHP when a script -; is invoked. $argc contains an integer representing the number of arguments -; that were passed when the script was invoked. These arrays are extremely -; useful when running scripts from the command line. When this directive is -; enabled, registering these variables consumes CPU cycles and memory each time -; a script is executed. For performance reasons, this feature should be disabled -; on production servers. -; Default Value: On -; Development Value: Off -; Production Value: Off -; http://www.php.net/manual/en/ini.core.php#ini.register-argc-argv -register_argc_argv = Off - -; When enabled, the SERVER and ENV variables are created when they're first -; used (Just In Time) instead of when the script starts. If these variables -; are not used within a script, having this directive on will result in a -; performance gain. The PHP directives register_globals, register_long_arrays, -; and register_argc_argv must be disabled for this directive to have any affect. -; http://www.php.net/manual/en/ini.core.php#ini.auto-globals-jit -auto_globals_jit = On - -; Maximum size of POST data that PHP will accept. -; http://www.php.net/manual/en/ini.core.php#ini.post-max-size -post_max_size = 8M - -; Magic quotes are a preprocessing feature of PHP where PHP will attempt to -; escape any character sequences in GET, POST, COOKIE and ENV data which might -; otherwise corrupt data being placed in resources such as databases before -; making that data available to you. Because of character encoding issues and -; non-standard SQL implementations across many databases, it's not currently -; possible for this feature to be 100% accurate. PHP's default behavior is to -; enable the feature. We strongly recommend you use the escaping mechanisms -; designed specifically for the database your using instead of relying on this -; feature. Also note, this feature has been deprecated as of PHP 5.3.0 and is -; scheduled for removal in PHP 6. -; Default Value: On -; Development Value: Off -; Production Value: Off -; http://www.php.net/manual/en/info.configuration.php#ini.magic-quotes-gpc -magic_quotes_gpc = Off - -; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc. -; http://www.php.net/manual/en/info.configuration.php#ini.magic-quotes-runtime -magic_quotes_runtime = Off - -; Use Sybase-style magic quotes (escape ' with '' instead of \'). -; http://www.php.net/manual/en/sybase.configuration.php#ini.magic-quotes-sybase -magic_quotes_sybase = Off - -; Automatically add files before PHP document. -; http://www.php.net/manual/en/ini.core.php#ini.auto-prepend-file -auto_prepend_file = - -; Automatically add files after PHP document. -; http://www.php.net/manual/en/ini.core.php#ini.auto-append-file -auto_append_file = - -; As of 4.0b4, PHP always outputs a character encoding by default in -; the Content-type: header. To disable sending of the charset, simply -; set it to be empty. -; -; PHP's built-in default is text/html -; http://www.php.net/manual/en/ini.core.php#ini.default-mimetype -default_mimetype = "text/html" - -; PHP's default character set is set to empty. -; http://www.php.net/manual/en/ini.core.php#ini.default-charset -;default_charset = "iso-8859-1" - -; Always populate the $HTTP_RAW_POST_DATA variable. PHP's default behavior is -; to disable this feature. -; http://www.php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data -;always_populate_raw_post_data = On - -;;;;;;;;;;;;;;;;;;;;;;;;; -; Paths and Directories ; -;;;;;;;;;;;;;;;;;;;;;;;;; - -; UNIX: "/path1:/path2" -;include_path = ".:/php/includes" -; -; Windows: "\path1;\path2" -;include_path = ".;c:\php\includes" -; -; PHP's default setting for include_path is ".;/path/to/php/pear" -; http://www.php.net/manual/en/ini.core.php#ini.include-path - -; The root of the PHP pages, used only if nonempty. -; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root -; if you are running php as a CGI under any web server (other than IIS) -; see documentation for security issues. The alternate is to use the -; cgi.force_redirect configuration below -; http://www.php.net/manual/en/ini.core.php#ini.doc-root -doc_root = - -; The directory under which PHP opens the script using /~username used only -; if nonempty. -; http://www.php.net/manual/en/ini.core.php#ini.user-dir -user_dir = - -; Directory in which the loadable extensions (modules) reside. -; http://www.php.net/manual/en/ini.core.php#ini.extension-dir -; extension_dir = "./" - -; Whether or not to enable the dl() function. The dl() function does NOT work -; properly in multithreaded servers, such as IIS or Zeus, and is automatically -; disabled on them. -; http://www.php.net/manual/en/info.configuration.php#ini.enable-dl -enable_dl = Off - -; cgi.force_redirect is necessary to provide security running PHP as a CGI under -; most web servers. Left undefined, PHP turns this on by default. You can -; turn it off here AT YOUR OWN RISK -; **You CAN safely turn this off for IIS, in fact, you MUST.** -; http://www.php.net/manual/en/ini.core.php#ini.cgi.force-redirect -;cgi.force_redirect = 1 - -; if cgi.nph is enabled it will force cgi to always sent Status: 200 with -; every request. PHP's default behavior is to disable this feature. -;cgi.nph = 1 - -; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape -; (iPlanet) web servers, you MAY need to set an environment variable name that PHP -; will look for to know it is OK to continue execution. Setting this variable MAY -; cause security issues, KNOW WHAT YOU ARE DOING FIRST. -; http://www.php.net/manual/en/ini.core.php#ini.cgi.redirect-status-env -;cgi.redirect_status_env = ; - -; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's -; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok -; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting -; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting -; of zero causes PHP to behave as before. Default is 1. You should fix your scripts -; to use SCRIPT_FILENAME rather than PATH_TRANSLATED. -; http://www.php.net/manual/en/ini.core.php#ini.cgi.fix-pathinfo -cgi.fix_pathinfo=1 - -; FastCGI under IIS (on WINNT based OS) supports the ability to impersonate -; security tokens of the calling client. This allows IIS to define the -; security context that the request runs under. mod_fastcgi under Apache -; does not currently support this feature (03/17/2002) -; Set to 1 if running under IIS. Default is zero. -; http://www.php.net/manual/en/ini.core.php#ini.fastcgi.impersonate -;fastcgi.impersonate = 1; - -; Disable logging through FastCGI connection. PHP's default behavior is to enable -; this feature. -;fastcgi.logging = 0 - -; cgi.rfc2616_headers configuration option tells PHP what type of headers to -; use when sending HTTP response code. If it's set 0 PHP sends Status: header that -; is supported by Apache. When this option is set to 1 PHP will send -; RFC2616 compliant header. -; Default is zero. -; http://www.php.net/manual/en/ini.core.php#ini.cgi.rfc2616-headers -;cgi.rfc2616_headers = 0 - -;;;;;;;;;;;;;;;; -; File Uploads ; -;;;;;;;;;;;;;;;; - -; Whether to allow HTTP file uploads. -; http://www.php.net/manual/en/ini.core.php#ini.file-uploads -file_uploads = On - -; Temporary directory for HTTP uploaded files (will use system default if not -; specified). -; http://www.php.net/manual/en/ini.core.php#ini.upload-tmp-dir -;upload_tmp_dir = - -; Maximum allowed size for uploaded files. -; http://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize -upload_max_filesize = 2M - -;;;;;;;;;;;;;;;;;; -; Fopen wrappers ; -;;;;;;;;;;;;;;;;;; - -; Whether to allow the treatment of URLs (like http:// or ftp://) as files. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen -allow_url_fopen = On - -; Whether to allow include/require to open URLs (like http:// or ftp://) as files. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-include -allow_url_include = Off - -; Define the anonymous ftp password (your email address). PHP's default setting -; for this is empty. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.from -;from="john@doe.com" - -; Define the User-Agent string. PHP's default setting for this is empty. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.user-agent -;user_agent="PHP" - -; Default timeout for socket based streams (seconds) -; http://www.php.net/manual/en/filesystem.configuration.php#ini.default-socket-timeout -default_socket_timeout = 60 - -; If your scripts have to deal with files from Macintosh systems, -; or you are running on a Mac and need to deal with files from -; unix or win32 systems, setting this flag will cause PHP to -; automatically detect the EOL character in those files so that -; fgets() and file() will work regardless of the source of the file. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.auto-detect-line-endings -;auto_detect_line_endings = Off - -;;;;;;;;;;;;;;;;;;;;;; -; Dynamic Extensions ; -;;;;;;;;;;;;;;;;;;;;;; - -; If you wish to have an extension loaded automatically, use the following -; syntax: -; -; extension=modulename.extension -; -; For example -; -; extension=msql.so -; -; ... or with a path: -; -; extension=/path/to/extension/msql.so -; -; If you only provide the name of the extension, PHP will look for it in its -; default extension directory. - -;;;; -; Note: packaged extension modules are now loaded via the .ini files -; found in the directory /etc/php.d; these are loaded by default. -;;;; - - -;;;;;;;;;;;;;;;;;;; -; Module Settings ; -;;;;;;;;;;;;;;;;;;; - -[Date] -; Defines the default timezone used by the date functions -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone -;date.timezone = - -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.default-latitude -;date.default_latitude = 31.7667 - -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.default-longitude -;date.default_longitude = 35.2333 - -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.sunrise-zenith -;date.sunrise_zenith = 90.583333 - -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.sunset-zenith -;date.sunset_zenith = 90.583333 - -[filter] -; http://www.php.net/manual/en/filter.configuration.php#ini.filter.default -;filter.default = unsafe_raw - -; http://www.php.net/manual/en/filter.configuration.php#ini.filter.default-flags -;filter.default_flags = - -[iconv] -;iconv.input_encoding = ISO-8859-1 -;iconv.internal_encoding = ISO-8859-1 -;iconv.output_encoding = ISO-8859-1 - -[intl] -;intl.default_locale = - -[sqlite] -; http://www.php.net/manual/en/sqlite.configuration.php#ini.sqlite.assoc-case -;sqlite.assoc_case = 0 - -[sqlite3] -;sqlite3.extension_dir = - -[Pcre] -;PCRE library backtracking limit. -; http://www.php.net/manual/en/pcre.configuration.php#ini.pcre.backtrack-limit -;pcre.backtrack_limit=100000 - -;PCRE library recursion limit. -;Please note that if you set this value to a high number you may consume all -;the available process stack and eventually crash PHP (due to reaching the -;stack size limit imposed by the Operating System). -; http://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit -;pcre.recursion_limit=100000 - -[Pdo] -; Whether to pool ODBC connections. Can be one of "strict", "relaxed" or "off" -; http://www.php.net/manual/en/ref.pdo-odbc.php#ini.pdo-odbc.connection-pooling -;pdo_odbc.connection_pooling=strict - -[Phar] -; http://www.php.net/manual/en/phar.configuration.php#ini.phar.readonly -;phar.readonly = On - -; http://www.php.net/manual/en/phar.configuration.php#ini.phar.require-hash -;phar.require_hash = On - -;phar.cache_list = - -[Syslog] -; Whether or not to define the various syslog variables (e.g. $LOG_PID, -; $LOG_CRON, etc.). Turning it off is a good idea performance-wise. In -; runtime, you can define these variables by calling define_syslog_variables(). -; http://www.php.net/manual/en/network.configuration.php#ini.define-syslog-variables -define_syslog_variables = Off - -[mail function] -; For Win32 only. -; http://www.php.net/manual/en/mail.configuration.php#ini.smtp -SMTP = localhost -; http://www.php.net/manual/en/mail.configuration.php#ini.smtp-port -smtp_port = 25 - -; For Win32 only. -; http://www.php.net/manual/en/mail.configuration.php#ini.sendmail-from -;sendmail_from = me@example.com - -; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). -; http://www.php.net/manual/en/mail.configuration.php#ini.sendmail-path -sendmail_path = /usr/sbin/sendmail -t -i - -; Force the addition of the specified parameters to be passed as extra parameters -; to the sendmail binary. These parameters will always replace the value of -; the 5th parameter to mail(), even in safe mode. -;mail.force_extra_parameters = - -; Add X-PHP-Originaiting-Script: that will include uid of the script followed by the filename -mail.add_x_header = On - -; Log all mail() calls including the full path of the script, line #, to address and headers -;mail.log = - -[SQL] -; http://www.php.net/manual/en/ini.core.php#ini.sql.safe-mode -sql.safe_mode = Off - -[ODBC] -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.default-db -;odbc.default_db = Not yet implemented - -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.default-user -;odbc.default_user = Not yet implemented - -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.default-pw -;odbc.default_pw = Not yet implemented - -; Allow or prevent persistent links. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.allow-persistent -odbc.allow_persistent = On - -; Check that a connection is still valid before reuse. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.check-persistent -odbc.check_persistent = On - -; Maximum number of persistent links. -1 means no limit. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.max-persistent -odbc.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.max-links -odbc.max_links = -1 - -; Handling of LONG fields. Returns number of bytes to variables. 0 means -; passthru. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.defaultlrl -odbc.defaultlrl = 4096 - -; Handling of binary data. 0 means passthru, 1 return as is, 2 convert to char. -; See the documentation on odbc_binmode and odbc_longreadlen for an explanation -; of uodbc.defaultlrl and uodbc.defaultbinmode -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.defaultbinmode -odbc.defaultbinmode = 1 - -;birdstep.max_links = -1 - -[MySQL] -; Allow or prevent persistent links. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.allow-persistent -mysql.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.max-persistent -mysql.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.max-links -mysql.max_links = -1 - -; Default port number for mysql_connect(). If unset, mysql_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the -; compile-time value defined MYSQL_PORT (in that order). Win32 will only look -; at MYSQL_PORT. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-port -mysql.default_port = - -; Default socket name for local MySQL connects. If empty, uses the built-in -; MySQL defaults. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-socket -mysql.default_socket = - -; Default host for mysql_connect() (doesn't apply in safe mode). -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-host -mysql.default_host = - -; Default user for mysql_connect() (doesn't apply in safe mode). -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-user -mysql.default_user = - -; Default password for mysql_connect() (doesn't apply in safe mode). -; Note that this is generally a *bad* idea to store passwords in this file. -; *Any* user with PHP access can run 'echo get_cfg_var("mysql.default_password") -; and reveal this password! And of course, any users with read access to this -; file will be able to reveal the password as well. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-password -mysql.default_password = - -; Maximum time (in seconds) for connect timeout. -1 means no limit -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.connect-timeout -mysql.connect_timeout = 60 - -; Trace mode. When trace_mode is active (=On), warnings for table/index scans and -; SQL-Errors will be displayed. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.trace-mode -mysql.trace_mode = Off - -[MySQLi] - -; Maximum number of links. -1 means no limit. -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.max-links -mysqli.max_links = -1 - -; Default port number for mysqli_connect(). If unset, mysqli_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the -; compile-time value defined MYSQL_PORT (in that order). Win32 will only look -; at MYSQL_PORT. -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-port -mysqli.default_port = 3306 - -; Default socket name for local MySQL connects. If empty, uses the built-in -; MySQL defaults. -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-socket -mysqli.default_socket = - -; Default host for mysql_connect() (doesn't apply in safe mode). -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-host -mysqli.default_host = - -; Default user for mysql_connect() (doesn't apply in safe mode). -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-user -mysqli.default_user = - -; Default password for mysqli_connect() (doesn't apply in safe mode). -; Note that this is generally a *bad* idea to store passwords in this file. -; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw") -; and reveal this password! And of course, any users with read access to this -; file will be able to reveal the password as well. -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-pw -mysqli.default_pw = - -; Allow or prevent reconnect -mysqli.reconnect = Off - -[PostgresSQL] -; Allow or prevent persistent links. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.allow-persistent -pgsql.allow_persistent = On - -; Detect broken persistent links always with pg_pconnect(). -; Auto reset feature requires a little overheads. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.auto-reset-persistent -pgsql.auto_reset_persistent = Off - -; Maximum number of persistent links. -1 means no limit. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.max-persistent -pgsql.max_persistent = -1 - -; Maximum number of links (persistent+non persistent). -1 means no limit. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.max-links -pgsql.max_links = -1 - -; Ignore PostgreSQL backends Notice message or not. -; Notice message logging require a little overheads. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.ignore-notice -pgsql.ignore_notice = 0 - -; Log PostgreSQL backends Noitce message or not. -; Unless pgsql.ignore_notice=0, module cannot log notice message. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.log-notice -pgsql.log_notice = 0 - -[Sybase-CT] -; Allow or prevent persistent links. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.allow-persistent -sybct.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.max-persistent -sybct.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.max-links -sybct.max_links = -1 - -; Minimum server message severity to display. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.min-server-severity -sybct.min_server_severity = 10 - -; Minimum client message severity to display. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.min-client-severity -sybct.min_client_severity = 10 - -; Set per-context timeout -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.timeout -;sybct.timeout= - -;sybct.packet_size - -[bcmath] -; Number of decimal digits for all bcmath functions. -; http://www.php.net/manual/en/bc.configuration.php#ini.bcmath.scale -bcmath.scale = 0 - -[browscap] -; http://www.php.net/manual/en/misc.configuration.php#ini.browscap -;browscap = extra/browscap.ini - -[Session] -; Handler used to store/retrieve data. -; http://www.php.net/manual/en/session.configuration.php#ini.session.save-handler -session.save_handler = files - -; Argument passed to save_handler. In the case of files, this is the path -; where data files are stored. Note: Windows users have to change this -; variable in order to use PHP's session functions. -; -; As of PHP 4.0.1, you can define the path as: -; -; session.save_path = "N;/path" -; -; where N is an integer. Instead of storing all the session files in -; /path, what this will do is use subdirectories N-levels deep, and -; store the session data in those directories. This is useful if you -; or your OS have problems with lots of files in one directory, and is -; a more efficient layout for servers that handle lots of sessions. -; -; NOTE 1: PHP will not create this directory structure automatically. -; You can use the script in the ext/session dir for that purpose. -; NOTE 2: See the section on garbage collection below if you choose to -; use subdirectories for session storage -; -; The file storage module creates files using mode 600 by default. -; You can change that by using -; -; session.save_path = "N;MODE;/path" -; -; where MODE is the octal representation of the mode. Note that this -; does not overwrite the process's umask. -; http://www.php.net/manual/en/session.configuration.php#ini.session.save-path -session.save_path = "/tmp" - -; Whether to use cookies. -; http://www.php.net/manual/en/session.configuration.php#ini.session.use-cookies -session.use_cookies = 1 - -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-secure -;session.cookie_secure = - -; This option forces PHP to fetch and use a cookie for storing and maintaining -; the session id. We encourage this operation as it's very helpful in combatting -; session hijacking when not specifying and managing your own session id. It is -; not the end all be all of session hijacking defense, but it's a good start. -; http://www.php.net/manual/en/session.configuration.php#ini.session.use-only-cookies -session.use_only_cookies = 1 - -; Name of the session (used as cookie name). -; http://www.php.net/manual/en/session.configuration.php#ini.session.name -session.name = PHPSESSID - -; Initialize session on request startup. -; http://www.php.net/manual/en/session.configuration.php#ini.session.auto-start -session.auto_start = 0 - -; Lifetime in seconds of cookie or, if 0, until browser is restarted. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime -session.cookie_lifetime = 0 - -; The path for which the cookie is valid. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-path -session.cookie_path = / - -; The domain for which the cookie is valid. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-domain -session.cookie_domain = - -; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-httponly -session.cookie_httponly = - -; Handler used to serialize data. php is the standard serializer of PHP. -; http://www.php.net/manual/en/session.configuration.php#ini.session.serialize-handler -session.serialize_handler = php - -; Defines the probability that the 'garbage collection' process is started -; on every session initialization. The probability is calculated by using -; gc_probability/gc_divisor. Where session.gc_probability is the numerator -; and gc_divisor is the denominator in the equation. Setting this value to 1 -; when the session.gc_divisor value is 100 will give you approximately a 1% chance -; the gc will run on any give request. -; Default Value: 1 -; Development Value: 1 -; Production Value: 1 -; http://www.php.net/manual/en/session.configuration.php#ini.session.gc-probability -session.gc_probability = 1 - -; Defines the probability that the 'garbage collection' process is started on every -; session initialization. The probability is calculated by using the following equation: -; gc_probability/gc_divisor. Where session.gc_probability is the numerator and -; session.gc_divisor is the denominator in the equation. Setting this value to 1 -; when the session.gc_divisor value is 100 will give you approximately a 1% chance -; the gc will run on any give request. Increasing this value to 1000 will give you -; a 0.1% chance the gc will run on any give request. For high volume production servers, -; this is a more efficient approach. -; Default Value: 100 -; Development Value: 1000 -; Production Value: 1000 -; http://www.php.net/manual/en/session.configuration.php#ini.session.gc-divisor -session.gc_divisor = 1000 - -; After this number of seconds, stored data will be seen as 'garbage' and -; cleaned up by the garbage collection process. -; http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime -session.gc_maxlifetime = 1440 - -; NOTE: If you are using the subdirectory option for storing session files -; (see session.save_path above), then garbage collection does *not* -; happen automatically. You will need to do your own garbage -; collection through a shell script, cron entry, or some other method. -; For example, the following script would is the equivalent of -; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): -; cd /path/to/sessions; find -cmin +24 | xargs rm - -; PHP 4.2 and less have an undocumented feature/bug that allows you to -; to initialize a session variable in the global scope, even when register_globals -; is disabled. PHP 4.3 and later will warn you, if this feature is used. -; You can disable the feature and the warning separately. At this time, -; the warning is only displayed, if bug_compat_42 is enabled. This feature -; introduces some serious security problems if not handled correctly. It's -; recommended that you do not use this feature on production servers. But you -; should enable this on development servers and enable the warning as well. If you -; do not enable the feature on development servers, you won't be warned when it's -; used and debugging errors caused by this can be difficult to track down. -; Default Value: On -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/session.configuration.php#ini.session.bug-compat-42 -session.bug_compat_42 = Off - -; This setting controls whether or not you are warned by PHP when initializing a -; session value into the global space. session.bug_compat_42 must be enabled before -; these warnings can be issued by PHP. See the directive above for more information. -; Default Value: On -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/session.configuration.php#ini.session.bug-compat-warn -session.bug_compat_warn = Off - -; Check HTTP Referer to invalidate externally stored URLs containing ids. -; HTTP_REFERER has to contain this substring for the session to be -; considered as valid. -; http://www.php.net/manual/en/session.configuration.php#ini.session.referer-check -session.referer_check = - -; How many bytes to read from the file. -; http://www.php.net/manual/en/session.configuration.php#ini.session.entropy-length -session.entropy_length = 0 - -; Specified here to create the session id. -; http://www.php.net/manual/en/session.configuration.php#ini.session.entropy-file -;session.entropy_file = /dev/urandom -session.entropy_file = - -; http://www.php.net/manual/en/session.configuration.php#ini.session.entropy-length -;session.entropy_length = 16 - -; Set to {nocache,private,public,} to determine HTTP caching aspects -; or leave this empty to avoid sending anti-caching headers. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cache-limiter -session.cache_limiter = nocache - -; Document expires after n minutes. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cache-expire -session.cache_expire = 180 - -; trans sid support is disabled by default. -; Use of trans sid may risk your users security. -; Use this option with caution. -; - User may send URL contains active session ID -; to other person via. email/irc/etc. -; - URL that contains active session ID may be stored -; in publically accessible computer. -; - User may access your site with the same session ID -; always using URL stored in browser's history or bookmarks. -; http://www.php.net/manual/en/session.configuration.php#ini.session.use-trans-sid -session.use_trans_sid = 0 - -; Select a hash function for use in generating session ids. -; Possible Values -; 0 (MD5 128 bits) -; 1 (SHA-1 160 bits) -; http://www.php.net/manual/en/session.configuration.php#ini.session.hash-function -session.hash_function = 0 - -; Define how many bits are stored in each character when converting -; the binary hash data to something readable. -; Possible values: -; 4 (4 bits: 0-9, a-f) -; 5 (5 bits: 0-9, a-v) -; 6 (6 bits: 0-9, a-z, A-Z, "-", ",") -; Default Value: 4 -; Development Value: 5 -; Production Value: 5 -; http://www.php.net/manual/en/session.configuration.php#ini.session.hash-bits-per-character -session.hash_bits_per_character = 5 - -; The URL rewriter will look for URLs in a defined set of HTML tags. -; form/fieldset are special; if you include them here, the rewriter will -; add a hidden field with the info which is otherwise appended -; to URLs. If you want XHTML conformity, remove the form entry. -; Note that all valid entries require a "=", even if no value follows. -; Default Value: "a=href,area=href,frame=src,form=,fieldset=" -; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry" -; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry" -; http://www.php.net/manual/en/session.configuration.php#ini.url-rewriter.tags -url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" - -[MSSQL] -; Allow or prevent persistent links. -mssql.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -mssql.max_persistent = -1 - -; Maximum number of links (persistent+non persistent). -1 means no limit. -mssql.max_links = -1 - -; Minimum error severity to display. -mssql.min_error_severity = 10 - -; Minimum message severity to display. -mssql.min_message_severity = 10 - -; Compatibility mode with old versions of PHP 3.0. -mssql.compatability_mode = Off - -; Connect timeout -;mssql.connect_timeout = 5 - -; Query timeout -;mssql.timeout = 60 - -; Valid range 0 - 2147483647. Default = 4096. -;mssql.textlimit = 4096 - -; Valid range 0 - 2147483647. Default = 4096. -;mssql.textsize = 4096 - -; Limits the number of records in each batch. 0 = all records in one batch. -;mssql.batchsize = 0 - -; Specify how datetime and datetim4 columns are returned -; On => Returns data converted to SQL server settings -; Off => Returns values as YYYY-MM-DD hh:mm:ss -;mssql.datetimeconvert = On - -; Use NT authentication when connecting to the server -mssql.secure_connection = Off - -; Specify max number of processes. -1 = library default -; msdlib defaults to 25 -; FreeTDS defaults to 4096 -;mssql.max_procs = -1 - -; Specify client character set. -; If empty or not set the client charset from freetds.comf is used -; This is only used when compiled with FreeTDS -;mssql.charset = "ISO-8859-1" - -[Assertion] -; Assert(expr); active by default. -; http://www.php.net/manual/en/info.configuration.php#ini.assert.active -;assert.active = On - -; Issue a PHP warning for each failed assertion. -; http://www.php.net/manual/en/info.configuration.php#ini.assert.warning -;assert.warning = On - -; Don't bail out by default. -; http://www.php.net/manual/en/info.configuration.php#ini.assert.bail -;assert.bail = Off - -; User-function to be called if an assertion fails. -; http://www.php.net/manual/en/info.configuration.php#ini.assert.callback -;assert.callback = 0 - -; Eval the expression with current error_reporting(). Set to true if you want -; error_reporting(0) around the eval(). -; http://www.php.net/manual/en/info.configuration.php#ini.assert.quiet-eval -;assert.quiet_eval = 0 - -[COM] -; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs -; http://www.php.net/manual/en/com.configuration.php#ini.com.typelib-file -;com.typelib_file = - -; allow Distributed-COM calls -; http://www.php.net/manual/en/com.configuration.php#ini.com.allow-dcom -;com.allow_dcom = true - -; autoregister constants of a components typlib on com_load() -; http://www.php.net/manual/en/com.configuration.php#ini.com.autoregister-typelib -;com.autoregister_typelib = true - -; register constants casesensitive -; http://www.php.net/manual/en/com.configuration.php#ini.com.autoregister-casesensitive -;com.autoregister_casesensitive = false - -; show warnings on duplicate constant registrations -; http://www.php.net/manual/en/com.configuration.php#ini.com.autoregister-verbose -;com.autoregister_verbose = true - -[mbstring] -; language for internal character representation. -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.language -;mbstring.language = Japanese - -; internal/script encoding. -; Some encoding cannot work as internal encoding. -; (e.g. SJIS, BIG5, ISO-2022-*) -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.internal-encoding -;mbstring.internal_encoding = EUC-JP - -; http input encoding. -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.http-input -;mbstring.http_input = auto - -; http output encoding. mb_output_handler must be -; registered as output buffer to function -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.http-output -;mbstring.http_output = SJIS - -; enable automatic encoding translation according to -; mbstring.internal_encoding setting. Input chars are -; converted to internal encoding by setting this to On. -; Note: Do _not_ use automatic encoding translation for -; portable libs/applications. -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.encoding-translation -;mbstring.encoding_translation = Off - -; automatic encoding detection order. -; auto means -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.detect-order -;mbstring.detect_order = auto - -; substitute_character used when character cannot be converted -; one from another -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.substitute-character -;mbstring.substitute_character = none; - -; overload(replace) single byte functions by mbstring functions. -; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(), -; etc. Possible values are 0,1,2,4 or combination of them. -; For example, 7 for overload everything. -; 0: No overload -; 1: Overload mail() function -; 2: Overload str*() functions -; 4: Overload ereg*() functions -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.func-overload -;mbstring.func_overload = 0 - -; enable strict encoding detection. -;mbstring.strict_detection = Off - -; This directive specifies the regex pattern of content types for which mb_output_handler() -; is activated. -; Default: mbstring.http_output_conv_mimetype=^(text/|application/xhtml\+xml) -;mbstring.http_output_conv_mimetype= - -[gd] -; Tell the jpeg decode to ignore warnings and try to create -; a gd image. The warning will then be displayed as notices -; disabled by default -; http://www.php.net/manual/en/image.configuration.php#ini.image.jpeg-ignore-warning -;gd.jpeg_ignore_warning = 0 - -[exif] -; Exif UNICODE user comments are handled as UCS-2BE/UCS-2LE and JIS as JIS. -; With mbstring support this will automatically be converted into the encoding -; given by corresponding encode setting. When empty mbstring.internal_encoding -; is used. For the decode settings you can distinguish between motorola and -; intel byte order. A decode setting cannot be empty. -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.encode-unicode -;exif.encode_unicode = ISO-8859-15 - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.decode-unicode-motorola -;exif.decode_unicode_motorola = UCS-2BE - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.decode-unicode-intel -;exif.decode_unicode_intel = UCS-2LE - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.encode-jis -;exif.encode_jis = - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.decode-jis-motorola -;exif.decode_jis_motorola = JIS - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.decode-jis-intel -;exif.decode_jis_intel = JIS - -[Tidy] -; The path to a default tidy configuration file to use when using tidy -; http://www.php.net/manual/en/tidy.configuration.php#ini.tidy.default-config -;tidy.default_config = /usr/local/lib/php/default.tcfg - -; Should tidy clean and repair output automatically? -; WARNING: Do not use this option if you are generating non-html content -; such as dynamic images -; http://www.php.net/manual/en/tidy.configuration.php#ini.tidy.clean-output -tidy.clean_output = Off - -[soap] -; Enables or disables WSDL caching feature. -; http://www.php.net/manual/en/soap.configuration.php#ini.soap.wsdl-cache-enabled -soap.wsdl_cache_enabled=1 - -; Sets the directory name where SOAP extension will put cache files. -; http://www.php.net/manual/en/soap.configuration.php#ini.soap.wsdl-cache-dir -soap.wsdl_cache_dir="/tmp" - -; (time to live) Sets the number of second while cached file will be used -; instead of original one. -; http://www.php.net/manual/en/soap.configuration.php#ini.soap.wsdl-cache-ttl -soap.wsdl_cache_ttl=86400 - -[sysvshm] -; A default size of the shared memory segment -;sysvshm.init_mem = 10000 - - -; Local Variables: -; tab-width: 4 -; End: - --- a/aws/postgresql.conf +++ /dev/null @@ -1,502 +1,1 @@ -# ----------------------------- -# 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 - --- a/aws/rc.local +++ /dev/null @@ -1,14 +1,1 @@ -#!/bin/sh -# -# This script will be executed *after* all the other init scripts. -# You can put your own initialization stuff in here if you don't -# want to do the full Sys V style init stuff. -touch /var/lock/subsys/local -cd /tmp -rm -rfv busui -git clone http://maxious.lambdacomplex.org/busui/git -sh busui/aws/awsStartup.sh - - - --- a/css/jquery-ui-1.8.12.custom.css +++ b/css/jquery-ui-1.8.12.custom.css @@ -31,7 +31,7 @@ ----------------------------------*/ /* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } +.jqui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } /* Misc visuals @@ -89,7 +89,7 @@ ----------------------------------*/ /* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.jqui-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); } --- a/css/jquery.mobile-1.0b1.css +++ /dev/null @@ -1,1662 +1,1 @@ -/*! - * jQuery Mobile v1.0b1 - * http://jquerymobile.com/ - * - * Copyright 2010, jQuery Project - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - */ -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. -* Note: Code is in draft form and is subject to change -*/ - -/* A ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-a { - border: 1px solid #2A2A2A; - background: #111111; - color: #ffffff; - font-weight: bold; - text-shadow: 0 -1px 1px #000000; - background-image: -moz-linear-gradient(top, - #3c3c3c, - #111111); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #3c3c3c), - color-stop(1, #111111)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#3c3c3c', EndColorStr='#111111')"; -} -.ui-bar-a, -.ui-bar-a input, -.ui-bar-a select, -.ui-bar-a textarea, -.ui-bar-a button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-bar-a .ui-link-inherit { - color: #fff; -} -.ui-bar-a .ui-link { - color: #7cc4e7; - font-weight: bold; -} -.ui-body-a { - border: 1px solid #2A2A2A; - background: #222222; - color: #fff; - text-shadow: 0 1px 0 #000; - font-weight: normal; - background-image: -moz-linear-gradient(top, - #666666, - #222222); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #666666), - color-stop(1, #222222)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#666666', EndColorStr='#222222)')"; -} -.ui-body-a, -.ui-body-a input, -.ui-body-a select, -.ui-body-a textarea, -.ui-body-a button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-a .ui-link-inherit { - color: #fff; -} -.ui-body-a .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-br { - border-bottom: rgb(130,130,130); - border-bottom: rgba(130,130,130,.3); - border-bottom-width: 1px; - border-bottom-style: solid; -} -.ui-btn-up-a { - border: 1px solid #222; - background: #333333; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #000; - background-image: -moz-linear-gradient(top, - #555555, - #333333); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #555555), - color-stop(1, #333333)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#555555', EndColorStr='#333333')"; -} -.ui-btn-up-a a.ui-link-inherit { - color: #fff; -} -.ui-btn-hover-a { - border: 1px solid #000; - background: #444444; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #000; - background-image: -moz-linear-gradient(top, - #666666, - #444444); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #666666), - color-stop(1, #444444)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#666666', EndColorStr='#444444')"; -} -.ui-btn-hover-a a.ui-link-inherit { - color: #fff; -} -.ui-btn-down-a { - border: 1px solid #000; - background: #3d3d3d; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #000; - background-image: -moz-linear-gradient(top, - #333333, - #5a5a5a); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #333333), - color-stop(1, #5a5a5a)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#333333', EndColorStr='#5a5a5a')"; -} -.ui-btn-down-a a.ui-link-inherit { - color: #fff; -} -.ui-btn-up-a, -.ui-btn-hover-a, -.ui-btn-down-a { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* B ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-b { - border: 1px solid #456f9a; - background: #5e87b0; - color: #fff; - font-weight: bold; - text-shadow: 0 -1px 1px #254f7a; - background-image: -moz-linear-gradient(top, - #81a8ce, - #5e87b0); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #81a8ce), - color-stop(1, #5e87b0)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#81a8ce', EndColorStr='#5e87b0')"; -} -.ui-bar-b, -.ui-bar-b input, -.ui-bar-b select, -.ui-bar-b textarea, -.ui-bar-b button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-bar-b .ui-link-inherit { - color: #fff; -} -.ui-bar-b .ui-link { - color: #7cc4e7; - font-weight: bold; -} - -.ui-body-b { - border: 1px solid #C6C6C6; - background: #cccccc; - color: #333333; - text-shadow: 0 1px 0 #fff; - font-weight: normal; - background-image: -moz-linear-gradient(top, - #e6e6e6, - #cccccc); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #e6e6e6), - color-stop(1, #cccccc)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#e6e6e6', EndColorStr='#cccccc')"; -} -.ui-body-b, -.ui-body-b input, -.ui-body-b select, -.ui-body-b textarea, -.ui-body-b button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-b .ui-link-inherit { - color: #333333; -} -.ui-body-b .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-btn-up-b { - border: 1px solid #145072; - background: #2567ab; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #145072; - background-image: -moz-linear-gradient(top, - #4e89c5, - #2567ab); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #5f9cc5), - color-stop(1, #396b9e)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#4e89c5', EndColorStr='#2567ab')"; -} -.ui-btn-up-b a.ui-link-inherit { - color: #fff; -} -.ui-btn-hover-b { - border: 1px solid #00516e; - background: #4b88b6; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #014D68; - background-image: -moz-linear-gradient(top, - #72b0d4, - #4b88b6); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #72b0d4), - color-stop(1, #4b88b6)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#72b0d4', EndColorStr='#4b88b6')"; -} -.ui-btn-hover-b a.ui-link-inherit { - color: #fff; -} -.ui-btn-down-b { - border: 1px solid #225377; - background: #4e89c5; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #225377; - background-image: -moz-linear-gradient(top, - #396b9e, - #4e89c5); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #396b9e), - color-stop(1, #4e89c5)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#396b9e', EndColorStr='#4e89c5')"; -} -.ui-btn-down-b a.ui-link-inherit { - color: #fff; -} -.ui-btn-up-b, -.ui-btn-hover-b, -.ui-btn-down-b { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* C ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-c { - border: 1px solid #B3B3B3; - background: #e9eaeb; - color: #3E3E3E; - font-weight: bold; - text-shadow: 0 1px 1px #fff; - background-image: -moz-linear-gradient(top, - #f0f0f0, - #e9eaeb); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #f0f0f0), - color-stop(1, #e9eaeb)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#f0f0f0', EndColorStr='#e9eaeb')"; -} -.ui-bar-c, -.ui-bar-c input, -.ui-bar-c select, -.ui-bar-c textarea, -.ui-bar-c button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-c { - border: 1px solid #B3B3B3; - color: #333333; - text-shadow: 0 1px 0 #fff; - background: #f0f0f0; - background-image: -moz-linear-gradient(top, - #eeeeee, - #dddddd); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #eeeeee), - color-stop(1, #dddddd)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#dddddd')"; -} -.ui-body-c, -.ui-body-c input, -.ui-body-c select, -.ui-body-c textarea, -.ui-body-c button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-c .ui-link-inherit { - color: #333333; -} -.ui-body-c .ui-link { - color: #2489CE; - font-weight: bold; -} - -.ui-btn-up-c { - border: 1px solid #ccc; - background: #eee; - font-weight: bold; - color: #444; - text-shadow: 0 1px 1px #f6f6f6; - background-image: -moz-linear-gradient(top, - #fefefe, - #eeeeee); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fdfdfd), - color-stop(1, #eeeeee)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fdfdfd', EndColorStr='#eeeeee')"; -} -.ui-btn-up-c a.ui-link-inherit { - color: #2F3E46; -} - -.ui-btn-hover-c { - border: 1px solid #bbb; - background: #dadada; - font-weight: bold; - color: #101010; - text-shadow: 0 1px 1px #fff; - background-image: -moz-linear-gradient(top, - #ededed, - #dadada); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #ededed), - color-stop(1, #dadada)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ededed', EndColorStr='#dadada')"; -} -.ui-btn-hover-c a.ui-link-inherit { - color: #2F3E46; -} -.ui-btn-down-c { - border: 1px solid #808080; - background: #fdfdfd; - font-weight: bold; - color: #111111; - text-shadow: 0 1px 1px #ffffff; - background-image: -moz-linear-gradient(top, - #eeeeee, - #fdfdfd); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #eeeeee), - color-stop(1, #fdfdfd)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#fdfdfd')"; -} -.ui-btn-down-c a.ui-link-inherit { - color: #2F3E46; -} -.ui-btn-up-c, -.ui-btn-hover-c, -.ui-btn-down-c { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* D ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-d { - border: 1px solid #ccc; - background: #bbb; - color: #333; - text-shadow: 0 1px 0 #eee; - background-image: -moz-linear-gradient(top, - #ddd, - #bbb); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #ddd), - color-stop(1, #bbb)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#dddddd', EndColorStr='#bbbbbb')"; -} -.ui-bar-d, -.ui-bar-d input, -.ui-bar-d select, -.ui-bar-d textarea, -.ui-bar-d button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-bar-d .ui-link-inherit { - color: #333; -} -.ui-bar-d .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-body-d { - border: 1px solid #ccc; - color: #333333; - text-shadow: 0 1px 0 #fff; - background: #ffffff; -} -.ui-body-d, -.ui-body-d input, -.ui-body-d select, -.ui-body-d textarea, -.ui-body-d button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-d .ui-link-inherit { - color: #333333; -} -.ui-body-d .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-btn-up-d { - border: 1px solid #ccc; - background: #fff; - font-weight: bold; - color: #444; - text-shadow: 0 1px 1px #fff; -} -.ui-btn-up-d a.ui-link-inherit { - color: #333; -} -.ui-btn-hover-d { - border: 1px solid #aaa; - background: #eeeeee; - font-weight: bold; - color: #222; - cursor: pointer; - text-shadow: 0 1px 1px #fff; - background-image: -moz-linear-gradient(top, - #fdfdfd, - #eeeeee); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fdfdfd), - color-stop(1, #eeeeee)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fdfdfd', EndColorStr='#eeeeee')"; -} -.ui-btn-hover-d a.ui-link-inherit { - color: #222; -} -.ui-btn-down-d { - border: 1px solid #aaaaaa; - background: #ffffff; - font-weight: bold; - color: #111; - text-shadow: 0 1px 1px #ffffff; - background-image: -moz-linear-gradient(top, - #eeeeee, - #ffffff); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #eeeeee), - color-stop(1, #ffffff)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#ffffff')"; -} -.ui-btn-down-d a.ui-link-inherit { - color: #111; -} -.ui-btn-up-d, -.ui-btn-hover-d, -.ui-btn-down-d { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* E ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-e { - border: 1px solid #F7C942; - background: #fadb4e; - color: #333; - text-shadow: 0 1px 0 #fff; - background-image: -moz-linear-gradient(top, - #fceda7, - #fadb4e); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fceda7), - color-stop(1, #fadb4e)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fceda7', EndColorStr='#fadb4e')"; -} -.ui-bar-e, -.ui-bar-e input, -.ui-bar-e select, -.ui-bar-e textarea, -.ui-bar-d button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-bar-e .ui-link-inherit { - color: #333; -} -.ui-bar-e .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-body-e { - border: 1px solid #F7C942; - color: #333333; - text-shadow: 0 1px 0 #fff; - background: #faeb9e; - background-image: -moz-linear-gradient(top, - #fff, - #faeb9e); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fff), - color-stop(1, #faeb9e)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff', EndColorStr='#faeb9e')"; -} -.ui-body-e, -.ui-body-e input, -.ui-body-e select, -.ui-body-e textarea, -.ui-body-e button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-e .ui-link-inherit { - color: #333333; -} -.ui-body-e .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-btn-up-e { - border: 1px solid #F7C942; - background: #fadb4e; - font-weight: bold; - color: #333; - text-shadow: 0 1px 0 #fff; - background-image: -moz-linear-gradient(top, - #fceda7, - #fadb4e); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fceda7), - color-stop(1, #fadb4e)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fceda7', EndColorStr='#fadb4e')"; -} -.ui-btn-up-e a.ui-link-inherit { - color: #333; -} -.ui-btn-hover-e { - border: 1px solid #e79952; - background: #fbe26f; - font-weight: bold; - color: #111; - text-shadow: 0 1px 1px #fff; - background-image: -moz-linear-gradient(top, - #fcf0b5, - #fbe26f); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fcf0b5), - color-stop(1, #fbe26f)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fcf0b5', EndColorStr='#fbe26f')"; -} - -.ui-btn-hover-e a.ui-link-inherit { - color: #333; -} -.ui-btn-down-e { - border: 1px solid #F7C942; - background: #fceda7; - font-weight: bold; - color: #111; - text-shadow: 0 1px 1px #ffffff; - background-image: -moz-linear-gradient(top, - #fadb4e, - #fceda7); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fadb4e), - color-stop(1, #fceda7)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fadb4e', EndColorStr='#fceda7')"; -} -.ui-btn-down-e a.ui-link-inherit { - color: #333; -} -.ui-btn-up-e, -.ui-btn-hover-e, -.ui-btn-down-e { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* links within "buttons" ------------------------------------------------------------------------------------------------------------*/ - -a.ui-link-inherit { - text-decoration: none !important; -} - - -/* Active class used as the "on" state across all themes ------------------------------------------------------------------------------------------------------------*/ - -.ui-btn-active { - border: 1px solid #155678; - background: #4596ce; - font-weight: bold; - color: #fff; - cursor: pointer; - text-shadow: 0 -1px 1px #145072; - text-decoration: none; - background-image: -moz-linear-gradient(top, - #85bae4, - #5393c5); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #85bae4), - color-stop(1, #5393c5)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#85bae4', EndColorStr='#5393c5')"; - outline: none; -} -.ui-btn-active a.ui-link-inherit { - color: #fff; -} - - -/* button inner top highlight ------------------------------------------------------------------------------------------------------------*/ - -.ui-btn-inner { - border-top: 1px solid #fff; - border-color: rgba(255,255,255,.3); -} - - -/* corner rounding classes ------------------------------------------------------------------------------------------------------------*/ - -.ui-corner-tl { - -moz-border-radius-topleft: .6em; - -webkit-border-top-left-radius: .6em; - border-top-left-radius: .6em; -} -.ui-corner-tr { - -moz-border-radius-topright: .6em; - -webkit-border-top-right-radius: .6em; - border-top-right-radius: .6em; -} -.ui-corner-bl { - -moz-border-radius-bottomleft: .6em; - -webkit-border-bottom-left-radius: .6em; - border-bottom-left-radius: .6em; -} -.ui-corner-br { - -moz-border-radius-bottomright: .6em; - -webkit-border-bottom-right-radius: .6em; - border-bottom-right-radius: .6em; -} -.ui-corner-top { - -moz-border-radius-topleft: .6em; - -webkit-border-top-left-radius: .6em; - border-top-left-radius: .6em; - -moz-border-radius-topright: .6em; - -webkit-border-top-right-radius: .6em; - border-top-right-radius: .6em; -} -.ui-corner-bottom { - -moz-border-radius-bottomleft: .6em; - -webkit-border-bottom-left-radius: .6em; - border-bottom-left-radius: .6em; - -moz-border-radius-bottomright: .6em; - -webkit-border-bottom-right-radius: .6em; - border-bottom-right-radius: .6em; - } -.ui-corner-right { - -moz-border-radius-topright: .6em; - -webkit-border-top-right-radius: .6em; - border-top-right-radius: .6em; - -moz-border-radius-bottomright: .6em; - -webkit-border-bottom-right-radius: .6em; - border-bottom-right-radius: .6em; -} -.ui-corner-left { - -moz-border-radius-topleft: .6em; - -webkit-border-top-left-radius: .6em; - border-top-left-radius: .6em; - -moz-border-radius-bottomleft: .6em; - -webkit-border-bottom-left-radius: .6em; - border-bottom-left-radius: .6em; -} -.ui-corner-all { - -moz-border-radius: .6em; - -webkit-border-radius: .6em; - border-radius: .6em; -} - - - -/* Interaction cues ------------------------------------------------------------------------------------------------------------*/ -.ui-disabled { - opacity: .3; -} -.ui-disabled, -.ui-disabled a { - cursor: default; -} - -/* Icons ------------------------------------------------------------------------------------------------------------*/ - -.ui-icon { - background: #666; - background: rgba(0,0,0,.4); - background-image: url(images/icons-18-white.png); - background-repeat: no-repeat; - -moz-border-radius: 9px; - -webkit-border-radius: 9px; - border-radius: 9px; -} - - -/* Alt icon color ------------------------------------------------------------------------------------------------------------*/ - -.ui-icon-alt { - background: #fff; - background: rgba(255,255,255,.3); - background-image: url(images/icons-18-black.png); - background-repeat: no-repeat; -} - -/* HD/"retina" sprite ------------------------------------------------------------------------------------------------------------*/ - -@media only screen and (-webkit-min-device-pixel-ratio: 1.5), - only screen and (min--moz-device-pixel-ratio: 1.5), - only screen and (min-resolution: 240dpi) { - - .ui-icon-plus, .ui-icon-minus, .ui-icon-delete, .ui-icon-arrow-r, - .ui-icon-arrow-l, .ui-icon-arrow-u, .ui-icon-arrow-d, .ui-icon-check, - .ui-icon-gear, .ui-icon-refresh, .ui-icon-forward, .ui-icon-back, - .ui-icon-grid, .ui-icon-star, .ui-icon-alert, .ui-icon-info, .ui-icon-home, .ui-icon-search, - .ui-icon-checkbox-off, .ui-icon-checkbox-on, .ui-icon-radio-off, .ui-icon-radio-on { - background-image: url(images/icons-36-white.png); - -moz-background-size: 776px 18px; - -o-background-size: 776px 18px; - -webkit-background-size: 776px 18px; - background-size: 776px 18px; - } - .ui-icon-alt { - background-image: url(images/icons-36-black.png); - } -} - -/* plus minus */ -.ui-icon-plus { - background-position: -0 50%; -} -.ui-icon-minus { - background-position: -36px 50%; -} - -/* delete/close */ -.ui-icon-delete { - background-position: -72px 50%; -} - -/* arrows */ -.ui-icon-arrow-r { - background-position: -108px 50%; -} -.ui-icon-arrow-l { - background-position: -144px 50%; -} -.ui-icon-arrow-u { - background-position: -180px 50%; -} -.ui-icon-arrow-d { - background-position: -216px 50%; -} - -/* misc */ -.ui-icon-check { - background-position: -252px 50%; -} -.ui-icon-gear { - background-position: -288px 50%; -} -.ui-icon-refresh { - background-position: -324px 50%; -} -.ui-icon-forward { - background-position: -360px 50%; -} -.ui-icon-back { - background-position: -396px 50%; -} -.ui-icon-grid { - background-position: -432px 50%; -} -.ui-icon-star { - background-position: -468px 50%; -} -.ui-icon-alert { - background-position: -504px 50%; -} -.ui-icon-info { - background-position: -540px 50%; -} -.ui-icon-home { - background-position: -576px 50%; -} -.ui-icon-search { - background-position: -612px 50%; -} -.ui-icon-checkbox-off { - background-position: -684px 50%; -} -.ui-icon-checkbox-on { - background-position: -648px 50%; -} -.ui-icon-radio-off { - background-position: -756px 50%; -} -.ui-icon-radio-on { - background-position: -720px 50%; -} - - -/* checks,radios */ -.ui-icon-checkbox-off, -.ui-icon-checkbox-on, -.ui-icon-radio-off, -.ui-icon-radio-on { - background-color: transparent; - -moz-border-radius: 0; - -webkit-border-radius: 0; - border-radius: 0; -} -.ui-icon-searchfield { - background-image: url(images/icon-search-black.png); - background-size: 16px 16px; -} - -/* loading icon */ -.ui-icon-loading { - background-image: url(images/ajax-loader.png); - width: 40px; - height: 40px; - -moz-border-radius: 20px; - -webkit-border-radius: 20px; - border-radius: 20px; - background-size: 35px 35px; -} - - -/* Button corner classes ------------------------------------------------------------------------------------------------------------*/ - -.ui-btn-corner-tl { - -moz-border-radius-topleft: 1em; - -webkit-border-top-left-radius: 1em; - border-top-left-radius: 1em; -} -.ui-btn-corner-tr { - -moz-border-radius-topright: 1em; - -webkit-border-top-right-radius: 1em; - border-top-right-radius: 1em; -} -.ui-btn-corner-bl { - -moz-border-radius-bottomleft: 1em; - -webkit-border-bottom-left-radius: 1em; - border-bottom-left-radius: 1em; -} -.ui-btn-corner-br { - -moz-border-radius-bottomright: 1em; - -webkit-border-bottom-right-radius: 1em; - border-bottom-right-radius: 1em; -} -.ui-btn-corner-top { - -moz-border-radius-topleft: 1em; - -webkit-border-top-left-radius: 1em; - border-top-left-radius: 1em; - -moz-border-radius-topright: 1em; - -webkit-border-top-right-radius: 1em; - border-top-right-radius: 1em; -} -.ui-btn-corner-bottom { - -moz-border-radius-bottomleft: 1em; - -webkit-border-bottom-left-radius: 1em; - border-bottom-left-radius: 1em; - -moz-border-radius-bottomright: 1em; - -webkit-border-bottom-right-radius: 1em; - border-bottom-right-radius: 1em; -} -.ui-btn-corner-right { - -moz-border-radius-topright: 1em; - -webkit-border-top-right-radius: 1em; - border-top-right-radius: 1em; - -moz-border-radius-bottomright: 1em; - -webkit-border-bottom-right-radius: 1em; - border-bottom-right-radius: 1em; -} -.ui-btn-corner-left { - -moz-border-radius-topleft: 1em; - -webkit-border-top-left-radius: 1em; - border-top-left-radius: 1em; - -moz-border-radius-bottomleft: 1em; - -webkit-border-bottom-left-radius: 1em; - border-bottom-left-radius: 1em; -} -.ui-btn-corner-all { - -moz-border-radius: 1em; - -webkit-border-radius: 1em; - border-radius: 1em; -} - -/* radius clip workaround for cleaning up corner trapping */ -.ui-corner-tl, -.ui-corner-tr, -.ui-corner-bl, -.ui-corner-br, -.ui-corner-top, -.ui-corner-bottom, -.ui-corner-right, -.ui-corner-left, -.ui-corner-all, -.ui-btn-corner-tl, -.ui-btn-corner-tr, -.ui-btn-corner-bl, -.ui-btn-corner-br, -.ui-btn-corner-top, -.ui-btn-corner-bottom, -.ui-btn-corner-right, -.ui-btn-corner-left, -.ui-btn-corner-all { - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; -} - -/* Overlay / modal ------------------------------------------------------------------------------------------------------------*/ - -.ui-overlay { - background: #666; - opacity: .5; - filter: Alpha(Opacity=50); - position: absolute; - width: 100%; - height: 100%; -} -.ui-overlay-shadow { - -moz-box-shadow: 0px 0px 12px rgba(0,0,0,.6); - -webkit-box-shadow: 0px 0px 12px rgba(0,0,0,.6); - box-shadow: 0px 0px 12px rgba(0,0,0,.6); -} -.ui-shadow { - -moz-box-shadow: 0px 1px 4px rgba(0,0,0,.3); - -webkit-box-shadow: 0px 1px 4px rgba(0,0,0,.3); - box-shadow: 0px 1px 4px rgba(0,0,0,.3); -} -.ui-bar-a .ui-shadow, -.ui-bar-b .ui-shadow , -.ui-bar-c .ui-shadow { - -moz-box-shadow: 0px 1px 0 rgba(255,255,255,.3); - -webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.3); - box-shadow: 0px 1px 0 rgba(255,255,255,.3); -} -.ui-shadow-inset { - -moz-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); - -webkit-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); - box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); -} -.ui-icon-shadow { - -moz-box-shadow: 0px 1px 0 rgba(255,255,255,.4); - -webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.4); - box-shadow: 0px 1px 0 rgba(255,255,255,.4); -} - - -/* Focus state - set here for specificity ------------------------------------------------------------------------------------------------------------*/ - -.ui-focus { - -moz-box-shadow: 0px 0px 12px #387bbe; - -webkit-box-shadow: 0px 0px 12px #387bbe; - box-shadow: 0px 0px 12px #387bbe; -} - -/* unset box shadow in browsers that don't do it right ------------------------------------------------------------------------------------------------------------*/ - -.ui-mobile-nosupport-boxshadow * { - -moz-box-shadow: none !important; - -webkit-box-shadow: none !important; - box-shadow: none !important; -} - -/* ...and bring back focus */ -.ui-mobile-nosupport-boxshadow .ui-focus { - outline-width: 2px; -}/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. -* Note: Code is in draft form and is subject to change -*/ - -/* some unsets - more probably needed */ -.ui-mobile, .ui-mobile body { height: 100%; } -.ui-mobile fieldset, .ui-page { padding: 0; margin: 0; } -.ui-mobile a img, .ui-mobile fieldset { border: 0; } - -/* responsive page widths */ -.ui-mobile-viewport { margin: 0; overflow-x: hidden; -webkit-text-size-adjust: none; -ms-text-size-adjust:none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } - -/* "page" containers - full-screen views, one should always be in view post-pageload */ -.ui-mobile [data-role=page], .ui-mobile [data-role=dialog], .ui-page { top: 0; left: 0; width: 100%; min-height: 100%; position: absolute; display: none; border: 0; } -.ui-mobile .ui-page-active { display: block; overflow: visible; } - -/*orientations from js are available */ -.portrait, -.portrait .ui-page { min-height: 420px; } -.landscape, -.landscape .ui-page { min-height: 300px; } - -/* loading screen */ -.ui-loading .ui-mobile-viewport { overflow: hidden !important; } -.ui-loading .ui-loader { display: block; } -.ui-loading .ui-page { overflow: hidden; } -.ui-loader { display: none; position: absolute; opacity: .85; z-index: 100; left: 50%; width: 200px; margin-left: -130px; margin-top: -35px; padding: 10px 30px; } -.ui-loader h1 { font-size: 15px; text-align: center; } -.ui-loader .ui-icon { position: static; display: block; opacity: .9; margin: 0 auto; width: 35px; height: 35px; background-color: transparent; } - -/*fouc*/ -.ui-mobile-rendering > * { visibility: hidden; } - -/*headers, content panels*/ -.ui-bar, .ui-body { position: relative; padding: .4em 15px; overflow: hidden; display: block; clear:both; } -.ui-bar { font-size: 16px; margin: 0; } -.ui-bar h1, .ui-bar h2, .ui-bar h3, .ui-bar h4, .ui-bar h5, .ui-bar h6 { margin: 0; padding: 0; font-size: 16px; display: inline-block; } - -.ui-header, .ui-footer { display: block; } -.ui-page .ui-header, .ui-page .ui-footer { position: relative; } -.ui-header .ui-btn-left { position: absolute; left: 10px; top: .4em; } -.ui-header .ui-btn-right { position: absolute; right: 10px; top: .4em; } -.ui-header .ui-title, .ui-footer .ui-title { min-height: 1.1em; text-align: center; font-size: 16px; display: block; margin: .6em 90px .8em; padding: 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; outline: 0 !important; } - -/*content area*/ -.ui-content { border-width: 0; overflow: visible; overflow-x: hidden; padding: 15px; } -.ui-page-fullscreen .ui-content { padding:0; } - -/* icons sizing */ -.ui-icon { width: 18px; height: 18px; } - -/* fullscreen class on ui-content div */ -.ui-fullscreen { } -.ui-fullscreen img { max-width: 100%; } - -/* non-js content hiding */ -.ui-nojs { position: absolute; left: -9999px; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.spin { - -webkit-transform: rotate(360deg); - -webkit-animation-name: spin; - -webkit-animation-duration: 1s; - -webkit-animation-iteration-count: infinite; -} -@-webkit-keyframes spin { - from {-webkit-transform: rotate(0deg);} - to {-webkit-transform: rotate(360deg);} -} - -/* Transitions from jQtouch (with small modifications): http://www.jqtouch.com/ -Built by David Kaneda and maintained by Jonathan Stark. -*/ -.in, .out { - -webkit-animation-timing-function: ease-in-out; - -webkit-animation-duration: 350ms; -} - -.slide.in { - -webkit-transform: translateX(0); - -webkit-animation-name: slideinfromright; -} - -.slide.out { - -webkit-transform: translateX(-100%); - -webkit-animation-name: slideouttoleft; -} - -.slide.in.reverse { - -webkit-transform: translateX(0); - -webkit-animation-name: slideinfromleft; -} - -.slide.out.reverse { - -webkit-transform: translateX(100%); - -webkit-animation-name: slideouttoright; -} - -.slideup.in { - -webkit-transform: translateY(0); - -webkit-animation-name: slideinfrombottom; - z-index: 10; -} - -.slideup.out { - -webkit-animation-name: dontmove; - z-index: 0; -} - -.slideup.out.reverse { - -webkit-transform: translateY(100%); - z-index: 10; - -webkit-animation-name: slideouttobottom; -} - -.slideup.in.reverse { - z-index: 0; - -webkit-animation-name: dontmove; -} -.slidedown.in { - -webkit-transform: translateY(0); - -webkit-animation-name: slideinfromtop; - z-index: 10; -} - -.slidedown.out { - -webkit-animation-name: dontmove; - z-index: 0; -} - -.slidedown.out.reverse { - -webkit-transform: translateY(-100%); - z-index: 10; - -webkit-animation-name: slideouttotop; -} - -.slidedown.in.reverse { - z-index: 0; - -webkit-animation-name: dontmove; -} - -@-webkit-keyframes slideinfromright { - from { -webkit-transform: translateX(100%); } - to { -webkit-transform: translateX(0); } -} - -@-webkit-keyframes slideinfromleft { - from { -webkit-transform: translateX(-100%); } - to { -webkit-transform: translateX(0); } -} - -@-webkit-keyframes slideouttoleft { - from { -webkit-transform: translateX(0); } - to { -webkit-transform: translateX(-100%); } -} - -@-webkit-keyframes slideouttoright { - from { -webkit-transform: translateX(0); } - to { -webkit-transform: translateX(100%); } -} - - -@-webkit-keyframes slideinfromtop { - from { -webkit-transform: translateY(-100%); } - to { -webkit-transform: translateY(0); } -} - -@-webkit-keyframes slideinfrombottom { - from { -webkit-transform: translateY(100%); } - to { -webkit-transform: translateY(0); } -} - -@-webkit-keyframes slideouttobottom { - from { -webkit-transform: translateY(0); } - to { -webkit-transform: translateY(100%); } -} - -@-webkit-keyframes slideouttotop { - from { -webkit-transform: translateY(0); } - to { -webkit-transform: translateY(-100%); } -} -@-webkit-keyframes fadein { - from { opacity: 0; } - to { opacity: 1; } -} - -@-webkit-keyframes fadeout { - from { opacity: 1; } - to { opacity: 0; } -} - -.fade.in { - opacity: 1; - z-index: 10; - -webkit-animation-name: fadein; -} -.fade.out { - z-index: 0; - -webkit-animation-name: fadeout; -} - -/* The properties in this rule are only necessary for the 'flip' transition. - * We need specify the perspective to create a projection matrix. This will add - * some depth as the element flips. The depth number represents the distance of - * the viewer from the z-plane. According to the CSS3 spec, 1000 is a moderate - * value. - */ -.viewport-flip { - -webkit-perspective: 1000; - position: absolute; -} - -.ui-mobile-viewport-transitioning, -.ui-mobile-viewport-transitioning .ui-page { - width: 100%; - height: 100%; - overflow: hidden; -} - -.flip { - -webkit-animation-duration: .65s; - -webkit-backface-visibility:hidden; - -webkit-transform:translateX(0); /* Needed to work around an iOS 3.1 bug that causes listview thumbs to disappear when -webkit-visibility:hidden is used. */ -} - -.flip.in { - -webkit-transform: rotateY(0) scale(1); - -webkit-animation-name: flipinfromleft; -} - -.flip.out { - -webkit-transform: rotateY(-180deg) scale(.8); - -webkit-animation-name: flipouttoleft; -} - -/* Shake it all about */ - -.flip.in.reverse { - -webkit-transform: rotateY(0) scale(1); - -webkit-animation-name: flipinfromright; -} - -.flip.out.reverse { - -webkit-transform: rotateY(180deg) scale(.8); - -webkit-animation-name: flipouttoright; -} - -@-webkit-keyframes flipinfromright { - from { -webkit-transform: rotateY(-180deg) scale(.8); } - to { -webkit-transform: rotateY(0) scale(1); } -} - -@-webkit-keyframes flipinfromleft { - from { -webkit-transform: rotateY(180deg) scale(.8); } - to { -webkit-transform: rotateY(0) scale(1); } -} - -@-webkit-keyframes flipouttoleft { - from { -webkit-transform: rotateY(0) scale(1); } - to { -webkit-transform: rotateY(-180deg) scale(.8); } -} - -@-webkit-keyframes flipouttoright { - from { -webkit-transform: rotateY(0) scale(1); } - to { -webkit-transform: rotateY(180deg) scale(.8); } -} - - -/* Hackish, but reliable. */ - -@-webkit-keyframes dontmove { - from { opacity: 1; } - to { opacity: 1; } -} - -.pop { - -webkit-transform-origin: 50% 50%; -} - -.pop.in { - -webkit-transform: scale(1); - opacity: 1; - -webkit-animation-name: popin; - z-index: 10; -} - -.pop.out.reverse { - -webkit-transform: scale(.2); - opacity: 0; - -webkit-animation-name: popout; - z-index: 10; -} - -.pop.in.reverse { - z-index: 0; - -webkit-animation-name: dontmove; -} - -@-webkit-keyframes popin { - from { - -webkit-transform: scale(.2); - opacity: 0; - } - to { - -webkit-transform: scale(1); - opacity: 1; - } -} - -@-webkit-keyframes popout { - from { - -webkit-transform: scale(1); - opacity: 1; - } - to { - -webkit-transform: scale(.2); - opacity: 0; - } -}/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ - -/* content configurations. */ -.ui-grid-a, .ui-grid-b, .ui-grid-c, .ui-grid-d { overflow: hidden; } -.ui-block-a, .ui-block-b, .ui-block-c, .ui-block-d, .ui-block-e { margin: 0; padding: 0; border: 0; float: left; min-height:1px;} - -/* grid solo: 100 - single item fallback */ -.ui-grid-solo .ui-block-a { width: 100%; float: none; } - -/* grid a: 50/50 */ -.ui-grid-a .ui-block-a, .ui-grid-a .ui-block-b { width: 50%; } -.ui-grid-a .ui-block-a { clear: left; } - -/* grid b: 33/33/33 */ -.ui-grid-b .ui-block-a, .ui-grid-b .ui-block-b, .ui-grid-b .ui-block-c { width: 33.333%; } -.ui-grid-b .ui-block-a { clear: left; } - -/* grid c: 25/25/25/25 */ -.ui-grid-c .ui-block-a, .ui-grid-c .ui-block-b, .ui-grid-c .ui-block-c, .ui-grid-c .ui-block-d { width: 25%; } -.ui-grid-c .ui-block-a { clear: left; } - -/* grid d: 20/20/20/20/20 */ -.ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e { width: 20%; } -.ui-grid-d .ui-block-a { clear: left; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -/* fixed page header & footer configuration */ -.ui-header, .ui-footer, .ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { position: absolute; overflow: hidden; width: 100%; border-left-width: 0; border-right-width: 0; } -.ui-header-fixed, .ui-footer-fixed { - z-index: 1000; - -webkit-transform: translateZ(0); /* Force header/footer rendering to go through the same rendering pipeline as native page scrolling. */ -} -.ui-footer-duplicate, .ui-page-fullscreen .ui-fixed-inline { display: none; } -.ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { opacity: .9; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-navbar { overflow: hidden; } -.ui-navbar ul, .ui-navbar-expanded ul { list-style:none; padding: 0; margin: 0; position: relative; display: block; border: 0;} -.ui-navbar-collapsed ul { float: left; width: 75%; margin-right: -2px; } -.ui-navbar-collapsed .ui-navbar-toggle { float: left; width: 25%; } -.ui-navbar li.ui-navbar-truncate { position: absolute; left: -9999px; top: -9999px; } -.ui-navbar li .ui-btn, .ui-navbar .ui-navbar-toggle .ui-btn { display: block; font-size: 12px; text-align: center; margin: 0; border-right-width: 0; } -.ui-navbar li .ui-btn { margin-right: -1px; } -.ui-navbar li .ui-btn:last-child { margin-right: 0; } -.ui-header .ui-navbar li .ui-btn, .ui-header .ui-navbar .ui-navbar-toggle .ui-btn, -.ui-footer .ui-navbar li .ui-btn, .ui-footer .ui-navbar .ui-navbar-toggle .ui-btn { border-top-width: 0; border-bottom-width: 0; } -.ui-navbar .ui-btn-inner { padding-left: 2px; padding-right: 2px; } -.ui-navbar-noicons li .ui-btn .ui-btn-inner, .ui-navbar-noicons .ui-navbar-toggle .ui-btn-inner { padding-top: .8em; padding-bottom: .9em; } -/*expanded page styles*/ -.ui-navbar-expanded .ui-btn { margin: 0; font-size: 14px; } -.ui-navbar-expanded .ui-btn-inner { padding-left: 5px; padding-right: 5px; } -.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner { padding: 45px 5px 15px; text-align: center; } -.ui-navbar-expanded .ui-btn-icon-top .ui-icon { top: 15px; } -.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner { padding: 15px 5px 45px; text-align: center; } -.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon { bottom: 15px; } -.ui-navbar-expanded li .ui-btn .ui-btn-inner { min-height: 2.5em; } -.ui-navbar-expanded .ui-navbar-noicons .ui-btn .ui-btn-inner { padding-top: 1.8em; padding-bottom: 1.9em; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-btn { display: block; text-align: center; cursor:pointer; position: relative; margin: .5em 5px; padding: 0; } -.ui-btn:focus, .ui-btn:active { outline: none; } -.ui-header .ui-btn, .ui-footer .ui-btn, .ui-bar .ui-btn { display: inline-block; font-size: 13px; margin: 0; } -.ui-btn-inline { display: inline-block; } -.ui-btn-inner { padding: .6em 25px; display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; position: relative; } -.ui-header .ui-btn-inner, .ui-footer .ui-btn-inner, .ui-bar .ui-btn-inner { padding: .4em 8px .5em; } -.ui-btn-icon-notext { display: inline-block; width: 20px; height: 20px; padding: 2px 1px 2px 3px; text-indent: -9999px; } -.ui-btn-icon-notext .ui-btn-inner { padding: 0; } -.ui-btn-icon-notext .ui-btn-text { position: absolute; left: -999px; } -.ui-btn-icon-left .ui-btn-inner { padding-left: 33px; } -.ui-header .ui-btn-icon-left .ui-btn-inner, -.ui-footer .ui-btn-icon-left .ui-btn-inner, -.ui-bar .ui-btn-icon-left .ui-btn-inner { padding-left: 27px; } -.ui-btn-icon-right .ui-btn-inner { padding-right: 33px; } -.ui-header .ui-btn-icon-right .ui-btn-inner, -.ui-footer .ui-btn-icon-right .ui-btn-inner, -.ui-bar .ui-btn-icon-right .ui-btn-inner { padding-right: 27px; } -.ui-btn-icon-top .ui-btn-inner { padding-top: 33px; } -.ui-header .ui-btn-icon-top .ui-btn-inner, -.ui-footer .ui-btn-icon-top .ui-btn-inner, -.ui-bar .ui-btn-icon-top .ui-btn-inner { padding-top: 27px; } -.ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 33px; } -.ui-header .ui-btn-icon-bottom .ui-btn-inner, -.ui-footer .ui-btn-icon-bottom .ui-btn-inner, -.ui-bar .ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 27px; } - -/*btn icon positioning*/ -.ui-btn-icon-notext .ui-icon { display: block; } -.ui-btn-icon-left .ui-icon, .ui-btn-icon-right .ui-icon { position: absolute; top: 50%; margin-top: -9px; } -.ui-btn-icon-top .ui-icon, .ui-btn-icon-bottom .ui-icon { position: absolute; left: 50%; margin-left: -9px; } -.ui-btn-icon-left .ui-icon { left: 10px; } -.ui-btn-icon-right .ui-icon {right: 10px; } -.ui-header .ui-btn-icon-left .ui-icon, -.ui-footer .ui-btn-icon-left .ui-icon, -.ui-bar .ui-btn-icon-left .ui-icon { left: 4px; } -.ui-header .ui-btn-icon-right .ui-icon, -.ui-footer .ui-btn-icon-right .ui-icon, -.ui-bar .ui-btn-icon-right .ui-icon { right: 4px; } -.ui-header .ui-btn-icon-top .ui-icon, -.ui-footer .ui-btn-icon-top .ui-icon, -.ui-bar .ui-btn-icon-top .ui-icon { top: 4px; } -.ui-header .ui-btn-icon-bottom .ui-icon, -.ui-footer .ui-btn-icon-bottom .ui-icon, -.ui-bar .ui-btn-icon-bottom .ui-icon { bottom: 4px; } -.ui-btn-icon-top .ui-icon { top: 5px; } -.ui-btn-icon-bottom .ui-icon { bottom: 5px; } -/*hiding native button,inputs */ -.ui-btn-hidden { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: button; opacity: 0; cursor: pointer; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); background: transparent; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-collapsible-contain { margin: .5em 0; } -.ui-collapsible-heading { font-size: 16px; display: block; margin: 0 -8px; padding: 0; border-width: 0 0 1px 0; position: relative; } -.ui-collapsible-heading a { text-align: left; margin: 0; } -.ui-collapsible-heading a .ui-btn-inner { padding-left: 40px; } -.ui-collapsible-heading a span.ui-btn { position: absolute; left: 6px; top: 50%; margin: -12px 0 0 0; width: 20px; height: 20px; padding: 1px 0px 1px 2px; text-indent: -9999px; } -.ui-collapsible-heading a span.ui-btn .ui-btn-inner { padding: 10px 0; } -.ui-collapsible-heading a span.ui-btn .ui-icon { left: 0; margin-top: -10px; } -.ui-collapsible-heading-status { position:absolute; left:-9999px; } -.ui-collapsible-content { display: block; padding: 10px 0 10px 8px; } -.ui-collapsible-content-collapsed { display: none; } - -.ui-collapsible-set { margin: .5em 0; } -.ui-collapsible-set .ui-collapsible-contain { margin: -1px 0 0; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-controlgroup, fieldset.ui-controlgroup { padding: 0; margin: .5em 0 1em; } -.ui-bar .ui-controlgroup { margin: 0 .3em; } -.ui-controlgroup-label { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; } -.ui-controlgroup-controls { display: block; width: 95%;} -.ui-controlgroup li { list-style: none; } -.ui-controlgroup-vertical .ui-btn, -.ui-controlgroup-vertical .ui-checkbox, .ui-controlgroup-vertical .ui-radio { margin: 0; border-bottom-width: 0; } -.ui-controlgroup-vertical .ui-controlgroup-last { border-bottom-width: 1px; } -.ui-controlgroup-horizontal { padding: 0; } -.ui-controlgroup-horizontal .ui-btn, -.ui-controlgroup-horizontal .ui-checkbox, .ui-controlgroup-horizontal .ui-radio { display: inline-block; margin: 0 -5px 0 0; } -.ui-controlgroup-horizontal .ui-checkbox, .ui-controlgroup-horizontal .ui-radio { display: inline; } -.ui-controlgroup-horizontal .ui-checkbox .ui-btn, .ui-controlgroup-horizontal .ui-radio .ui-btn, -.ui-controlgroup-horizontal .ui-checkbox:last-child, .ui-controlgroup-horizontal .ui-radio:last-child { margin-right: 0; } -.ui-controlgroup-horizontal .ui-controlgroup-last { margin-right: 0; } -.ui-controlgroup .ui-checkbox label, .ui-controlgroup .ui-radio label { font-size: 16px; } -/* conflicts with listview.. -.ui-controlgroup .ui-btn-icon-notext { width: 30px; height: 30px; text-indent: -9999px; } -.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner { padding: 5px 6px 5px 5px; } -*/ - -@media all and (min-width: 450px){ - .ui-controlgroup-label { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0; } - .ui-controlgroup-controls { width: 60%; display: inline-block; } -} /* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-dialog { min-height: 480px; } -.ui-dialog .ui-header, .ui-dialog .ui-content, .ui-dialog .ui-footer { margin: 15px; position: relative; } -.ui-dialog .ui-header, .ui-dialog .ui-footer { z-index: 10; width: auto; } -.ui-dialog .ui-content, .ui-dialog .ui-footer { margin-top: -15px; }/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-checkbox, .ui-radio { position:relative; margin: .2em 0 .5em; z-index: 1; } -.ui-checkbox .ui-btn, .ui-radio .ui-btn { margin: 0; text-align: left; z-index: 2; } -.ui-checkbox .ui-btn-inner, .ui-radio .ui-btn-inner { white-space: normal; } -.ui-checkbox .ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-btn-icon-left .ui-btn-inner { padding-left: 45px; } -.ui-checkbox .ui-btn-icon-right .ui-btn-inner, .ui-radio .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } -.ui-checkbox .ui-icon, .ui-radio .ui-icon { top: 1.1em; } -.ui-checkbox .ui-btn-icon-left .ui-icon, .ui-radio .ui-btn-icon-left .ui-icon {left: 15px; } -.ui-checkbox .ui-btn-icon-right .ui-icon, .ui-radio .ui-btn-icon-right .ui-icon {right: 15px; } -/* input, label positioning */ -.ui-checkbox input,.ui-radio input { position:absolute; left:20px; top:50%; width: 10px; height: 10px; margin:-5px 0 0 0; outline: 0 !important; z-index: 1; }/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-field-contain { background: none; padding: 1.5em 0; margin: 0; border-bottom-width: 1px; overflow: visible; } -.ui-field-contain:first-child { border-top-width: 0; } -@media all and (min-width: 450px){ - .ui-field-contain { border-width: 0; padding: 0; margin: 1em 0; } -} /* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-select { display: block; position: relative; } -.ui-select select { position: absolute; left: -9999px; top: -9999px; } -.ui-select .ui-btn { overflow: hidden; } -.ui-select .ui-btn select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; height: 100%; opacity: 0; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); } -@-moz-document url-prefix() {.ui-select .ui-btn select { opacity: 0.0001; }} -.ui-select .ui-btn select.ui-select-nativeonly { opacity: 1; text-indent: 0; } - -.ui-select .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } -.ui-select .ui-btn-icon-right .ui-icon { right: 15px; } - -/* labels */ -label.ui-select { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; display: block; } - -/*listbox*/ -.ui-select .ui-btn-text, .ui-selectmenu .ui-btn-text { display: inline-block; min-height: 1em; } -.ui-select .ui-btn-text { text-overflow: ellipsis; overflow: hidden; display: block;} - -.ui-selectmenu { position: absolute; padding: 0; z-index: 100 !important; width: 80%; max-width: 350px; padding: 6px; } -.ui-selectmenu .ui-listview { margin: 0; } -.ui-selectmenu .ui-btn.ui-li-divider { cursor: default; } -.ui-selectmenu-hidden { top: -9999px; left: -9999px; } -.ui-selectmenu-screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 99; } -.ui-screen-hidden, .ui-selectmenu-list .ui-li .ui-icon { display: none; } -.ui-selectmenu-list .ui-li .ui-icon { display: block; } -.ui-li.ui-selectmenu-placeholder { display: none; } -.ui-selectmenu .ui-header .ui-title { margin: 0.6em 46px 0.8em; } - -@media all and (min-width: 450px){ - label.ui-select { display: inline-block; width: 20%; margin: 0 2% 0 0; } - .ui-select { width: 60%; display: inline-block; } -} - -/* when no placeholder is defined in a multiple select, the header height doesn't even extend past the close button. this shim's content in there */ -.ui-selectmenu .ui-header h1:after { content: '.'; visibility: hidden; }/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -label.ui-input-text { font-size: 16px; line-height: 1.4; display: block; font-weight: normal; margin: 0 0 .3em; } -input.ui-input-text, textarea.ui-input-text { background-image: none; padding: .4em; line-height: 1.4; font-size: 16px; display: block; width: 95%; } -input.ui-input-text { -webkit-appearance: none; } -textarea.ui-input-text { height: 50px; -webkit-transition: height 200ms linear; -moz-transition: height 200ms linear; -o-transition: height 200ms linear; transition: height 200ms linear; } -.ui-input-search { padding: 0 30px; width: 77%; background-position: 8px 50%; background-repeat: no-repeat; position: relative; } -.ui-input-search input.ui-input-text { border: none; width: 98%; padding: .4em 0; margin: 0; display: block; background: transparent none; outline: 0 !important; } -.ui-input-search .ui-input-clear { position: absolute; right: 0; top: 50%; margin-top: -14px; } -.ui-input-search .ui-input-clear-hidden { display: none; } - -/* orientation adjustments - incomplete!*/ -@media all and (min-width: 450px){ - label.ui-input-text { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0 } - input.ui-input-text, - textarea.ui-input-text, - .ui-input-search { width: 60%; display: inline-block; } - .ui-input-search { width: 50%; } - .ui-input-search input.ui-input-text { width: 98%; /*echos rule from above*/ } -}/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-listview { margin: 0; counter-reset: listnumbering; } -.ui-content .ui-listview { margin: -15px; } -.ui-content .ui-listview-inset { margin: 1em 0; } -.ui-listview, .ui-li { list-style:none; padding:0; } -.ui-li, .ui-li.ui-field-contain { display: block; margin:0; position: relative; overflow: visible; text-align: left; border-width: 0; border-top-width: 1px; } -.ui-li .ui-btn-text a.ui-link-inherit { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } -.ui-li-divider, .ui-li-static { padding: .5em 15px; font-size: 14px; font-weight: bold; } -.ui-li-divider { counter-reset: listnumbering; } -ol.ui-listview .ui-link-inherit:before, ol.ui-listview .ui-li-static:before, .ui-li-dec { font-size: .8em; display: inline-block; padding-right: .3em; font-weight: normal;counter-increment: listnumbering; content: counter(listnumbering) ". "; } -ol.ui-listview .ui-li-jsnumbering:before { content: "" !important; } /* to avoid chance of duplication */ -.ui-listview-inset .ui-li { border-right-width: 1px; border-left-width: 1px; } -.ui-li:last-child, .ui-li.ui-field-contain:last-child { border-bottom-width: 1px; } -.ui-li>.ui-btn-inner { display: block; position: relative; padding: 0; } -.ui-li .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li { padding: .7em 75px .7em 15px; display: block; } -.ui-li-has-thumb .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-thumb { min-height: 60px; padding-left: 100px; } -.ui-li-has-icon .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-icon { min-height: 20px; padding-left: 40px; } -.ui-li-heading { font-size: 16px; font-weight: bold; display: block; margin: .6em 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } -.ui-li-desc { font-size: 12px; font-weight: normal; display: block; margin: -.5em 0 .6em; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } -.ui-li-thumb, .ui-li-icon { position: absolute; left: 1px; top: 0; max-height: 80px; max-width: 80px; } -.ui-li-icon { max-height: 40px; max-width: 40px; left: 10px; top: .9em; } -.ui-li-thumb, .ui-li-icon, .ui-li-content { float: left; margin-right: 10px; } - -.ui-li-aside { float: right; width: 50%; text-align: right; margin: .3em 0; } -@media all and (min-width: 480px){ - .ui-li-aside { width: 45%; } -} -.ui-li-divider { cursor: default; } -.ui-li-has-alt .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-alt { padding-right: 95px; } -.ui-li-count { position: absolute; font-size: 11px; font-weight: bold; padding: .2em .5em; top: 50%; margin-top: -.9em; right: 38px; } -.ui-li-divider .ui-li-count, .ui-li-static .ui-li-count { right: 10px; } -.ui-li-has-alt .ui-li-count { right: 55px; } -.ui-li-link-alt { position: absolute; width: 40px; height: 100%; border-width: 0; border-left-width: 1px; top: 0; right: 0; margin: 0; padding: 0; } -.ui-li-link-alt .ui-btn { overflow: hidden; position: absolute; right: 8px; top: 50%; margin: -11px 0 0 0; border-bottom-width: 1px; } -.ui-li-link-alt .ui-btn-inner { padding: 0; position: static; } -.ui-li-link-alt .ui-btn .ui-icon { right: 50%; margin-right: -9px; } - -.ui-listview-filter { border-width: 0; overflow: hidden; margin: -15px -15px 15px -15px } -.ui-listview-filter .ui-input-search { margin: 5px; width: auto; display: block; } - -.ui-listview-filter-inset { margin: -15px -5px -15px -5px; background: transparent; } -.ui-li.ui-screen-hidden{display:none;} -/* Odd iPad positioning issue. */ -@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { - .ui-li .ui-btn-text { overflow: visible; } -}/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -label.ui-slider { display: block; } -input.ui-slider-input { display: inline-block; width: 50px; } -select.ui-slider-switch { display: none; } -div.ui-slider { position: relative; display: inline-block; overflow: visible; height: 15px; padding: 0; margin: 0 2% 0 20px; top: 4px; width: 66%; } -a.ui-slider-handle { position: absolute; z-index: 10; top: 50%; width: 28px; height: 28px; margin-top: -15px; margin-left: -15px; } -a.ui-slider-handle .ui-btn-inner { padding-left: 0; padding-right: 0; } -@media all and (min-width: 480px){ - label.ui-slider { display: inline-block; width: 20%; margin: 0 2% 0 0; } - div.ui-slider { width: 45%; } -} - -div.ui-slider-switch { height: 32px; overflow: hidden; margin-left: 0; } -div.ui-slider-inneroffset { margin-left: 50%; position: absolute; top: 1px; height: 100%; width: 50%; } -div.ui-slider-handle-snapping { -webkit-transition: left 100ms linear; } -div.ui-slider-labelbg { position: absolute; top:0; margin: 0; border-width: 0; } -div.ui-slider-switch div.ui-slider-labelbg-a { width: 60%; height: 100%; left: 0; } -div.ui-slider-switch div.ui-slider-labelbg-b { width: 60%; height: 100%; right: 0; } -.ui-slider-switch-a div.ui-slider-labelbg-a, .ui-slider-switch-b div.ui-slider-labelbg-b { z-index: -1; } -.ui-slider-switch-a div.ui-slider-labelbg-b, .ui-slider-switch-b div.ui-slider-labelbg-a { z-index: 0; } - -div.ui-slider-switch a.ui-slider-handle { z-index: 20; width: 101%; height: 32px; margin-top: -18px; margin-left: -101%; } -span.ui-slider-label { width: 100%; position: absolute;height: 32px; font-size: 16px; text-align: center; line-height: 2; background: none; border-color: transparent; } -span.ui-slider-label-a { left: -100%; margin-right: -1px } -span.ui-slider-label-b { right: -100%; margin-left: -1px } - --- /dev/null +++ b/css/local.css.php @@ -1,1 +1,221 @@ - + + --- a/dotcloud/postinstall +++ b/dotcloud/postinstall @@ -3,8 +3,8 @@ 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 +curl 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 --- a/feedback.php +++ b/feedback.php @@ -1,28 +1,15 @@ verifyEmailAddress($address); - //$con->listVerifiedEmailAddresses(); - $m = new SimpleEmailServiceMessage(); - $m->addTo($address); - $m->setFrom($address); - $m->setSubject($topic); - $m->setMessageFromString($message); - $con->sendEmail($m); - } - else { // In case any of our lines are larger than 70 characters, we should use wordwrap() $message = wordwrap($message, 70); // Send mail($address, $topic, $message); - } + } if (isset($_REQUEST['feedback']) || isset($_REQUEST['newlocation'])){ sendEmail("bus.lambda feedback",print_r($_REQUEST,true)); @@ -30,7 +17,7 @@ } else { $stopid = ""; $stopcode = ""; -$urlparts = explode("?",$_SERVER["HTTP_REFERER"]); +if (isset($_SERVER["HTTP_REFERER"])) $urlparts = explode("?",$_SERVER["HTTP_REFERER"]); if (isset($urlparts[1])) { $getparams = explode("&",$urlparts[1]); foreach ($getparams as $param) { @@ -59,14 +46,14 @@ --- a/geo/route.kml.php +++ b/geo/route.kml.php @@ -1,30 +1,105 @@ '; echo ' - + + + '; + + + '; $route = getRoute($routeid); - echo "\n\n"; - $link = curPageURL()."/../trip.php?routeid=".htmlspecialchars ($route["route_id"]); - echo "".$route['route_short_name'].""; - echo ''; - echo ''.$route['route_short_name']." ".$route['route_long_name']."]]> "; -echo "#yellowLineGreenPoly"; +echo "\n\n"; +$_REQUEST['time'] = "12:00"; +$trip = getRouteNextTrip($routeid, 0); +$link = curPageURL() . "/../trip.php?routeid=" . htmlspecialchars($route["route_id"]. "&directionid=0&tripid=".$trip['trip_id']) ; +echo "" . $route['route_short_name'] . " Direction 0 "; +echo ''; +echo '' . $route['route_short_name'] . " Direction 0]]> "; +echo "#yellowLineYellowPoly"; - $trips = getRouteTrips($routeid); - echo getTripShape($trips[0]['trip_id']); +echo getTripShape($trip['trip_id']); + echo "\n"; +$stops = Array(); +foreach (getTripStops($trip['trip_id']) as $stop) { + $stop['style'] = "#ylw-pushpin"; + $stops[$stop['stop_id']] = $stop; +} -echo "\n\n"; + +echo "\n\n"; +$trip = getRouteNextTrip($routeid, 1); +$link = curPageURL() . "/../trip.php?routeid=" . htmlspecialchars($route["route_id"]. "&directionid=1&tripid=".$trip['trip_id']) ; +echo "" . $route['route_short_name'] . " Direction 1 "; +echo ''; +echo '' . $route['route_short_name'] . " Direction 1]]> "; +echo "#blueLineBluePoly"; + +echo getTripShape($trip['trip_id']); + echo "\n"; +foreach (getTripStops($trip['trip_id']) as $stop) { + if (isset($stops[$stop['stop_id']])) { + $stop['style'] = "#grn-pushpin"; + } else { + $stop['style'] = "#blue-pushpin"; + } + $stops[$stop['stop_id']] = $stop; +} +foreach ($stops as $stop) { + echo "\n\n"; + $link = curPageURL() . '/../stop.php?stopid=' . htmlspecialchars($stop['stop_id']); + echo "" . htmlspecialchars($stop['stop_name']) . ""; + echo ''; + echo '' . htmlspecialchars($stop['stop_name']) . "]]> "; + echo "" . $stop['style'] . ""; + echo $stop['positionkml']; + echo "\n"; +} + +echo "\n"; ?> --- a/geo/stops.kml.php +++ b/geo/stops.kml.php @@ -1,10 +1,13 @@ createElementNS('http://earth.google.com/kml/2.1', 'kml'); +$node = $dom->createElementNS('http://www.opengis.net/kml/2.2', 'kml'); $parNode = $dom->appendChild($node); // Creates a KML Document element and append it to the KML element. $dnode = $dom->createElement('Document'); @@ -12,7 +15,7 @@ if ($suburb != "") $result_stops = getStopsBySuburb($suburb); else $result_stops = getStops(); foreach ($result_stops as $stop) { - $description = 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] . "
"; + $description = 'View stop page
'; // Creates a Placemark and append it to the Document. $node = $dom->createElement('Placemark'); $placeNode = $docNode->appendChild($node); @@ -33,4 +36,5 @@ } $kmlOutput = $dom->saveXML(); echo $kmlOutput; -?> +?> + --- /dev/null +++ b/geo/trip.kml.php @@ -1,1 +1,70 @@ + +'; +echo ' + + + + '; +$trip = getTrip($tripid); +echo "\n\n"; +$link = curPageURL() . "/../trip.php?tripid=" . htmlspecialchars($$tripid); +echo "" . $tripid . ""; +echo ''; +echo '' . $tripid . "]]> "; +echo "#yellowLineGreenPoly"; + +echo getTripShape($tripid); + +echo "\n"; +foreach (getTripStopTimes($tripid) as $stop) { + echo "\n\n"; + $link = curPageURL() . '/../trip.php?tripid=' . htmlspecialchars($tripid); + echo "" . $stop['arrival_time'] . " @ " . htmlspecialchars($stop['stop_name']) . ""; + echo ''; + echo '' . htmlspecialchars($stop['stop_name']) . "]]> "; + echo "#blue-pushpin"; + echo "" . $stop['stop_lon'] . "," . $stop['stop_lat'] . ""; + + echo "\n"; +} +echo "\n"; +?> + + --- /dev/null +++ b/include/common-auth.inc.php @@ -1,1 +1,33 @@ +mode) { + $openid->required = array('contact/email'); + $openid->identity = 'https://www.google.com/accounts/o8/id'; + header('Location: ' . $openid->authUrl()); + } + } + +function auth() + +{ + if ($_SESSION['authed'] == true) return true; + global $openid; + + if($openid->mode) { + $attr = $openid->getAttributes(); + if ($attr["contact/email"] != "maxious@gmail.com") { + die("Access Denied"); + } else { + $_SESSION['authed'] = true; + } + } else { + login(); + } + } + --- a/include/common-db.inc.php +++ b/include/common-db.inc.php @@ -1,23 +1,39 @@ --- a/include/common-geo.inc.php +++ b/include/common-geo.inc.php @@ -1,152 +1,170 @@ $mapPoint) { - $markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . $markerImage . ($index + 1); - if ($index + 1 != sizeof($mapPoints)) $markers.= "|"; - if ($mapPoint[0] < $minlat) $minlat = $mapPoint[0]; - if ($mapPoint[0] > $maxlat) $maxlat = $mapPoint[0]; - if ($mapPoint[1] < $minlon) $minlon = $mapPoint[1]; - if ($mapPoint[1] > $maxlon) $maxlon = $mapPoint[1]; - $totalLat+= $mapPoint[0]; - $totalLon+= $mapPoint[1]; - } - if ($zoom == 0) { - $mapwidthinmeters = distance($minlat, $minlon, $minlat, $maxlon); - foreach (array_reverse($metersperpixel, true) as $zoomLevel => $maxdistance) { - if ($zoom == 0 && $mapwidthinmeters < ($maxdistance + 50)) $zoom = $zoomLevel; - } - } - $center = $totalLat / sizeof($mapPoints) . "," . $totalLon / sizeof($mapPoints); - } - $output = ""; - if ($collapsible) $output.= '

Open Map...

'; - $output.= ''; - if ($collapsible) $output.= '
'; - return $output; -} -function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false) -{ - $pi80 = M_PI / 180; - $lat1*= $pi80; - $lng1*= $pi80; - $lat2*= $pi80; - $lng2*= $pi80; - $r = 6372.797; // mean radius of Earth in km - $dlat = $lat2 - $lat1; - $dlng = $lng2 - $lng1; - $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2); - $c = 2 * atan2(sqrt($a) , sqrt(1 - $a)); - $km = $r * $c; - if ($roundLargeValues) { - if ($km < 1) return floor($km * 1000); - else return round($km,2)."k"; - } else return floor($km * 1000); + +function staticmap($mapPoints, $collapsible = true, $twotone = false, $path = false, $numbered = false) { + + $markers = ""; + $height = 300; + $width = $height; + $index = 0; + if (sizeof($mapPoints) < 1) + return "map error"; + if (sizeof($mapPoints) === 1) { + $markers = "markers={$mapPoints[0][0]},{$mapPoints[0][1]}"; + } else { + if (!$numbered) { + $markers = "markers="; + } + if ($path) { + $markers.= "markers={$mapPoints[0][0]},{$mapPoints[0][1]}&path="; + } + foreach ($mapPoints as $index => $mapPoint) { + if ($twotone && $index == 0) { + $markers = "markerd=color:red|".$mapPoint[0] . "," . $mapPoint[1]."&markers="; + } else { + if ($numbered) { + $label = ($index > 9 ? 9 : $index); + $markers.= "markers=label:$label|" . $mapPoint[0] . "," . $mapPoint[1]; + if ($index + 1 != sizeof($mapPoints)) { + $markers.= "&"; + } + } else { + $markers.= $mapPoint[0] . "," . $mapPoint[1]; + if ($index + 1 != sizeof($mapPoints)) { + $markers.= "|"; + } + } + $index++; + } + } + } + $output = ""; + if ($collapsible) + $output.= '

Open Map...

'; + if (isIOSDevice()) $output.= 'map of stop location'; + else $output.= 'map of stop location'; + + if ($collapsible) + $output.= '
'; + return $output; } -function decodePolylineToArray($encoded) -{ - // source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5 - $length = strlen($encoded); - $index = 0; - $points = array(); - $lat = 0; - $lng = 0; - while ($index < $length) { - // Temporary variable to hold each ASCII byte. - $b = 0; - // The encoded polyline consists of a latitude value followed by a - // longitude value. They should always come in pairs. Read the - // latitude value first. - $shift = 0; - $result = 0; - do { - // The `ord(substr($encoded, $index++))` statement returns the ASCII - // code for the character at $index. Subtract 63 to get the original - // value. (63 was added to ensure proper ASCII characters are displayed - // in the encoded polyline string, which is `human` readable) - $b = ord(substr($encoded, $index++)) - 63; - // AND the bits of the byte with 0x1f to get the original 5-bit `chunk. - // Then left shift the bits by the required amount, which increases - // by 5 bits each time. - // OR the value into $results, which sums up the individual 5-bit chunks - // into the original value. Since the 5-bit chunks were reversed in - // order during encoding, reading them in this way ensures proper - // summation. - $result|= ($b & 0x1f) << $shift; - $shift+= 5; - } - // Continue while the read byte is >= 0x20 since the last `chunk` - // was not OR'd with 0x20 during the conversion process. (Signals the end) - while ($b >= 0x20); - // Check if negative, and convert. (All negative values have the last bit - // set) - $dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1)); - // Compute actual latitude since value is offset from previous value. - $lat+= $dlat; - // The next values will correspond to the longitude for this point. - $shift = 0; - $result = 0; - do { - $b = ord(substr($encoded, $index++)) - 63; - $result|= ($b & 0x1f) << $shift; - $shift+= 5; - } while ($b >= 0x20); - $dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1)); - $lng+= $dlng; - // The actual latitude and longitude values were multiplied by - // 1e5 before encoding so that they could be converted to a 32-bit - // integer representation. (With a decimal accuracy of 5 places) - // Convert back to original values. - $points[] = array( - $lat * 1e-5, - $lng * 1e-5 - ); - } - return $points; +function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false) { + $pi80 = M_PI / 180; + $lat1*= $pi80; + $lng1*= $pi80; + $lat2*= $pi80; + $lng2*= $pi80; + $r = 6372.797; // mean radius of Earth in km + $dlat = $lat2 - $lat1; + $dlng = $lng2 - $lng1; + $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2); + $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); + $km = $r * $c; + if ($roundLargeValues) { + if ($km < 1) + return floor($km * 1000); + else + return round($km, 2) . "k"; + } + else + return floor($km * 1000); } -function geocode($query, $giveOptions) -{ - global $cloudmadeAPIkey; - $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?query=" . urlencode($query) . "&bbox=-35.5,149.00,-35.15,149.1930&return_location=true&bbox_only=true"; - $contents = json_decode(getPage($url)); - if ($giveOptions) return $contents->features; - elseif (isset($contents->features[0]->centroid)) return $contents->features[0]->centroid->coordinates[0] . "," . $contents->features[0]->centroid->coordinates[1]; - else return ""; + +function decodePolylineToArray($encoded) { + // source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5 + $length = strlen($encoded); + $index = 0; + $points = array(); + $lat = 0; + $lng = 0; + while ($index < $length) { + // Temporary variable to hold each ASCII byte. + $b = 0; + // The encoded polyline consists of a latitude value followed by a + // longitude value. They should always come in pairs. Read the + // latitude value first. + $shift = 0; + $result = 0; + do { + // The `ord(substr($encoded, $index++))` statement returns the ASCII + // code for the character at $index. Subtract 63 to get the original + // value. (63 was added to ensure proper ASCII characters are displayed + // in the encoded polyline string, which is `human` readable) + $b = ord(substr($encoded, $index++)) - 63; + // AND the bits of the byte with 0x1f to get the original 5-bit `chunk. + // Then left shift the bits by the required amount, which increases + // by 5 bits each time. + // OR the value into $results, which sums up the individual 5-bit chunks + // into the original value. Since the 5-bit chunks were reversed in + // order during encoding, reading them in this way ensures proper + // summation. + $result|= ($b & 0x1f) << $shift; + $shift+= 5; + } + // Continue while the read byte is >= 0x20 since the last `chunk` + // was not OR'd with 0x20 during the conversion process. (Signals the end) + while ($b >= 0x20); + // Check if negative, and convert. (All negative values have the last bit + // set) + $dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1)); + // Compute actual latitude since value is offset from previous value. + $lat+= $dlat; + // The next values will correspond to the longitude for this point. + $shift = 0; + $result = 0; + do { + $b = ord(substr($encoded, $index++)) - 63; + $result|= ($b & 0x1f) << $shift; + $shift+= 5; + } while ($b >= 0x20); + $dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1)); + $lng+= $dlng; + // The actual latitude and longitude values were multiplied by + // 1e5 before encoding so that they could be converted to a 32-bit + // integer representation. (With a decimal accuracy of 5 places) + // Convert back to original values. + $points[] = array( + $lat * 1e-5, + $lng * 1e-5 + ); + } + return $points; } -function reverseGeocode($lat, $lng) -{ - global $cloudmadeAPIkey; - $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?around=" . $lat . "," . $lng . "&distance=closest&object_type=road"; - $contents = json_decode(getPage($url)); - return $contents->features[0]->properties->name; + +function geocode($query, $giveOptions) { + global $cloudmadeAPIkey; + $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?query=" . urlencode($query) . "&bbox=-35.5,149.00,-35.15,149.1930&return_location=true&bbox_only=true"; + $contents = json_decode(getPage($url)); + if ($giveOptions) + return $contents->features; + elseif (isset($contents->features[0]->centroid)) + return $contents->features[0]->centroid->coordinates[0] . "," . $contents->features[0]->centroid->coordinates[1]; + else + return ""; } -?> +function reverseGeocode($lat, $lng) { + global $cloudmadeAPIkey; + $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?around=" . $lat . "," . $lng . "&distance=closest&object_type=road"; + $contents = json_decode(getPage($url)); + return $contents->features[0]->properties->name; +} + --- a/include/common-net.inc.php +++ b/include/common-net.inc.php @@ -1,31 +1,46 @@ Database temporarily unavailable: "; - echo curl_errno($ch) . " " . curl_error($ch); - if (isDebug()) { - echo $url; - } - echo "
"; - } - curl_close($ch); - debug(print_r($page,true),"json"); - return $page; + +/* + * Copyright 2010,2011 Alexander Sadleir + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +function getPage($url) { + debug($url, "json"); + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_TIMEOUT, 45); + $page = curl_exec($ch); + if (curl_errno($ch)) { + echo " Database temporarily unavailable: "; + echo curl_errno($ch) . " " . curl_error($ch); + if (isDebug()) { + echo $url; + } + echo "
"; + } + curl_close($ch); + debug(print_r($page, true), "json"); + return $page; } -function curPageURL() -{ - $isHTTPS = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"); - $port = (isset($_SERVER["SERVER_PORT"]) && ((!$isHTTPS && $_SERVER["SERVER_PORT"] != "80") || ($isHTTPS && $_SERVER["SERVER_PORT"] != "443"))); - $port = ($port) ? ':' . $_SERVER["SERVER_PORT"] : ''; - $url = ($isHTTPS ? 'https://' : 'http://') . $_SERVER["SERVER_NAME"] . $port . htmlentities(dirname($_SERVER['PHP_SELF']) , ENT_QUOTES); - return $url; +function curPageURL() { + $isHTTPS = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"); + $port = (isset($_SERVER["SERVER_PORT"]) && ((!$isHTTPS && $_SERVER["SERVER_PORT"] != "80") || ($isHTTPS && $_SERVER["SERVER_PORT"] != "443"))); + $port = ($port) ? ':' . $_SERVER["SERVER_PORT"] : ''; + $url = ($isHTTPS ? 'https://' : 'http://') . $_SERVER["SERVER_NAME"] . $port . htmlentities(dirname($_SERVER['PHP_SELF']), ENT_QUOTES); + return $url; } -?> + --- a/include/common-request.inc.php +++ b/include/common-request.inc.php @@ -1,48 +1,84 @@ + --- a/include/common-session.inc.php +++ b/include/common-session.inc.php @@ -1,63 +1,70 @@ centroid)) { + $geocoded = true; + $_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; + $_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; + } else { + $_SESSION['lat'] = ""; + $_SESSION['lon'] = ""; + } + } + } + sessionUpdated(); } -if (isset($_REQUEST['time'])) { - $_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING); - sessionUpdated(); + +function sessionUpdated() { + $_SESSION['lastUpdated'] = time(); } -if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") { - $geocoded = false; - if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) { - $_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); - $_SESSION['lon'] = trim(filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); - } - else { - if (startsWith($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['lon'] = $locateparts[1]; - } - else { - $contents = geocode($geolocate, true); - print_r($contents); - if (isset($contents[0]->centroid)) { - $geocoded = true; - $_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; - $_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; - } - else { - $_SESSION['lat'] = ""; - $_SESSION['lon'] = ""; - } - } - } - sessionUpdated(); -} -function sessionUpdated() -{ - $_SESSION['lastUpdated'] = time(); -} + // timeoutSession $TIMEOUT_LIMIT = 60 * 5; // 5 minutes if (isset($_SESSION['lastUpdated']) && $_SESSION['lastUpdated'] + $TIMEOUT_LIMIT < time()) { - debug("Session timeout " . ($_SESSION['lastUpdated'] + $TIMEOUT_LIMIT) . ">" . time() , "session"); - session_destroy(); - session_start(); + debug("Session timeout " . ($_SESSION['lastUpdated'] + $TIMEOUT_LIMIT) . ">" . time(), "session"); + session_destroy(); + session_start(); } + //debug(print_r($_SESSION, true) , "session"); -function current_time() -{ - return ($_SESSION['time'] ? $_SESSION['time'] : date("H:i:s")); +function current_time($time = "") { + if (isset($_REQUEST['time'])) return $_REQUEST['time']; + else if ($time != "") date("H:i:s",$time); + else return date("H:i:s"); } -?> + --- a/include/common-template.inc.php +++ b/include/common-template.inc.php @@ -1,65 +1,75 @@ - ' . $pageTitle . ' - - '; - if (isDebugServer()) { - echo ' - - - + - '; - } - else { - echo ' - - - '; - } - echo ' - - - - - + } + + +}]); + + '; - echo ''; - if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad')) { - echo ' + echo ''; + echo ''; + if (isIOSDevice()) { + echo ' '; - } - if ($geolocate) { - echo " "; - } - if (isAnalyticsOn()) echo ' + if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") + echo "geolocate();"; + echo " "; + } + if (isAnalyticsOn()) + echo ' "; - echo ' + echo ' '; - if ($opendiv) { - echo '
+ if ($opendiv) { + echo '
Back

' . $pageTitle . '

- Home + Home
'; - $overrides = getServiceOverride(); - if ($overrides['service_id']) { - if ($overrides['service_id'] == "noservice") { - echo '
Buses are not running today due to industrial action/public holiday. See Buses are not running today due to industrial action/public holiday. See http://www.action.act.gov.au for details.
'; - } - else { - echo '
Buses are running on an altered timetable today due to industrial action/public holiday. See http://www.action.act.gov.au for details.
'; - } - } - } - -} -function include_footer() -{ - echo ''; - if (isAnalyticsOn()) { - echo ""; - $googleAnalyticsImageUrl = googleAnalyticsGetImageUrl(); - echo ''; - - } - echo "\n
"; -} -function timePlaceSettings($geolocate = false) -{ - global $service_periods; - $geoerror = false; - if ($geolocate == true) { - $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; - } - echo '
'; - if ($geoerror) { - echo 'Sorry, but your location could not currently be detected. + $googleAnalyticsImageUrl = googleAnalyticsGetImageUrl(); + echo ''; + } + echo "\n
"; +} + +function timeSettings() { + global $service_periods; + echo '
+

Change Time (' . (isset($_REQUEST['time']) ? $_REQUEST['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...

+
+ + + + +
+
+ + + Current Time? +
+
+ + + +
+ + +
+
'; +} + +function placeSettings() { + + $geoerror = false; + $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; + + echo '
'; + if ($geoerror) { + echo 'Sorry, but your location could not currently be detected. Please allow location permission, wait for your location to be detected, or enter an address/co-ordinates in the box below.'; - } - echo '
'; - echo '
-

Change Time/Place (' . (isset($_SESSION['time']) ? $_SESSION['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...

+ } + echo '
'; + echo '
+

Change Location...

-
- - - Current Time? -
-
- - - -
'; } -function trackEvent($category, $action, $label = "", $value = - 1) -{ - if (isAnalyticsOn()) { - echo "\n"; - } -} -?> - + +function trackEvent($category, $action, $label = "", $value = - 1) { + if (isAnalyticsOn()) { + echo "\n"; + } +} + +//stop list collapsing +function stopCompare($stopName) { + return substr(trim(preg_replace("/\(Platform.*/", "", $stopName)), 0, 9); +} + +function stopGroupTitle($stopName, $stopdesc) { + if (preg_match("/Dr |Cct |Cir |Av |St |Cr |Parade |Way |Bank /", $stopName)) { + $descParts = explode("
", $stopdesc); + return trim(str_replace("Street: ", "", $descParts[0])); + } else { + return trim(preg_replace("/\(Platform.*/", "", $stopName)); + } +} + +function viaPointNames($tripid, $stop_sequence = "") { + $viaPointNames = Array(); + foreach (viaPoints($tripid, $stop_sequence) as $point) { + if (strstr($point['stop_name'], "Station") + || strstr($point['stop_name'], "Shops") + || strstr($point['stop_name'], "CIT") + || strstr($point['stop_name'], "School") + || strstr($point['stop_name'], "University") + ) { + $viaPointNames[] = $point['stop_name']; + } + } + if (sizeof($viaPointNames) > 0) { + return r_implode(", ", $viaPointNames); + } else { + return ""; + } +} + --- a/include/common-transit.inc.php +++ b/include/common-transit.inc.php @@ -1,46 +1,339 @@ 0) { - $midnight = mktime(0, 0, 0, date("n") , date("j") , date("Y")); - return date("h:ia", $midnight + $seconds); - } - else { - return ""; - } -} -?> - +function service_period($date = "") { + + if (isset($_REQUEST['service_period'])) { + return $_REQUEST['service_period']; + } + + $override = getServiceOverride($date); + if (isset($override['service_id'])) { + return strtolower($override['service_id']); + } + $date = ($date != "" ? $date : time()); + $dow = date('w', $date); + + switch ($dow) { + case 0: + return 'sunday'; + case 6: + return 'saturday'; + default: + return 'weekday'; + } +} + +function service_ids($service_period, $date = "") { + switch ($service_period) { + case 'sunday': + return Array("Sunday", "Sunday"); + case 'saturday': + return Array("Saturday", "Saturday"); + default: + $date = ($date != "" ? $date : time()); +// school holidays + $ymd = date('Ymd', $date); + $dow = date('w', $date); + if (intval($ymd) < "20120203" && $dow != 0 && $dow != 6) { + return Array("Weekday-SchoolVacation", "Weekday-SchoolVacation"); + } else { + return Array("Weekday", "Weekday"); + } + } +} + +function valid_service_ids() { + return array_merge(service_ids(""), service_ids('saturday'), service_ids('sunday')); +} + +function midnight_seconds($time = "") { + // from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html + if ($time != "") { + return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); + } + if (isset($_SESSION['time'])) { + $time = strtotime($_SESSION['time']); + return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); + } + return (date("G") * 3600) + (date("i") * 60) + date("s"); +} + +function midnight_seconds_to_time($seconds) { + if ($seconds > 0) { + $midnight = mktime(0, 0, 0, date("n"), date("j"), date("Y")); + return date("h:ia", $midnight + $seconds); + } else { + return ""; + } +} + +if ($GTFSREnabled) { + $serviceAlertCause = Array( + "UNKNOWN_CAUSE" => "Unknown cause", + "OTHER_CAUSE" => "Other cause", + "TECHNICAL_PROBLEM" => "Technical problem", + "STRIKE" => "Strike", + "DEMONSTRATION" => "Demonstration", + "ACCIDENT" => "Accident", + "HOLIDAY" => "Holiday", + "WEATHER" => "Weather", + "MAINTENANCE" => "Maintenance", + "CONSTRUCTION" => "Construction", + "POLICE_ACTIVITY" => "Police activity", + "MEDICAL_EMERGENCY" => "Medical emergency" + ); + $serviceAlertEffect = Array( + "NO_SERVICE" => "No service", + "REDUCED_SERVICE" => "Reduced service", + "SIGNIFICANT_DELAYS" => "Significant delays", + "DETOUR" => "Detour", + "ADDITIONAL_SERVICE" => "Additional service", + "MODIFIED_SERVICE" => "Modified service", + "OTHER_EFFECT" => "Other effect", + "UNKNOWN_EFFECT" => "Unknown effect", + "STOP_MOVED" => "Stop moved"); + + set_include_path(get_include_path() . PATH_SEPARATOR . ($basePath . "lib/Protobuf-PHP/library/DrSlump/")); + + include_once("Protobuf.php"); + include_once("Protobuf/Message.php"); + include_once("Protobuf/Registry.php"); + include_once("Protobuf/Descriptor.php"); + include_once("Protobuf/Field.php"); + + include_once($basePath . "lib/Protobuf-PHP/gtfs-realtime.php"); + include_once("Protobuf/CodecInterface.php"); + include_once("Protobuf/Codec/PhpArray.php"); + include_once("Protobuf/Codec/Binary.php"); + include_once("Protobuf/Codec/Binary/Writer.php"); + include_once("Protobuf/Codec/Json.php"); + + function getServiceAlerts($filter_class = "", $filter_id = "") { + /* + + also need last modified epoch of client gtfs + + - add,remove,patch,inform (null) + - stop + - trip + - network + - classes (WHERE=) + - route (short_name or route_id) + - street + - stop + - trip + Currently support: + network inform + trip patch: stop remove + street inform: route inform, trip inform, stop inform + route patch: trip remove + */ + $current_alerts = getCurrentAlerts(); + $informed_count = 0; + if (sizeof($current_alerts) > 0) { + + $fm = new transit_realtime\FeedMessage(); + $fh = new transit_realtime\FeedHeader(); + $fh->setGtfsRealtimeVersion(1); + $fh->setTimestamp(time()); + $fm->setHeader($fh); + foreach ($current_alerts as $current_alert) { + $affectsFilteredEntities = false; + $fe = new transit_realtime\FeedEntity(); + $fe->setId($current_alert['id']); + $fe->setIsDeleted(false); + $alert = new transit_realtime\Alert(); + $tr = new transit_realtime\TimeRange(); + $tr->setStart($current_alert['start']); + $tr->setEnd($current_alert['end']); + $alert->addActivePeriod($tr); + $informedEntities = getInformedAlerts($current_alert['id'], $filter_class, $filter_id); + if (sizeof($informedEntities) > 0) { + + $affectsFilteredEntities = true; + foreach ($informedEntities as $informedEntity) { + $informed_count++; + $informed = Array(); + $es = new transit_realtime\EntitySelector(); + if ($informedEntity['informed_class'] == "agency") { + $es->setAgencyId($informedEntity['informed_id']); + } + if ($informedEntity['informed_class'] == "stop") { + $es->setStopId($informedEntity['informed_id']); + } + if ($informedEntity['informed_class'] == "route") { + $es->setRouteId($informedEntity['informed_id']); + } + if ($informedEntity['informed_class'] == "trip") { + $td = new transit_realtime\TripDescriptor(); + $td->setTripId($informedEntity['informed_id']); + $es->setTrip($td); + } + $alert->addInformedEntity($es); +} + } + if ($current_alert['cause'] != "") { + $alert->setCause(constant("transit_realtime\Alert\Cause::" . $current_alert['cause'])); + } + if ($current_alert['effect'] != "") { + $alert->setEffect(constant("transit_realtime\Alert\Effect::" . $current_alert['effect'])); + } + if ($current_alert['url'] != "") { + $tsUrl = new transit_realtime\TranslatedString(); + $tUrl = new transit_realtime\TranslatedString\Translation(); + $tUrl->setText($current_alert['url']); + $tUrl->setLanguage("en"); + $tsUrl->addTranslation($tUrl); + $alert->setUrl($tsUrl); + } + if ($current_alert['header'] != "") { + $tsHeaderText = new transit_realtime\TranslatedString(); + $tHeaderText = new transit_realtime\TranslatedString\Translation(); + $tHeaderText->setText($current_alert['header']); + $tHeaderText->setLanguage("en"); + $tsHeaderText->addTranslation($tHeaderText); + $alert->setHeaderText($tsHeaderText); + } + if ($current_alert['description'] != "") { + $tsDescriptionText = new transit_realtime\TranslatedString(); + $tDescriptionText = new transit_realtime\TranslatedString\Translation(); + $tDescriptionText->setText(trim($current_alert['description'])); + $tDescriptionText->setLanguage("en"); + $tsDescriptionText->addTranslation($tDescriptionText); + $alert->setDescriptionText($tsDescriptionText); + } + $fe->setAlert($alert); + if ($affectsFilteredEntities) { + $fm->addEntity($fe); + } + } + if ($informed_count > 0) { + return $fm; + } else { + return null; + } + } else + return null; + } + + function getServiceAlertsAsArray($filter_class = "", $filter_id = "") { + + $alerts = getServiceAlerts($filter_class, $filter_id); + if ($alerts != null) { + $codec = new DrSlump\Protobuf\Codec\PhpArray(); + + return $codec->encode($alerts); + } else { + return null; + } + } + + function getServiceAlertsAsBinary($filter_class = "", $filter_id = "") { + $codec = new DrSlump\Protobuf\Codec\Binary(); + return $codec->encode(getServiceAlerts($filter_class, $filter_id)); + } + + function getServiceAlertsAsJSON($filter_class = "", $filter_id = "") { + $codec = new DrSlump\Protobuf\Codec\Json(); + return $codec->encode(getServiceAlerts($filter_class, $filter_id)); + } + + function getServiceAlertsByClass() { + $return = Array(); + $alerts = getServiceAlertsAsArray("", ""); + foreach ($alerts['entities'] as $entity) { + foreach ($entity['informed'] as $informed) { + foreach ($informed as $key => $value) { + if (strpos("_id", $key) > 0) { + $parts = explode($key); + $class = $parts[0]; + $id = $value; + } + } + $return[$class][$id][] = $entity; + } + } + } + + function getTripUpdates($filter_class = "", $filter_id = "") { + $fm = new transit_realtime\FeedMessage(); + $fh = new transit_realtime\FeedHeader(); + $fh->setGtfsRealtimeVersion(1); + $fh->setTimestamp(time()); + $fm->setHeader($fh); + foreach (getCurrentAlerts() as $alert) { + $informedEntities = getInformedAlerts($alert['id'], $_REQUEST['filter_class'], $_REQUEST['filter_id']); + $stops = Array(); + $routestrips = Array(); + if (sizeof($informedEntities) > 0) { + if ($informedEntity['informed_class'] == "stop" && $informed["x-action"] == "remove") { + $stops[] = $informedEntity['informed_id']; + } + if (($informedEntity['informed_class'] == "route" || $informedEntity['informed_class'] == "trip") && $informed["x-action"] == "patch") { + $routestrips[] = Array("id" => $informedEntity['informed_id'], + "type" => $informedEntity['informed_class']); + } + } + foreach ($routestrips as $routetrip) { + $fe = new transit_realtime\FeedEntity(); + $fe->setId($alert['id'] . $routetrip['id']); + $fe->setIsDeleted(false); + $tu = new transit_realtime\TripUpdate(); + $td = new transit_realtime\TripDescriptor(); + if ($routetrip['type'] == "route") { + $td->setRouteId($routetrip['id']); + } else if ($routetrip['type'] == "trip") { + $td->setTripId($routetrip['id']); + } + $tu->setTrip($td); + foreach ($stops as $stop) { + $stu = new transit_realtime\TripUpdate\StopTimeUpdate(); + $stu->setStopId($stop); + $stu->setScheduleRelationship(transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SKIPPED); + $tu->addStopTimeUpdate($stu); + } + $fe->setTripUpdate($tu); + $fm->addEntity($fe); + } + } + return $fm; + } + + function getTripUpdatesAsArray($filter_class = "", $filter_id = "") { + $codec = new DrSlump\Protobuf\Codec\PhpArray(); + return $codec->encode(getTripUpdates($filter_class, $filter_id)); + } + + function getTripUpdatesAsBinary($filter_class = "", $filter_id = "") { + $codec = new DrSlump\Protobuf\Codec\Binary(); + return $codec->encode(getTripUpdates($filter_class, $filter_id)); + } + + function getTripUpdatesAsJSON($filter_class = "", $filter_id = "") { + $codec = new DrSlump\Protobuf\Codec\Json(); + return $codec->encode(getTripUpdates($filter_class, $filter_id)); + } + +} + --- a/include/common.inc.php +++ b/include/common.inc.php @@ -1,185 +1,210 @@ \n"; -} -function isJQueryMobileDevice() -{ - // http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897 - $user_agent = $_SERVER['HTTP_USER_AGENT']; - return preg_match('/iphone/i', $user_agent) || preg_match('/android/i', $user_agent) || preg_match('/webos/i', $user_agent) || preg_match('/ios/i', $user_agent) || preg_match('/bada/i', $user_agent) || preg_match('/maemo/i', $user_agent) || preg_match('/meego/i', $user_agent) || preg_match('/fennec/i', $user_agent) || (preg_match('/symbian/i', $user_agent) && preg_match('/s60/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/symbian/i', $user_agent) && preg_match('/platform/i', $user_agent) && $browser['majorver'] >= 3) || (preg_match('/blackberry/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/opera mobile/i', $user_agent) && $browser['majorver'] >= 10) || (preg_match('/opera mini/i', $user_agent) && $browser['majorver'] >= 5); -} -function isFastDevice() -{ - $ua = $_SERVER['HTTP_USER_AGENT']; - $fastDevices = Array( - "Mozilla/5.0 (X11;", - "Mozilla/5.0 (Windows;", - "Mozilla/5.0 (iP", - "Mozilla/5.0 (Linux; U; Android", - "Mozilla/4.0 (compatible; MSIE" - ); - $slowDevices = Array( - "J2ME", - "MIDP", - "Opera/", - "Mozilla/2.0 (compatible;", - "Mozilla/3.0 (compatible;" - ); - return true; -} -function array_flatten($a, $f = array()) -{ - if (!$a || !is_array($a)) return ''; - foreach ($a as $k => $v) { - if (is_array($v)) $f = array_flatten($v, $f); - else $f[$k] = $v; - } - return $f; -} -function remove_spaces($string) -{ - return str_replace(' ', '', $string); -} -function object2array($object) -{ - if (is_object($object)) { - foreach ($object as $key => $value) { - $array[$key] = $value; - } - } - else { - $array = $object; - } - return $array; -} -function startsWith($haystack, $needle, $case = true) -{ - if ($case) { - return (strcmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); - } - return (strcasecmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); -} - -function endsWith($haystack, $needle, $case = true) -{ - if ($case) { - return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); - } - return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); -} -function bracketsMeanNewLine($input) -{ - return str_replace(")", "", str_replace("(", "
", $input)); -} -function sksort(&$array, $subkey = "id", $sort_ascending = false) -{ - if (count($array)) $temp_array[key($array) ] = array_shift($array); - foreach ($array as $key => $val) { - $offset = 0; - $found = false; - foreach ($temp_array as $tmp_key => $tmp_val) { - if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { - $temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( - $key => $val - ) , array_slice($temp_array, $offset)); - $found = true; - } - $offset++; - } - if (!$found) $temp_array = array_merge($temp_array, array( - $key => $val - )); - } - if ($sort_ascending) $array = array_reverse($temp_array); - else $array = $temp_array; -} -function sktimesort(&$array, $subkey = "id", $sort_ascending = false) -{ - if (count($array)) $temp_array[key($array) ] = array_shift($array); - foreach ($array as $key => $val) { - $offset = 0; - $found = false; - foreach ($temp_array as $tmp_key => $tmp_val) { - if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) { - $temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( - $key => $val - ) , array_slice($temp_array, $offset)); - $found = true; - } - $offset++; - } - if (!$found) $temp_array = array_merge($temp_array, array( - $key => $val - )); - } - if ($sort_ascending && isset($temp_array)) $array = array_reverse($temp_array); - else $array = $temp_array; -} -function r_implode( $glue, $pieces ) -{ - foreach( $pieces as $r_pieces ) - { - if( is_array( $r_pieces ) ) - { - $retVal[] = r_implode( $glue, $r_pieces ); - } - else - { - $retVal[] = $r_pieces; - } - } - return implode( $glue, $retVal ); -} -?> - +function isAnalyticsOn() { + $user_agent = $_SERVER['HTTP_USER_AGENT']; + return !isDebugServer() && !preg_match('/cloudkick/i', $user_agent) && !preg_match('/googlebot/i', $user_agent) && + !preg_match('/baidu/i', $user_agent); +} + +function isDebug($debugReason = "other") { + global $debugOkay; + return in_array($debugReason, $debugOkay, false) && isDebugServer(); +} + +function debug($msg, $debugReason = "other") { + if (isDebug($debugReason)) + echo "\n\n"; +} +function isIOSDevice() { + return strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad'); +} +function isJQueryMobileDevice() { + // http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897 + $user_agent = $_SERVER['HTTP_USER_AGENT']; + return preg_match('/iphone/i', $user_agent) || preg_match('/android/i', $user_agent) || preg_match('/webos/i', $user_agent) || preg_match('/ios/i', $user_agent) || preg_match('/bada/i', $user_agent) || preg_match('/maemo/i', $user_agent) || preg_match('/meego/i', $user_agent) || preg_match('/fennec/i', $user_agent) || (preg_match('/symbian/i', $user_agent) && preg_match('/s60/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/symbian/i', $user_agent) && preg_match('/platform/i', $user_agent) && $browser['majorver'] >= 3) || (preg_match('/blackberry/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/opera mobile/i', $user_agent) && $browser['majorver'] >= 10) || (preg_match('/opera mini/i', $user_agent) && $browser['majorver'] >= 5); +} + + +function array_flatten($a, $f = array()) { + if (!$a || !is_array($a)) + return ''; + foreach ($a as $k => $v) { + if (is_array($v)) + $f = array_flatten($v, $f); + else + $f[$k] = $v; + } + return $f; +} + +function remove_spaces($string) { + return str_replace(' ', '', $string); +} + +function object2array($object) { + if (is_object($object)) { + foreach ($object as $key => $value) { + $array[$key] = $value; + } + } else { + $array = $object; + } + return $array; +} + +function startsWith($haystack, $needle, $case = true) { + if ($case) { + return (strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0); + } + return (strcasecmp(substr($haystack, 0, strlen($needle)), $needle) === 0); +} + +function endsWith($haystack, $needle, $case = true) { + if ($case) { + return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0); + } + return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0); +} + +function sksort(&$array, $subkey = "id", $sort_ascending = false) { + if (count($array)) + $temp_array[key($array)] = array_shift($array); + foreach ($array as $key => $val) { + $offset = 0; + $found = false; + foreach ($temp_array as $tmp_key => $tmp_val) { + if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { + $temp_array = array_merge((array) array_slice($temp_array, 0, $offset), array( + $key => $val + ), array_slice($temp_array, $offset)); + $found = true; + } + $offset++; + } + if (!$found) + $temp_array = array_merge($temp_array, array( + $key => $val + )); + } + if ($sort_ascending) + $array = array_reverse($temp_array); + else + $array = $temp_array; +} + +function sktimesort(&$array, $subkey = "id", $sort_ascending = false) { + if (count($array)) + $temp_array[key($array)] = array_shift($array); + foreach ($array as $key => $val) { + $offset = 0; + $found = false; + foreach ($temp_array as $tmp_key => $tmp_val) { + if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) { + $temp_array = array_merge((array) array_slice($temp_array, 0, $offset), array( + $key => $val + ), array_slice($temp_array, $offset)); + $found = true; + } + $offset++; + } + if (!$found) + $temp_array = array_merge($temp_array, array( + $key => $val + )); + } + if ($sort_ascending && isset($temp_array)) + $array = array_reverse($temp_array); + else + $array = $temp_array; +} + +function r_implode($glue, $pieces) { + foreach ($pieces as $r_pieces) { + if (is_array($r_pieces)) { + $retVal[] = r_implode($glue, $r_pieces); + } else { + $retVal[] = $r_pieces; + } + } + return implode($glue, $retVal); +} + --- a/include/db/route-dao.inc.php +++ b/include/db/route-dao.inc.php @@ -1,212 +1,307 @@ prepare($query); - $query->bindParam(":routeID", $routeID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetch(PDO::FETCH_ASSOC); -} - -function getRoutes() -{ - global $conn; - $query = "Select * from routes order by route_short_name;"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - 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 = + +/* + * Copyright 2010,2011 Alexander Sadleir + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +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 getRoutesByShortName($routeShortName) { + global $conn; + $query = "Select distinct route_id, route_short_name from routes where route_short_name = :routeShortName"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":routeShortName", $routeShortName); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRouteHeadsigns($routeID) { + global $conn; + $query = "select stops.stop_name, trip_headsign, direction_id,max(service_id) as service_id, count(*) + from routes join trips on trips.route_id = routes.route_id +join stop_times on stop_times.trip_id = trips.trip_id join stops on +stop_times.stop_id = stops.stop_id where trips.route_id = :routeID +and stop_times.stop_sequence = 1 group by stops.stop_name, trip_headsign, direction_id having count(*) > 2"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":routeID", $routeID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $results = $query->fetchAll(); + if (is_array($results)) { + return $results; + } else { + return Array($results); + } +} +function getRouteDescription($routeID, $directionID) { + $trip = getRouteNextTrip($routeID, $directionID); + $start = getTripStartingPoint($trip['trip_id']); + $end = getTripDestination($trip['trip_id']); + return "From ".$start['stop_name']." to ".$end['stop_name']; +} +function getRouteByFullName($routeFullName) { + global $conn; + $query = "Select * from routes where route_short_name||route_long_name = :routeFullName LIMIT 1"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":routeFullName", $routeFullName); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function getRoutes() { + global $conn; + $query = "Select * from routes order by route_short_name;"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRoutesByNumberSeries($routeNumberSeries = "") { + global $conn; + if (strlen($routeNumberSeries) == 1) { + return getRoute($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 + 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, $directionID) { + global $conn; + + $query = "select routes.route_id,routes.route_url,direction_id,trips.trip_id,trip_headsign,departure_time,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 arrival_time between :currentTime and :futureTime +and routes.route_id = :routeID and trips.direction_id = :directionID 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); - - // past last trip of the day special case - if (sizeof($r) < 16) { - $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 + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":currentTime", current_time()); + $futureTime = current_time(strtotime(current_time() ." +2h")); + if (date("h",strtotime(current_time()) > 22)) $futureTime = "23:59:59"; + $query->bindParam(":futureTime", $futureTime); + $query->bindParam(":routeID", $routeID); + $query->bindParam(":directionID", $directionID); + $query->execute(); + databaseError($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r; +} + +function getRouteFirstTrip($routeID,$directionID) { + 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 routes.route_id = :routeID +and trips.direction_id = :directionID order by arrival_time DESC limit 1"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":routeID", $routeID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - - $r = $query->fetch(PDO::FETCH_ASSOC); - } - return $r; -} -function getTimeInterpolatedRouteAtStop($routeID, $stop_id) -{ - $nextTrip = getRouteNextTrip($routeID); - if ($nextTrip['trip_id']) { - foreach (getTimeInterpolatedTrip($nextTrip['trip_id']) as $tripStop) { - if ($tripStop['stop_id'] == $stop_id) return $tripStop; - } - } - return Array(); -} -function getRouteTrips($routeID) -{ - 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 -join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID and stop_sequence = '1' order by + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":routeID", $routeID); + + $query->bindParam(":directionID", $directionID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r; +} + +function getRouteAtStop($routeID, $directionID, $stop_id) { + $nextTrip = getRouteNextTrip($routeID, $directionID); + if ($nextTrip['trip_id']) { + foreach (getTripStopTimes($nextTrip['trip_id']) as $tripStop) { + if ($tripStop['stop_id'] == $stop_id) + return $tripStop; + } + } + return Array(); +} + +function getRouteTrips($routeID, $directionID = "", $service_period = "") { + global $conn; + if ($service_period == "") + $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + $directionSQL = ""; + if ($directionID != "") + $directionSQL = " and direction_id = :directionID "; + $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 (service_id=:service_periodA OR service_id=:service_periodB) +AND (routes.route_id = :routeID) " . $directionSQL . " and stop_sequence = '1' order by arrival_time "; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":routeID", $routeID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function getRoutesByDestination($destination = "", $service_period = "") -{ - 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 + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":routeID", $routeID); + $query->bindParam(":service_periodA", $sidA); + $query->bindParam(":service_periodB", $sidB); + if ($directionSQL != "") + $query->bindParam(":directionID", $directionID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRoutesByDestination($destination = "", $service_period = "") { + global $conn; + if ($service_period == "") + $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + 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 = 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"; - } - else { - $query = "SELECT DISTINCT route_long_name -FROM stop_times join trips on trips.trip_id = -stop_times.trip_id join routes on trips.route_id = routes.route_id -WHERE service_id= :service_period order by route_long_name"; - } - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); - if ($destination != "") $query->bindParam(":destination", $destination); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function getRoutesBySuburb($suburb, $service_period = "") -{ - if ($service_period == "") $service_period = service_period(); - global $conn; - $query = "SELECT DISTINCT service_id,trips.route_id,route_short_name,route_long_name +WHERE route_long_name = :destination AND (service_id=:service_periodA OR service_id=:service_periodB) + order by route_short_name";*/ + $query = "select route_id, direction_id, stop_name, b.trip_id, b.stop_sequence from (select route_id, direction_id, max(stop_sequence) as stop_sequence, max(a.trip_id) as trip_id from stop_times inner join (SELECT route_id, direction_id, max(trip_id) as trip_id + from trips group by route_id,direction_id) as a on stop_times.trip_id = a.trip_id group by route_id, direction_id) as b inner join stop_times on b.trip_id = stop_times.trip_id inner join stops on stop_times.stop_id = stops.stop_id where stop_times.stop_sequence = b.stop_sequence and stop_name = :destination order by route_id;"; + } else { + $query = "select stop_name from (select route_id, direction_id, max(stop_sequence) as stop_sequence, max(a.trip_id) as trip_id from stop_times inner join (SELECT route_id, direction_id, max(trip_id) as trip_id + from trips group by route_id,direction_id) as a on stop_times.trip_id = a.trip_id group by route_id, direction_id) as b inner join stop_times on b.trip_id = stop_times.trip_id inner join stops on stop_times.stop_id = stops.stop_id where stop_times.stop_sequence = b.stop_sequence group by stop_name order by stop_name;"; + } + debug($query, "database"); + $query = $conn->prepare($query); + + //$query->bindParam(":service_periodA", $sidA); + //$query->bindParam(":service_periodB", $sidB); + if ($destination != "") + $query->bindParam(":destination", $destination); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRoutesBySuburb($suburb, $service_period = "") { + if ($service_period == "") + $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + + 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 join routes on trips.route_id = routes.route_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"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); - $suburb = "%" . $suburb . ";%"; - $query->bindParam(":suburb", $suburb); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function getRoutesNearby($lat, $lng, $limit = "", $distance = 500) -{ - if ($service_period == "") $service_period = service_period(); - 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, +WHERE stop_desc LIKE :suburb AND (service_id=:service_periodA OR service_id=:service_periodB) + ORDER BY route_short_name"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":service_periodA", $sidA); + $query->bindParam(":service_periodB", $sidB); + $suburb = "%Suburb: %" . $suburb . "%"; + $query->bindParam(":suburb", $suburb); + $query->execute(); + + databaseError($conn->errorInfo()); + + return $query->fetchAll(); +} + +function getRoutesNearby($lat, $lng, $limit = "", $distance = 500) { + // if ($service_period == "") + $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + $limitSQL = ""; + if ($limit != "") + $limitSQL = " LIMIT :limit "; + global $conn; + $query = "SELECT service_id,trips.route_id,trips.direction_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 FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id join stops on stops.stop_id = stop_times.stop_id -WHERE service_id=:service_period +WHERE (service_id=:service_periodA OR service_id=:service_periodB) 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,trips.direction_id,route_short_name,route_long_name order by distance $limitSQL"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); - $query->bindParam(":distance", $distance); - if ($limit != "") $query->bindParam(":limit", $limit); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -?> + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":service_periodA", $sidA); + $query->bindParam(":service_periodB", $sidB); + $query->bindParam(":distance", $distance); + if ($limit != "") + $query->bindParam(":limit", $limit); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + --- a/include/db/servicealert-dao.inc.php +++ b/include/db/servicealert-dao.inc.php @@ -1,15 +1,185 @@ 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); + +/* + * Copyright 2010,2011 Alexander Sadleir + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +function getServiceOverride($date = "") { + 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 + $date = date("Ymd", ($date != "" ? $date : time())); + $query->bindParam(":date", $date); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); } -?> + +function getServiceAlert($alertID) { + global $conn; + $query = "SELECT id,extract('epoch' from start) as start, extract('epoch' from \"end\") as \"end\",cause,effect,header,description,url from servicealerts_alerts where id = :servicealert_id"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":servicealert_id", $alertID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function updateServiceAlert($alertID, $alert) { + global $conn; + $query = 'update servicealerts_alerts set start=:start, "end"=:end, header=:header, description=:description, url=:url, cause=:cause, effect=:effect where id = :servicealert_id'; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindValue(":servicealert_id", $alertID); + $query->bindValue(":start", $alert['startdate']); + $query->bindValue(":end", $alert['enddate']); + $query->bindValue(":header", $alert['header']); + $query->bindValue(":description", $alert['description']); + $query->bindValue(":url", $alert['url']); + $query->bindValue(":cause", $alert['cause']); + $query->bindValue(":effect", $alert['effect']); + $query->execute(); + + print_r($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function addServiceAlert($alert) { + global $conn; + $query = 'INSERT INTO servicealerts_alerts (start, "end", header, description, url,cause,effect) VALUES (:start, :end, :header, :description, :url,:cause,:effect) '; + debug($query, "database"); + $query = $conn->prepare($query); + //print_r($alert); + $query->bindValue(":start", $alert['startdate']); + $query->bindValue(":end", $alert['enddate']); + $query->bindValue(":header", $alert['header']); + $query->bindValue(":description", $alert['description']); + $query->bindValue(":url", $alert['url']); + $query->bindValue(":cause", $alert['cause']); + $query->bindValue(":effect", $alert['effect']); + $query->execute(); + + print_r($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function getCurrentAlerts() { + global $conn; + $query = "SELECT id,extract('epoch' from start) as start, extract('epoch' from \"end\") as \"end\",cause,effect,header,description,url from servicealerts_alerts where NOW() > start and NOW() < \"end\""; + // debug($query, "database"); + $query = $conn->prepare($query); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getFutureAlerts() { + global $conn; + $query = "SELECT id,extract('epoch' from start) as start, extract('epoch' from \"end\") as \"end\",cause,effect,header,description,url from servicealerts_alerts where NOW() > start or NOW() < \"end\""; + // debug($query, "database"); + $query = $conn->prepare($query); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getInformedAlerts($id, $filter_class, $filter_id) { + + global $conn; + //echo "$id, $filter_class, $filter_id\n"; + $query = "SELECT * from servicealerts_informed where servicealert_id = :servicealert_id"; + + if ($filter_class != "") { + $query .= " AND informed_class = :informed_class "; + } + if ($filter_id != "") { + $query .= " AND informed_id = :informed_id "; + } + // debug($query, "database"); + $query = $conn->prepare($query); + if ($filter_class != "") { + $query->bindParam(":informed_class", $filter_class); + } + if ($filter_id != "") { + $query->bindParam(":informed_id", $filter_id); + } + $query->bindParam(":servicealert_id", $id); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function deleteInformedAlert($serviceAlertID, $class, $id) { + global $conn; + $query = 'DELETE from servicealerts_informed where servicealert_id = :servicealert_id and informed_class = :informed_class AND informed_id = :informed_id'; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":servicealert_id", $serviceAlertID); + $query->bindParam(":informed_class", $class); + $query->bindParam(":informed_id", $id); + $query->execute(); + print_r($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return null; +} + +function addInformedAlert($serviceAlertID, $class, $id, $action) { + global $conn; + $query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id, informed_action) + VALUES(:servicealert_id ,:informed_class, :informed_id, :informed_action)'; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":servicealert_id", $serviceAlertID); + $query->bindParam(":informed_class", $class); + $query->bindParam(":informed_id", $id); + $query->bindParam(":informed_action", $action); + $query->execute(); + + print_r($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return null; +} + --- a/include/db/stop-dao.inc.php +++ b/include/db/stop-dao.inc.php @@ -1,101 +1,182 @@ prepare($query); - $query->bindParam(":stopID", $stopID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetch(PDO::FETCH_ASSOC); -} -function getStops($timingPointsOnly = false, $firstLetter = "") -{ - global $conn; - $conditions = Array(); - if ($timingPointsOnly) $conditions[] = "substr(stop_code,1,2) != 'Wj'"; - if ($firstLetter != "") $conditions[] = "substr(stop_name,1,1) = :firstLetter"; - $query = "Select * from stops"; - if (sizeof($conditions) > 0) { - if (sizeof($conditions) > 1) { - $query.= " Where " . implode(" AND ", $conditions) . " "; - } - else { - $query.= " Where " . $conditions[0] . " "; - } - } - $query.= " order by stop_name;"; - $query = $conn->prepare($query); - if ($firstLetter != "") $query->bindParam(":firstLetter", $firstLetter); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function getNearbyStops($lat, $lng, $limit = "", $distance = 1000) -{ - if ($lat == null || $lng == null) return Array(); - if ($limit != "") $limitSQL = " LIMIT :limit "; - global $conn; - $query = "Select *, ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE) as distance + +/* + * Copyright 2010,2011 Alexander Sadleir + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +function getStop($stopID) { + global $conn; + $query = "Select * from stops where stop_id = :stopID LIMIT 1"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":stopID", $stopID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function getStops($firstLetter = "", $startsWith = "") { + global $conn; + $conditions = Array(); + if ($firstLetter != "") + $conditions[] = "substr(stop_name,1,1) = :firstLetter"; + if ($startsWith != "") + $conditions[] = "stop_name like :startsWith"; + $query = "Select * from stops"; + if (sizeof($conditions) > 0) { + if (sizeof($conditions) > 1) { + $query .= " Where " . implode(" AND ", $conditions) . " "; + } else { + $query .= " Where " . $conditions[0] . " "; + } + } + $query .= " order by stop_name;"; + debug($query, "database"); + $query = $conn->prepare($query); + if ($firstLetter != "") + $query->bindParam(":firstLetter", $firstLetter); + + if ($startsWith != "") { + $startsWith = $startsWith . "%"; + $query->bindParam(":startsWith", $startsWith); + } + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getNearbyStops($lat, $lng, $limit = "", $distance = 1000) { + if ($lat == null || $lng == null) + return Array(); + if ($limit != "") + $limitSQL = " LIMIT :limit "; + global $conn; + $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) order by distance $limitSQL;"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":distance", $distance); - $query->bindParam(":limit", $limit); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function getStopsBySuburb($suburb) -{ - global $conn; - $query = "Select * from stops where zone_id LIKE :suburb order by stop_name;"; - debug($query, "database"); - $query = $conn->prepare($query); - $suburb = "%" . $suburb . ";%"; - $query->bindParam(":suburb", $suburb); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function getStopRoutes($stopID, $service_period) -{ - if ($service_period == "") $service_period = service_period(); - global $conn; - $query = "SELECT service_id,trips.route_id,route_short_name,route_long_name + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":distance", $distance); + $query->bindParam(":limit", $limit); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopsByName($name) { + global $conn; + $query = "Select * from stops where stop_name LIKE :name;"; + debug($query, "database"); + $query = $conn->prepare($query); + $name = $name . "%"; + $query->bindParam(":name", $name); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopsBySuburb($suburb) { + global $conn; + $query = "Select * from stops where stop_desc LIKE :suburb order by stop_name;"; + debug($query, "database"); + $query = $conn->prepare($query); + $suburb = "%
Suburb: %" . $suburb . "%"; + $query->bindParam(":suburb", $suburb); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopsByStopCode($stop_code, $startsWith = "") { + global $conn; + $query = "Select * from stops where (stop_code = :stop_code OR stop_code LIKE :stop_code2)"; + if ($startsWith != "") + $query .= " AND stop_name like :startsWith"; + + debug($query, "database"); + $query = $conn->prepare($query); + + $query->bindParam(":stop_code", $stop_code); + $stop_code2 = $stop_code . "%"; + $query->bindParam(":stop_code2", $stop_code2); + if ($startsWith != "") { + $startsWith = $startsWith . "%"; + $query->bindParam(":startsWith", $startsWith); + } + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopRoutes($stopID, $service_period) { + if ($service_period == "") { + $service_period = service_period(); + } + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + 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 join routes on trips.route_id = routes.route_id WHERE stop_id = :stopID AND service_id=:service_period"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); - $query->bindParam(":stopID", $stopID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function getStopTrips($stopID, $service_period = "", $afterTime = "") -{ - if ($service_period == "") $service_period = service_period(); - global $conn; - 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 +stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_id = :stopID +AND (service_id=:service_periodA OR service_id=:service_periodB)"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":service_periodA", $sidA); + $query->bindParam(":service_periodB", $sidB); + $query->bindParam(":stopID", $stopID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopTrips($stopID, $service_period = "", $afterTime = "", $limit = "", $route_short_name = "") { + if ($service_period == "") { + $service_period = service_period(); + } + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + $limitSQL = ""; + if ($limit != "") + $limitSQL .= " LIMIT :limit "; + + global $conn; + if ($afterTime != "") { + $query = " SELECT stop_times.trip_id,stop_times.arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,trips.direction_id,trips.trip_headsign,route_short_name,route_long_name,end_times.arrival_time as end_time FROM stop_times join trips on trips.trip_id = stop_times.trip_id @@ -103,57 +184,66 @@ WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times WHERE stop_times.stop_id = :stopID AND stop_times.trip_id = end_times.trip_id -AND service_id=:service_period +AND (service_id=:service_periodA OR service_id=:service_periodB) " . ($route_short_name != "" ? " AND route_short_name = :route_short_name " : "") . " AND end_times.arrival_time > :afterTime -ORDER BY end_time"; - } - 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 +ORDER BY end_time $limitSQL"; + } 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 FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_times.stop_id = :stopID -AND service_id=:service_period -ORDER BY arrival_time"; - } - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":service_period", $service_period); - $query->bindParam(":stopID", $stopID); - if ($afterTime != "") $query->bindParam(":afterTime", $afterTime); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function getStopTripsWithTimes($stopID, $time = "", $service_period = "", $time_range = "", $limit = "") -{ - if ($service_period == "") $service_period = service_period(); - if ($time_range == "") $time_range = (24 * 60 * 60); - if ($time == "") $time = current_time(); - if ($limit == "") $limit = 10; - $trips = getStopTrips($stopID, $service_period, $time); - $timedTrips = Array(); - if ($trips && sizeof($trips) > 0) { - foreach ($trips as $trip) { - if ($trip['arrival_time'] != "") { - if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) { - $timedTrips[] = $trip; - } - } - else { - $timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']); - if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) { - $timedTrips[] = $timedTrip; - } - } - if (sizeof($timedTrips) > $limit) break; - } - sktimesort($timedTrips, "arrival_time", true); +AND (service_id=:service_periodA OR service_id=:service_periodB) " . ($route_short_name != "" ? " AND route_short_name = :route_short_name " : "") . " +ORDER BY arrival_time $limitSQL"; + } + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":service_periodA", $sidA); + $query->bindParam(":service_periodB", $sidB); + $query->bindParam(":stopID", $stopID); + if ($limit != "") + $query->bindParam(":limit", $limit); + if ($afterTime != "") + $query->bindParam(":afterTime", $afterTime); + if ($route_short_name != "") + $query->bindParam(":route_short_name", $route_short_name); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopTripsWithTimes($stopID, $time = "", $service_period = "", $time_range = "", $limit = "") { + if ($service_period == "") + $service_period = service_period(); + if ($time_range == "") + $time_range = (24 * 60 * 60); + if ($time == "") + $time = current_time(); + if ($limit == "") + $limit = 10; + $trips = getStopTrips($stopID, $service_period, $time); + $timedTrips = Array(); + if ($trips && sizeof($trips) > 0) { + foreach ($trips as $trip) { + if ($trip['arrival_time'] != "") { + if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) { + $timedTrips[] = $trip; + } + } else { + $timedTrip = getTripAtStop($trip['trip_id'], $trip['stop_sequence']); + if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) { + $timedTrips[] = $timedTrip; + } + } + if (sizeof($timedTrips) > $limit) + break; } - return $timedTrips; -} -?> + sktimesort($timedTrips, "arrival_time", true); + } + return $timedTrips; +} + --- a/include/db/trip-dao.inc.php +++ b/include/db/trip-dao.inc.php @@ -1,219 +1,224 @@ prepare($query); - $query->bindParam(":tripID", $tripID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetch(PDO::FETCH_ASSOC); -} -function getTripShape($tripID) -{ - global $conn; - $query = "SELECT ST_AsKML(ST_MakeLine(geometry(a.position))) as the_route -FROM (SELECT position, + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} +function getTripStops($tripID) { + global $conn; + $query = "SELECT stops.stop_id, stop_name, ST_AsKML(position) as positionkml, stop_sequence, trips.trip_id FROM stop_times join trips on trips.trip_id = stop_times.trip_id join stops on stops.stop_id = stop_times.stop_id -WHERE trips.trip_id = :tripID ORDER BY stop_sequence) as a group by a.trip_id"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":tripID", $tripID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchColumn(0); -} -function getTimeInterpolatedTrip($tripID, $range = "") -{ - global $conn; - $query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_lat,stop_lon,stop_name,stop_code, +WHERE trips.trip_id = :tripID ORDER BY stop_sequence"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getTripHasStop($tripID, $stopID) { + global $conn; + $query = "SELECT stop_id +FROM stop_times +join trips on trips.trip_id = stop_times.trip_id +WHERE trips.trip_id = :tripID and stop_times.stop_id = :stopID"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->bindParam(":stopID", $stopID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return ($query->fetchColumn() > 0); +} + +function getTripShape($tripID) { + // todo, use shapes table if shape_id specified + global $conn; + $query = "SELECT ST_AsKML(ST_MakeLine(geometry(a.shape_pt))) as the_route +FROM (SELECT shapes.shape_id,shape_pt from shapes +inner join trips on shapes.shape_id = trips.shape_id +WHERE trips.trip_id = :tripID ORDER BY shape_pt_sequence) as a group by a.shape_id"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchColumn(0); +} + +function getTripStopTimes($tripID) { + global $conn; + $query = "SELECT stop_times.trip_id,trip_headsign,arrival_time,stop_times.stop_id + ,stop_lat,stop_lon,stop_name,stop_desc,stop_code, stop_sequence,service_id,trips.route_id,route_short_name,route_long_name FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id join stops on stops.stop_id = stop_times.stop_id -WHERE trips.trip_id = :tripID $range ORDER BY stop_sequence"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":tripID", $tripID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - $stopTimes = $query->fetchAll(); - $cur_timepoint = Array(); - $next_timepoint = Array(); - $distance_between_timepoints = 0.0; - $distance_traveled_between_timepoints = 0.0; - $rv = Array(); - foreach ($stopTimes as $i => $stopTime) { - if ($stopTime['arrival_time'] != "") { - // is timepoint - $cur_timepoint = $stopTime; - $distance_between_timepoints = 0.0; - $distance_traveled_between_timepoints = 0.0; - if ($i + 1 < sizeof($stopTimes)) { - $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"]); - while ($stopTimes[$k]["arrival_time"] == "" && $k + 1 < sizeof($stopTimes)) { - $k+= 1; - //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"]); - } - $next_timepoint = $stopTimes[$k]; - $rv[] = $stopTime; - } - } - else { - // is untimed point - //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"]); - //echo "$distance_traveled_between_timepoints / $distance_between_timepoints
"; - $distance_percent = $distance_traveled_between_timepoints / $distance_between_timepoints; - if ($next_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"])."
"; - $time_estimate = ($distance_percent * $total_time) + strtotime($cur_timepoint["arrival_time"]); - $stopTime["arrival_time"] = date("H:i:s", $time_estimate); - } - else { - $stopTime["arrival_time"] = $cur_timepoint["arrival_time"]; - } - $rv[] = $stopTime; - //var_dump($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) -{ - global $conn; - // limit interpolation to between nearest actual points. - $prevTimePoint = getTripPreviousTimePoint($tripID, $stop_sequence); - $nextTimePoint = getTripNextTimePoint($tripID, $stop_sequence); - $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; - } - return Array(); -} -function getTripStartTime($tripID) -{ - global $conn; - $query = "Select * from stop_times +WHERE trips.trip_id = :tripID ORDER BY stop_sequence"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $stopTimes = $query->fetchAll(); + return $stopTimes; +} + +function getTripAtStop($tripID, $stop_sequence) { + global $conn; + foreach (getTripStopTimes($tripID) as $tripStop) { + if ($tripStop['stop_sequence'] == $stop_sequence) + return $tripStop; + } + return Array(); +} + +function getTripStartTime($tripID) { + global $conn; + $query = "Select * from stop_times where trip_id = :tripID AND arrival_time IS NOT NULL AND stop_sequence = '1'"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":tripID", $tripID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - $r = $query->fetch(PDO::FETCH_ASSOC); - return $r['arrival_time']; -} -function getActiveTrips($time) -{ - global $conn; - 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 + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r['arrival_time']; +} + +function getTripEndTime($tripID) { + global $conn; + $query = "SELECT trip_id,max(arrival_time) as arrival_time from stop_times + WHERE stop_times.arrival_time IS NOT NULL and trip_id = :tripID group by trip_id"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r['arrival_time']; +} +function getTripStartingPoint($tripID) { + global $conn; + $query = "SELECT stops.stop_id, stops.stop_name, stops.stop_desc + from stop_times inner join stops on stop_times.stop_id = stops.stop_id + WHERE trip_id = :tripID and stop_sequence = '1' limit 1"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r; +} + +function getTripDestination($tripID) { + global $conn; + $query = "SELECT stops.stop_id, stops.stop_name, stops.stop_desc + from stop_times inner join stops on stop_times.stop_id = stops.stop_id + WHERE trip_id = :tripID order by stop_sequence desc limit 1"; + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r; +} + +function getActiveTrips($time) { + global $conn; + 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 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"; - debug($query, "database"); - $query = $conn->prepare($query); - $query->bindParam(":time", $time); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function viaPoints($tripID, $stop_sequence = "") -{ - global $conn; - $query = "SELECT stops.stop_id, stop_name, arrival_time + debug($query, "database"); + $query = $conn->prepare($query); + $query->bindParam(":time", $time); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function viaPoints($tripID, $stop_sequence = "") { + global $conn; + $query = "SELECT stops.stop_id, stop_name, arrival_time FROM stop_times join stops on stops.stop_id = stop_times.stop_id WHERE stop_times.trip_id = :tripID -" . ($stop_sequence != "" ? " AND stop_sequence > :stop_sequence " : "") . "AND substr(stop_code,1,2) != 'Wj' ORDER BY stop_sequence"; - debug($query, "database"); - $query = $conn->prepare($query); - if ($stop_sequence != "") $query->bindParam(":stop_sequence", $stop_sequence); - $query->bindParam(":tripID", $tripID); - $query->execute(); - if (!$query) { - databaseError($conn->errorInfo()); - return Array(); - } - return $query->fetchAll(); -} -function viaPointNames($tripid, $stop_sequence = "") -{ - $viaPointNames = Array(); - foreach (viaPoints($tripid, $stop_sequence) as $point) { - $viaPointNames[] = $point['stop_name']; - } - if (sizeof($viaPointNames) > 0) { - return r_implode(", ", $viaPointNames); - } - else { - return ""; - } -} -?> +" . ($stop_sequence != "" ? " AND stop_sequence > :stop_sequence " : "") . " ORDER BY stop_sequence"; + debug($query, "database"); + $query = $conn->prepare($query); + if ($stop_sequence != "") + $query->bindParam(":stop_sequence", $stop_sequence); + $query->bindParam(":tripID", $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} --- a/index.php +++ b/index.php @@ -1,31 +1,45 @@
-
-
-

busness time


Canberra Bus Timetables and Trip Planner -
- - Launch Trip Planner... - - -Busness R&D'; -include_footer(true) -?> +
+
+

busness time


Canberra Bus Timetables and Trip Planner +
+ + Launch Trip Planner... + + + + MyWay Balance and Timeliness Survey Results + --- /dev/null +++ b/js/FlashCanvas --- a/js/flotr/flotr-0.2.0-alpha.js +++ /dev/null @@ -1,2 +1,1 @@ -//Flotr 0.2.0-alpha Copyright (c) 2009 Bas Wenneker, , MIT License. -var Flotr={version:"0.2.0-alpha",author:"Bas Wenneker",website:"http://www.solutoire.com",_registeredTypes:{lines:"drawSeriesLines",points:"drawSeriesPoints",bars:"drawSeriesBars",candles:"drawSeriesCandles",pie:"drawSeriesPie"},register:function(A,B){Flotr._registeredTypes[A]=B+""},draw:function(B,D,A,C){C=C||Flotr.Graph;return new C(B,D,A)},getSeries:function(A){return A.collect(function(C){var B,C=(C.data)?Object.clone(C):{data:C};for(B=C.data.length-1;B>-1;--B){C.data[B][1]=(C.data[B][1]===null?null:parseFloat(C.data[B][1]))}return C})},merge:function(D,B){var A=B||{};for(var C in D){A[C]=(D[C]!=null&&typeof (D[C])=="object"&&!(D[C].constructor==Array||D[C].constructor==RegExp)&&!Object.isElement(D[C]))?Flotr.merge(D[C],B[C]):A[C]=D[C]}return A},getTickSize:function(E,D,A,B){var H=(A-D)/E;var G=Flotr.getMagnitude(H);var C=H/G;var F=10;if(C<1.5){F=1}else{if(C<2.25){F=2}else{if(C<3){F=((B==0)?2:2.5)}else{if(C<7.5){F=5}}}}return F*G},defaultTickFormatter:function(A){return A+""},defaultTrackFormatter:function(A){return"("+A.x+", "+A.y+")"},defaultPieLabelFormatter:function(A){return(A.fraction*100).toFixed(2)+"%"},getMagnitude:function(A){return Math.pow(10,Math.floor(Math.log(A)/Math.LN10))},toPixel:function(A){return Math.floor(A)+0.5},toRad:function(A){return -A*(Math.PI/180)},parseColor:function(D){if(D instanceof Flotr.Color){return D}var A,C=Flotr.Color;if((A=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(D))){return new C(parseInt(A[1]),parseInt(A[2]),parseInt(A[3]))}if((A=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(D))){return new C(parseInt(A[1]),parseInt(A[2]),parseInt(A[3]),parseFloat(A[4]))}if((A=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(D))){return new C(parseFloat(A[1])*2.55,parseFloat(A[2])*2.55,parseFloat(A[3])*2.55)}if((A=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(D))){return new C(parseFloat(A[1])*2.55,parseFloat(A[2])*2.55,parseFloat(A[3])*2.55,parseFloat(A[4]))}if((A=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(D))){return new C(parseInt(A[1],16),parseInt(A[2],16),parseInt(A[3],16))}if((A=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(D))){return new C(parseInt(A[1]+A[1],16),parseInt(A[2]+A[2],16),parseInt(A[3]+A[3],16))}var B=D.strip().toLowerCase();if(B=="transparent"){return new C(255,255,255,0)}return((A=C.lookupColors[B]))?new C(A[0],A[1],A[2]):false},extractColor:function(B){var A;do{A=B.getStyle("background-color").toLowerCase();if(!(A==""||A=="transparent")){break}B=B.up(0)}while(!B.nodeName.match(/^body$/i));return(A=="rgba(0, 0, 0, 0)")?"transparent":A}};Flotr.Graph=Class.create({initialize:function(B,C,A){this.el=$(B);if(!this.el){throw"The target container doesn't exist"}this.data=C;this.series=Flotr.getSeries(C);this.setOptions(A);this.lastMousePos={pageX:null,pageY:null};this.selection={first:{x:-1,y:-1},second:{x:-1,y:-1}};this.prevSelection=null;this.selectionInterval=null;this.ignoreClick=false;this.prevHit=null;this.constructCanvas();this.initEvents();this.findDataRanges();this.calculateTicks(this.axes.x);this.calculateTicks(this.axes.x2);this.calculateTicks(this.axes.y);this.calculateTicks(this.axes.y2);this.calculateSpacing();this.draw();this.insertLegend();if(this.options.spreadsheet.show){this.constructTabs()}},setOptions:function(B){var P={colors:["#00A8F0","#C0D800","#CB4B4B","#4DA74D","#9440ED"],title:null,subtitle:null,legend:{show:true,noColumns:1,labelFormatter:Prototype.K,labelBoxBorderColor:"#CCCCCC",labelBoxWidth:14,labelBoxHeight:10,labelBoxMargin:5,container:null,position:"nw",margin:5,backgroundColor:null,backgroundOpacity:0.85},xaxis:{ticks:null,showLabels:true,labelsAngle:0,title:null,titleAngle:0,noTicks:5,tickFormatter:Flotr.defaultTickFormatter,tickDecimals:null,min:null,max:null,autoscaleMargin:0,color:null},x2axis:{},yaxis:{ticks:null,showLabels:true,labelsAngle:0,title:null,titleAngle:90,noTicks:5,tickFormatter:Flotr.defaultTickFormatter,tickDecimals:null,min:null,max:null,autoscaleMargin:0,color:null},y2axis:{titleAngle:270},points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#FFFFFF",fillOpacity:0.4},lines:{show:false,lineWidth:2,fill:false,fillColor:null,fillOpacity:0.4},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null,fillOpacity:0.4,horizontal:false,stacked:false},candles:{show:false,lineWidth:1,wickLineWidth:1,candleWidth:0.6,fill:true,upFillColor:"#00A8F0",downFillColor:"#CB4B4B",fillOpacity:0.5,barcharts:false},pie:{show:false,lineWidth:1,fill:true,fillColor:null,fillOpacity:0.6,explode:6,sizeRatio:0.6,startAngle:Math.PI/4,labelFormatter:Flotr.defaultPieLabelFormatter,pie3D:false,pie3DviewAngle:(Math.PI/2*0.8),pie3DspliceThickness:20},grid:{color:"#545454",backgroundColor:null,tickColor:"#DDDDDD",labelMargin:3,verticalLines:true,horizontalLines:true,outlineWidth:2},selection:{mode:null,color:"#B6D9FF",fps:20},mouse:{track:false,position:"se",relative:false,trackFormatter:Flotr.defaultTrackFormatter,margin:5,lineColor:"#FF3F19",trackDecimals:1,sensibility:2,radius:3},shadowSize:4,defaultType:"lines",HtmlText:true,fontSize:7.5,spreadsheet:{show:false,tabGraphLabel:"Graph",tabDataLabel:"Data",toolbarDownload:"Download CSV",toolbarSelectAll:"Select all"}};P.x2axis=Object.extend(Object.clone(P.xaxis),P.x2axis);P.y2axis=Object.extend(Object.clone(P.yaxis),P.y2axis);this.options=Flotr.merge((B||{}),P);this.axes={x:{options:this.options.xaxis,n:1},x2:{options:this.options.x2axis,n:2},y:{options:this.options.yaxis,n:1},y2:{options:this.options.y2axis,n:2}};var H=[],C=[],K=this.series.length,N=this.series.length,D=this.options.colors,A=[],G=0,M,J,I,O,E;for(J=N-1;J>-1;--J){M=this.series[J].color;if(M!=null){--N;if(Object.isNumber(M)){H.push(M)}else{A.push(Flotr.parseColor(M))}}}for(J=H.length-1;J>-1;--J){N=Math.max(N,H[J]+1)}for(J=0;C.length=D.length){J=0;++G}}for(J=0,I=0;J'+F+"
").select(".flotr-dummy-div")[0];dim=A.getDimensions();A.remove();return dim}},loadDataGrid:function(){if(this.seriesData){return this.seriesData}var A=this.series;var B=[];for(i=0;i"];var F=[''];F.push(" ");for(D=0;D'+(L[D].label||String.fromCharCode(65+D))+"");C.push("")}F.push("");for(B=0;B");for(D=0;D"+G+"")}F.push("")}C.push("");K.update(C.join("")+F.join(""));if(!Prototype.Browser.IE){K.select("td").each(function(N){N.observe("mouseover",function(O){N=O.element();var P=N.previousSiblings();K.select("th[scope=col]")[P.length-1].addClassName("hover");K.select("colgroup col")[P.length].addClassName("hover")});N.observe("mouseout",function(){K.select("colgroup col.hover, th.hover").each(function(O){O.removeClassName("hover")})})})}var H=new Element("div",{className:"flotr-datagrid-toolbar"}).insert(new Element("button",{type:"button",className:"flotr-datagrid-toolbar-button"}).update(this.options.spreadsheet.toolbarDownload).observe("click",this.downloadCSV.bind(this))).insert(new Element("button",{type:"button",className:"flotr-datagrid-toolbar-button"}).update(this.options.spreadsheet.toolbarSelectAll).observe("click",this.selectAllData.bind(this)));var A=new Element("div",{className:"flotr-datagrid-container",style:"left:0px;top:0px;width:"+this.canvasWidth+"px;height:"+this.canvasHeight+"px;overflow:auto;"});A.insert(H);K.wrap(A.hide());this.el.insert(A);return K},selectAllData:function(){if(this.tabs){var B,A,E,D,C=this.constructDataGrid();this.showTab("data");(function(){if((E=C.ownerDocument)&&(D=E.defaultView)&&D.getSelection&&E.createRange&&(B=window.getSelection())&&B.removeAllRanges){A=E.createRange();A.selectNode(C);B.removeAllRanges();B.addRange(A)}else{if(document.body&&document.body.createTextRange&&(A=document.body.createTextRange())){A.moveToElementText(C);A.select()}}}).defer();return true}else{return false}},downloadCSV:function(){var D,A='"x"',C=this.series,E=this.loadDataGrid();for(D=0;D0){var C,A,D,H,F,B,I,E;for(C=0;C0&&!J[C].hide){if(!I.used){I.datamin=I.datamax=B[0][0]}if(!E.used){E.datamin=E.datamax=B[0][1]}I.used=true;E.used=true;for(D=B.length-1;D>-1;--D){H=B[D][0];if(HI.datamax){I.datamax=H}}for(A=1;AE.datamax){E.datamax=F}}}}}}}this.findXAxesValues();this.calculateRange(G.x);this.extendXRangeIfNeededByBar(G.x);if(G.x2.used){this.calculateRange(G.x2);this.extendXRangeIfNeededByBar(G.x2)}this.calculateRange(G.y);this.extendYRangeIfNeededByBar(G.y);if(G.y2.used){this.calculateRange(G.y2);this.extendYRangeIfNeededByBar(G.y2)}},calculateRange:function(D){var F=D.options,C=F.min!=null?F.min:D.datamin,A=F.max!=null?F.max:D.datamax,E;if(A-C==0){var B=(A==0)?1:0.01;C-=B;A+=B}D.tickSize=Flotr.getTickSize(F.noTicks,C,A,F.tickDecimals);if(F.min==null){E=F.autoscaleMargin;if(E!=0){C-=D.tickSize*E;if(C<0&&D.datamin>=0){C=0}C=D.tickSize*Math.floor(C/D.tickSize)}}if(F.max==null){E=F.autoscaleMargin;if(E!=0){A+=D.tickSize*E;if(A>0&&D.datamax<=0){A=0}A=D.tickSize*Math.ceil(A/D.tickSize)}}D.min=C;D.max=A},extendXRangeIfNeededByBar:function(A){if(A.options.max==null){var D=A.max,B,I,F,E,H=[],C=null;for(B=0;BD)||(E.candleWidth+A.datamax>D)){D=A.max+I.bars.barWidth}if(F.stacked&&F.horizontal){for(j=0;jD)||(E.candleWidth+A.datamax>D)){D=A.max+F.barWidth}if(F.stacked&&!F.horizontal){for(j=0;j-1;--i){s=this.series[i];s.xaxis.values=s.xaxis.values||[];for(j=s.data.length-1;j>-1;--j){s.xaxis.values[s.data[j][0]]={}}}},calculateTicks:function(D){var B=D.options,E,H;D.ticks=[];if(B.ticks){var G=B.ticks,I,F;if(Object.isFunction(G)){G=G({min:D.min,max:D.max})}for(E=0;E1)?I[1]:B.tickFormatter(H)}else{H=I;F=B.tickFormatter(H)}D.ticks[E]={v:H,label:F}}}else{var A=D.tickSize*Math.ceil(D.min/D.tickSize),C;for(E=0;A+E*D.tickSize<=D.max;++E){H=A+E*D.tickSize;C=B.tickDecimals;if(C==null){C=1-Math.floor(Math.log(D.tickSize)/Math.LN10)}if(C<0){C=0}H=H.toFixed(C);D.ticks.push({v:H,label:B.tickFormatter(H)})}}},calculateSpacing:function(){var L=this.axes,N=this.options,H=this.series,D=N.grid.labelMargin,M=L.x,A=L.x2,J=L.y,K=L.y2,F=2,G,E,C,I;[M,A,J,K].each(function(P){var O="";if(P.options.showLabels){for(G=0;GO.length){O=P.ticks[G].label}}}P.maxLabel=this.getTextDimensions(O,{size:N.fontSize,angle:Flotr.toRad(P.options.labelsAngle)},"font-size:smaller;","flotr-grid-label");P.titleSize=this.getTextDimensions(P.options.title,{size:N.fontSize*1.2,angle:Flotr.toRad(P.options.titleAngle)},"font-weight:bold;","flotr-axis-title")},this);I=this.getTextDimensions(N.title,{size:N.fontSize*1.5},"font-size:1em;font-weight:bold;","flotr-title");this.titleHeight=I.height;I=this.getTextDimensions(N.subtitle,{size:N.fontSize},"font-size:smaller;","flotr-subtitle");this.subtitleHeight=I.height;if(N.show){F=Math.max(F,N.points.radius+N.points.lineWidth/2)}for(E=0;E'];D=H.x;if(D.options.showLabels){for(E=0;E'+G.label+"
")}}D=H.x2;if(D.options.showLabels&&D.used){for(E=0;E'+G.label+"
")}}D=H.y;if(D.options.showLabels){for(E=0;E'+G.label+"")}}D=H.y2;if(D.options.showLabels&&D.used){I.save();I.strokeStyle=D.options.color||J.grid.color;I.beginPath();for(E=0;E'+G.label+"");I.moveTo(this.plotOffset.left+this.plotWidth-8,this.plotOffset.top+this.tVert(G.v,D));I.lineTo(this.plotOffset.left+this.plotWidth,this.plotOffset.top+this.tVert(G.v,D))}I.stroke();I.restore()}F.push("");this.el.insert(F.join(""))}}},drawTitles:function(){var D,C=this.options,F=C.grid.labelMargin,B=this.ctx,A=this.axes;if(!C.HtmlText&&this.textEnabled){var E={size:C.fontSize,color:C.grid.color,halign:"c"};if(C.subtitle){B.drawText(C.subtitle,this.plotOffset.left+this.plotWidth/2,this.titleHeight+this.subtitleHeight-2,E)}E.weight=1.5;E.size*=1.5;if(C.title){B.drawText(C.title,this.plotOffset.left+this.plotWidth/2,this.titleHeight-2,E)}E.weight=1.8;E.size*=0.8;E.adjustAlign=true;if(A.x.options.title&&A.x.used){E.halign="c";E.valign="t";E.angle=Flotr.toRad(A.x.options.titleAngle);B.drawText(A.x.options.title,this.plotOffset.left+this.plotWidth/2,this.plotOffset.top+A.x.maxLabel.height+this.plotHeight+2*F,E)}if(A.x2.options.title&&A.x2.used){E.halign="c";E.valign="b";E.angle=Flotr.toRad(A.x2.options.titleAngle);B.drawText(A.x2.options.title,this.plotOffset.left+this.plotWidth/2,this.plotOffset.top-A.x2.maxLabel.height-2*F,E)}if(A.y.options.title&&A.y.used){E.halign="r";E.valign="m";E.angle=Flotr.toRad(A.y.options.titleAngle);B.drawText(A.y.options.title,this.plotOffset.left-A.y.maxLabel.width-2*F,this.plotOffset.top+this.plotHeight/2,E)}if(A.y2.options.title&&A.y2.used){E.halign="l";E.valign="m";E.angle=Flotr.toRad(A.y2.options.titleAngle);B.drawText(A.y2.options.title,this.plotOffset.left+this.plotWidth+A.y2.maxLabel.width+2*F,this.plotOffset.top+this.plotHeight/2,E)}}else{D=['
'];if(C.title){D.push('
'+C.title+"
")}if(C.subtitle){D.push('
'+C.subtitle+"
")}D.push("
");D.push('
');if(A.x.options.title&&A.x.used){D.push('
'+A.x.options.title+"
")}if(A.x2.options.title&&A.x2.used){D.push('
'+A.x2.options.title+"
")}if(A.y.options.title&&A.y.used){D.push('
'+A.y.options.title+"
")}if(A.y2.options.title&&A.y2.used){D.push('
'+A.y2.options.title+"
")}D.push("
");this.el.insert(D.join(""))}},drawSeries:function(A){A=A||this.series;var C=false;for(var B in Flotr._registeredTypes){if(A[B]&&A[B].show){this[Flotr._registeredTypes[B]](A);C=true}}if(!C){this[Flotr._registeredTypes[this.options.defaultType]](A)}},plotLine:function(I,F){var O=this.ctx,A=I.xaxis,K=I.yaxis,J=this.tHoz.bind(this),M=this.tVert.bind(this),H=I.data;if(H.length<2){return }var E=J(H[0][0],A),D=M(H[0][1],K)+F;O.beginPath();O.moveTo(E,D);for(var G=0;G=L&&N>K.max){if(L>K.max){continue}C=(K.max-N)/(L-N)*(B-C)+C;N=K.max}else{if(L>=N&&L>K.max){if(N>K.max){continue}B=(K.max-N)/(L-N)*(B-C)+C;L=K.max}}if(C<=B&&C=B&&C>A.max){if(B>A.max){continue}N=(A.max-C)/(B-C)*(L-N)+N;C=A.max}else{if(B>=C&&B>A.max){if(C>A.max){continue}L=(A.max-C)/(B-C)*(L-N)+N;B=A.max}}if(E!=J(C,A)||D!=M(N,K)+F){O.moveTo(J(C,A),M(N,K)+F)}E=J(B,A);D=M(L,K)+F;O.lineTo(E,D)}O.stroke()},plotLineArea:function(J,D){var S=J.data;if(S.length<2){return }var L,G=0,N=this.ctx,Q=J.xaxis,B=J.yaxis,E=this.tHoz.bind(this),M=this.tVert.bind(this),H=Math.min(Math.max(0,B.min),B.max),F=true;N.beginPath();for(var O=0;O=P&&R>Q.max){if(P>Q.max){continue}C=(Q.max-R)/(P-R)*(A-C)+C;R=Q.max}else{if(P>=R&&P>Q.max){if(R>Q.max){continue}A=(Q.max-R)/(P-R)*(A-C)+C;P=Q.max}}if(F){N.moveTo(E(R,Q),M(H,B)+D);F=false}if(C>=B.max&&A>=B.max){N.lineTo(E(R,Q),M(B.max,B)+D);N.lineTo(E(P,Q),M(B.max,B)+D);continue}else{if(C<=B.min&&A<=B.min){N.lineTo(E(R,Q),M(B.min,B)+D);N.lineTo(E(P,Q),M(B.min,B)+D);continue}}var I=R,K=P;if(C<=A&&C=B.min){R=(B.min-C)/(A-C)*(P-R)+R;C=B.min}else{if(A<=C&&A=B.min){P=(B.min-C)/(A-C)*(P-R)+R;A=B.min}}if(C>=A&&C>B.max&&A<=B.max){R=(B.max-C)/(A-C)*(P-R)+R;C=B.max}else{if(A>=C&&A>B.max&&C<=B.max){P=(B.max-C)/(A-C)*(P-R)+R;A=B.max}}if(R!=I){L=(C<=B.min)?L=B.min:B.max;N.lineTo(E(I,Q),M(L,B)+D);N.lineTo(E(R,Q),M(L,B)+D)}N.lineTo(E(R,Q),M(C,B)+D);N.lineTo(E(P,Q),M(A,B)+D);if(P!=K){L=(A<=B.min)?B.min:B.max;N.lineTo(E(K,Q),M(L,B)+D);N.lineTo(E(P,Q),M(L,B)+D)}G=Math.max(P,K)}N.lineTo(E(G,Q),M(H,B)+D);N.closePath();N.fill()},drawSeriesLines:function(C){C=C||this.series;var B=this.ctx;B.save();B.translate(this.plotOffset.left,this.plotOffset.top);B.lineJoin="round";var D=C.lines.lineWidth;var A=C.shadowSize;if(A>0){B.lineWidth=A/2;var E=D/2+B.lineWidth/2;B.strokeStyle="rgba(0,0,0,0.1)";this.plotLine(C,E+A/2);B.strokeStyle="rgba(0,0,0,0.2)";this.plotLine(C,E);if(C.lines.fill){B.fillStyle="rgba(0,0,0,0.05)";this.plotLineArea(C,E+A/2)}}B.lineWidth=D;B.strokeStyle=C.color;if(C.lines.fill){B.fillStyle=C.lines.fillColor!=null?C.lines.fillColor:Flotr.parseColor(C.color).scale(null,null,null,C.lines.fillOpacity).toString();this.plotLineArea(C,0)}this.plotLine(C,0);B.restore()},drawSeriesPoints:function(C){var B=this.ctx;B.save();B.translate(this.plotOffset.left,this.plotOffset.top);var D=C.lines.lineWidth;var A=C.shadowSize;if(A>0){B.lineWidth=A/2;B.strokeStyle="rgba(0,0,0,0.1)";this.plotPointShadows(C,A/2+B.lineWidth/2,C.points.radius);B.strokeStyle="rgba(0,0,0,0.2)";this.plotPointShadows(C,B.lineWidth/2,C.points.radius)}B.lineWidth=C.points.lineWidth;B.strokeStyle=C.color;B.fillStyle=C.points.fillColor!=null?C.points.fillColor:C.color;this.plotPoints(C,C.points.radius,C.points.fill);B.restore()},plotPoints:function(C,E,I){var A=C.xaxis,F=C.yaxis,J=this.ctx,D,B=C.data;for(D=B.length-1;D>-1;--D){var H=B[D][0],G=B[D][1];if(HA.max||GF.max){continue}J.beginPath();J.arc(this.tHoz(H,A),this.tVert(G,F),E,0,2*Math.PI,true);if(I){J.fill()}J.stroke()}},plotPointShadows:function(D,B,F){var A=D.xaxis,G=D.yaxis,J=this.ctx,E,C=D.data;for(E=C.length-1;E>-1;--E){var I=C[E][0],H=C[E][1];if(IA.max||HG.max){continue}J.beginPath();J.arc(this.tHoz(I,A),this.tVert(H,G)+B,F,0,Math.PI,false);J.stroke()}},drawSeriesBars:function(B){var A=this.ctx,D=B.bars.barWidth,C=Math.min(B.bars.lineWidth,D);A.save();A.translate(this.plotOffset.left,this.plotOffset.top);A.lineJoin="miter";A.lineWidth=C;A.strokeStyle=B.color;this.plotBarsShadows(B,D,0,B.bars.fill);if(B.bars.fill){A.fillStyle=B.bars.fillColor!=null?B.bars.fillColor:Flotr.parseColor(B.color).scale(null,null,null,B.bars.fillOpacity).toString()}this.plotBars(B,D,0,B.bars.fill);A.restore()},plotBars:function(K,N,D,Q){var U=K.data;if(U.length<1){return }var S=K.xaxis,B=K.yaxis,P=this.ctx,F=this.tHoz.bind(this),O=this.tVert.bind(this);for(var R=0;RS.max||MB.max){continue}if(CS.max){T=S.max;if(S.lastSerie!=K&&K.bars.horizontal){L=false}}if(GB.max){M=B.max;if(B.lastSerie!=K&&!K.bars.horizontal){L=false}}if(Q){P.beginPath();P.moveTo(F(C,S),O(G,B)+D);P.lineTo(F(C,S),O(M,B)+D);P.lineTo(F(T,S),O(M,B)+D);P.lineTo(F(T,S),O(G,B)+D);P.fill()}if(K.bars.lineWidth!=0&&(E||A||L)){P.beginPath();P.moveTo(F(C,S),O(G,B)+D);P[E?"lineTo":"moveTo"](F(C,S),O(M,B)+D);P[L?"lineTo":"moveTo"](F(T,S),O(M,B)+D);P[A?"lineTo":"moveTo"](F(T,S),O(G,B)+D);P.stroke()}}},plotBarsShadows:function(I,K,C){var T=I.data;if(T.length<1){return }var R=I.xaxis,A=I.yaxis,P=this.ctx,D=this.tHoz.bind(this),M=this.tVert.bind(this),N=this.options.shadowSize;for(var Q=0;QR.max||JA.max){continue}if(BR.max){S=R.max}if(FA.max){J=A.max}var O=D(S,R)-D(B,R)-((D(S,R)+N<=this.plotWidth)?0:N);var L=Math.max(0,M(F,A)-M(J,A)-((M(F,A)+N<=this.plotHeight)?0:N));P.fillStyle="rgba(0,0,0,0.05)";P.fillRect(Math.min(D(B,R)+N,this.plotWidth),Math.min(M(J,A)+N,this.plotWidth),O,L)}},drawSeriesCandles:function(B){var A=this.ctx,C=B.candles.candleWidth;A.save();A.translate(this.plotOffset.left,this.plotOffset.top);A.lineJoin="miter";A.lineWidth=B.candles.lineWidth;this.plotCandlesShadows(B,C/2);this.plotCandles(B,C/2);A.restore()},plotCandles:function(K,D){var W=K.data;if(W.length<1){return }var T=K.xaxis,B=K.yaxis,P=this.ctx,E=this.tHoz.bind(this),O=this.tVert.bind(this);for(var S=0;ST.max||MB.max){continue}var Q=K.candles[L>N?"downFillColor":"upFillColor"];if(K.candles.fill&&!K.candles.barcharts){P.fillStyle=Flotr.parseColor(Q).scale(null,null,null,K.candles.fillOpacity).toString();P.fillRect(E(C,T),O(R,B)+D,E(V,T)-E(C,T),O(A,B)-O(R,B))}if(K.candles.lineWidth||K.candles.wickLineWidth){var J,H,F=(K.candles.wickLineWidth%2)/2;J=Math.floor(E((C+V)/2),T)+F;P.save();P.strokeStyle=Q;P.lineWidth=K.candles.wickLineWidth;P.lineCap="butt";if(K.candles.barcharts){P.beginPath();P.moveTo(J,Math.floor(O(M,B)+D));P.lineTo(J,Math.floor(O(G,B)+D));H=Math.floor(O(L,B)+D)+0.5;P.moveTo(Math.floor(E(C,T))+F,H);P.lineTo(J,H);H=Math.floor(O(N,B)+D)+0.5;P.moveTo(Math.floor(E(V,T))+F,H);P.lineTo(J,H)}else{P.strokeRect(E(C,T),O(R,B)+D,E(V,T)-E(C,T),O(A,B)-O(R,B));P.beginPath();P.moveTo(J,Math.floor(O(R,B)+D));P.lineTo(J,Math.floor(O(M,B)+D));P.moveTo(J,Math.floor(O(A,B)+D));P.lineTo(J,Math.floor(O(G,B)+D))}P.stroke();P.restore()}}},plotCandlesShadows:function(H,C){var T=H.data;if(T.length<1||H.candles.barcharts){return }var Q=H.xaxis,A=H.yaxis,D=this.tHoz.bind(this),M=this.tVert.bind(this),N=this.options.shadowSize;for(var P=0;PQ.max||JA.max){continue}var O=D(S,Q)-D(B,Q)-((D(S,Q)+N<=this.plotWidth)?0:N);var L=Math.max(0,M(E,A)-M(J,A)-((M(E,A)+N<=this.plotHeight)?0:N));this.ctx.fillStyle="rgba(0,0,0,0.05)";this.ctx.fillRect(Math.min(D(B,Q)+N,this.plotWidth),Math.min(M(J,A)+N,this.plotWidth),O,L)}},drawSeriesPie:function(G){if(!this.options.pie.drawn){var K=this.ctx,C=this.options,E=G.pie.lineWidth,I=G.shadowSize,R=G.data,D=(Math.min(this.canvasWidth,this.canvasHeight)*G.pie.sizeRatio)/2,H=[];var L=1;var P=Math.sin(G.pie.viewAngle)*G.pie.spliceThickness/L;var M={size:C.fontSize*1.2,color:C.grid.color,weight:1.5};var Q={x:(this.canvasWidth+this.plotOffset.left)/2,y:(this.canvasHeight-this.plotOffset.bottom)/2};var O=this.series.collect(function(T,S){if(T.pie.show){return{name:(T.label||T.data[0][1]),value:[S,T.data[0][1]],explode:T.pie.explode}}});var B=O.pluck("value").pluck(1).inject(0,function(S,T){return S+T});var F=0,N=G.pie.startAngle,J=0;var A=O.collect(function(S){N+=F;J=parseFloat(S.value[1]);F=J/B;return{name:S.name,fraction:F,x:S.value[0],y:J,explode:S.explode,startAngle:2*N*Math.PI,endAngle:2*(N+F)*Math.PI}});K.save();if(I>0){A.each(function(V){var S=(V.startAngle+V.endAngle)/2;var T=Q.x+Math.cos(S)*V.explode+I;var U=Q.y+Math.sin(S)*V.explode+I;this.plotSlice(T,U,D,V.startAngle,V.endAngle,false,L);K.fillStyle="rgba(0,0,0,0.1)";K.fill()},this)}if(C.HtmlText){H=['
']}A.each(function(c,X){var W=(c.startAngle+c.endAngle)/2;var V=C.colors[X];var Y=Q.x+Math.cos(W)*c.explode;var U=Q.y+Math.sin(W)*c.explode;this.plotSlice(Y,U,D,c.startAngle,c.endAngle,false,L);if(G.pie.fill){K.fillStyle=Flotr.parseColor(V).scale(null,null,null,G.pie.fillOpacity).toString();K.fill()}K.lineWidth=E;K.strokeStyle=V;K.stroke();var b=C.pie.labelFormatter(c);var S=(Math.cos(W)<0);var a=Y+Math.cos(W)*(G.pie.explode+D);var Z=U+Math.sin(W)*(G.pie.explode+D);if(c.fraction&&b){if(C.HtmlText){var T="position:absolute;top:"+(Z-5)+"px;";if(S){T+="right:"+(this.canvasWidth-a)+"px;text-align:right;"}else{T+="left:"+a+"px;text-align:left;"}H.push('
'+b+"
")}else{M.halign=S?"r":"l";K.drawText(b,a,Z+M.size/2,M)}}},this);if(C.HtmlText){H.push("
");this.el.insert(H.join(""))}K.restore();C.pie.drawn=true}},plotSlice:function(B,H,A,E,D,F,G){var C=this.ctx;G=G||1;C.save();C.scale(1,G);C.beginPath();C.moveTo(B,H);C.arc(B,H,A,E,D,F);C.lineTo(B,H);C.closePath();C.restore()},plotPie:function(){},insertLegend:function(){if(!this.options.legend.show){return }var H=this.series,I=this.plotOffset,B=this.options,b=[],A=false,O=this.ctx,R;var Q=H.findAll(function(c){return(c.label&&!c.hide)}).size();if(Q){if(!B.HtmlText&&this.textEnabled){var T={size:B.fontSize*1.1,color:B.grid.color};var M=B.legend.position,N=B.legend.margin,L=B.legend.labelBoxWidth,Z=B.legend.labelBoxHeight,S=B.legend.labelBoxMargin,W=I.left+N,U=I.top+N;var a=0;for(R=H.length-1;R>-1;--R){if(!H[R].label||H[R].hide){continue}var E=B.legend.labelFormatter(H[R].label);a=Math.max(a,O.measureText(E,T))}var K=Math.round(L+S*3+a),C=Math.round(Q*(S+Z)+S);if(M.charAt(0)=="s"){U=I.top+this.plotHeight-(N+C)}if(M.charAt(1)=="e"){W=I.left+this.plotWidth-(N+K)}var P=Flotr.parseColor(B.legend.backgroundColor||"rgb(240,240,240)").scale(null,null,null,B.legend.backgroundOpacity||0.1).toString();O.fillStyle=P;O.fillRect(W,U,K,C);O.strokeStyle=B.legend.labelBoxBorderColor;O.strokeRect(Flotr.toPixel(W),Flotr.toPixel(U),K,C);var G=W+S;var F=U+S;for(R=0;R":"");A=true}var E=B.legend.labelFormatter(H[R].label);b.push('
'+E+"")}if(A){b.push("")}if(b.length>0){var V=''+b.join("")+"
";if(B.legend.container!=null){$(B.legend.container).update(V)}else{var D="";var M=B.legend.position,N=B.legend.margin;if(M.charAt(0)=="n"){D+="top:"+(N+I.top)+"px;"}else{if(M.charAt(0)=="s"){D+="bottom:"+(N+I.bottom)+"px;"}}if(M.charAt(1)=="e"){D+="right:"+(N+I.right)+"px;"}else{if(M.charAt(1)=="w"){D+="left:"+(N+I.left)+"px;"}}var J=this.el.insert('
'+V+"
").select("div.flotr-legend").first();if(B.legend.backgroundOpacity!=0){var Y=B.legend.backgroundColor;if(Y==null){var X=(B.grid.backgroundColor!=null)?B.grid.backgroundColor:Flotr.extractColor(J);Y=Flotr.parseColor(X).adjust(null,null,null,1).toString()}this.el.insert('
').select("div.flotr-legend-bg").first().setStyle({opacity:B.legend.backgroundOpacity})}}}}}},getEventPosition:function(C){var G=this.overlay.cumulativeOffset(),F=(C.pageX-G.left-this.plotOffset.left),E=(C.pageY-G.top-this.plotOffset.top),D=0,B=0;if(C.pageX==null&&C.clientX!=null){var H=document.documentElement,A=document.body;D=C.clientX+(H&&H.scrollLeft||A.scrollLeft||0);B=C.clientY+(H&&H.scrollTop||A.scrollTop||0)}else{D=C.pageX;B=C.pageY}return{x:this.axes.x.min+F/this.axes.x.scale,x2:this.axes.x2.min+F/this.axes.x2.scale,y:this.axes.y.max-E/this.axes.y.scale,y2:this.axes.y2.max-E/this.axes.y2.scale,relX:F,relY:E,absX:D,absY:B}},clickHandler:function(A){if(this.ignoreClick){this.ignoreClick=false;return }this.el.fire("flotr:click",[this.getEventPosition(A),this])},mouseMoveHandler:function(A){var B=this.getEventPosition(A);this.lastMousePos.pageX=B.absX;this.lastMousePos.pageY=B.absY;if(this.selectionInterval==null&&(this.options.mouse.track||this.series.any(function(C){return C.mouse&&C.mouse.track}))){this.hit(B)}this.el.fire("flotr:mousemove",[A,B,this])},mouseDownHandler:function(C){if(C.isRightClick()){C.stop();var B=this.overlay;B.hide();function A(){B.show();$(document).stopObserving("mousemove",A)}$(document).observe("mousemove",A);return }if(!this.options.selection.mode||!C.isLeftClick()){return }this.setSelectionPos(this.selection.first,C);if(this.selectionInterval!=null){clearInterval(this.selectionInterval)}this.lastMousePos.pageX=null;this.selectionInterval=setInterval(this.updateSelection.bind(this),1000/this.options.selection.fps);this.mouseUpHandler=this.mouseUpHandler.bind(this);$(document).observe("mouseup",this.mouseUpHandler)},fireSelectEvent:function(){var A=this.axes,F=this.selection,C=(F.first.x<=F.second.x)?F.first.x:F.second.x,B=(F.first.x<=F.second.x)?F.second.x:F.first.x,E=(F.first.y>=F.second.y)?F.first.y:F.second.y,D=(F.first.y>=F.second.y)?F.second.y:F.first.y;C=A.x.min+C/A.x.scale;B=A.x.min+B/A.x.scale;E=A.y.max-E/A.y.scale;D=A.y.max-D/A.y.scale;this.el.fire("flotr:select",[{x1:C,y1:E,x2:B,y2:D},this])},mouseUpHandler:function(A){$(document).stopObserving("mouseup",this.mouseUpHandler);A.stop();if(this.selectionInterval!=null){clearInterval(this.selectionInterval);this.selectionInterval=null}this.setSelectionPos(this.selection.second,A);this.clearSelection();if(this.selectionIsSane()){this.drawSelection();this.fireSelectEvent();this.ignoreClick=true}},setSelectionPos:function(D,B){var A=this.options,C=$(this.overlay).cumulativeOffset();if(A.selection.mode.indexOf("x")==-1){D.x=(D==this.selection.first)?0:this.plotWidth}else{D.x=B.pageX-C.left-this.plotOffset.left;D.x=Math.min(Math.max(0,D.x),this.plotWidth)}if(A.selection.mode.indexOf("y")==-1){D.y=(D==this.selection.first)?0:this.plotHeight}else{D.y=B.pageY-C.top-this.plotOffset.top;D.y=Math.min(Math.max(0,D.y),this.plotHeight)}},updateSelection:function(){if(this.lastMousePos.pageX==null){return }this.setSelectionPos(this.selection.second,this.lastMousePos);this.clearSelection();if(this.selectionIsSane()){this.drawSelection()}},clearSelection:function(){if(this.prevSelection==null){return }var G=this.prevSelection,E=this.octx,C=this.plotOffset,A=Math.min(G.first.x,G.second.x),F=Math.min(G.first.y,G.second.y),B=Math.abs(G.second.x-G.first.x),D=Math.abs(G.second.y-G.first.y);E.clearRect(A+C.left-E.lineWidth,F+C.top-E.lineWidth,B+E.lineWidth*2,D+E.lineWidth*2);this.prevSelection=null},setSelection:function(G){var B=this.options,H=this.axes.x,A=this.axes.y,F=yaxis.scale,D=xaxis.scale,E=B.selection.mode.indexOf("x")!=-1,C=B.selection.mode.indexOf("y")!=-1;this.clearSelection();this.selection.first.y=E?0:(A.max-G.y1)*F;this.selection.second.y=E?this.plotHeight:(A.max-G.y2)*F;this.selection.first.x=C?0:(G.x1-H.min)*D;this.selection.second.x=C?this.plotWidth:(G.x2-H.min)*D;this.drawSelection();this.fireSelectEvent()},drawSelection:function(){var C=this.prevSelection,F=this.selection,H=this.octx,I=this.options,A=this.plotOffset;if(C!=null&&F.first.x==C.first.x&&F.first.y==C.first.y&&F.second.x==C.second.x&&F.second.y==C.second.y){return }H.strokeStyle=Flotr.parseColor(I.selection.color).scale(null,null,null,0.8).toString();H.lineWidth=1;H.lineJoin="round";H.fillStyle=Flotr.parseColor(I.selection.color).scale(null,null,null,0.4).toString();this.prevSelection={first:{x:F.first.x,y:F.first.y},second:{x:F.second.x,y:F.second.y}};var E=Math.min(F.first.x,F.second.x),D=Math.min(F.first.y,F.second.y),G=Math.abs(F.second.x-F.first.x),B=Math.abs(F.second.y-F.first.y);H.fillRect(E+A.left,D+A.top,G,B);H.strokeRect(E+A.left,D+A.top,G,B)},selectionIsSane:function(){var A=this.selection;return Math.abs(A.second.x-A.first.x)>=5&&Math.abs(A.second.y-A.first.y)>=5},clearHit:function(){if(this.prevHit){var B=this.options,A=this.plotOffset,C=this.prevHit;this.octx.clearRect(this.tHoz(C.x)+A.left-B.points.radius*2,this.tVert(C.y)+A.top-B.points.radius*2,B.points.radius*3+B.points.lineWidth*3,B.points.radius*3+B.points.lineWidth*3);this.prevHit=null}},hit:function(I){var G=this.series,C=this.options,R=this.prevHit,H=this.plotOffset,D=this.octx,S,A,M,Q,L={dist:Number.MAX_VALUE,x:null,y:null,relX:I.relX,relY:I.relY,absX:I.absX,absY:I.absY,mouse:null};for(Q=0;Q');K=this.mouseTrack=this.el.select(".flotr-mouse-value").first()}else{this.mouseTrack=K.setStyle(O)}if(L.x!==null&&L.y!==null){K.show();this.clearHit();if(L.mouse.lineColor!=null){D.save();D.translate(H.left,H.top);D.lineWidth=C.points.lineWidth;D.strokeStyle=L.mouse.lineColor;D.fillStyle="#ffffff";D.beginPath();D.arc(this.tHoz(L.x),this.tVert(L.y),C.mouse.radius,0,2*Math.PI,true);D.fill();D.stroke();D.restore()}this.prevHit=L;var T=L.mouse.trackDecimals;if(T==null||T<0){T=0}K.innerHTML=L.mouse.trackFormatter({x:L.x.toFixed(T),y:L.y.toFixed(T)});K.fire("flotr:hit",[L,this])}else{if(R){K.hide();this.clearHit()}}}},saveImage:function(D,C,A,B){var E=null;switch(D){case"jpeg":case"jpg":E=Canvas2Image.saveAsJPEG(this.canvas,B,C,A);break;default:case"png":E=Canvas2Image.saveAsPNG(this.canvas,B,C,A);break;case"bmp":E=Canvas2Image.saveAsBMP(this.canvas,B,C,A);break}if(Object.isElement(E)&&B){this.restoreCanvas();this.canvas.hide();this.overlay.hide();this.el.insert(E.setStyle({position:"absolute"}))}},restoreCanvas:function(){this.canvas.show();this.overlay.show();this.el.select("img").invoke("remove")}});Flotr.Color=Class.create({initialize:function(E,D,B,C){this.rgba=["r","g","b","a"];var A=4;while(-1<--A){this[this.rgba[A]]=arguments[A]||((A==3)?1:0)}this.normalize()},adjust:function(D,C,E,B){var A=4;while(-1<--A){if(arguments[A]!=null){this[this.rgba[A]]+=arguments[A]}}return this.normalize()},clone:function(){return new Flotr.Color(this.r,this.b,this.g,this.a)},limit:function(B,A,C){return Math.max(Math.min(B,C),A)},normalize:function(){var A=this.limit;this.r=A(parseInt(this.r),0,255);this.g=A(parseInt(this.g),0,255);this.b=A(parseInt(this.b),0,255);this.a=A(this.a,0,1);return this},scale:function(D,C,E,B){var A=4;while(-1<--A){if(arguments[A]!=null){this[this.rgba[A]]*=arguments[A]}}return this.normalize()},distance:function(B){if(!B){return }B=new Flotr.parseColor(B);var C=0;var A=3;while(-1<--A){C+=Math.abs(this[this.rgba[A]]-B[this.rgba[A]])}return C},toString:function(){return(this.a>=1)?"rgb("+[this.r,this.g,this.b].join(",")+")":"rgba("+[this.r,this.g,this.b,this.a].join(",")+")"}});Flotr.Color.lookupColors={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]};Flotr.Date={format:function(F,E){if(!F){return }var A=function(H){H=H.toString();return H.length==1?"0"+H:H};var D=[];var C=false;for(var B=0;B, MIT License. -// -//Radar chart added by Ryan Simmons -// -/* $Id: flotr.js 82 2009-01-12 19:19:31Z fabien.menager $ */ - -var Flotr = { - version: '0.2.0-alpha', - author: 'Bas Wenneker', - website: 'http://www.solutoire.com', - /** - * An object of the default registered graph types. Use Flotr.register(type, functionName) - * to add your own type. - */ - _registeredTypes:{ - 'lines': 'drawSeriesLines', - 'points': 'drawSeriesPoints', - 'bars': 'drawSeriesBars', - 'candles': 'drawSeriesCandles', - 'pie': 'drawSeriesPie', - 'radar':'drawSeriesRadar' - }, - /** - * Can be used to register your own chart type. Default types are 'lines', 'points' and 'bars'. - * This is still experimental. - * @todo Test and confirm. - * @param {String} type - type of chart, like 'pies', 'bars' etc. - * @param {String} functionName - Name of the draw function, like 'drawSeriesPies', 'drawSeriesBars' etc. - */ - register: function(type, functionName){ - Flotr._registeredTypes[type] = functionName+''; - }, - /** - * Draws the graph. This function is here for backwards compatibility with Flotr version 0.1.0alpha. - * You could also draw graphs by directly calling Flotr.Graph(element, data, options). - * @param {Element} el - element to insert the graph into - * @param {Object} data - an array or object of dataseries - * @param {Object} options - an object containing options - * @param {Class} _GraphKlass_ - (optional) Class to pass the arguments to, defaults to Flotr.Graph - * @return {Class} returns a new graph object and of course draws the graph. - */ - draw: function(el, data, options, _GraphKlass_){ - _GraphKlass_ = _GraphKlass_ || Flotr.Graph; - return new _GraphKlass_(el, data, options); - }, - /** - * Collects dataseries from input and parses the series into the right format. It returns an Array - * of Objects each having at least the 'data' key set. - * @param {Array/Object} data - Object or array of dataseries - * @return {Array} Array of Objects parsed into the right format ({(...,) data: [[x1,y1], [x2,y2], ...] (, ...)}) - */ - getSeries: function(data){ - return data.collect(function(serie){ - var i, serie = (serie.data) ? Object.clone(serie) : {'data': serie}; - for (i = serie.data.length-1; i > -1; --i) { - serie.data[i][1] = (serie.data[i][1] === null ? null : parseFloat(serie.data[i][1])); - } - return serie; - }); - }, - /** - * Recursively merges two objects. - * @param {Object} src - source object (likely the object with the least properties) - * @param {Object} dest - destination object (optional, object with the most properties) - * @return {Object} recursively merged Object - */ - merge: function(src, dest){ - var result = dest || {}; - for(var i in src){ - result[i] = (src[i] != null && typeof(src[i]) == 'object' && !(src[i].constructor == Array || src[i].constructor == RegExp) && !Object.isElement(src[i])) ? Flotr.merge(src[i], dest[i]) : result[i] = src[i]; - } - return result; - }, - /** - * Function calculates the ticksize and returns it. - * @param {Integer} noTicks - number of ticks - * @param {Integer} min - lower bound integer value for the current axis - * @param {Integer} max - upper bound integer value for the current axis - * @param {Integer} decimals - number of decimals for the ticks - * @return {Integer} returns the ticksize in pixels - */ - getTickSize: function(noTicks, min, max, decimals){ - var delta = (max - min) / noTicks; - var magn = Flotr.getMagnitude(delta); - - // Norm is between 1.0 and 10.0. - var norm = delta / magn; - - var tickSize = 10; - if(norm < 1.5) tickSize = 1; - else if(norm < 2.25) tickSize = 2; - else if(norm < 3) tickSize = ((decimals == 0) ? 2 : 2.5); - else if(norm < 7.5) tickSize = 5; - - return tickSize * magn; - }, - /** - * Default tick formatter. - * @param {String/Integer} val - tick value integer - * @return {String} formatted tick string - */ - defaultTickFormatter: function(val){ - return val+''; - }, - /** - * Formats the mouse tracker values. - * @param {Object} obj - Track value Object {x:..,y:..} - * @return {String} Formatted track string - */ - defaultTrackFormatter: function(obj){ - return '('+obj.x+', '+obj.y+')'; - }, - defaultPieLabelFormatter: function(slice) { - return (slice.fraction*100).toFixed(2)+'%'; - }, - /** - * Returns the magnitude of the input value. - * @param {Integer/Float} x - integer or float value - * @return {Integer/Float} returns the magnitude of the input value - */ - getMagnitude: function(x){ - return Math.pow(10, Math.floor(Math.log(x) / Math.LN10)); - }, - toPixel: function(val){ - return Math.floor(val)+0.5;//((val-Math.round(val) < 0.4) ? (Math.floor(val)-0.5) : val); - }, - toRad: function(angle){ - return -angle * (Math.PI/180); - }, - /** - * Parses a color string and returns a corresponding Color. - * @param {String} str - string thats representing a color - * @return {Color} returns a Color object or false - */ - parseColor: function(str){ - if (str instanceof Flotr.Color) return str; - - var result, Color = Flotr.Color; - - // 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(str))) - return new Color(parseInt(result[1]), parseInt(result[2]), parseInt(result[3])); - - // rgba(num,num,num,num) - if((result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))) - return new Color(parseInt(result[1]), parseInt(result[2]), parseInt(result[3]), parseFloat(result[4])); - - // 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(str))) - return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55); - - // rgba(num%,num%,num%,num) - if((result = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))) - return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55, parseFloat(result[4])); - - // #a0b1c2 - if((result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))) - return new Color(parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)); - - // #fff - if((result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))) - return new Color(parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)); - - // Otherwise, we're most likely dealing with a named color. - var name = str.strip().toLowerCase(); - if(name == 'transparent'){ - return new Color(255, 255, 255, 0); - } - return ((result = Color.lookupColors[name])) ? new Color(result[0], result[1], result[2]) : false; - }, - /** - * Extracts the background-color of the passed element. - * @param {Element} element - * @return {String} color string - */ - extractColor: function(element){ - var color; - // Loop until we find an element with a background color and stop when we hit the body element. - do { - color = element.getStyle('background-color').toLowerCase(); - if(!(color == '' || color == 'transparent')) break; - element = element.up(0); - } while(!element.nodeName.match(/^body$/i)); - - // Catch Safari's way of signaling transparent. - return (color == 'rgba(0, 0, 0, 0)') ? 'transparent' : color; - } -}; -/** - * Flotr Graph class that plots a graph on creation. - - */ -Flotr.Graph = Class.create({ - /** - * Flotr Graph constructor. - * @param {Element} el - element to insert the graph into - * @param {Object} data - an array or object of dataseries - * @param {Object} options - an object containing options - */ - initialize: function(el, data, options){ - this.el = $(el); - - if (!this.el) throw 'The target container doesn\'t exist'; - - this.data = data; - this.series = Flotr.getSeries(data); - this.setOptions(options); - - // Initialize some variables - this.lastMousePos = { pageX: null, pageY: null }; - this.selection = { first: { x: -1, y: -1}, second: { x: -1, y: -1} }; - this.prevSelection = null; - this.selectionInterval = null; - this.ignoreClick = false; - this.prevHit = null; - - // Create and prepare canvas. - this.constructCanvas(); - - // Add event handlers for mouse tracking, clicking and selection - this.initEvents(); - - this.findDataRanges(); - this.calculateTicks(this.axes.x); - this.calculateTicks(this.axes.x2); - this.calculateTicks(this.axes.y); - this.calculateTicks(this.axes.y2); - - this.calculateSpacing(); - this.draw(); - this.insertLegend(); - - // Graph and Data tabs - if (this.options.spreadsheet.show) - this.constructTabs(); - }, - /** - * Sets options and initializes some variables and color specific values, used by the constructor. - * @param {Object} opts - options object - */ - setOptions: function(opts){ - var options = { - colors: ['#00A8F0', '#C0D800', '#CB4B4B', '#4DA74D', '#9440ED'], //=> The default colorscheme. When there are > 5 series, additional colors are generated. - title: null, - subtitle: null, - legend: { - show: true, // => setting to true will show the legend, hide otherwise - noColumns: 1, // => number of colums in legend table // @todo: doesn't work for HtmlText = false - labelFormatter: Prototype.K, // => fn: string -> string - labelBoxBorderColor: '#CCCCCC', // => border color for the little label boxes - labelBoxWidth: 14, - labelBoxHeight: 10, - labelBoxMargin: 5, - container: null, // => container (as jQuery object) to put legend in, null means default on top of graph - position: 'nw', // => position of default legend container within plot - margin: 5, // => distance from grid edge to default legend container within plot - backgroundColor: null, // => null means auto-detect - backgroundOpacity: 0.85// => set to 0 to avoid background, set to 1 for a solid background - }, - xaxis: { - ticks: null, // => format: either [1, 3] or [[1, 'a'], 3] - showLabels: true, // => setting to true will show the axis ticks labels, hide otherwise - labelsAngle: 0, // => Labels' angle, in degrees - title: null, // => axis title - titleAngle: 0, // => axis title's angle, in degrees - noTicks: 5, // => number of ticks for automagically generated ticks - tickFormatter: Flotr.defaultTickFormatter, // => fn: number -> string - tickDecimals: null, // => no. of decimals, null means auto - min: null, // => min. value to show, null means set automatically - max: null, // => max. value to show, null means set automatically - autoscaleMargin: 0, // => margin in % to add if auto-setting min/max - color: null - }, - x2axis: {}, - yaxis: { - ticks: null, // => format: either [1, 3] or [[1, 'a'], 3] - showLabels: true, // => setting to true will show the axis ticks labels, hide otherwise - labelsAngle: 0, // => Labels' angle, in degrees - title: null, // => axis title - titleAngle: 90, // => axis title's angle, in degrees - noTicks: 5, // => number of ticks for automagically generated ticks - tickFormatter: Flotr.defaultTickFormatter, // => fn: number -> string - tickDecimals: null, // => no. of decimals, null means auto - min: null, // => min. value to show, null means set automatically - max: null, // => max. value to show, null means set automatically - autoscaleMargin: 0, // => margin in % to add if auto-setting min/max - color: null - }, - y2axis: { - titleAngle: 270 - }, - points: { - show: false, // => setting to true will show points, false will hide - radius: 3, // => point radius (pixels) - lineWidth: 2, // => line width in pixels - fill: true, // => true to fill the points with a color, false for (transparent) no fill - fillColor: '#FFFFFF', // => fill color - fillOpacity: 0.4 - }, - lines: { - show: false, // => setting to true will show lines, false will hide - lineWidth: 2, // => line width in pixels - fill: false, // => true to fill the area from the line to the x axis, false for (transparent) no fill - fillColor: null, // => fill color - fillOpacity: 0.4 // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - }, - radar: { - show: false, // => setting to true will show radar chart, false will hide - lineWidth: 2, // => line width in pixels - fill: false, // => true to fill the area from the line to the x axis, false for (transparent) no fill - fillColor: null, // => fill color - fillOpacity: 0.4 // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - }, - bars: { - show: false, // => setting to true will show bars, false will hide - lineWidth: 2, // => in pixels - barWidth: 1, // => in units of the x axis - fill: true, // => true to fill the area from the line to the x axis, false for (transparent) no fill - fillColor: null, // => fill color - fillOpacity: 0.4, // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - horizontal: false, - stacked: false - }, - candles: { - show: false, // => setting to true will show candle sticks, false will hide - lineWidth: 1, // => in pixels - wickLineWidth: 1, // => in pixels - candleWidth: 0.6, // => in units of the x axis - fill: true, // => true to fill the area from the line to the x axis, false for (transparent) no fill - upFillColor: '#00A8F0',// => up sticks fill color - downFillColor: '#CB4B4B',// => down sticks fill color - fillOpacity: 0.5, // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - barcharts: false // => draw as barcharts (not standard bars but financial barcharts) - }, - pie: { - show: false, // => setting to true will show bars, false will hide - lineWidth: 1, // => in pixels - fill: true, // => true to fill the area from the line to the x axis, false for (transparent) no fill - fillColor: null, // => fill color - fillOpacity: 0.6, // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - explode: 6, - sizeRatio: 0.6, - startAngle: Math.PI/4, - labelFormatter: Flotr.defaultPieLabelFormatter, - pie3D: false, - pie3DviewAngle: (Math.PI/2 * 0.8), - pie3DspliceThickness: 20 - }, - grid: { - color: '#545454', // => primary color used for outline and labels - backgroundColor: null, // => null for transparent, else color - tickColor: '#DDDDDD', // => color used for the ticks - labelMargin: 3, // => margin in pixels - verticalLines: true, // => whether to show gridlines in vertical direction - horizontalLines: true, // => whether to show gridlines in horizontal direction - outlineWidth: 2 // => width of the grid outline/border in pixels - }, - selection: { - mode: null, // => one of null, 'x', 'y' or 'xy' - color: '#B6D9FF', // => selection box color - fps: 20 // => frames-per-second - }, - mouse: { - track: false, // => true to track the mouse, no tracking otherwise - position: 'se', // => position of the value box (default south-east) - relative: false, // => next to the mouse cursor - trackFormatter: Flotr.defaultTrackFormatter, // => formats the values in the value box - margin: 5, // => margin in pixels of the valuebox - lineColor: '#FF3F19', // => line color of points that are drawn when mouse comes near a value of a series - trackDecimals: 1, // => decimals for the track values - sensibility: 2, // => the lower this number, the more precise you have to aim to show a value - radius: 3 // => radius of the track point - }, - radarChartMode: false, // => true to render radar grid / and setup scaling for radar chart - shadowSize: 4, // => size of the 'fake' shadow - defaultType: 'lines', // => default series type - HtmlText: true, // => wether to draw the text using HTML or on the canvas - fontSize: 7.5, // => canvas' text font size - spreadsheet: { - show: false, // => show the data grid using two tabs - tabGraphLabel: 'Graph', - tabDataLabel: 'Data', - toolbarDownload: 'Download CSV', // @todo: add language support - toolbarSelectAll: 'Select all' - } - } - - options.x2axis = Object.extend(Object.clone(options.xaxis), options.x2axis); - options.y2axis = Object.extend(Object.clone(options.yaxis), options.y2axis); - this.options = Flotr.merge((opts || {}), options); - - this.axes = { - x: {options: this.options.xaxis, n: 1}, - x2: {options: this.options.x2axis, n: 2}, - y: {options: this.options.yaxis, n: 1}, - y2: {options: this.options.y2axis, n: 2} - }; - - // Initialize some variables used throughout this function. - var assignedColors = [], - colors = [], - ln = this.series.length, - neededColors = this.series.length, - oc = this.options.colors, - usedColors = [], - variation = 0, - c, i, j, s, tooClose; - - // Collect user-defined colors from series. - for(i = neededColors - 1; i > -1; --i){ - c = this.series[i].color; - if(c != null){ - --neededColors; - if(Object.isNumber(c)) assignedColors.push(c); - else usedColors.push(Flotr.parseColor(c)); - } - } - - // Calculate the number of colors that need to be generated. - for(i = assignedColors.length - 1; i > -1; --i) - neededColors = Math.max(neededColors, assignedColors[i] + 1); - - // Generate needed number of colors. - for(i = 0; colors.length < neededColors;){ - c = (oc.length == i) ? new Flotr.Color(100, 100, 100) : Flotr.parseColor(oc[i]); - - // Make sure each serie gets a different color. - var sign = variation % 2 == 1 ? -1 : 1; - var factor = 1 + sign * Math.ceil(variation / 2) * 0.2; - c.scale(factor, factor, factor); - - /** - * @todo if we're getting too close to something else, we should probably skip this one - */ - colors.push(c); - - if(++i >= oc.length){ - i = 0; - ++variation; - } - } - - // Fill the options with the generated colors. - for(i = 0, j = 0; i < ln; ++i){ - s = this.series[i]; - - // Assign the color. - if(s.color == null){ - s.color = colors[j++].toString(); - }else if(Object.isNumber(s.color)){ - s.color = colors[s.color].toString(); - } - - if (!s.xaxis) s.xaxis = this.axes.x; - if (s.xaxis == 1) s.xaxis = this.axes.x; - else if (s.xaxis == 2) s.xaxis = this.axes.x2; - - if (!s.yaxis) s.yaxis = this.axes.y; - if (s.yaxis == 1) s.yaxis = this.axes.y; - else if (s.yaxis == 2) s.yaxis = this.axes.y2; - - // Apply missing options to the series. - s.lines = Object.extend(Object.clone(this.options.lines), s.lines); - s.points = Object.extend(Object.clone(this.options.points), s.points); - s.bars = Object.extend(Object.clone(this.options.bars), s.bars); - s.candles = Object.extend(Object.clone(this.options.candles), s.candles); - s.pie = Object.extend(Object.clone(this.options.pie), s.pie); - s.radar = Object.extend(Object.clone(this.options.radar), s.radar); - s.mouse = Object.extend(Object.clone(this.options.mouse), s.mouse); - - if(s.shadowSize == null) s.shadowSize = this.options.shadowSize; - } - }, - /** - * Initializes the canvas and it's overlay canvas element. When the browser is IE, this makes use - * of excanvas. The overlay canvas is inserted for displaying interactions. After the canvas elements - * are created, the elements are inserted into the container element. - */ - constructCanvas: function(){ - var el = this.el, - size, c, oc; - - this.canvas = el.select('.flotr-canvas')[0]; - this.overlay = el.select('.flotr-overlay')[0]; - - el.childElements().invoke('remove'); - - // For positioning labels and overlay. - el.setStyle({position:'relative', cursor:'default'}); - - this.canvasWidth = el.getWidth(); - this.canvasHeight = el.getHeight(); - size = {'width': this.canvasWidth, 'height': this.canvasHeight}; - - if(this.canvasWidth <= 0 || this.canvasHeight <= 0){ - throw 'Invalid dimensions for plot, width = ' + this.canvasWidth + ', height = ' + this.canvasHeight; - } - - // Insert main canvas. - if (!this.canvas) { - c = this.canvas = new Element('canvas', size); - c.className = 'flotr-canvas'; - c = c.writeAttribute('style', 'position:absolute;left:0px;top:0px;'); - } else { - c = this.canvas.writeAttribute(size); - } - el.insert(c); - - if(Prototype.Browser.IE){ - c = window.G_vmlCanvasManager.initElement(c); - } - this.ctx = c.getContext('2d'); - - // Insert overlay canvas for interactive features. - if (!this.overlay) { - oc = this.overlay = new Element('canvas', size); - oc.className = 'flotr-overlay'; - oc = oc.writeAttribute('style', 'position:absolute;left:0px;top:0px;'); - } else { - oc = this.overlay.writeAttribute(size); - } - el.insert(oc); - - if(Prototype.Browser.IE){ - oc = window.G_vmlCanvasManager.initElement(oc); - } - this.octx = oc.getContext('2d'); - - // Enable text functions - if (window.CanvasText) { - CanvasText.enable(this.ctx); - CanvasText.enable(this.octx); - this.textEnabled = true; - } - }, - getTextDimensions: function(text, canvasStyle, HtmlStyle, className) { - if (!text) return {width:0, height:0}; - - if (!this.options.HtmlText && this.textEnabled) { - var bounds = this.ctx.getTextBounds(text, canvasStyle); - return { - width: bounds.width+2, - height: bounds.height+6 - }; - } - else { - var dummyDiv = this.el.insert('
' + text + '
').select(".flotr-dummy-div")[0]; - dim = dummyDiv.getDimensions(); - dummyDiv.remove(); - return dim; - } - }, - loadDataGrid: function(){ - if (this.seriesData) return this.seriesData; - - var s = this.series; - var dg = []; - - /* The data grid is a 2 dimensions array. There is a row for each X value. - * Each row contains the x value and the corresponding y value for each serie ('undefined' if there isn't one) - **/ - for(i = 0; i < s.length; ++i){ - s[i].data.each(function(v) { - var x = v[0], - y = v[1]; - if (r = dg.find(function(row) {return row[0] == x})) { - r[i+1] = y; - } - else { - var newRow = []; - newRow[0] = x; - newRow[i+1] = y - dg.push(newRow); - } - }); - } - - // The data grid is sorted by x value - dg = dg.sortBy(function(v) { - return v[0]; - }); - return this.seriesData = dg; - }, - - // @todo: make a tab manager (Flotr.Tabs) - showTab: function(tabName, onComplete){ - var elementsClassNames = 'canvas, .flotr-labels, .flotr-legend, .flotr-legend-bg, .flotr-title, .flotr-subtitle'; - switch(tabName) { - case 'graph': - this.datagrid.up().hide(); - this.el.select(elementsClassNames).invoke('show'); - this.tabs.data.removeClassName('selected'); - this.tabs.graph.addClassName('selected'); - break; - case 'data': - this.constructDataGrid(); - this.datagrid.up().show(); - this.el.select(elementsClassNames).invoke('hide'); - this.tabs.data.addClassName('selected'); - this.tabs.graph.removeClassName('selected'); - break; - } - }, - constructTabs: function(){ - var tabsContainer = new Element('div', {className:'flotr-tabs-group', style:'position:absolute;left:0px;top:'+this.canvasHeight+'px;width:'+this.canvasWidth+'px;'}); - this.el.insert({bottom: tabsContainer}); - this.tabs = { - graph: new Element('div', {className:'flotr-tab selected', style:'float:left;'}).update(this.options.spreadsheet.tabGraphLabel), - data: new Element('div', {className:'flotr-tab', style:'float:left;'}).update(this.options.spreadsheet.tabDataLabel) - } - - tabsContainer.insert(this.tabs.graph).insert(this.tabs.data); - - this.el.setStyle({height: this.canvasHeight+this.tabs.data.getHeight()+2+'px'}); - - this.tabs.graph.observe('click', (function() {this.showTab('graph')}).bind(this)); - this.tabs.data.observe('click', (function() {this.showTab('data')}).bind(this)); - }, - - // @todo: make a spreadsheet manager (Flotr.Spreadsheet) - constructDataGrid: function(){ - // If the data grid has already been built, nothing to do here - if (this.datagrid) return this.datagrid; - - var i, j, - s = this.series, - datagrid = this.loadDataGrid(); - - var t = this.datagrid = new Element('table', {className:'flotr-datagrid', style:'height:100px;'}); - var colgroup = ['']; - - // First row : series' labels - var html = ['']; - html.push(' '); - for (i = 0; i < s.length; ++i) { - html.push(''+(s[i].label || String.fromCharCode(65+i))+''); - colgroup.push(''); - } - html.push(''); - - // Data rows - for (j = 0; j < datagrid.length; ++j) { - html.push(''); - for (i = 0; i < s.length+1; ++i) { - var tag = 'td'; - var content = (datagrid[j][i] != null ? Math.round(datagrid[j][i]*100000)/100000 : ''); - - if (i == 0) { - tag = 'th'; - var label; - if(this.options.xaxis.ticks) { - var tick = this.options.xaxis.ticks.find(function (x) { return x[0] == datagrid[j][i] }); - if (tick) label = tick[1]; - } - else { - label = this.options.xaxis.tickFormatter(content); - } - - if (label) content = label; - } - - html.push('<'+tag+(tag=='th'?' scope="row"':'')+'>'+content+''); - } - html.push(''); - } - colgroup.push(''); - t.update(colgroup.join('')+html.join('')); - - if (!Prototype.Browser.IE) { - t.select('td').each(function(td) { - td.observe('mouseover', function(e){ - td = e.element(); - var siblings = td.previousSiblings(); - - t.select('th[scope=col]')[siblings.length-1].addClassName('hover'); - t.select('colgroup col')[siblings.length].addClassName('hover'); - }); - - td.observe('mouseout', function(){ - t.select('colgroup col.hover, th.hover').each(function(e){e.removeClassName('hover')}); - }); - }); - } - - var toolbar = new Element('div', {className: 'flotr-datagrid-toolbar'}). - insert(new Element('button', {type:'button', className:'flotr-datagrid-toolbar-button'}).update(this.options.spreadsheet.toolbarDownload).observe('click', this.downloadCSV.bind(this))). - insert(new Element('button', {type:'button', className:'flotr-datagrid-toolbar-button'}).update(this.options.spreadsheet.toolbarSelectAll).observe('click', this.selectAllData.bind(this))); - - var container = new Element('div', {className:'flotr-datagrid-container', style:'left:0px;top:0px;width:'+this.canvasWidth+'px;height:'+this.canvasHeight+'px;overflow:auto;'}); - container.insert(toolbar); - t.wrap(container.hide()); - - this.el.insert(container); - return t; - }, - selectAllData: function(){ - if (this.tabs) { - var selection, range, doc, win, node = this.constructDataGrid(); - - this.showTab('data'); - - // deferred to be able to select the table - (function () { - if ((doc = node.ownerDocument) && (win = doc.defaultView) && - win.getSelection && doc.createRange && - (selection = window.getSelection()) && - selection.removeAllRanges) { - range = doc.createRange(); - range.selectNode(node); - selection.removeAllRanges(); - selection.addRange(range); - } - else if (document.body && document.body.createTextRange && - (range = document.body.createTextRange())) { - range.moveToElementText(node); - range.select(); - } - }).defer(); - return true; - } - else return false; - }, - downloadCSV: function(){ - var i, csv = '"x"', - series = this.series, - dg = this.loadDataGrid(); - - for (i = 0; i < series.length; ++i) { - csv += '%09"'+(series[i].label || String.fromCharCode(65+i))+'"'; // \t - } - csv += "%0D%0A"; // \r\n - - for (i = 0; i < dg.length; ++i) { - if (this.options.xaxis.ticks) { - var tick = this.options.xaxis.ticks.find(function (x) { return x[0] == dg[i][0] }); - if (tick) dg[i][0] = tick[1]; - } else { - dg[i][0] = this.options.xaxis.tickFormatter(dg[i][0]); - } - csv += dg[i].join('%09')+"%0D%0A"; // \t and \r\n - } - if (Prototype.Browser.IE) { - csv = csv.gsub('%09', '\t').gsub('%0A', '\n').gsub('%0D', '\r'); - window.open().document.write(csv); - } - else { - window.open('data:text/csv,'+csv); - } - }, - /** - * Initializes event some handlers. - */ - initEvents: function () { - //@todo: maybe stopObserving with only flotr functions - this.overlay.stopObserving(); - this.overlay.observe('mousedown', this.mouseDownHandler.bind(this)); - this.overlay.observe('mousemove', this.mouseMoveHandler.bind(this)); - this.overlay.observe('click', this.clickHandler.bind(this)); - }, - /** - * Function determines the min and max values for the xaxis and yaxis. - */ - findDataRanges: function(){ - var s = this.series, - a = this.axes; - - a.x.datamin = 0; a.x.datamax = 0; - a.x2.datamin = 0; a.x2.datamax = 0; - a.y.datamin = 0; a.y.datamax = 0; - a.y2.datamin = 0; a.y2.datamax = 0; - - if(s.length > 0){ - var i, j, h, x, y, data, xaxis, yaxis; - - // Get datamin, datamax start values - for(i = 0; i < s.length; ++i) { - data = s[i].data, - xaxis = s[i].xaxis, - yaxis = s[i].yaxis; - - if (data.length > 0 && !s[i].hide) { - if (!xaxis.used) xaxis.datamin = xaxis.datamax = data[0][0]; - if (!yaxis.used) yaxis.datamin = yaxis.datamax = data[0][1]; - xaxis.used = true; - yaxis.used = true; - - for(h = data.length - 1; h > -1; --h){ - x = data[h][0]; - if(x < xaxis.datamin) xaxis.datamin = x; - else if(x > xaxis.datamax) xaxis.datamax = x; - - for(j = 1; j < data[h].length; j++){ - y = data[h][j]; - if(y < yaxis.datamin) yaxis.datamin = y; - else if(y > yaxis.datamax) yaxis.datamax = y; - } - } - } - if (this.options.radarChartMode) { - xaxis.datamin = yaxis.datamin = - yaxis.datamax; - xaxis.datamax = yaxis.datamax; - if (!this.options.radarChartSides) this.options.radarChartSides = data.length; - } - } - } - - this.findXAxesValues(); - - this.calculateRange(a.x); - this.extendXRangeIfNeededByBar(a.x); - - if (a.x2.used) { - this.calculateRange(a.x2); - this.extendXRangeIfNeededByBar(a.x2); - } - - this.calculateRange(a.y); - this.extendYRangeIfNeededByBar(a.y); - - if (a.y2.used) { - this.calculateRange(a.y2); - this.extendYRangeIfNeededByBar(a.y2); - } - }, - /** - * Calculates the range of an axis to apply autoscaling. - */ - calculateRange: function(axis){ - var o = axis.options, - min = o.min != null ? o.min : axis.datamin, - max = o.max != null ? o.max : axis.datamax, - margin; - - if(max - min == 0.0){ - var widen = (max == 0.0) ? 1.0 : 0.01; - min -= widen; - max += widen; - } - axis.tickSize = Flotr.getTickSize(o.noTicks, ((this.options.radarChartMode) ? 0 : min), max, o.tickDecimals); - - // Autoscaling. - if(o.min == null){ - // Add a margin. - margin = o.autoscaleMargin; - if(margin != 0){ - min -= axis.tickSize * margin; - - // Make sure we don't go below zero if all values are positive. - if(min < 0 && axis.datamin >= 0) min = 0; - min = axis.tickSize * Math.floor(min / axis.tickSize); - } - } - if(o.max == null){ - margin = o.autoscaleMargin; - if(margin != 0){ - max += axis.tickSize * margin; - if(max > 0 && axis.datamax <= 0) max = 0; - max = axis.tickSize * Math.ceil(max / axis.tickSize); - } - } - axis.min = min; - axis.max = max; - }, - /** - * Bar series autoscaling in x direction. - */ - extendXRangeIfNeededByBar: function(axis){ - if(axis.options.max == null){ - var newmax = axis.max, - i, s, b, c, - stackedSums = [], - lastSerie = null; - - for(i = 0; i < this.series.length; ++i){ - s = this.series[i]; - b = s.bars; - c = s.candles; - if(s.axis == axis && (b.show || c.show)) { - if (!b.horizontal && (b.barWidth + axis.datamax > newmax) || (c.candleWidth + axis.datamax > newmax)){ - newmax = axis.max + s.bars.barWidth; - } - if(b.stacked && b.horizontal){ - for (j = 0; j < s.data.length; j++) { - if (s.bars.show && s.bars.stacked) { - var x = s.data[j][0]; - stackedSums[x] = (stackedSums[x] || 0) + s.data[j][1]; - lastSerie = s; - } - } - - for (j = 0; j < stackedSums.length; j++) { - newmax = Math.max(stackedSums[j], newmax); - } - } - } - } - axis.lastSerie = lastSerie; - axis.max = newmax; - } - }, - /** - * Bar series autoscaling in y direction. - */ - extendYRangeIfNeededByBar: function(axis){ - if(axis.options.max == null){ - var newmax = axis.max, - i, s, b, c, - stackedSums = [], - lastSerie = null; - - for(i = 0; i < this.series.length; ++i){ - s = this.series[i]; - b = s.bars; - c = s.candles; - if (s.yaxis == axis && b.show && !s.hide) { - if (b.horizontal && (b.barWidth + axis.datamax > newmax) || (c.candleWidth + axis.datamax > newmax)){ - newmax = axis.max + b.barWidth; - } - if(b.stacked && !b.horizontal){ - for (j = 0; j < s.data.length; j++) { - if (s.bars.show && s.bars.stacked) { - var x = s.data[j][0]; - stackedSums[x] = (stackedSums[x] || 0) + s.data[j][1]; - lastSerie = s; - } - } - - for (j = 0; j < stackedSums.length; j++) { - newmax = Math.max(stackedSums[j], newmax); - } - } - } - } - axis.lastSerie = lastSerie; - axis.max = newmax; - } - }, - /** - * Find every values of the x axes - */ - findXAxesValues: function(){ - for(i = this.series.length-1; i > -1 ; --i){ - s = this.series[i]; - s.xaxis.values = s.xaxis.values || []; - for (j = s.data.length-1; j > -1 ; --j){ - s.xaxis.values[s.data[j][0]] = {}; - } - } - }, - /** - * Calculate axis ticks. - * @param {Object} axis - axis object - * @param {Object} o - axis options - */ - calculateTicks: function(axis){ - var o = axis.options, i, v; - - axis.ticks = []; - if(o.ticks){ - var ticks = o.ticks, t, label; - - if(Object.isFunction(ticks)){ - ticks = ticks({min: axis.min, max: axis.max}); - } - - // Clean up the user-supplied ticks, copy them over. - for(i = 0; i < ticks.length; ++i){ - t = ticks[i]; - if(typeof(t) == 'object'){ - v = t[0]; - label = (t.length > 1) ? t[1] : o.tickFormatter(v); - }else{ - v = t; - label = o.tickFormatter(v); - } - axis.ticks[i] = { v: v, label: label }; - } - } - else { - // Round to nearest multiple of tick size. - var start = axis.tickSize * Math.ceil(axis.min / axis.tickSize), - decimals; - - // Then store all possible ticks. - for(i = 0; start + i * axis.tickSize <= axis.max; ++i){ - v = start + i * axis.tickSize; - - // Round (this is always needed to fix numerical instability). - decimals = o.tickDecimals; - if(decimals == null) decimals = 1 - Math.floor(Math.log(axis.tickSize) / Math.LN10); - if(decimals < 0) decimals = 0; - - v = v.toFixed(decimals); - axis.ticks.push({ v: v, label: o.tickFormatter(v) }); - } - } - }, - /** - * Calculates axis label sizes. - */ - calculateSpacing: function(){ - var a = this.axes, - options = this.options, - series = this.series, - margin = options.grid.labelMargin, - x = a.x, - x2 = a.x2, - y = a.y, - y2 = a.y2, - maxOutset = 2, - i, j, l, dim; - - // Labels width and height - [x, x2, y, y2].each(function(axis) { - var maxLabel = ''; - - if (axis.options.showLabels) { - for(i = 0; i < axis.ticks.length; ++i){ - l = axis.ticks[i].label.length; - if(l > maxLabel.length){ - maxLabel = axis.ticks[i].label; - } - } - } - axis.maxLabel = this.getTextDimensions(maxLabel, {size:options.fontSize, angle: Flotr.toRad(axis.options.labelsAngle)}, 'font-size:smaller;', 'flotr-grid-label'); - axis.titleSize = this.getTextDimensions(axis.options.title, {size: options.fontSize*1.2, angle: Flotr.toRad(axis.options.titleAngle)}, 'font-weight:bold;', 'flotr-axis-title'); - }, this); - - // Title height - dim = this.getTextDimensions(options.title, {size: options.fontSize*1.5}, 'font-size:1em;font-weight:bold;', 'flotr-title'); - this.titleHeight = dim.height; - - // Subtitle height - dim = this.getTextDimensions(options.subtitle, {size: options.fontSize}, 'font-size:smaller;', 'flotr-subtitle'); - this.subtitleHeight = dim.height; - - // Grid outline line width. - if(options.show){ - maxOutset = Math.max(maxOutset, options.points.radius + options.points.lineWidth/2); - } - for(j = 0; j < options.length; ++j){ - if (series[j].points.show){ - maxOutset = Math.max(maxOutset, series[j].points.radius + series[j].points.lineWidth/2); - } - } - - var p = this.plotOffset = {left: 0, right: 0, top: 0, bottom: 0}; - p.left = p.right = p.top = p.bottom = maxOutset; - - p.bottom += (x.options.showLabels ? (x.maxLabel.height + margin) : 0) + - (x.options.title ? (x.titleSize.height + margin) : 0); - - p.top += (x2.options.showLabels ? (x2.maxLabel.height + margin) : 0) + - (x2.options.title ? (x2.titleSize.height + margin) : 0) + this.subtitleHeight + this.titleHeight + - this.options.radarChartMode ? (y.options.showLabels ? (y.maxLabel.height + margin) : 0) : 0; - - p.left += (y.options.showLabels ? (y.maxLabel.width + margin) : 0) + - (y.options.title ? (y.titleSize.width + margin) : 0); - - p.right += (y2.options.showLabels ? (y2.maxLabel.width + margin) : 0) + - (y2.options.title ? (y2.titleSize.width + margin) : 0) + - this.options.radarChartMode ? (x.options.showLabels ? (x.maxLabel.width + margin) : 0) : 0; - - p.top = Math.floor(p.top); // In order the outline not to be blured - - this.plotWidth = this.canvasWidth - p.left - p.right; - this.plotHeight = this.canvasHeight - p.bottom - p.top; - - x.scale = this.plotWidth / (x.max - x.min); - x2.scale = this.plotWidth / (x2.max - x2.min); - y.scale = this.plotHeight / (y.max - y.min); - y2.scale = this.plotHeight / (y2.max - y2.min); - }, - /** - * Draws grid, labels and series. - */ - draw: function() { - this.drawGrid(); - this.drawLabels(); - this.drawTitles(); - - if(this.series.length){ - this.el.fire('flotr:beforedraw', [this.series, this]); - for(var i = 0; i < this.series.length; i++){ - if (!this.series[i].hide) - this.drawSeries(this.series[i]); - } - } - this.el.fire('flotr:afterdraw', [this.series, this]); - }, - /** - * Translates absolute horizontal x coordinates to relative coordinates. - * @param {Integer} x - absolute integer x coordinate - * @return {Integer} translated relative x coordinate - */ - tHoz: function(x, axis){ - axis = axis || this.axes.x; - return (x - axis.min) * axis.scale; - }, - /** - * Translates absolute vertical x coordinates to relative coordinates. - * @param {Integer} y - absolute integer y coordinate - * @return {Integer} translated relative y coordinate - */ - tVert: function(y, axis){ - axis = axis || this.axes.y; - return this.plotHeight - (y - axis.min) * axis.scale; - }, - /** - * Draws a grid for the graph. - */ - drawGrid: function(){ - if (this.options.radarChartMode) { // If we are in radar chart mode call drawRadarGrid instead and exit - this.drawRadarGrid(); - return; - } - var v, o = this.options, - ctx = this.ctx; - if(o.grid.verticalLines || o.grid.horizontalLines){ - this.el.fire('flotr:beforegrid', [this.axes.x, this.axes.y, o, this]); - } - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - - // Draw grid background, if present in options. - if(o.grid.backgroundColor != null){ - ctx.fillStyle = o.grid.backgroundColor; - ctx.fillRect(0, 0, this.plotWidth, this.plotHeight); - } - - // Draw grid lines in vertical direction. - ctx.lineWidth = 1; - ctx.strokeStyle = o.grid.tickColor; - ctx.beginPath(); - if(o.grid.verticalLines){ - for(var i = 0; i < this.axes.x.ticks.length; ++i){ - v = this.axes.x.ticks[i].v; - // Don't show lines on upper and lower bounds. - if ((v == this.axes.x.min || v == this.axes.x.max) && o.grid.outlineWidth != 0) - continue; - - ctx.moveTo(Math.floor(this.tHoz(v)) + ctx.lineWidth/2, 0); - ctx.lineTo(Math.floor(this.tHoz(v)) + ctx.lineWidth/2, this.plotHeight); - } - } - - // Draw grid lines in horizontal direction. - if(o.grid.horizontalLines){ - for(var j = 0; j < this.axes.y.ticks.length; ++j){ - v = this.axes.y.ticks[j].v; - // Don't show lines on upper and lower bounds. - if ((v == this.axes.y.min || v == this.axes.y.max) && o.grid.outlineWidth != 0) - continue; - - ctx.moveTo(0, Math.floor(this.tVert(v)) + ctx.lineWidth/2); - ctx.lineTo(this.plotWidth, Math.floor(this.tVert(v)) + ctx.lineWidth/2); - } - } - ctx.stroke(); - - // Draw axis/grid border. - if(o.grid.outlineWidth != 0) { - ctx.lineWidth = o.grid.outlineWidth; - ctx.strokeStyle = o.grid.color; - ctx.lineJoin = 'round'; - ctx.strokeRect(0, 0, this.plotWidth, this.plotHeight); - } - ctx.restore(); - if(o.grid.verticalLines || o.grid.horizontalLines){ - this.el.fire('flotr:aftergrid', [this.axes.x, this.axes.y, o, this]); - } - }, - /** - * Draws a grid for the graph. - */ - drawRadarGrid: function(){ - - var v, o = this.options, - ctx = this.ctx; - - var sides = this.options.radarChartSides, - degreesInRadiansForAngle = Math.PI * 2 / sides, - nintyDegrees = Math.PI / 2; - - if(o.grid.verticalLines || o.grid.horizontalLines){ - this.el.fire('flotr:beforegrid', [this.axes.x, this.axes.y, o, this]); - } - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'round'; - - // Draw grid background, if present in options. - if(o.grid.backgroundColor != null){ - ctx.fillStyle = o.grid.backgroundColor; - ctx.fillRect(0, 0, this.plotWidth, this.plotHeight); - } - - // Draw grid lines - var regPoly = {}; - regPoly.xaxis = {}; - regPoly.yaxis = {}; - regPoly.xaxis.min = regPoly.yaxis.min = this.axes.x.min; - regPoly.xaxis.max = regPoly.yaxis.max = this.axes.x.max; - regPoly.xaxis.scale = this.plotWidth / (this.axes.x.max - this.axes.x.min); - regPoly.yaxis.scale = this.plotHeight / (this.axes.x.max - this.axes.x.min); - - ctx.lineWidth = 1; - ctx.strokeStyle = o.grid.tickColor; - - if(o.grid.horizontalLines){ - for(var j = 0; j < this.axes.y.ticks.length; ++j){ - v = this.axes.y.ticks[j].v; - if (v < 0) continue; - // Don't show lines on upper and lower bounds. - if ((v == this.axes.y.min || v == this.axes.y.max) && o.grid.outlineWidth != 0) - continue; - regPoly.data = new Array(); - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - regPoly.data[i] = [v * Math.cos(angle), v * Math.sin(angle)] - } - regPoly.data[sides] = regPoly.data[0]; - this.plotLine(regPoly,0); - } - } - - // Draw axis/grid border. - if(o.grid.outlineWidth != 0) { - ctx.lineWidth = o.grid.outlineWidth; - ctx.strokeStyle = o.grid.color; - regPoly.data = new Array(); - var radius = this.axes.x.max; - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - regPoly.data[i] = [radius * Math.cos(angle), radius * Math.sin(angle)] - } - regPoly.data[sides] = regPoly.data[0]; - this.plotLine(regPoly,0); - } - - ctx.lineWidth = 1; - ctx.strokeStyle = o.grid.tickColor; - ctx.beginPath(); - - if(o.grid.verticalLines){ - for(var i = 0; i < sides; ++i){ - ctx.moveTo(Math.floor(this.tHoz(0)) + ctx.lineWidth/2, - Math.floor(this.tVert(0)) + ctx.lineWidth/2); - ctx.lineTo(Math.floor(this.tHoz(regPoly.data[i][0])) + ctx.lineWidth/2, - Math.floor(this.tVert(regPoly.data[i][1])) + ctx.lineWidth/2); - } - } - - ctx.stroke(); - - ctx.restore(); - if(o.grid.verticalLines || o.grid.horizontalLines){ - this.el.fire('flotr:aftergrid', [this.axes.x, this.axes.y, o, this]); - } - }, - /** - * Draws labels aroung radar chart - */ - drawRadarLabels:function(){ - var ctx = this.ctx, - options = this.options, - axis = this.axes.x, - tick, minY = 0, maxY = 0, - xOffset, yOffset; - var style = { - size: options.fontSize, - adjustAlign: true - }; - style.color = axis.options.color || options.grid.color; - style.angle = Flotr.toRad(axis.options.labelsAngle); - var radius = axis.max * 1, - closeTo = axis.max * 0.1, - sides = this.options.radarChartSides, - degreesInRadiansForAngle = Math.PI * 2 / sides, - nintyDegrees = Math.PI / 2, - posdata = new Array(); - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - posdata[i] = [radius * Math.cos(angle), radius * Math.sin(angle)]; - if (minY > posdata[i][1]) minY = posdata[i][1]; - if (maxY < posdata[i][1]) maxY = posdata[i][1]; - } - for (i = 0; i < sides; i++) { - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - yOffset = 0; - if (posdata[i][0] > 0) { - style.halign = 'l'; - xOffset = options.grid.labelMargin; - } else { - style.halign = 'r'; - xOffset = - options.grid.labelMargin; - } - style.valign = 'm'; - - if ((posdata[i][1] + closeTo) >= minY && (posdata[i][1] - closeTo) <= minY) { - style.valign = 't' ; - style.halign = 'c'; - yOffset = options.grid.labelMargin; - }; - if (posdata[i][1] == maxY) { - style.valign = 'b' ; - style.halign = 'c'; - yOffset = - options.grid.labelMargin; - } - ctx.drawText( - tick.label, - this.plotOffset.left + this.tHoz(posdata[i][0]) + xOffset, - this.plotOffset.top + this.tVert(posdata[i][1]) + yOffset, - style - ); - } - - }, - /** - * Draws labels for x and y axis. - */ - drawLabels: function(){ - // Construct fixed width label boxes, which can be styled easily. - var noLabels = 0, axis, - xBoxWidth, i, html, tick, - options = this.options, - ctx = this.ctx, - a = this.axes; - - for(i = 0; i < a.x.ticks.length; ++i){ - if (a.x.ticks[i].label) { - ++noLabels; - } - } - xBoxWidth = this.plotWidth / noLabels; - - if (!options.HtmlText && this.textEnabled) { - var style = { - size: options.fontSize, - adjustAlign: true - }; - - // Add x labels. - if (options.radarChartMode) { - this.drawRadarLabels();} else { - axis = a.x; - style.color = axis.options.color || options.grid.color; - for(i = 0; i < axis.ticks.length && axis.options.showLabels && axis.used; ++i){ - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - - style.angle = Flotr.toRad(axis.options.labelsAngle); - style.halign = 'c'; - style.valign = 't'; - - ctx.drawText( - tick.label, - this.plotOffset.left + this.tHoz(tick.v, axis), - this.plotOffset.top + this.plotHeight + options.grid.labelMargin, - style - ); - }} - - // Add x2 labels. - axis = a.x2; - style.color = axis.options.color || options.grid.color; - for(i = 0; i < axis.ticks.length && axis.options.showLabels && axis.used; ++i){ - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - - style.angle = Flotr.toRad(axis.options.labelsAngle); - style.halign = 'c'; - style.valign = 'b'; - - ctx.drawText( - tick.label, - this.plotOffset.left + this.tHoz(tick.v, axis), - this.plotOffset.top + options.grid.labelMargin, - style - ); - } - - // Add y labels. - axis = a.y; - style.color = axis.options.color || options.grid.color; - for(i = 0; i < axis.ticks.length && axis.options.showLabels && axis.used; ++i){ - tick = axis.ticks[i]; - if (!tick.label || tick.label.length == 0 || (tick.v < 0 && this.options.radarChartMode)) continue; - - style.angle = Flotr.toRad(axis.options.labelsAngle); - style.halign = 'r'; - style.valign = 'm'; - - ctx.drawText( - tick.label, - this.plotOffset.left + (this.options.radarChartMode ? this.tHoz(0) : 0) - options.grid.labelMargin, - this.plotOffset.top + this.tVert(tick.v, axis), - style - ); - } - - // Add y2 labels. - axis = a.y2; - style.color = axis.options.color || options.grid.color; - for(i = 0; i < axis.ticks.length && axis.options.showLabels && axis.used; ++i){ - tick = axis.ticks[i]; - if (!tick.label || tick.label.length == 0) continue; - - style.angle = Flotr.toRad(axis.options.labelsAngle); - style.halign = 'l'; - style.valign = 'm'; - - ctx.drawText( - tick.label, - this.plotOffset.left + this.plotWidth + options.grid.labelMargin, - this.plotOffset.top + this.tVert(tick.v, axis), - style - ); - - ctx.save(); - ctx.strokeStyle = style.color; - ctx.beginPath(); - ctx.moveTo(this.plotOffset.left + this.plotWidth - 8, this.plotOffset.top + this.tVert(tick.v, axis)); - ctx.lineTo(this.plotOffset.left + this.plotWidth, this.plotOffset.top + this.tVert(tick.v, axis)); - ctx.stroke(); - ctx.restore(); - } - } - else if (a.x.options.showLabels || - a.x2.options.showLabels || - a.y.options.showLabels || - a.y2.options.showLabels) { - html = ['
']; - - // Add x labels. - axis = a.x; - if (axis.options.showLabels){ - for(i = 0; i < axis.ticks.length; ++i){ - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - html.push('
' + tick.label + '
'); - } - } - - // Add x2 labels. - axis = a.x2; - if (axis.options.showLabels && axis.used){ - for(i = 0; i < axis.ticks.length; ++i){ - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - html.push('
' + tick.label + '
'); - } - } - - // Add y labels. - axis = a.y; - if (axis.options.showLabels){ - for(i = 0; i < axis.ticks.length; ++i){ - tick = axis.ticks[i]; - if (!tick.label || tick.label.length == 0) continue; - html.push('
' + tick.label + '
'); - } - } - - // Add y2 labels. - axis = a.y2; - if (axis.options.showLabels && axis.used){ - ctx.save(); - ctx.strokeStyle = axis.options.color || options.grid.color; - ctx.beginPath(); - - for(i = 0; i < axis.ticks.length; ++i){ - tick = axis.ticks[i]; - if (!tick.label || tick.label.length == 0) continue; - html.push('
' + tick.label + '
'); - - ctx.moveTo(this.plotOffset.left + this.plotWidth - 8, this.plotOffset.top + this.tVert(tick.v, axis)); - ctx.lineTo(this.plotOffset.left + this.plotWidth, this.plotOffset.top + this.tVert(tick.v, axis)); - } - ctx.stroke(); - ctx.restore(); - } - - html.push('
'); - this.el.insert(html.join('')); - } - }, - /** - * Draws the title and the subtitle - */ - drawTitles: function(){ - var html, - options = this.options, - margin = options.grid.labelMargin, - ctx = this.ctx, - a = this.axes; - - if (!options.HtmlText && this.textEnabled) { - var style = { - size: options.fontSize, - color: options.grid.color, - halign: 'c' - }; - - // Add subtitle - if (options.subtitle){ - ctx.drawText( - options.subtitle, - this.plotOffset.left + this.plotWidth/2, - this.titleHeight + this.subtitleHeight - 2, - style - ); - } - - style.weight = 1.5; - style.size *= 1.5; - - // Add title - if (options.title){ - ctx.drawText( - options.title, - this.plotOffset.left + this.plotWidth/2, - this.titleHeight - 2, - style - ); - } - - style.weight = 1.8; - style.size *= 0.8; - style.adjustAlign = true; - - // Add x axis title - if (a.x.options.title && a.x.used){ - style.halign = 'c'; - style.valign = 't'; - style.angle = Flotr.toRad(a.x.options.titleAngle); - ctx.drawText( - a.x.options.title, - this.plotOffset.left + this.plotWidth/2, - this.plotOffset.top + a.x.maxLabel.height + this.plotHeight + 2 * margin, - style - ); - } - - // Add x2 axis title - if (a.x2.options.title && a.x2.used){ - style.halign = 'c'; - style.valign = 'b'; - style.angle = Flotr.toRad(a.x2.options.titleAngle); - ctx.drawText( - a.x2.options.title, - this.plotOffset.left + this.plotWidth/2, - this.plotOffset.top - a.x2.maxLabel.height - 2 * margin, - style - ); - } - - // Add y axis title - if (a.y.options.title && a.y.used){ - style.halign = 'r'; - style.valign = 'm'; - style.angle = Flotr.toRad(a.y.options.titleAngle); - ctx.drawText( - a.y.options.title, - this.plotOffset.left - a.y.maxLabel.width - 2 * margin, - this.plotOffset.top + this.plotHeight / 2, - style - ); - } - - // Add y2 axis title - if (a.y2.options.title && a.y2.used){ - style.halign = 'l'; - style.valign = 'm'; - style.angle = Flotr.toRad(a.y2.options.titleAngle); - ctx.drawText( - a.y2.options.title, - this.plotOffset.left + this.plotWidth + a.y2.maxLabel.width + 2 * margin, - this.plotOffset.top + this.plotHeight / 2, - style - ); - } - } - else { - html = ['
']; - - // Add title - if (options.title){ - html.push('
'+options.title+'
'); - } - - // Add subtitle - if (options.subtitle){ - html.push('
'+options.subtitle+'
'); - } - html.push('
'); - - - html.push('
'); - // Add x axis title - if (a.x.options.title && a.x.used){ - html.push('
' + a.x.options.title + '
'); - } - - // Add x2 axis title - if (a.x2.options.title && a.x2.used){ - html.push('
' + a.x2.options.title + '
'); - } - - // Add y axis title - if (a.y.options.title && a.y.used){ - html.push('
' + a.y.options.title + '
'); - } - - // Add y2 axis title - if (a.y2.options.title && a.y2.used){ - html.push('
' + a.y2.options.title + '
'); - } - html.push('
'); - - this.el.insert(html.join('')); - } - }, - /** - * Actually draws the graph. - * @param {Object} series - series to draw - */ - drawSeries: function(series){ - series = series || this.series; - - var drawn = false; - for(var type in Flotr._registeredTypes){ - if(series[type] && series[type].show){ - this[Flotr._registeredTypes[type]](series); - drawn = true; - } - } - - if(!drawn){ - this[Flotr._registeredTypes[this.options.defaultType]](series); - } - }, - - plotLine: function(series, offset){ - var ctx = this.ctx, - xa = series.xaxis, - ya = series.yaxis, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this), - data = series.data; - - if(data.length < 2) return; - - var prevx = tHoz(data[0][0], xa), - prevy = tVert(data[0][1], ya) + offset; - ctx.beginPath(); - ctx.moveTo(prevx, prevy); - for(var i = 0; i < data.length - 1; ++i){ - var x1 = data[i][0], y1 = data[i][1], - x2 = data[i+1][0], y2 = data[i+1][1]; - - // To allow empty values - if (y1 === null || y2 === null) continue; - - /** - * Clip with ymin. - */ - if(y1 <= y2 && y1 < ya.min){ - /** - * Line segment is outside the drawing area. - */ - if(y2 < ya.min) continue; - - /** - * Compute new intersection point. - */ - x1 = (ya.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = ya.min; - }else if(y2 <= y1 && y2 < ya.min){ - if(y1 < ya.min) continue; - x2 = (ya.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = ya.min; - } - - /** - * Clip with ymax. - */ - if(y1 >= y2 && y1 > ya.max) { - if(y2 > ya.max) continue; - x1 = (ya.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = ya.max; - } - else if(y2 >= y1 && y2 > ya.max){ - if(y1 > ya.max) continue; - x2 = (ya.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = ya.max; - } - - /** - * Clip with xmin. - */ - if(x1 <= x2 && x1 < xa.min){ - if(x2 < xa.min) continue; - y1 = (xa.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = xa.min; - }else if(x2 <= x1 && x2 < xa.min){ - if(x1 < xa.min) continue; - y2 = (xa.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = xa.min; - } - - /** - * Clip with xmax. - */ - if(x1 >= x2 && x1 > xa.max){ - if (x2 > xa.max) continue; - y1 = (xa.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = xa.max; - }else if(x2 >= x1 && x2 > xa.max){ - if(x1 > xa.max) continue; - y2 = (xa.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = xa.max; - } - - if(prevx != tHoz(x1, xa) || prevy != tVert(y1, ya) + offset) - ctx.moveTo(tHoz(x1, xa), tVert(y1, ya) + offset); - - prevx = tHoz(x2, xa); - prevy = tVert(y2, ya) + offset; - ctx.lineTo(prevx, prevy); - } - ctx.stroke(); - }, - /** - * Function used to fill - * @param {Object} data - */ - plotLineArea: function(series, offset){ - var data = series.data; - if(data.length < 2) return; - - var top, lastX = 0, - ctx = this.ctx, - xa = series.xaxis, - ya = series.yaxis, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this), - bottom = Math.min(Math.max(0, ya.min), ya.max), - first = true; - - ctx.beginPath(); - for(var i = 0; i < data.length - 1; ++i){ - - var x1 = data[i][0], y1 = data[i][1], - x2 = data[i+1][0], y2 = data[i+1][1]; - - if(x1 <= x2 && x1 < xa.min){ - if(x2 < xa.min) continue; - y1 = (xa.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = xa.min; - }else if(x2 <= x1 && x2 < xa.min){ - if(x1 < xa.min) continue; - y2 = (xa.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = xa.min; - } - - if(x1 >= x2 && x1 > xa.max){ - if(x2 > xa.max) continue; - y1 = (xa.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = xa.max; - }else if(x2 >= x1 && x2 > xa.max){ - if (x1 > xa.max) continue; - y2 = (xa.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = xa.max; - } - - if(first){ - ctx.moveTo(tHoz(x1, xa), tVert(bottom, ya) + offset); - first = false; - } - - /** - * Now check the case where both is outside. - */ - if(y1 >= ya.max && y2 >= ya.max){ - ctx.lineTo(tHoz(x1, xa), tVert(ya.max, ya) + offset); - ctx.lineTo(tHoz(x2, xa), tVert(ya.max, ya) + offset); - continue; - }else if(y1 <= ya.min && y2 <= ya.min){ - ctx.lineTo(tHoz(x1, xa), tVert(ya.min, ya) + offset); - ctx.lineTo(tHoz(x2, xa), tVert(ya.min, ya) + offset); - continue; - } - - /** - * Else it's a bit more complicated, there might - * be two rectangles and two triangles we need to fill - * in; to find these keep track of the current x values. - */ - var x1old = x1, x2old = x2; - - /** - * And clip the y values, without shortcutting. - * Clip with ymin. - */ - if(y1 <= y2 && y1 < ya.min && y2 >= ya.min){ - x1 = (ya.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = ya.min; - }else if(y2 <= y1 && y2 < ya.min && y1 >= ya.min){ - x2 = (ya.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = ya.min; - } - - /** - * Clip with ymax. - */ - if(y1 >= y2 && y1 > ya.max && y2 <= ya.max){ - x1 = (ya.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = ya.max; - }else if(y2 >= y1 && y2 > ya.max && y1 <= ya.max){ - x2 = (ya.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = ya.max; - } - - /** - * If the x value was changed we got a rectangle to fill. - */ - if(x1 != x1old){ - top = (y1 <= ya.min) ? top = ya.min : ya.max; - ctx.lineTo(tHoz(x1old, xa), tVert(top, ya) + offset); - ctx.lineTo(tHoz(x1, xa), tVert(top, ya) + offset); - } - - /** - * Fill the triangles. - */ - ctx.lineTo(tHoz(x1, xa), tVert(y1, ya) + offset); - ctx.lineTo(tHoz(x2, xa), tVert(y2, ya) + offset); - - /** - * Fill the other rectangle if it's there. - */ - if(x2 != x2old){ - top = (y2 <= ya.min) ? ya.min : ya.max; - ctx.lineTo(tHoz(x2old, xa), tVert(top, ya) + offset); - ctx.lineTo(tHoz(x2, xa), tVert(top, ya) + offset); - } - - lastX = Math.max(x2, x2old); - } - - ctx.lineTo(tHoz(lastX, xa), tVert(bottom, ya) + offset); - ctx.closePath(); - ctx.fill(); - }, - /** - * Function: (private) drawSeriesLines - * - * Function draws lines series in the canvas element. - * - * Parameters: - * series - Series with options.lines.show = true. - * - * Returns: - * void - */ - drawSeriesLines: function(series){ - series = series || this.series; - var ctx = this.ctx; - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'round'; - - var lw = series.lines.lineWidth; - var sw = series.shadowSize; - - if(sw > 0){ - ctx.lineWidth = sw / 2; - - var offset = lw/2 + ctx.lineWidth/2; - - ctx.strokeStyle = "rgba(0,0,0,0.1)"; - this.plotLine(series, offset + sw/2); - - ctx.strokeStyle = "rgba(0,0,0,0.2)"; - this.plotLine(series, offset); - - if(series.lines.fill) { - ctx.fillStyle = "rgba(0,0,0,0.05)"; - this.plotLineArea(series, offset + sw/2); - } - } - - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - if(series.lines.fill){ - ctx.fillStyle = series.lines.fillColor != null ? series.lines.fillColor : Flotr.parseColor(series.color).scale(null, null, null, series.lines.fillOpacity).toString(); - this.plotLineArea(series, 0); - } - - this.plotLine(series, 0); - ctx.restore(); - }, - /** - * Function: drawSeriesPoints - * - * Function draws point series in the canvas element. - * - * Parameters: - * series - Series with options.points.show = true. - * - * Returns: - * void - */ - drawSeriesPoints: function(series) { - var ctx = this.ctx; - - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - - var lw = series.lines.lineWidth; - var sw = series.shadowSize; - - if(sw > 0){ - ctx.lineWidth = sw / 2; - - ctx.strokeStyle = 'rgba(0,0,0,0.1)'; - this.plotPointShadows(series, sw/2 + ctx.lineWidth/2, series.points.radius); - - ctx.strokeStyle = 'rgba(0,0,0,0.2)'; - this.plotPointShadows(series, ctx.lineWidth/2, series.points.radius); - } - - ctx.lineWidth = series.points.lineWidth; - ctx.strokeStyle = series.color; - ctx.fillStyle = series.points.fillColor != null ? series.points.fillColor : series.color; - this.plotPoints(series, series.points.radius, series.points.fill); - ctx.restore(); - }, - plotPoints: function (series, radius, fill) { - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, i, - data = series.data; - - for(i = data.length - 1; i > -1; --i){ - var x = data[i][0], y = data[i][1]; - if(x < xa.min || x > xa.max || y < ya.min || y > ya.max) - continue; - - ctx.beginPath(); - ctx.arc(this.tHoz(x, xa), this.tVert(y, ya), radius, 0, 2 * Math.PI, true); - if(fill) ctx.fill(); - ctx.stroke(); - } - }, - plotPointShadows: function(series, offset, radius){ - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, i, - data = series.data; - - for(i = data.length - 1; i > -1; --i){ - var x = data[i][0], y = data[i][1]; - if (x < xa.min || x > xa.max || y < ya.min || y > ya.max) - continue; - ctx.beginPath(); - ctx.arc(this.tHoz(x, xa), this.tVert(y, ya) + offset, radius, 0, Math.PI, false); - ctx.stroke(); - } - }, - /** - * Function: drawSeriesBars - * - * Function draws bar series in the canvas element. - * - * Parameters: - * series - Series with options.bars.show = true. - * - * Returns: - * void - */ - drawSeriesBars: function(series) { - var ctx = this.ctx, - bw = series.bars.barWidth, - lw = Math.min(series.bars.lineWidth, bw); - - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'miter'; - - /** - * @todo linewidth not interpreted the right way. - */ - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - - this.plotBarsShadows(series, bw, 0, series.bars.fill); - - if(series.bars.fill){ - ctx.fillStyle = series.bars.fillColor != null ? series.bars.fillColor : Flotr.parseColor(series.color).scale(null, null, null, series.bars.fillOpacity).toString(); - } - - this.plotBars(series, bw, 0, series.bars.fill); - ctx.restore(); - }, - plotBars: function(series, barWidth, offset, fill){ - var data = series.data; - if(data.length < 1) return; - - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this); - - for(var i = 0; i < data.length; i++){ - var x = data[i][0], - y = data[i][1]; - var drawLeft = true, drawTop = true, drawRight = true; - - // Stacked bars - var stackOffset = 0; - if(series.bars.stacked) { - xa.values.each(function(o, v) { - if (v == x) { - stackOffset = o.stack || 0; - o.stack = stackOffset + y; - } - }); - } - - // @todo: fix horizontal bars support - // Horizontal bars - if(series.bars.horizontal) - var left = stackOffset, right = x + stackOffset, bottom = y, top = y + barWidth; - else - var left = x, right = x + barWidth, bottom = stackOffset, top = y + stackOffset; - - if(right < xa.min || left > xa.max || top < ya.min || bottom > ya.max) - continue; - - if(left < xa.min){ - left = xa.min; - drawLeft = false; - } - - if(right > xa.max){ - right = xa.max; - if (xa.lastSerie != series && series.bars.horizontal) - drawTop = false; - } - - if(bottom < ya.min) - bottom = ya.min; - - if(top > ya.max){ - top = ya.max; - if (ya.lastSerie != series && !series.bars.horizontal) - drawTop = false; - } - - /** - * Fill the bar. - */ - if(fill){ - ctx.beginPath(); - ctx.moveTo(tHoz(left, xa), tVert(bottom, ya) + offset); - ctx.lineTo(tHoz(left, xa), tVert(top, ya) + offset); - ctx.lineTo(tHoz(right, xa), tVert(top, ya) + offset); - ctx.lineTo(tHoz(right, xa), tVert(bottom, ya) + offset); - ctx.fill(); - } - - /** - * Draw bar outline/border. - */ - if(series.bars.lineWidth != 0 && (drawLeft || drawRight || drawTop)){ - ctx.beginPath(); - ctx.moveTo(tHoz(left, xa), tVert(bottom, ya) + offset); - - ctx[drawLeft ?'lineTo':'moveTo'](tHoz(left, xa), tVert(top, ya) + offset); - ctx[drawTop ?'lineTo':'moveTo'](tHoz(right, xa), tVert(top, ya) + offset); - ctx[drawRight?'lineTo':'moveTo'](tHoz(right, xa), tVert(bottom, ya) + offset); - - ctx.stroke(); - } - } - }, - plotBarsShadows: function(series, barWidth, offset){ - var data = series.data; - if(data.length < 1) return; - - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this), - sw = this.options.shadowSize; - - for(var i = 0; i < data.length; i++){ - var x = data[i][0], - y = data[i][1]; - - // Stacked bars - var stackOffset = 0; - if(series.bars.stacked) { - xa.values.each(function(o, v) { - if (v == x) { - stackOffset = o.stackShadow || 0; - o.stackShadow = stackOffset + y; - } - }); - } - - // Horizontal bars - if(series.bars.horizontal) - var left = stackOffset, right = x + stackOffset, bottom = y, top = y + barWidth; - else - var left = x, right = x + barWidth, bottom = stackOffset, top = y + stackOffset; - - if(right < xa.min || left > xa.max || top < ya.min || bottom > ya.max) - continue; - - if(left < xa.min) left = xa.min; - if(right > xa.max) right = xa.max; - if(bottom < ya.min) bottom = ya.min; - if(top > ya.max) top = ya.max; - - var width = tHoz(right, xa)-tHoz(left, xa)-((tHoz(right, xa)+sw <= this.plotWidth) ? 0 : sw); - var height = Math.max(0, tVert(bottom, ya)-tVert(top, ya)-((tVert(bottom, ya)+sw <= this.plotHeight) ? 0 : sw)); - - ctx.fillStyle = 'rgba(0,0,0,0.05)'; - ctx.fillRect(Math.min(tHoz(left, xa)+sw, this.plotWidth), Math.min(tVert(top, ya)+sw, this.plotWidth), width, height); - } - }, - /** - * Function: drawSeriesCandles - * - * Function draws candles series in the canvas element. - * - * Parameters: - * series - Series with options.candles.show = true. - * - * Returns: - * void - */ - drawSeriesCandles: function(series) { - var ctx = this.ctx, - bw = series.candles.candleWidth; - - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'miter'; - - /** - * @todo linewidth not interpreted the right way. - */ - ctx.lineWidth = series.candles.lineWidth; - this.plotCandlesShadows(series, bw/2); - this.plotCandles(series, bw/2); - - ctx.restore(); - }, - plotCandles: function(series, offset){ - var data = series.data; - if(data.length < 1) return; - - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this); - - for(var i = 0; i < data.length; i++){ - var d = data[i], - x = d[0], - open = d[1], - high = d[2], - low = d[3], - close = d[4]; - - var left = x, - right = x + series.candles.candleWidth, - bottom = Math.max(ya.min, low), - top = Math.min(ya.max, high), - bottom2 = Math.max(ya.min, Math.min(open, close)), - top2 = Math.min(ya.max, Math.max(open, close)); - - if(right < xa.min || left > xa.max || top < ya.min || bottom > ya.max) - continue; - - var color = series.candles[open>close?'downFillColor':'upFillColor']; - /** - * Fill the candle. - */ - if(series.candles.fill && !series.candles.barcharts){ - ctx.fillStyle = Flotr.parseColor(color).scale(null, null, null, series.candles.fillOpacity).toString(); - ctx.fillRect(tHoz(left, xa), tVert(top2, ya) + offset, tHoz(right, xa) - tHoz(left, xa), tVert(bottom2, ya) - tVert(top2, ya)); - } - - /** - * Draw candle outline/border, high, low. - */ - if(series.candles.lineWidth || series.candles.wickLineWidth){ - var x, y, pixelOffset = (series.candles.wickLineWidth % 2) / 2; - - x = Math.floor(tHoz((left + right) / 2), xa) + pixelOffset; - - ctx.save(); - ctx.strokeStyle = color; - ctx.lineWidth = series.candles.wickLineWidth; - ctx.lineCap = 'butt'; - - if (series.candles.barcharts) { - ctx.beginPath(); - - ctx.moveTo(x, Math.floor(tVert(top, ya) + offset)); - ctx.lineTo(x, Math.floor(tVert(bottom, ya) + offset)); - - y = Math.floor(tVert(open, ya) + offset)+0.5; - ctx.moveTo(Math.floor(tHoz(left, xa))+pixelOffset, y); - ctx.lineTo(x, y); - - y = Math.floor(tVert(close, ya) + offset)+0.5; - ctx.moveTo(Math.floor(tHoz(right, xa))+pixelOffset, y); - ctx.lineTo(x, y); - } - else { - ctx.strokeRect(tHoz(left, xa), tVert(top2, ya) + offset, tHoz(right, xa) - tHoz(left, xa), tVert(bottom2, ya) - tVert(top2, ya)); - - ctx.beginPath(); - ctx.moveTo(x, Math.floor(tVert(top2, ya) + offset)); - ctx.lineTo(x, Math.floor(tVert(top, ya) + offset)); - ctx.moveTo(x, Math.floor(tVert(bottom2, ya) + offset)); - ctx.lineTo(x, Math.floor(tVert(bottom, ya) + offset)); - } - - ctx.stroke(); - ctx.restore(); - } - } - }, - plotCandlesShadows: function(series, offset){ - var data = series.data; - if(data.length < 1 || series.candles.barcharts) return; - - var xa = series.xaxis, - ya = series.yaxis, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this), - sw = this.options.shadowSize; - - for(var i = 0; i < data.length; i++){ - var d = data[i], - x = d[0], - open = d[1], - high = d[2], - low = d[3], - close = d[4]; - - var left = x, - right = x + series.candles.candleWidth, - bottom = Math.max(ya.min, Math.min(open, close)), - top = Math.min(ya.max, Math.max(open, close)); - - if(right < xa.min || left > xa.max || top < ya.min || bottom > ya.max) - continue; - - var width = tHoz(right, xa)-tHoz(left, xa)-((tHoz(right, xa)+sw <= this.plotWidth) ? 0 : sw); - var height = Math.max(0, tVert(bottom, ya)-tVert(top, ya)-((tVert(bottom, ya)+sw <= this.plotHeight) ? 0 : sw)); - - this.ctx.fillStyle = 'rgba(0,0,0,0.05)'; - this.ctx.fillRect(Math.min(tHoz(left, xa)+sw, this.plotWidth), Math.min(tVert(top, ya)+sw, this.plotWidth), width, height); - } - }, - /** - * Function: drawSeriesRadar - * - * Function draws a radar chart on the canvas element. - * - * Parameters: - * series - Series with options.radar.show = true. - * - * Returns: - * void - */ - drawSeriesRadar: function(series) { - var ctx = this.ctx, - options = this.options, sides= series.data.length; - - var degreesInRadiansForAngle = Math.PI * 2 / sides, - nintyDegrees = Math.PI / 2; - - var poly = {}; - - /* - Draw radar grid - - poly.xaxis = series.xaxis; - poly.yaxis = series.yaxis; - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'round'; - for (radius = 20; radius <= 100; radius += 20) { - poly.data = new Array(); - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - poly.data[i] = [radius * Math.cos(angle), radius * Math.sin(angle)] - } - poly.data[sides] = poly.data[0]; - this.plotLine(poly,0);} - - var outside = poly.data; - for (i = 0; i < sides; i++) { - poly.data = new Array(); - poly.data[0] = [0,0]; - poly.data[1] = outside[i]; - this.plotLine(poly,0); - } - */ - - /* - Convert Series data into X, Y co-ordinates - */ - if (!series.dataInRadarFormat) { - poly.data = new Array(); - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - poly.data[i] = [series.data[i][1] * Math.cos(angle), series.data[i][1] * Math.sin(angle), series.data[i][0], series.data[i][1]] - } - poly.data[sides] = poly.data[0]; - series.data = poly.data; - series.lines = series.radar; - series.lines.show = false; - series.dataInRadarFormat = true; - } - - this.drawSeriesLines(series); - -}, - - - /** - * Function: drawSeriesPie - * - * Function draws a pie in the canvas element. - * - * Parameters: - * series - Series with options.pie.show = true. - * - * Returns: - * void - */ - drawSeriesPie: function(series) { - if (!this.options.pie.drawn) { - var ctx = this.ctx, - options = this.options, - lw = series.pie.lineWidth, - sw = series.shadowSize, - data = series.data, - radius = (Math.min(this.canvasWidth, this.canvasHeight) * series.pie.sizeRatio) / 2, - html = []; - - var vScale = 1;//Math.cos(series.pie.viewAngle); - var plotTickness = Math.sin(series.pie.viewAngle)*series.pie.spliceThickness / vScale; - - var style = { - size: options.fontSize*1.2, - color: options.grid.color, - weight: 1.5 - }; - - var center = { - x: (this.canvasWidth+this.plotOffset.left)/2, - y: (this.canvasHeight-this.plotOffset.bottom)/2 - }; - - // Pie portions - var portions = this.series.collect(function(hash, index){ - if (hash.pie.show) - return { - name: (hash.label || hash.data[0][1]), - value: [index, hash.data[0][1]], - explode: hash.pie.explode - }; - }); - - // Sum of the portions' angles - var sum = portions.pluck('value').pluck(1).inject(0, function(acc, n) { return acc + n; }); - - var fraction = 0.0, - angle = series.pie.startAngle, - value = 0.0; - - var slices = portions.collect(function(slice){ - angle += fraction; - value = parseFloat(slice.value[1]); // @warning : won't support null values !! - fraction = value/sum; - return { - name: slice.name, - fraction: fraction, - x: slice.value[0], - y: value, - explode: slice.explode, - startAngle: 2 * angle * Math.PI, - endAngle: 2 * (angle + fraction) * Math.PI - }; - }); - - ctx.save(); - - if(sw > 0){ - slices.each(function (slice) { - var bisection = (slice.startAngle + slice.endAngle) / 2; - - var xOffset = center.x + Math.cos(bisection) * slice.explode + sw; - var yOffset = center.y + Math.sin(bisection) * slice.explode + sw; - - this.plotSlice(xOffset, yOffset, radius, slice.startAngle, slice.endAngle, false, vScale); - - ctx.fillStyle = 'rgba(0,0,0,0.1)'; - ctx.fill(); - }, this); - } - - if (options.HtmlText) { - html = ['
']; - } - - slices.each(function (slice, index) { - var bisection = (slice.startAngle + slice.endAngle) / 2; - var color = options.colors[index]; - - var xOffset = center.x + Math.cos(bisection) * slice.explode; - var yOffset = center.y + Math.sin(bisection) * slice.explode; - - this.plotSlice(xOffset, yOffset, radius, slice.startAngle, slice.endAngle, false, vScale); - - if(series.pie.fill){ - ctx.fillStyle = Flotr.parseColor(color).scale(null, null, null, series.pie.fillOpacity).toString(); - ctx.fill(); - } - ctx.lineWidth = lw; - ctx.strokeStyle = color; - ctx.stroke(); - - /*ctx.save(); - ctx.scale(1, vScale); - - ctx.moveTo(xOffset, yOffset); - ctx.beginPath(); - ctx.lineTo(xOffset, yOffset+plotTickness); - ctx.lineTo(xOffset+Math.cos(slice.startAngle)*radius, yOffset+Math.sin(slice.startAngle)*radius+plotTickness); - ctx.lineTo(xOffset+Math.cos(slice.startAngle)*radius, yOffset+Math.sin(slice.startAngle)*radius); - ctx.lineTo(xOffset, yOffset); - ctx.closePath(); - ctx.fill();ctx.stroke(); - - ctx.moveTo(xOffset, yOffset); - ctx.beginPath(); - ctx.lineTo(xOffset, yOffset+plotTickness); - ctx.lineTo(xOffset+Math.cos(slice.endAngle)*radius, yOffset+Math.sin(slice.endAngle)*radius+plotTickness); - ctx.lineTo(xOffset+Math.cos(slice.endAngle)*radius, yOffset+Math.sin(slice.endAngle)*radius); - ctx.lineTo(xOffset, yOffset); - ctx.closePath(); - ctx.fill();ctx.stroke(); - - ctx.moveTo(xOffset+Math.cos(slice.startAngle)*radius, yOffset+Math.sin(slice.startAngle)*radius); - ctx.beginPath(); - ctx.lineTo(xOffset+Math.cos(slice.startAngle)*radius, yOffset+Math.sin(slice.startAngle)*radius+plotTickness); - ctx.arc(xOffset, yOffset+plotTickness, radius, slice.startAngle, slice.endAngle, false); - ctx.lineTo(xOffset+Math.cos(slice.endAngle)*radius, yOffset+Math.sin(slice.endAngle)*radius); - ctx.arc(xOffset, yOffset, radius, slice.endAngle, slice.startAngle, true); - ctx.closePath(); - ctx.fill();ctx.stroke(); - - ctx.scale(1, 1/vScale); - this.plotSlice(xOffset, yOffset+plotTickness, radius, slice.startAngle, slice.endAngle, false, vScale); - ctx.stroke(); - if(series.pie.fill){ - ctx.fillStyle = Flotr.parseColor(color).scale(null, null, null, series.pie.fillOpacity).toString(); - ctx.fill(); - } - - ctx.restore();*/ - - var label = options.pie.labelFormatter(slice); - - var textAlignRight = (Math.cos(bisection) < 0); - var distX = xOffset + Math.cos(bisection) * (series.pie.explode + radius); - var distY = yOffset + Math.sin(bisection) * (series.pie.explode + radius); - - if (slice.fraction && label) { - if (options.HtmlText) { - var divStyle = 'position:absolute;top:' + (distY - 5) + 'px;'; //@todo: change - if (textAlignRight) { - divStyle += 'right:'+(this.canvasWidth - distX)+'px;text-align:right;'; - } - else { - divStyle += 'left:'+distX+'px;text-align:left;'; - } - html.push('
' + label + '
'); - } - else { - style.halign = textAlignRight ? 'r' : 'l'; - ctx.drawText( - label, - distX, - distY + style.size / 2, - style - ); - } - } - }, this); - - if (options.HtmlText) { - html.push('
'); - this.el.insert(html.join('')); - } - - ctx.restore(); - options.pie.drawn = true; - } - }, - plotSlice: function(x, y, radius, startAngle, endAngle, fill, vScale) { - var ctx = this.ctx; - vScale = vScale || 1; - - ctx.save(); - ctx.scale(1, vScale); - ctx.beginPath(); - ctx.moveTo(x, y); - ctx.arc (x, y, radius, startAngle, endAngle, fill); - ctx.lineTo(x, y); - ctx.closePath(); - ctx.restore(); - }, - plotPie: function() {}, - /** - * Function: insertLegend - * - * Function adds a legend div to the canvas container or draws it on the canvas. - * - * Parameters: - * none - * - * Returns: - * void - */ - insertLegend: function(){ - if(!this.options.legend.show) - return; - - var series = this.series, - plotOffset = this.plotOffset, - options = this.options, - fragments = [], - rowStarted = false, - ctx = this.ctx, - i; - - var noLegendItems = series.findAll(function(s) {return (s.label && !s.hide)}).size(); - - if (noLegendItems) { - if (!options.HtmlText && this.textEnabled) { - var style = { - size: options.fontSize*1.1, - color: options.grid.color - }; - - // @todo: take css into account - //var dummyDiv = this.el.insert('
'); - - var p = options.legend.position, - m = options.legend.margin, - lbw = options.legend.labelBoxWidth, - lbh = options.legend.labelBoxHeight, - lbm = options.legend.labelBoxMargin, - offsetX = plotOffset.left + m, - offsetY = plotOffset.top + m; - - // We calculate the labels' max width - var labelMaxWidth = 0; - for(i = series.length - 1; i > -1; --i){ - if(!series[i].label || series[i].hide) continue; - var label = options.legend.labelFormatter(series[i].label); - labelMaxWidth = Math.max(labelMaxWidth, ctx.measureText(label, style)); - } - - var legendWidth = Math.round(lbw + lbm*3 + labelMaxWidth), - legendHeight = Math.round(noLegendItems*(lbm+lbh) + lbm); - - if(p.charAt(0) == 's') offsetY = plotOffset.top + this.plotHeight - (m + legendHeight); - if(p.charAt(1) == 'e') offsetX = plotOffset.left + this.plotWidth - (m + legendWidth); - - // Legend box - var color = Flotr.parseColor(options.legend.backgroundColor || 'rgb(240,240,240)').scale(null, null, null, options.legend.backgroundOpacity || 0.1).toString(); - - ctx.fillStyle = color; - ctx.fillRect(offsetX, offsetY, legendWidth, legendHeight); - ctx.strokeStyle = options.legend.labelBoxBorderColor; - ctx.strokeRect(Flotr.toPixel(offsetX), Flotr.toPixel(offsetY), legendWidth, legendHeight); - - // Legend labels - var x = offsetX + lbm; - var y = offsetY + lbm; - for(i = 0; i < series.length; i++){ - if(!series[i].label || series[i].hide) continue; - var label = options.legend.labelFormatter(series[i].label); - - ctx.fillStyle = series[i].color; - ctx.fillRect(x, y, lbw-1, lbh-1); - - ctx.strokeStyle = options.legend.labelBoxBorderColor; - ctx.lineWidth = 1; - ctx.strokeRect(Math.ceil(x)-1.5, Math.ceil(y)-1.5, lbw+2, lbh+2); - - // Legend text - ctx.drawText( - label, - x + lbw + lbm, - y + (lbh + style.size - ctx.fontDescent(style))/2, - style - ); - - y += lbh + lbm; - } - } - else { - for(i = 0; i < series.length; ++i){ - if(!series[i].label || series[i].hide) continue; - - if(i % options.legend.noColumns == 0){ - fragments.push(rowStarted ? '' : ''); - rowStarted = true; - } - - var label = options.legend.labelFormatter(series[i].label); - - fragments.push('
' + - '' + label + ''); - } - if(rowStarted) fragments.push(''); - - if(fragments.length > 0){ - var table = '' + fragments.join("") + '
'; - if(options.legend.container != null){ - $(options.legend.container).update(table); - }else{ - var pos = ''; - var p = options.legend.position, m = options.legend.margin; - - if(p.charAt(0) == 'n') pos += 'top:' + (m + plotOffset.top) + 'px;'; - else if(p.charAt(0) == 's') pos += 'bottom:' + (m + plotOffset.bottom) + 'px;'; - if(p.charAt(1) == 'e') pos += 'right:' + (m + plotOffset.right) + 'px;'; - else if(p.charAt(1) == 'w') pos += 'left:' + (m + plotOffset.left) + 'px;'; - - var div = this.el.insert('
' + table + '
').select('div.flotr-legend').first(); - - if(options.legend.backgroundOpacity != 0.0){ - /** - * Put in the transparent background separately to avoid blended labels and - * label boxes. - */ - var c = options.legend.backgroundColor; - if(c == null){ - var tmp = (options.grid.backgroundColor != null) ? options.grid.backgroundColor : Flotr.extractColor(div); - c = Flotr.parseColor(tmp).adjust(null, null, null, 1).toString(); - } - this.el.insert('
').select('div.flotr-legend-bg').first().setStyle({ - 'opacity': options.legend.backgroundOpacity - }); - } - } - } - } - } - }, - /** - * Function: getEventPosition - * - * Calculates the coordinates from a mouse event object. - * - * Parameters: - * event - Mouse Event object. - * - * Returns: - * Object with x and y coordinates of the mouse. - */ - getEventPosition: function (event){ - var offset = this.overlay.cumulativeOffset(), - rx = (event.pageX - offset.left - this.plotOffset.left), - ry = (event.pageY - offset.top - this.plotOffset.top), - ax = 0, ay = 0 - - if(event.pageX == null && event.clientX != null){ - var de = document.documentElement, b = document.body; - ax = event.clientX + (de && de.scrollLeft || b.scrollLeft || 0); - ay = event.clientY + (de && de.scrollTop || b.scrollTop || 0); - }else{ - ax = event.pageX; - ay = event.pageY; - } - - return { - x: this.axes.x.min + rx / this.axes.x.scale, - x2: this.axes.x2.min + rx / this.axes.x2.scale, - y: this.axes.y.max - ry / this.axes.y.scale, - y2: this.axes.y2.max - ry / this.axes.y2.scale, - relX: rx, - relY: ry, - absX: ax, - absY: ay - }; - }, - /** - * Function: clickHandler - * - * Handler observes the 'click' event and fires the 'flotr:click' event. - * - * Parameters: - * event - 'click' Event object. - * - * Returns: - * void - */ - clickHandler: function(event){ - if(this.ignoreClick){ - this.ignoreClick = false; - return; - } - this.el.fire('flotr:click', [this.getEventPosition(event), this]); - }, - /** - * Function: mouseMoveHandler - * - * Handler observes mouse movement over the graph area. Fires the - * 'flotr:mousemove' event. - * - * Parameters: - * event - 'mousemove' Event object. - * - * Returns: - * void - */ - mouseMoveHandler: function(event){ - var pos = this.getEventPosition(event); - - this.lastMousePos.pageX = pos.absX; - this.lastMousePos.pageY = pos.absY; - if(this.selectionInterval == null && (this.options.mouse.track || this.series.any(function(s){return s.mouse && s.mouse.track;}))){ - this.hit(pos); - } - - this.el.fire('flotr:mousemove', [event, pos, this]); - }, - /** - * Function: mouseDownHandler - * - * Handler observes the 'mousedown' event. - * - * Parameters: - * event - 'mousedown' Event object. - * - * Returns: - * void - */ - mouseDownHandler: function (event){ - if(event.isRightClick()) { - event.stop(); - var overlay = this.overlay; - overlay.hide(); - - function cancelContextMenu () { - overlay.show(); - $(document).stopObserving('mousemove', cancelContextMenu); - } - $(document).observe('mousemove', cancelContextMenu); - return; - } - - if(!this.options.selection.mode || !event.isLeftClick()) return; - - this.setSelectionPos(this.selection.first, event); - if(this.selectionInterval != null){ - clearInterval(this.selectionInterval); - } - this.lastMousePos.pageX = null; - this.selectionInterval = setInterval(this.updateSelection.bind(this), 1000/this.options.selection.fps); - - this.mouseUpHandler = this.mouseUpHandler.bind(this); - $(document).observe('mouseup', this.mouseUpHandler); - }, - /** - * Function: (private) fireSelectEvent - * - * Fires the 'flotr:select' event when the user made a selection. - * - * Parameters: - * none - * - * Returns: - * void - */ - fireSelectEvent: function(){ - var a = this.axes, selection = this.selection, - x1 = (selection.first.x <= selection.second.x) ? selection.first.x : selection.second.x, - x2 = (selection.first.x <= selection.second.x) ? selection.second.x : selection.first.x, - y1 = (selection.first.y >= selection.second.y) ? selection.first.y : selection.second.y, - y2 = (selection.first.y >= selection.second.y) ? selection.second.y : selection.first.y; - - x1 = a.x.min + x1 / a.x.scale; - x2 = a.x.min + x2 / a.x.scale; - y1 = a.y.max - y1 / a.y.scale; - y2 = a.y.max - y2 / a.y.scale; - - this.el.fire('flotr:select', [{x1:x1, y1:y1, x2:x2, y2:y2}, this]); - }, - /** - * Function: (private) mouseUpHandler - * - * Handler observes the mouseup event for the document. - * - * Parameters: - * event - 'mouseup' Event object. - * - * Returns: - * void - */ - mouseUpHandler: function(event){ - $(document).stopObserving('mouseup', this.mouseUpHandler); - event.stop(); - - if(this.selectionInterval != null){ - clearInterval(this.selectionInterval); - this.selectionInterval = null; - } - - this.setSelectionPos(this.selection.second, event); - this.clearSelection(); - - if(this.selectionIsSane()){ - this.drawSelection(); - this.fireSelectEvent(); - this.ignoreClick = true; - } - }, - /** - * Function: setSelectionPos - * - * Calculates the position of the selection. - * - * Parameters: - * pos - Position object. - * event - Event object. - * - * Returns: - * void - */ - setSelectionPos: function(pos, event) { - var options = this.options, - offset = $(this.overlay).cumulativeOffset(); - - if(options.selection.mode.indexOf('x') == -1){ - pos.x = (pos == this.selection.first) ? 0 : this.plotWidth; - }else{ - pos.x = event.pageX - offset.left - this.plotOffset.left; - pos.x = Math.min(Math.max(0, pos.x), this.plotWidth); - } - - if (options.selection.mode.indexOf('y') == -1){ - pos.y = (pos == this.selection.first) ? 0 : this.plotHeight; - }else{ - pos.y = event.pageY - offset.top - this.plotOffset.top; - pos.y = Math.min(Math.max(0, pos.y), this.plotHeight); - } - }, - /** - * Function: updateSelection - * - * Updates (draws) the selection box. - * - * Parameters: - * none - * - * Returns: - * void - */ - updateSelection: function(){ - if(this.lastMousePos.pageX == null) return; - - this.setSelectionPos(this.selection.second, this.lastMousePos); - this.clearSelection(); - - if(this.selectionIsSane()) this.drawSelection(); - }, - /** - * Function: clearSelection - * - * Removes the selection box from the overlay canvas. - * - * Parameters: - * none - * - * Returns: - * void - */ - clearSelection: function() { - if(this.prevSelection == null) return; - - var prevSelection = this.prevSelection, - octx = this.octx, - plotOffset = this.plotOffset, - x = Math.min(prevSelection.first.x, prevSelection.second.x), - y = Math.min(prevSelection.first.y, prevSelection.second.y), - w = Math.abs(prevSelection.second.x - prevSelection.first.x), - h = Math.abs(prevSelection.second.y - prevSelection.first.y); - - octx.clearRect(x + plotOffset.left - octx.lineWidth, - y + plotOffset.top - octx.lineWidth, - w + octx.lineWidth*2, - h + octx.lineWidth*2); - - this.prevSelection = null; - }, - /** - * Function: setSelection - * - * Allows the user the manually select an area. - * - * Parameters: - * area - Object with coordinates to select. - * - * Returns: - * void - */ - setSelection: function(area){ - var options = this.options, - xa = this.axes.x, - ya = this.axes.y, - vertScale = yaxis.scale, - hozScale = xaxis.scale, - selX = options.selection.mode.indexOf('x') != -1, - selY = options.selection.mode.indexOf('y') != -1; - - this.clearSelection(); - - this.selection.first.y = selX ? 0 : (ya.max - area.y1) * vertScale; - this.selection.second.y = selX ? this.plotHeight : (ya.max - area.y2) * vertScale; - this.selection.first.x = selY ? 0 : (area.x1 - xa.min) * hozScale; - this.selection.second.x = selY ? this.plotWidth : (area.x2 - xa.min) * hozScale; - - this.drawSelection(); - this.fireSelectEvent(); - }, - /** - * Function: (private) drawSelection - * - * Draws the selection box. - * - * Parameters: - * none - * - * Returns: - * void - */ - drawSelection: function() { - var prevSelection = this.prevSelection, - selection = this.selection, - octx = this.octx, - options = this.options, - plotOffset = this.plotOffset; - - if(prevSelection != null && - selection.first.x == prevSelection.first.x && - selection.first.y == prevSelection.first.y && - selection.second.x == prevSelection.second.x && - selection.second.y == prevSelection.second.y) - return; - - octx.strokeStyle = Flotr.parseColor(options.selection.color).scale(null, null, null, 0.8).toString(); - octx.lineWidth = 1; - octx.lineJoin = 'round'; - octx.fillStyle = Flotr.parseColor(options.selection.color).scale(null, null, null, 0.4).toString(); - - this.prevSelection = { - first: { x: selection.first.x, y: selection.first.y }, - second: { x: selection.second.x, y: selection.second.y } - }; - - var x = Math.min(selection.first.x, selection.second.x), - y = Math.min(selection.first.y, selection.second.y), - w = Math.abs(selection.second.x - selection.first.x), - h = Math.abs(selection.second.y - selection.first.y); - - octx.fillRect(x + plotOffset.left, y + plotOffset.top, w, h); - octx.strokeRect(x + plotOffset.left, y + plotOffset.top, w, h); - }, - /** - * Function: (private) selectionIsSane - * - * Determines whether or not the selection is sane and should be drawn. - * - * Parameters: - * none - * - * Returns: - * boolean - True when sane, false otherwise. - */ - selectionIsSane: function(){ - var selection = this.selection; - return Math.abs(selection.second.x - selection.first.x) >= 5 && - Math.abs(selection.second.y - selection.first.y) >= 5; - }, - /** - * Function: clearHit - * - * Removes the mouse tracking point from the overlay. - * - * Parameters: - * none - * - * Returns: - * void - */ - clearHit: function(){ - if(this.prevHit){ - var options = this.options, - plotOffset = this.plotOffset, - prevHit = this.prevHit; - - this.octx.clearRect( - this.tHoz(prevHit.x) + plotOffset.left - options.points.radius*2, - this.tVert(prevHit.y) + plotOffset.top - options.points.radius*2, - options.points.radius*3 + options.points.lineWidth*3, - options.points.radius*3 + options.points.lineWidth*3 - ); - this.prevHit = null; - } - }, - /** - * Function: hit - * - * Retrieves the nearest data point from the mouse cursor. If it's within - * a certain range, draw a point on the overlay canvas and display the x and y - * value of the data. - * - * Parameters: - * mouse - Object that holds the relative x and y coordinates of the cursor. - * - * Returns: - * void - */ - hit: function(mouse){ - var series = this.series, - options = this.options, - prevHit = this.prevHit, - plotOffset = this.plotOffset, - octx = this.octx, - data, xsens, ysens, - /** - * Nearest data element. - */ - i, n = { - dist:Number.MAX_VALUE, - x:null, - y:null, - relX:mouse.relX, - relY:mouse.relY, - absX:mouse.absX, - absY:mouse.absY, - mouse:null, - radarData:null - }; - - for(i = 0; i < series.length; i++){ - s = series[i]; - if(!s.mouse.track) continue; - data = s.data; - xsens = (s.xaxis.scale*s.mouse.sensibility); - ysens = (s.yaxis.scale*s.mouse.sensibility); - - for(var j = 0, xpow, ypow; j < data.length; j++){ - if (data[j][1] === null) continue; - xpow = Math.pow(s.xaxis.scale*(data[j][0] - mouse.x), 2); - ypow = Math.pow(s.yaxis.scale*(data[j][1] - mouse.y), 2); - if(xpow < xsens && ypow < ysens && Math.sqrt(xpow+ypow) < n.dist){ - n.dist = Math.sqrt(xpow+ypow); - n.x = data[j][0]; - n.y = data[j][1]; - n.radarLabel = data[j][2]; - n.radarData = data[j][3]; - n.mouse = s.mouse; - } - } - } - - if(n.mouse && n.mouse.track && !prevHit || (prevHit && (n.x != prevHit.x || n.y != prevHit.y))){ - var mt = this.mouseTrack || this.el.select(".flotr-mouse-value")[0], - pos = '', - p = options.mouse.position, - m = options.mouse.margin, - elStyle = 'opacity:0.7;background-color:#000;color:#fff;display:none;position:absolute;padding:2px 8px;-moz-border-radius:4px;border-radius:4px;white-space:nowrap;'; - - if (!options.mouse.relative) { // absolute to the canvas - if(p.charAt(0) == 'n') pos += 'top:' + (m + plotOffset.top) + 'px;'; - else if(p.charAt(0) == 's') pos += 'bottom:' + (m + plotOffset.bottom) + 'px;'; - if(p.charAt(1) == 'e') pos += 'right:' + (m + plotOffset.right) + 'px;'; - else if(p.charAt(1) == 'w') pos += 'left:' + (m + plotOffset.left) + 'px;'; - } - else { // relative to the mouse - if(p.charAt(0) == 'n') pos += 'bottom:' + (m - plotOffset.top - this.tVert(n.y) + this.canvasHeight) + 'px;'; - else if(p.charAt(0) == 's') pos += 'top:' + (m + plotOffset.top + this.tVert(n.y)) + 'px;'; - if(p.charAt(1) == 'e') pos += 'left:' + (m + plotOffset.left + this.tHoz(n.x)) + 'px;'; - else if(p.charAt(1) == 'w') pos += 'right:' + (m - plotOffset.left - this.tHoz(n.x) + this.canvasWidth) + 'px;'; - } - - elStyle += pos; - - if(!mt){ - this.el.insert('
'); - mt = this.mouseTrack = this.el.select('.flotr-mouse-value').first(); - } - else { - this.mouseTrack = mt.setStyle(elStyle); - } - - if(n.x !== null && n.y !== null){ - mt.show(); - - this.clearHit(); - if(n.mouse.lineColor != null){ - octx.save(); - octx.translate(plotOffset.left, plotOffset.top); - octx.lineWidth = options.points.lineWidth; - octx.strokeStyle = n.mouse.lineColor; - octx.fillStyle = '#ffffff'; - octx.beginPath(); - octx.arc(this.tHoz(n.x), this.tVert(n.y), options.mouse.radius, 0, 2 * Math.PI, true); - octx.fill(); - octx.stroke(); - octx.restore(); - } - this.prevHit = n; - - var decimals = n.mouse.trackDecimals; - if(decimals == null || decimals < 0) decimals = 0; - - mt.innerHTML = n.mouse.trackFormatter({x: n.x.toFixed(decimals), y: n.y.toFixed(decimals), - radarLabel: n.radarLabel, radarData: n.radarData.toFixed(decimals)}); - mt.fire('flotr:hit', [n, this]); - } - else if(prevHit){ - mt.hide(); - this.clearHit(); - } - } - }, - saveImage: function (type, width, height, replaceCanvas) { - var image = null; - switch (type) { - case 'jpeg': - case 'jpg': image = Canvas2Image.saveAsJPEG(this.canvas, replaceCanvas, width, height); break; - default: - case 'png': image = Canvas2Image.saveAsPNG(this.canvas, replaceCanvas, width, height); break; - case 'bmp': image = Canvas2Image.saveAsBMP(this.canvas, replaceCanvas, width, height); break; - } - if (Object.isElement(image) && replaceCanvas) { - this.restoreCanvas(); - this.canvas.hide(); - this.overlay.hide(); - this.el.insert(image.setStyle({position: 'absolute'})); - } - }, - restoreCanvas: function() { - this.canvas.show(); - this.overlay.show(); - this.el.select('img').invoke('remove'); - } -}); - -Flotr.Color = Class.create({ - initialize: function(r, g, b, a){ - this.rgba = ['r','g','b','a']; - var x = 4; - while(-1<--x){ - this[this.rgba[x]] = arguments[x] || ((x==3) ? 1.0 : 0); - } - this.normalize(); - }, - - adjust: function(rd, gd, bd, ad) { - var x = 4; - while(-1<--x){ - if(arguments[x] != null) - this[this.rgba[x]] += arguments[x]; - } - return this.normalize(); - }, - - clone: function(){ - return new Flotr.Color(this.r, this.b, this.g, this.a); - }, - - limit: function(val,minVal,maxVal){ - return Math.max(Math.min(val, maxVal), minVal); - }, - - normalize: function(){ - var limit = this.limit; - this.r = limit(parseInt(this.r), 0, 255); - this.g = limit(parseInt(this.g), 0, 255); - this.b = limit(parseInt(this.b), 0, 255); - this.a = limit(this.a, 0, 1); - return this; - }, - - scale: function(rf, gf, bf, af){ - var x = 4; - while(-1<--x){ - if(arguments[x] != null) - this[this.rgba[x]] *= arguments[x]; - } - return this.normalize(); - }, - - distance: function(color){ - if (!color) return; - color = new Flotr.parseColor(color); - var dist = 0; - var x = 3; - while(-1<--x){ - dist += Math.abs(this[this.rgba[x]] - color[this.rgba[x]]); - } - return dist; - }, - - toString: function(){ - return (this.a >= 1.0) ? 'rgb('+[this.r,this.g,this.b].join(',')+')' : 'rgba('+[this.r,this.g,this.b,this.a].join(',')+')'; - } -}); - -Flotr.Color.lookupColors = { - 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] -}; - -// not used yet -Flotr.Date = { - format: function(d, format) { - if (!d) return; - - var leftPad = function(n) { - n = n.toString(); - return n.length == 1 ? "0" + n : n; - }; - - var r = []; - var escape = false; - - for (var i = 0; i < format.length; ++i) { - var c = format.charAt(i); - - if (escape) { - switch (c) { - case 'h': c = d.getUTCHours().toString(); break; - case 'H': c = leftPad(d.getUTCHours()); break; - case 'M': c = leftPad(d.getUTCMinutes()); break; - case 'S': c = leftPad(d.getUTCSeconds()); break; - case 'd': c = d.getUTCDate().toString(); break; - case 'm': c = (d.getUTCMonth() + 1).toString(); break; - case 'y': c = d.getUTCFullYear().toString(); break; - case 'b': c = Flotr.Date.monthNames[d.getUTCMonth()]; break; - } - r.push(c); - escape = false; - } - else { - if (c == "%") - escape = true; - else - r.push(c); - } - } - return r.join(""); - }, - timeUnits: { - "second": 1000, - "minute": 60 * 1000, - "hour": 60 * 60 * 1000, - "day": 24 * 60 * 60 * 1000, - "month": 30 * 24 * 60 * 60 * 1000, - "year": 365.2425 * 24 * 60 * 60 * 1000 - }, - // the allowed tick sizes, after 1 year we use an integer algorithm - spec: [ - [1, "second"], [2, "second"], [5, "second"], [10, "second"], [30, "second"], - [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], [30, "minute"], - [1, "hour"], [2, "hour"], [4, "hour"], [8, "hour"], [12, "hour"], - [1, "day"], [2, "day"], [3, "day"], - [0.25, "month"], [0.5, "month"], [1, "month"], [2, "month"], [3, "month"], [6, "month"], - [1, "year"] - ], - monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] -}; --- a/js/flotr/lib/base64.js +++ /dev/null @@ -1,113 +1,1 @@ -/* Copyright (C) 1999 Masanao Izumo - * Version: 1.0 - * LastModified: Dec 25 1999 - * This library is free. You can redistribute it and/or modify it. - */ - -/* - * Interfaces: - * b64 = base64encode(data); - * data = base64decode(b64); - */ - -(function() { - -var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -var base64DecodeChars = [ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1]; - -function base64encode(str) { - var out, i, len; - var c1, c2, c3; - - len = str.length; - i = 0; - out = ""; - while(i < len) { - c1 = str.charCodeAt(i++) & 0xff; - if(i == len) - { - out += base64EncodeChars.charAt(c1 >> 2); - out += base64EncodeChars.charAt((c1 & 0x3) << 4); - out += "=="; - break; - } - c2 = str.charCodeAt(i++); - if(i == len) - { - out += base64EncodeChars.charAt(c1 >> 2); - out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); - out += base64EncodeChars.charAt((c2 & 0xF) << 2); - out += "="; - break; - } - c3 = str.charCodeAt(i++); - out += base64EncodeChars.charAt(c1 >> 2); - out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); - out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)); - out += base64EncodeChars.charAt(c3 & 0x3F); - } - return out; -} - -function base64decode(str) { - var c1, c2, c3, c4; - var i, len, out; - - len = str.length; - i = 0; - out = ""; - while(i < len) { - /* c1 */ - do { - c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; - } while(i < len && c1 == -1); - if(c1 == -1) - break; - - /* c2 */ - do { - c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; - } while(i < len && c2 == -1); - if(c2 == -1) - break; - - out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4)); - - /* c3 */ - do { - c3 = str.charCodeAt(i++) & 0xff; - if(c3 == 61) - return out; - c3 = base64DecodeChars[c3]; - } while(i < len && c3 == -1); - if(c3 == -1) - break; - - out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2)); - - /* c4 */ - do { - c4 = str.charCodeAt(i++) & 0xff; - if(c4 == 61) - return out; - c4 = base64DecodeChars[c4]; - } while(i < len && c4 == -1); - if(c4 == -1) - break; - out += String.fromCharCode(((c3 & 0x03) << 6) | c4); - } - return out; -} - -if (!window.btoa) window.btoa = base64encode; -if (!window.atob) window.atob = base64decode; - -})(); + --- a/js/flotr/lib/canvas2image.js +++ /dev/null @@ -1,230 +1,1 @@ -/* - * Canvas2Image v0.1 - * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com - * MIT License [http://www.opensource.org/licenses/mit-license.php] - */ - -var Canvas2Image = (function() { - // check if we have canvas support - var oCanvas = document.createElement("canvas"); - - // no canvas, bail out. - if (!oCanvas.getContext) { - return { - saveAsBMP : function(){}, - saveAsPNG : function(){}, - saveAsJPEG : function(){} - } - } - - var bHasImageData = !!(oCanvas.getContext("2d").getImageData); - var bHasDataURL = !!(oCanvas.toDataURL); - var bHasBase64 = !!(window.btoa); - - var strDownloadMime = "image/octet-stream"; - - // ok, we're good - var readCanvasData = function(oCanvas) { - var iWidth = parseInt(oCanvas.width); - var iHeight = parseInt(oCanvas.height); - return oCanvas.getContext("2d").getImageData(0,0,iWidth,iHeight); - } - - // base64 encodes either a string or an array of charcodes - var encodeData = function(data) { - var strData = ""; - if (typeof data == "string") { - strData = data; - } else { - var aData = data; - for (var i = 0; i < aData.length; i++) { - strData += String.fromCharCode(aData[i]); - } - } - return btoa(strData); - } - - // creates a base64 encoded string containing BMP data - // takes an imagedata object as argument - var createBMP = function(oData) { - var aHeader = []; - - var iWidth = oData.width; - var iHeight = oData.height; - - aHeader.push(0x42); // magic 1 - aHeader.push(0x4D); - - var iFileSize = iWidth*iHeight*3 + 54; // total header size = 54 bytes - aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256); - aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256); - aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256); - aHeader.push(iFileSize % 256); - - aHeader.push(0); // reserved - aHeader.push(0); - aHeader.push(0); // reserved - aHeader.push(0); - - aHeader.push(54); // data offset - aHeader.push(0); - aHeader.push(0); - aHeader.push(0); - - var aInfoHeader = []; - aInfoHeader.push(40); // info header size - aInfoHeader.push(0); - aInfoHeader.push(0); - aInfoHeader.push(0); - - var iImageWidth = iWidth; - aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256); - aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256); - aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256); - aInfoHeader.push(iImageWidth % 256); - - var iImageHeight = iHeight; - aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256); - aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256); - aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256); - aInfoHeader.push(iImageHeight % 256); - - aInfoHeader.push(1); // num of planes - aInfoHeader.push(0); - - aInfoHeader.push(24); // num of bits per pixel - aInfoHeader.push(0); - - aInfoHeader.push(0); // compression = none - aInfoHeader.push(0); - aInfoHeader.push(0); - aInfoHeader.push(0); - - var iDataSize = iWidth*iHeight*3; - aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256); - aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256); - aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256); - aInfoHeader.push(iDataSize % 256); - - for (var i = 0; i < 16; i++) { - aInfoHeader.push(0); // these bytes not used - } - - var iPadding = (4 - ((iWidth * 3) % 4)) % 4; - - var aImgData = oData.data; - - var strPixelData = ""; - var y = iHeight; - do { - var iOffsetY = iWidth*(y-1)*4; - var strPixelRow = ""; - for (var x=0;x object containing the imagedata - var makeImageObject = function(strSource) { - var oImgElement = document.createElement("img"); - oImgElement.src = strSource; - return oImgElement; - } - - var scaleCanvas = function(oCanvas, iWidth, iHeight) { - if (iWidth && iHeight) { - var oSaveCanvas = document.createElement("canvas"); - - oSaveCanvas.width = iWidth; - oSaveCanvas.height = iHeight; - oSaveCanvas.style.width = iWidth+"px"; - oSaveCanvas.style.height = iHeight+"px"; - - var oSaveCtx = oSaveCanvas.getContext("2d"); - - oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, iWidth); - - return oSaveCanvas; - } - return oCanvas; - } - - return { - saveAsPNG : function(oCanvas, bReturnImg, iWidth, iHeight) { - if (!bHasDataURL) { - return false; - } - var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight); - var strData = oScaledCanvas.toDataURL("image/png"); - if (bReturnImg) { - return makeImageObject(strData); - } else { - saveFile(strData.replace("image/png", strDownloadMime)); - } - return true; - }, - - saveAsJPEG : function(oCanvas, bReturnImg, iWidth, iHeight) { - if (!bHasDataURL) { - return false; - } - - var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight); - var strMime = "image/jpeg"; - var strData = oScaledCanvas.toDataURL(strMime); - - // check if browser actually supports jpeg by looking for the mime type in the data uri. - // if not, return false - if (strData.indexOf(strMime) != 5) { - return false; - } - - if (bReturnImg) { - return makeImageObject(strData); - } else { - saveFile(strData.replace(strMime, strDownloadMime)); - } - return true; - }, - - saveAsBMP : function(oCanvas, bReturnImg, iWidth, iHeight) { - if (!(bHasImageData && bHasBase64)) { - return false; - } - - var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight); - - var oData = readCanvasData(oScaledCanvas); - var strImgData = createBMP(oData); - if (bReturnImg) { - return makeImageObject(makeDataURI(strImgData, "image/bmp")); - } else { - saveFile(makeDataURI(strImgData, strDownloadMime)); - } - return true; - } - }; - -})(); + --- a/js/flotr/lib/canvastext.js +++ /dev/null @@ -1,397 +1,1 @@ -/** - * This code is released to the public domain by Jim Studt, 2007. - * He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/ - * It as been modified by Fabien Ménager to handle font style like size, weight, color and rotation. - * A partial support for accentuated letters as been added too. - */ -var CanvasText = { - /** The letters definition. It is a list of letters, - * with their width, and the coordinates of points compositing them. - * The syntax for the points is : [x, y], null value means "pen up" - */ - letters: { - '\n':{ width: -1, points: [] }, - ' ': { width: 10, points: [] }, - '!': { width: 10, points: [[5,21],[5,7],null,[5,2],[4,1],[5,0],[6,1],[5,2]] }, - '"': { width: 16, points: [[4,21],[4,14],null,[12,21],[12,14]] }, - '#': { width: 21, points: [[11,25],[4,-7],null,[17,25],[10,-7],null,[4,12],[18,12],null,[3,6],[17,6]] }, - '$': { width: 20, points: [[8,25],[8,-4],null,[12,25],[12,-4],null,[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, - '%': { width: 24, points: [[21,21],[3,0],null,[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],null,[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] }, - '&': { width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] }, - '\'':{ width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] }, - '(': { width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] }, - ')': { width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] }, - '*': { width: 16, points: [[8,21],[8,9],null,[3,18],[13,12],null,[13,18],[3,12]] }, - '+': { width: 26, points: [[13,18],[13,0],null,[4,9],[22,9]] }, - ',': { width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, - '-': { width: 26, points: [[4,9],[22,9]] }, - '.': { width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] }, - '/': { width: 22, points: [[20,25],[2,-7]] }, - '0': { width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] }, - '1': { width: 20, points: [[6,17],[8,18],[11,21],[11,0]] }, - '2': { width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] }, - '3': { width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, - '4': { width: 20, points: [[13,21],[3,7],[18,7],null,[13,21],[13,0]] }, - '5': { width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, - '6': { width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] }, - '7': { width: 20, points: [[17,21],[7,0],null,[3,21],[17,21]] }, - '8': { width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] }, - '9': { width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] }, - ':': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],null,[5,2],[4,1],[5,0],[6,1],[5,2]] }, - ';': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],null,[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, - '<': { width: 24, points: [[20,18],[4,9],[20,0]] }, - '=': { width: 26, points: [[4,12],[22,12],null,[4,6],[22,6]] }, - '>': { width: 24, points: [[4,18],[20,9],[4,0]] }, - '?': { width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],null,[9,2],[8,1],[9,0],[10,1],[9,2]] }, - '@': { width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],null,[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],null,[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],null,[19,16],[18,8],[18,6],[19,5]] }, - 'A': { width: 18, points: [[9,21],[1,0],null,[9,21],[17,0],null,[4,7],[14,7]] }, - 'B': { width: 21, points: [[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],null,[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] }, - 'C': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] }, - 'D': { width: 21, points: [[4,21],[4,0],null,[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] }, - 'E': { width: 19, points: [[4,21],[4,0],null,[4,21],[17,21],null,[4,11],[12,11],null,[4,0],[17,0]] }, - 'F': { width: 18, points: [[4,21],[4,0],null,[4,21],[17,21],null,[4,11],[12,11]] }, - 'G': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],null,[13,8],[18,8]] }, - 'H': { width: 22, points: [[4,21],[4,0],null,[18,21],[18,0],null,[4,11],[18,11]] }, - 'I': { width: 8, points: [[4,21],[4,0]] }, - 'J': { width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] }, - 'K': { width: 21, points: [[4,21],[4,0],null,[18,21],[4,7],null,[9,12],[18,0]] }, - 'L': { width: 17, points: [[4,21],[4,0],null,[4,0],[16,0]] }, - 'M': { width: 24, points: [[4,21],[4,0],null,[4,21],[12,0],null,[20,21],[12,0],null,[20,21],[20,0]] }, - 'N': { width: 22, points: [[4,21],[4,0],null,[4,21],[18,0],null,[18,21],[18,0]] }, - 'O': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] }, - 'P': { width: 21, points: [[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] }, - 'Q': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],null,[12,4],[18,-2]] }, - 'R': { width: 21, points: [[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],null,[11,11],[18,0]] }, - 'S': { width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, - 'T': { width: 16, points: [[8,21],[8,0],null,[1,21],[15,21]] }, - 'U': { width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] }, - 'V': { width: 18, points: [[1,21],[9,0],null,[17,21],[9,0]] }, - 'W': { width: 24, points: [[2,21],[7,0],null,[12,21],[7,0],null,[12,21],[17,0],null,[22,21],[17,0]] }, - 'X': { width: 20, points: [[3,21],[17,0],null,[17,21],[3,0]] }, - 'Y': { width: 18, points: [[1,21],[9,11],[9,0],null,[17,21],[9,11]] }, - 'Z': { width: 20, points: [[17,21],[3,0],null,[3,21],[17,21],null,[3,0],[17,0]] }, - '[': { width: 14, points: [[4,25],[4,-7],null,[5,25],[5,-7],null,[4,25],[11,25],null,[4,-7],[11,-7]] }, - '\\':{ width: 14, points: [[0,21],[14,-3]] }, - ']': { width: 14, points: [[9,25],[9,-7],null,[10,25],[10,-7],null,[3,25],[10,25],null,[3,-7],[10,-7]] }, - '^': { width: 14, points: [[3,10],[8,18],[13,10]] }, - '_': { width: 16, points: [[0,-2],[16,-2]] }, - '`': { width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] }, - 'a': { width: 19, points: [[15,14],[15,0],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'b': { width: 19, points: [[4,21],[4,0],null,[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, - 'c': { width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'd': { width: 19, points: [[15,21],[15,0],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'e': { width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'f': { width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],null,[2,14],[9,14]] }, - 'g': { width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'h': { width: 19, points: [[4,21],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, - 'i': { width: 8, points: [[3,21],[4,20],[5,21],[4,22],[3,21],null,[4,14],[4,0]] }, - 'j': { width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],null,[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] }, - 'k': { width: 17, points: [[4,21],[4,0],null,[14,14],[4,4],null,[8,8],[15,0]] }, - 'l': { width: 8, points: [[4,21],[4,0]] }, - 'm': { width: 30, points: [[4,14],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],null,[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] }, - 'n': { width: 19, points: [[4,14],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, - 'o': { width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] }, - 'p': { width: 19, points: [[4,14],[4,-7],null,[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, - 'q': { width: 19, points: [[15,14],[15,-7],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'r': { width: 13, points: [[4,14],[4,0],null,[4,8],[5,11],[7,13],[9,14],[12,14]] }, - 's': { width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] }, - 't': { width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],null,[2,14],[9,14]] }, - 'u': { width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],null,[15,14],[15,0]] }, - 'v': { width: 16, points: [[2,14],[8,0],null,[14,14],[8,0]] }, - 'w': { width: 22, points: [[3,14],[7,0],null,[11,14],[7,0],null,[11,14],[15,0],null,[19,14],[15,0]] }, - 'x': { width: 17, points: [[3,14],[14,0],null,[14,14],[3,0]] }, - 'y': { width: 16, points: [[2,14],[8,0],null,[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] }, - 'z': { width: 17, points: [[14,14],[3,0],null,[3,14],[14,14],null,[3,0],[14,0]] }, - '{': { width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],null,[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],null,[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] }, - '|': { width: 8, points: [[4,25],[4,-7]] }, - '}': { width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],null,[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],null,[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] }, - '~': { width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],null,[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] }, - 'é': { diacritic: '´', letter: 'e' }, - 'è': { diacritic: '`', letter: 'e' }, - 'ê': { diacritic: '^', letter: 'e' }, - 'ë': { diacritic: '¨', letter: 'e' }, - 'à': { diacritic: '`', letter: 'a' }, - 'ç': { diacritic: '¸', letter: 'c' }, - 'ñ': { diacritic: '~', letter: 'n' }, - 'ô': { diacritic: '^', letter: 'o' }, - 'É': { diacritic: '´', letter: 'E' }, - 'È': { diacritic: '`', letter: 'E' }, - 'Ê': { diacritic: '^', letter: 'E' }, - 'Ë': { diacritic: '¨', letter: 'E' }, - 'À': { diacritic: '`', letter: 'A' }, - 'Ç': { diacritic: '¸', letter: 'C' }, - 'Ñ': { diacritic: '~', letter: 'N' }, - 'Ô': { diacritic: '^', letter: 'O' } - }, - - specialchars: { - 'pi': { width: 19, points: [[6,14],[6,0],null,[14,14],[14,0],null,[2,13],[6,16],[13,13],[17,16]] } - }, - - /** Diacritics, used to draw accentuated letters */ - diacritics: { - '¸': { entity: 'cedil', points: [[6,-4],[4,-6],[2,-7],[1,-7]] }, - '´': { entity: 'acute', points: [[8,19],[13,22]] }, - '`': { entity: 'grave', points: [[7,22],[12,19]] }, - '^': { entity: 'circ', points: [[5.5,19],[9.5,23],[12.5,19]] }, - '¨': { entity: 'trema', points: [[5,21],[6,20],[7,21],[6,22],[5,21],null,[12,21],[13,20],[14,21],[13,22],[12,21]] }, - '~': { entity: 'tilde', points: [[4,18],[7,22],[10,18],[13,22]] } - }, - - /** The default font styling */ - style: { - size: 8, // font height in pixels - font: null, // not yet implemented - color: '#000000', // - weight: 1, // float, 1 for 'normal' - halign: 'l', // l: left, r: right, c: center - valign: 'b', // t: top, m: middle, b: bottom - adjustAlign: false, // modifies the alignments if the angle is different from 0 to make the spin point always at the good position - angle: 0, // in radians, anticlockwise - tracking: 1, // space between the letters, float, 1 for 'normal' - boundingBoxColor: '#ff0000', //null // color of the bounding box (null to hide), can be used for debug and font drawing - originPointColor: '#000000' //null // color of the bounding box (null to hide), can be used for debug and font drawing - }, - - debug: false, - _bufferLexemes: {}, - - /** Get the letter data corresponding to a char - * @param {String} ch - The char - */ - letter: function(ch) { - return CanvasText.letters[ch]; - }, - - parseLexemes: function(str) { - if (CanvasText._bufferLexemes[str]) - return CanvasText._bufferLexemes[str]; - - var i, c, matches = str.match(/&[A-Za-z]{2,5};|\s|./g); - var result = [], chars = []; - for (i = 0; i < matches.length; i++) { - c = matches[i]; - if (c.length == 1) - chars.push(c); - else { - var entity = c.substring(1, c.length-1); - if (CanvasText.specialchars[entity]) - chars.push(entity); - else - chars = chars.concat(c.toArray()); - } - } - for (i = 0; i < chars.length; i++) { - c = chars[i]; - if (c = CanvasText.letters[c] || CanvasText.specialchars[c]) - result.push(c); - } - return CanvasText._bufferLexemes[str] = result.compact(); - }, - - /** Get the font ascent for a given style - * @param {Object} style - The reference style - */ - ascent: function(style) { - style = style || {}; - return (style.size || CanvasText.style.size); - }, - - /** Get the font descent for a given style - * @param {Object} style - The reference style - * */ - descent: function(style) { - style = style || {}; - return 7.0*(style.size || CanvasText.style.size)/25.0; - }, - - /** Measure the text horizontal size - * @param {String} str - The text - * @param {Object} style - Text style - * */ - measure: function(str, style) { - if (!str) return; - style = style || {}; - - var i, width, lexemes = CanvasText.parseLexemes(str), - total = 0; - - for (i = lexemes.length-1; i > -1; --i) { - c = lexemes[i]; - width = (c.diacritic) ? CanvasText.letter(c.letter).width : c.width; - total += width * (style.tracking || CanvasText.style.tracking) * (style.size || CanvasText.style.size) / 25.0; - } - return total; - }, - - getDimensions: function(str, style) { - var width = CanvasText.measure(str, style), - height = style.size || CanvasText.style.size, - angle = style.angle || CanvasText.style.angle; - - if (style.angle == 0) return {width: width, height: height}; - return { - width: Math.abs(Math.cos(angle) * width) + Math.abs(Math.sin(angle) * height), - height: Math.abs(Math.sin(angle) * width) + Math.abs(Math.cos(angle) * height) - } - }, - - getBestAlign: function(angle, style) { - angle += CanvasText.getAngleFromAlign(style.halign, style.valign); - var a = {h:'c', v:'m'}; - if (Math.round(Math.cos(angle)*1000)/1000 != 0) - a.h = (Math.cos(angle) > 0 ? 'r' : 'l'); - - if (Math.round(Math.sin(angle)*1000)/1000 != 0) - a.v = (Math.sin(angle) > 0 ? 't' : 'b'); - return a; - }, - - getAngleFromAlign: function(halign, valign) { - var pi = Math.PI, table = { - 'rm': 0, - 'rt': pi/4, - 'ct': pi/2, - 'lt': 3*(pi/4), - 'lm': pi, - 'lb': -3*(pi/4), - 'cb': -pi/2, - 'rb': -pi/4, - 'cm': 0 - } - return table[halign+valign]; - }, - - /** Draws serie of points at given coordinates - * @param {Canvas context} ctx - The canvas context - * @param {Array} points - The points to draw - * @param {Number} x - The X coordinate - * @param {Number} y - The Y coordinate - * @param {Number} mag - The scale - */ - drawPoints: function (ctx, points, x, y, mag, offset) { - var i, a, penUp = true, needStroke = 0; - offset = offset || {x:0, y:0}; - - ctx.beginPath(); - for (i = 0; i < points.length; i++) { - a = points[i]; - if (!a) { - penUp = true; - continue; - } - if (penUp) { - ctx.moveTo(x + a[0]*mag + offset.x, y - a[1]*mag + offset.y); - penUp = false; - } - else { - ctx.lineTo(x + a[0]*mag + offset.x, y - a[1]*mag + offset.y); - } - } - ctx.stroke(); - }, - - /** Draws a text at given coordinates and with a given style - * @param {Canvas context} ctx - The canvas context - * @param {String} str - The text to draw - * @param {Number} xOrig - The X coordinate - * @param {Number} yOrig - The Y coordinate - * @param {Object} style - The font style - */ - draw: function(ctx, str, xOrig, yOrig, style) { - if (!str) return; - style = style || CanvasText.style; - style.halign = style.halign || CanvasText.style.halign; - style.valign = style.valign || CanvasText.style.valign; - style.angle = style.angle || CanvasText.style.angle; - style.size = style.size || CanvasText.style.size; - style.adjustAlign = style.adjustAlign || CanvasText.style.adjustAlign; - - var i, c, total = 0, - mag = style.size / 25.0, - x = 0, y = 0, - lexemes = CanvasText.parseLexemes(str); - - var offset = {x:0, y:0}, - measure = CanvasText.measure(str, style), - align; - - if (style.adjustAlign) { - align = CanvasText.getBestAlign(style.angle, style); - style.halign = align.h; - style.valign = align.v; - } - - switch (style.halign) { - case 'l': break; - case 'c': offset.x = -measure / 2; break; - case 'r': offset.x = -measure; break; - } - - switch (style.valign) { - case 'b': break; - case 'm': offset.y = style.size / 2; break; - case 't': offset.y = style.size; break; - } - - ctx.save(); - ctx.translate(xOrig, yOrig); - ctx.rotate(style.angle); - ctx.lineCap = "round"; - ctx.lineWidth = 2.0 * mag * (style.weight || CanvasText.style.weight); - ctx.strokeStyle = style.color || CanvasText.style.color; - - for (i = 0; i < lexemes.length; i++) { - c = lexemes[i]; - if (c.width == -1) { - x = 0; - y = style.size * 1.4; - continue; - } - - var points = c.points, - width = c.width; - - if (c.diacritic) { - var dia = CanvasText.diacritics[c.diacritic]; - var char = CanvasText.letter(c.letter); - - CanvasText.drawPoints(ctx, dia.points, x, y - (c.letter.toUpperCase() == c.letter ? 3 : 0), mag, offset); - points = char.points; - width = char.width; - } - - CanvasText.drawPoints(ctx, points, x, y, mag, offset); - - if (CanvasText.debug) { - ctx.save(); - ctx.lineJoin = "miter"; - ctx.lineWidth = 0.5; - ctx.strokeStyle = (style.boundingBoxColor || CanvasText.style.boundingBoxColor); - ctx.strokeRect(x+offset.x, y+offset.y, width*mag, -style.size); - - ctx.fillStyle = (style.originPointColor || CanvasText.style.originPointColor); - ctx.beginPath(); - ctx.arc(0, 0, 1.5, 0, Math.PI*2, true); - ctx.fill(); - - ctx.restore(); - } - - x += width*mag*(style.tracking || CanvasText.style.tracking); - } - ctx.restore(); - return total; - }, - - /** Enables the text function for a Canvas context - * @param {Canvas context} ctx - The canvas context - */ - enable: function(ctx) { - ctx.drawText = function(text, x, y, style) { return CanvasText.draw(ctx, text, x, y, style); }; - ctx.measureText = function(text, style) { return CanvasText.measure(text, style); }; - ctx.getTextBounds = function(text, style) { return CanvasText.getDimensions(text, style); }; - ctx.fontAscent = function(style) { return CanvasText.ascent(style); }; - ctx.fontDescent = function(style) { return CanvasText.descent(style); }; - } -}; + --- a/js/flotr/lib/excanvas.js +++ /dev/null @@ -1,885 +1,1 @@ -// Copyright 2006 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Known Issues: -// -// * Patterns are not implemented. -// * Radial gradient are not implemented. The VML version of these look very -// different from the canvas one. -// * Clipping paths are not implemented. -// * Coordsize. The width and height attribute have higher priority than the -// width and height style values which isn't correct. -// * Painting mode isn't implemented. -// * Canvas width/height should is using content-box by default. IE in -// Quirks mode will draw the canvas using border-box. Either change your -// doctype to HTML5 -// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) -// or use Box Sizing Behavior from WebFX -// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) -// * Non uniform scaling does not correctly scale strokes. -// * Optimize. There is always room for speed improvements. - -// Only add this code if we do not already have a canvas implementation -if (!document.createElement('canvas').getContext) { - -(function() { - - // alias some functions to make (compiled) code shorter - var m = Math; - var mr = m.round; - var ms = m.sin; - var mc = m.cos; - var abs = m.abs; - var sqrt = m.sqrt; - - // this is used for sub pixel precision - var Z = 10; - var Z2 = Z / 2; - - /** - * This funtion is assigned to the elements as element.getContext(). - * @this {HTMLElement} - * @return {CanvasRenderingContext2D_} - */ - function getContext() { - return this.context_ || - (this.context_ = new CanvasRenderingContext2D_(this)); - } - - var slice = Array.prototype.slice; - - /** - * Binds a function to an object. The returned function will always use the - * passed in {@code obj} as {@code this}. - * - * Example: - * - * g = bind(f, obj, a, b) - * g(c, d) // will do f.call(obj, a, b, c, d) - * - * @param {Function} f The function to bind the object to - * @param {Object} obj The object that should act as this when the function - * is called - * @param {*} var_args Rest arguments that will be used as the initial - * arguments when the function is called - * @return {Function} A new function that has bound this - */ - function bind(f, obj, var_args) { - var a = slice.call(arguments, 2); - return function() { - return f.apply(obj, a.concat(slice.call(arguments))); - }; - } - - var G_vmlCanvasManager_ = { - init: function(opt_doc) { - if (/MSIE/.test(navigator.userAgent) && !window.opera) { - var doc = opt_doc || document; - // Create a dummy element so that IE will allow canvas elements to be - // recognized. - doc.createElement('canvas'); - doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); - } - }, - - init_: function(doc) { - // create xmlns - if (!doc.namespaces['g_vml_']) { - doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml', - '#default#VML'); - - } - if (!doc.namespaces['g_o_']) { - doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office', - '#default#VML'); - } - - // Setup default CSS. Only add one style sheet per document - if (!doc.styleSheets['ex_canvas_']) { - var ss = doc.createStyleSheet(); - ss.owningElement.id = 'ex_canvas_'; - ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + - // default size is 300x150 in Gecko and Opera - 'text-align:left;width:300px;height:150px}' + - 'g_vml_\\:*{behavior:url(#default#VML)}' + - 'g_o_\\:*{behavior:url(#default#VML)}'; - - } - - // find all canvas elements - var els = doc.getElementsByTagName('canvas'); - for (var i = 0; i < els.length; i++) { - this.initElement(els[i]); - } - }, - - /** - * Public initializes a canvas element so that it can be used as canvas - * element from now on. This is called automatically before the page is - * loaded but if you are creating elements using createElement you need to - * make sure this is called on the element. - * @param {HTMLElement} el The canvas element to initialize. - * @return {HTMLElement} the element that was created. - */ - initElement: function(el) { - if (!el.getContext) { - - el.getContext = getContext; - - // Remove fallback content. There is no way to hide text nodes so we - // just remove all childNodes. We could hide all elements and remove - // text nodes but who really cares about the fallback content. - el.innerHTML = ''; - - // do not use inline function because that will leak memory - el.attachEvent('onpropertychange', onPropertyChange); - el.attachEvent('onresize', onResize); - - var attrs = el.attributes; - if (attrs.width && attrs.width.specified) { - // TODO: use runtimeStyle and coordsize - // el.getContext().setWidth_(attrs.width.nodeValue); - el.style.width = attrs.width.nodeValue + 'px'; - } else { - el.width = el.clientWidth; - } - if (attrs.height && attrs.height.specified) { - // TODO: use runtimeStyle and coordsize - // el.getContext().setHeight_(attrs.height.nodeValue); - el.style.height = attrs.height.nodeValue + 'px'; - } else { - el.height = el.clientHeight; - } - //el.getContext().setCoordsize_() - } - return el; - } - }; - - function onPropertyChange(e) { - var el = e.srcElement; - - switch (e.propertyName) { - case 'width': - el.style.width = el.attributes.width.nodeValue + 'px'; - el.getContext().clearRect(); - break; - case 'height': - el.style.height = el.attributes.height.nodeValue + 'px'; - el.getContext().clearRect(); - break; - } - } - - function onResize(e) { - var el = e.srcElement; - if (el.firstChild) { - el.firstChild.style.width = el.clientWidth + 'px'; - el.firstChild.style.height = el.clientHeight + 'px'; - } - } - - G_vmlCanvasManager_.init(); - - // precompute "00" to "FF" - var dec2hex = []; - for (var i = 0; i < 16; i++) { - for (var j = 0; j < 16; j++) { - dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); - } - } - - function createMatrixIdentity() { - return [ - [1, 0, 0], - [0, 1, 0], - [0, 0, 1] - ]; - } - - function matrixMultiply(m1, m2) { - var result = createMatrixIdentity(); - - for (var x = 0; x < 3; x++) { - for (var y = 0; y < 3; y++) { - var sum = 0; - - for (var z = 0; z < 3; z++) { - sum += m1[x][z] * m2[z][y]; - } - - result[x][y] = sum; - } - } - return result; - } - - function copyState(o1, o2) { - o2.fillStyle = o1.fillStyle; - o2.lineCap = o1.lineCap; - o2.lineJoin = o1.lineJoin; - o2.lineWidth = o1.lineWidth; - o2.miterLimit = o1.miterLimit; - o2.shadowBlur = o1.shadowBlur; - o2.shadowColor = o1.shadowColor; - o2.shadowOffsetX = o1.shadowOffsetX; - o2.shadowOffsetY = o1.shadowOffsetY; - o2.strokeStyle = o1.strokeStyle; - o2.globalAlpha = o1.globalAlpha; - o2.arcScaleX_ = o1.arcScaleX_; - o2.arcScaleY_ = o1.arcScaleY_; - o2.lineScale_ = o1.lineScale_; - } - - function processStyle(styleString) { - var str, alpha = 1; - - styleString = String(styleString); - if (styleString.substring(0, 3) == 'rgb') { - var start = styleString.indexOf('(', 3); - var end = styleString.indexOf(')', start + 1); - var guts = styleString.substring(start + 1, end).split(','); - - str = '#'; - for (var i = 0; i < 3; i++) { - str += dec2hex[Number(guts[i])]; - } - - if (guts.length == 4 && styleString.substr(3, 1) == 'a') { - alpha = guts[3]; - } - } else { - str = styleString; - } - - return {color: str, alpha: alpha}; - } - - function processLineCap(lineCap) { - switch (lineCap) { - case 'butt': - return 'flat'; - case 'round': - return 'round'; - case 'square': - default: - return 'square'; - } - } - - /** - * This class implements CanvasRenderingContext2D interface as described by - * the WHATWG. - * @param {HTMLElement} surfaceElement The element that the 2D context should - * be associated with - */ - function CanvasRenderingContext2D_(surfaceElement) { - this.m_ = createMatrixIdentity(); - - this.mStack_ = []; - this.aStack_ = []; - this.currentPath_ = []; - - // Canvas context properties - this.strokeStyle = '#000'; - this.fillStyle = '#000'; - - this.lineWidth = 1; - this.lineJoin = 'miter'; - this.lineCap = 'butt'; - this.miterLimit = Z * 1; - this.globalAlpha = 1; - this.canvas = surfaceElement; - - var el = surfaceElement.ownerDocument.createElement('div'); - el.style.width = surfaceElement.clientWidth + 'px'; - el.style.height = surfaceElement.clientHeight + 'px'; - el.style.overflow = 'hidden'; - el.style.position = 'absolute'; - surfaceElement.appendChild(el); - - this.element_ = el; - this.arcScaleX_ = 1; - this.arcScaleY_ = 1; - this.lineScale_ = 1; - } - - var contextPrototype = CanvasRenderingContext2D_.prototype; - contextPrototype.clearRect = function() { - this.element_.innerHTML = ''; - }; - - contextPrototype.beginPath = function() { - // TODO: Branch current matrix so that save/restore has no effect - // as per safari docs. - this.currentPath_ = []; - }; - - contextPrototype.moveTo = function(aX, aY) { - var p = this.getCoords_(aX, aY); - this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); - this.currentX_ = p.x; - this.currentY_ = p.y; - }; - - contextPrototype.lineTo = function(aX, aY) { - var p = this.getCoords_(aX, aY); - this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); - - this.currentX_ = p.x; - this.currentY_ = p.y; - }; - - contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, - aCP2x, aCP2y, - aX, aY) { - var p = this.getCoords_(aX, aY); - var cp1 = this.getCoords_(aCP1x, aCP1y); - var cp2 = this.getCoords_(aCP2x, aCP2y); - bezierCurveTo(this, cp1, cp2, p); - }; - - // Helper function that takes the already fixed cordinates. - function bezierCurveTo(self, cp1, cp2, p) { - self.currentPath_.push({ - type: 'bezierCurveTo', - cp1x: cp1.x, - cp1y: cp1.y, - cp2x: cp2.x, - cp2y: cp2.y, - x: p.x, - y: p.y - }); - self.currentX_ = p.x; - self.currentY_ = p.y; - } - - contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { - // the following is lifted almost directly from - // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes - - var cp = this.getCoords_(aCPx, aCPy); - var p = this.getCoords_(aX, aY); - - var cp1 = { - x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), - y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) - }; - var cp2 = { - x: cp1.x + (p.x - this.currentX_) / 3.0, - y: cp1.y + (p.y - this.currentY_) / 3.0 - }; - - bezierCurveTo(this, cp1, cp2, p); - }; - - contextPrototype.arc = function(aX, aY, aRadius, - aStartAngle, aEndAngle, aClockwise) { - aRadius *= Z; - var arcType = aClockwise ? 'at' : 'wa'; - - var xStart = aX + mc(aStartAngle) * aRadius - Z2; - var yStart = aY + ms(aStartAngle) * aRadius - Z2; - - var xEnd = aX + mc(aEndAngle) * aRadius - Z2; - var yEnd = aY + ms(aEndAngle) * aRadius - Z2; - - // IE won't render arches drawn counter clockwise if xStart == xEnd. - if (xStart == xEnd && !aClockwise) { - xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something - // that can be represented in binary - } - - var p = this.getCoords_(aX, aY); - var pStart = this.getCoords_(xStart, yStart); - var pEnd = this.getCoords_(xEnd, yEnd); - - this.currentPath_.push({type: arcType, - x: p.x, - y: p.y, - radius: aRadius, - xStart: pStart.x, - yStart: pStart.y, - xEnd: pEnd.x, - yEnd: pEnd.y}); - - }; - - contextPrototype.rect = function(aX, aY, aWidth, aHeight) { - this.moveTo(aX, aY); - this.lineTo(aX + aWidth, aY); - this.lineTo(aX + aWidth, aY + aHeight); - this.lineTo(aX, aY + aHeight); - this.closePath(); - }; - - contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { - var oldPath = this.currentPath_; - this.beginPath(); - - this.moveTo(aX, aY); - this.lineTo(aX + aWidth, aY); - this.lineTo(aX + aWidth, aY + aHeight); - this.lineTo(aX, aY + aHeight); - this.closePath(); - this.stroke(); - - this.currentPath_ = oldPath; - }; - - contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { - var oldPath = this.currentPath_; - this.beginPath(); - - this.moveTo(aX, aY); - this.lineTo(aX + aWidth, aY); - this.lineTo(aX + aWidth, aY + aHeight); - this.lineTo(aX, aY + aHeight); - this.closePath(); - this.fill(); - - this.currentPath_ = oldPath; - }; - - contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { - var gradient = new CanvasGradient_('gradient'); - gradient.x0_ = aX0; - gradient.y0_ = aY0; - gradient.x1_ = aX1; - gradient.y1_ = aY1; - return gradient; - }; - - contextPrototype.createRadialGradient = function(aX0, aY0, aR0, - aX1, aY1, aR1) { - var gradient = new CanvasGradient_('gradientradial'); - gradient.x0_ = aX0; - gradient.y0_ = aY0; - gradient.r0_ = aR0; - gradient.x1_ = aX1; - gradient.y1_ = aY1; - gradient.r1_ = aR1; - return gradient; - }; - - contextPrototype.drawImage = function(image, var_args) { - var dx, dy, dw, dh, sx, sy, sw, sh; - - // to find the original width we overide the width and height - var oldRuntimeWidth = image.runtimeStyle.width; - var oldRuntimeHeight = image.runtimeStyle.height; - image.runtimeStyle.width = 'auto'; - image.runtimeStyle.height = 'auto'; - - // get the original size - var w = image.width; - var h = image.height; - - // and remove overides - image.runtimeStyle.width = oldRuntimeWidth; - image.runtimeStyle.height = oldRuntimeHeight; - - if (arguments.length == 3) { - dx = arguments[1]; - dy = arguments[2]; - sx = sy = 0; - sw = dw = w; - sh = dh = h; - } else if (arguments.length == 5) { - dx = arguments[1]; - dy = arguments[2]; - dw = arguments[3]; - dh = arguments[4]; - sx = sy = 0; - sw = w; - sh = h; - } else if (arguments.length == 9) { - sx = arguments[1]; - sy = arguments[2]; - sw = arguments[3]; - sh = arguments[4]; - dx = arguments[5]; - dy = arguments[6]; - dw = arguments[7]; - dh = arguments[8]; - } else { - throw Error('Invalid number of arguments'); - } - - var d = this.getCoords_(dx, dy); - - var w2 = sw / 2; - var h2 = sh / 2; - - var vmlStr = []; - - var W = 10; - var H = 10; - - // For some reason that I've now forgotten, using divs didn't work - vmlStr.push(' ' , - '', - ''); - - this.element_.insertAdjacentHTML('BeforeEnd', - vmlStr.join('')); - }; - - contextPrototype.stroke = function(aFill) { - var lineStr = []; - var lineOpen = false; - var a = processStyle(aFill ? this.fillStyle : this.strokeStyle); - var color = a.color; - var opacity = a.alpha * this.globalAlpha; - - var W = 10; - var H = 10; - - lineStr.push(''); - - if (!aFill) { - var lineWidth = this.lineScale_ * this.lineWidth; - - // VML cannot correctly render a line if the width is less than 1px. - // In that case, we dilute the color to make the line look thinner. - if (lineWidth < 1) { - opacity *= lineWidth; - } - - lineStr.push( - '' - ); - } else if (typeof this.fillStyle == 'object') { - var fillStyle = this.fillStyle; - var angle = 0; - var focus = {x: 0, y: 0}; - - // additional offset - var shift = 0; - // scale factor for offset - var expansion = 1; - - if (fillStyle.type_ == 'gradient') { - var x0 = fillStyle.x0_ / this.arcScaleX_; - var y0 = fillStyle.y0_ / this.arcScaleY_; - var x1 = fillStyle.x1_ / this.arcScaleX_; - var y1 = fillStyle.y1_ / this.arcScaleY_; - var p0 = this.getCoords_(x0, y0); - var p1 = this.getCoords_(x1, y1); - var dx = p1.x - p0.x; - var dy = p1.y - p0.y; - angle = Math.atan2(dx, dy) * 180 / Math.PI; - - // The angle should be a non-negative number. - if (angle < 0) { - angle += 360; - } - - // Very small angles produce an unexpected result because they are - // converted to a scientific notation string. - if (angle < 1e-6) { - angle = 0; - } - } else { - var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_); - var width = max.x - min.x; - var height = max.y - min.y; - focus = { - x: (p0.x - min.x) / width, - y: (p0.y - min.y) / height - }; - - width /= this.arcScaleX_ * Z; - height /= this.arcScaleY_ * Z; - var dimension = m.max(width, height); - shift = 2 * fillStyle.r0_ / dimension; - expansion = 2 * fillStyle.r1_ / dimension - shift; - } - - // We need to sort the color stops in ascending order by offset, - // otherwise IE won't interpret it correctly. - var stops = fillStyle.colors_; - stops.sort(function(cs1, cs2) { - return cs1.offset - cs2.offset; - }); - - var length = stops.length; - var color1 = stops[0].color; - var color2 = stops[length - 1].color; - var opacity1 = stops[0].alpha * this.globalAlpha; - var opacity2 = stops[length - 1].alpha * this.globalAlpha; - - var colors = []; - for (var i = 0; i < length; i++) { - var stop = stops[i]; - colors.push(stop.offset * expansion + shift + ' ' + stop.color); - } - - // When colors attribute is used, the meanings of opacity and o:opacity2 - // are reversed. - lineStr.push(''); - } else { - lineStr.push(''); - } - - lineStr.push(''); - - this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); - }; - - contextPrototype.fill = function() { - this.stroke(true); - } - - contextPrototype.closePath = function() { - this.currentPath_.push({type: 'close'}); - }; - - /** - * @private - */ - contextPrototype.getCoords_ = function(aX, aY) { - var m = this.m_; - return { - x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, - y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 - } - }; - - contextPrototype.save = function() { - var o = {}; - copyState(this, o); - this.aStack_.push(o); - this.mStack_.push(this.m_); - this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); - }; - - contextPrototype.restore = function() { - copyState(this.aStack_.pop(), this); - this.m_ = this.mStack_.pop(); - }; - - contextPrototype.translate = function(aX, aY) { - var m1 = [ - [1, 0, 0], - [0, 1, 0], - [aX, aY, 1] - ]; - - this.m_ = matrixMultiply(m1, this.m_); - }; - - contextPrototype.rotate = function(aRot) { - var c = mc(aRot); - var s = ms(aRot); - - var m1 = [ - [c, s, 0], - [-s, c, 0], - [0, 0, 1] - ]; - - this.m_ = matrixMultiply(m1, this.m_); - }; - - contextPrototype.scale = function(aX, aY) { - this.arcScaleX_ *= aX; - this.arcScaleY_ *= aY; - var m1 = [ - [aX, 0, 0], - [0, aY, 0], - [0, 0, 1] - ]; - - var m = this.m_ = matrixMultiply(m1, this.m_); - - // Get the line scale. - // Determinant of this.m_ means how much the area is enlarged by the - // transformation. So its square root can be used as a scale factor - // for width. - var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; - this.lineScale_ = sqrt(abs(det)); - }; - - /******** STUBS ********/ - contextPrototype.clip = function() { - // TODO: Implement - }; - - contextPrototype.arcTo = function() { - // TODO: Implement - }; - - contextPrototype.createPattern = function() { - return new CanvasPattern_; - }; - - // Gradient / Pattern Stubs - function CanvasGradient_(aType) { - this.type_ = aType; - this.x0_ = 0; - this.y0_ = 0; - this.r0_ = 0; - this.x1_ = 0; - this.y1_ = 0; - this.r1_ = 0; - this.colors_ = []; - } - - CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { - aColor = processStyle(aColor); - this.colors_.push({offset: aOffset, - color: aColor.color, - alpha: aColor.alpha}); - }; - - function CanvasPattern_() {} - - // set up externs - G_vmlCanvasManager = G_vmlCanvasManager_; - CanvasRenderingContext2D = CanvasRenderingContext2D_; - CanvasGradient = CanvasGradient_; - CanvasPattern = CanvasPattern_; - -})(); - -} // if - --- a/js/flotr/lib/prototype-1.6.0.2.js +++ /dev/null @@ -1,4221 +1,1 @@ -/* Prototype JavaScript framework, version 1.6.0.2 - * (c) 2005-2008 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://www.prototypejs.org/ - * - *--------------------------------------------------------------------------*/ - -var Prototype = { - Version: '1.6.0.2', - - Browser: { - IE: !!(window.attachEvent && !window.opera), - Opera: !!window.opera, - WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, - Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, - MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) - }, - - BrowserFeatures: { - XPath: !!document.evaluate, - ElementExtensions: !!window.HTMLElement, - SpecificElementExtensions: - document.createElement('div').__proto__ && - document.createElement('div').__proto__ !== - document.createElement('form').__proto__ - }, - - ScriptFragment: ']*>([\\S\\s]*?)<\/script>', - JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, - - emptyFunction: function() { }, - K: function(x) { return x } -}; - -if (Prototype.Browser.MobileSafari) - Prototype.BrowserFeatures.SpecificElementExtensions = false; - - -/* Based on Alex Arnell's inheritance implementation. */ -var Class = { - create: function() { - var parent = null, properties = $A(arguments); - if (Object.isFunction(properties[0])) - parent = properties.shift(); - - function klass() { - this.initialize.apply(this, arguments); - } - - Object.extend(klass, Class.Methods); - klass.superclass = parent; - klass.subclasses = []; - - if (parent) { - var subclass = function() { }; - subclass.prototype = parent.prototype; - klass.prototype = new subclass; - parent.subclasses.push(klass); - } - - for (var i = 0; i < properties.length; i++) - klass.addMethods(properties[i]); - - if (!klass.prototype.initialize) - klass.prototype.initialize = Prototype.emptyFunction; - - klass.prototype.constructor = klass; - - return klass; - } -}; - -Class.Methods = { - addMethods: function(source) { - var ancestor = this.superclass && this.superclass.prototype; - var properties = Object.keys(source); - - if (!Object.keys({ toString: true }).length) - properties.push("toString", "valueOf"); - - for (var i = 0, length = properties.length; i < length; i++) { - var property = properties[i], value = source[property]; - if (ancestor && Object.isFunction(value) && - value.argumentNames().first() == "$super") { - var method = value, value = Object.extend((function(m) { - return function() { return ancestor[m].apply(this, arguments) }; - })(property).wrap(method), { - valueOf: function() { return method }, - toString: function() { return method.toString() } - }); - } - this.prototype[property] = value; - } - - return this; - } -}; - -var Abstract = { }; - -Object.extend = function(destination, source) { - for (var property in source) - destination[property] = source[property]; - return destination; -}; - -Object.extend(Object, { - inspect: function(object) { - try { - if (Object.isUndefined(object)) return 'undefined'; - if (object === null) return 'null'; - return object.inspect ? object.inspect() : String(object); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } - }, - - toJSON: function(object) { - var type = typeof object; - switch (type) { - case 'undefined': - case 'function': - case 'unknown': return; - case 'boolean': return object.toString(); - } - - if (object === null) return 'null'; - if (object.toJSON) return object.toJSON(); - if (Object.isElement(object)) return; - - var results = []; - for (var property in object) { - var value = Object.toJSON(object[property]); - if (!Object.isUndefined(value)) - results.push(property.toJSON() + ': ' + value); - } - - return '{' + results.join(', ') + '}'; - }, - - toQueryString: function(object) { - return $H(object).toQueryString(); - }, - - toHTML: function(object) { - return object && object.toHTML ? object.toHTML() : String.interpret(object); - }, - - keys: function(object) { - var keys = []; - for (var property in object) - keys.push(property); - return keys; - }, - - values: function(object) { - var values = []; - for (var property in object) - values.push(object[property]); - return values; - }, - - clone: function(object) { - return Object.extend({ }, object); - }, - - isElement: function(object) { - return object && object.nodeType == 1; - }, - - isArray: function(object) { - return object != null && typeof object == "object" && - 'splice' in object && 'join' in object; - }, - - isHash: function(object) { - return object instanceof Hash; - }, - - isFunction: function(object) { - return typeof object == "function"; - }, - - isString: function(object) { - return typeof object == "string"; - }, - - isNumber: function(object) { - return typeof object == "number"; - }, - - isUndefined: function(object) { - return typeof object == "undefined"; - } -}); - -Object.extend(Function.prototype, { - argumentNames: function() { - var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip"); - return names.length == 1 && !names[0] ? [] : names; - }, - - bind: function() { - if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; - var __method = this, args = $A(arguments), object = args.shift(); - return function() { - return __method.apply(object, args.concat($A(arguments))); - } - }, - - bindAsEventListener: function() { - var __method = this, args = $A(arguments), object = args.shift(); - return function(event) { - return __method.apply(object, [event || window.event].concat(args)); - } - }, - - curry: function() { - if (!arguments.length) return this; - var __method = this, args = $A(arguments); - return function() { - return __method.apply(this, args.concat($A(arguments))); - } - }, - - delay: function() { - var __method = this, args = $A(arguments), timeout = args.shift() * 1000; - return window.setTimeout(function() { - return __method.apply(__method, args); - }, timeout); - }, - - wrap: function(wrapper) { - var __method = this; - return function() { - return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); - } - }, - - methodize: function() { - if (this._methodized) return this._methodized; - var __method = this; - return this._methodized = function() { - return __method.apply(null, [this].concat($A(arguments))); - }; - } -}); - -Function.prototype.defer = Function.prototype.delay.curry(0.01); - -Date.prototype.toJSON = function() { - return '"' + this.getUTCFullYear() + '-' + - (this.getUTCMonth() + 1).toPaddedString(2) + '-' + - this.getUTCDate().toPaddedString(2) + 'T' + - this.getUTCHours().toPaddedString(2) + ':' + - this.getUTCMinutes().toPaddedString(2) + ':' + - this.getUTCSeconds().toPaddedString(2) + 'Z"'; -}; - -var Try = { - these: function() { - var returnValue; - - for (var i = 0, length = arguments.length; i < length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) { } - } - - return returnValue; - } -}; - -RegExp.prototype.match = RegExp.prototype.test; - -RegExp.escape = function(str) { - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); -}; - -/*--------------------------------------------------------------------------*/ - -var PeriodicalExecuter = Class.create({ - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - execute: function() { - this.callback(this); - }, - - stop: function() { - if (!this.timer) return; - clearInterval(this.timer); - this.timer = null; - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.execute(); - } finally { - this.currentlyExecuting = false; - } - } - } -}); -Object.extend(String, { - interpret: function(value) { - return value == null ? '' : String(value); - }, - specialChar: { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '\\': '\\\\' - } -}); - -Object.extend(String.prototype, { - gsub: function(pattern, replacement) { - var result = '', source = this, match; - replacement = arguments.callee.prepareReplacement(replacement); - - while (source.length > 0) { - if (match = source.match(pattern)) { - result += source.slice(0, match.index); - result += String.interpret(replacement(match)); - source = source.slice(match.index + match[0].length); - } else { - result += source, source = ''; - } - } - return result; - }, - - sub: function(pattern, replacement, count) { - replacement = this.gsub.prepareReplacement(replacement); - count = Object.isUndefined(count) ? 1 : count; - - return this.gsub(pattern, function(match) { - if (--count < 0) return match[0]; - return replacement(match); - }); - }, - - scan: function(pattern, iterator) { - this.gsub(pattern, iterator); - return String(this); - }, - - truncate: function(length, truncation) { - length = length || 30; - truncation = Object.isUndefined(truncation) ? '...' : truncation; - return this.length > length ? - this.slice(0, length - truncation.length) + truncation : String(this); - }, - - strip: function() { - return this.replace(/^\s+/, '').replace(/\s+$/, ''); - }, - - stripTags: function() { - return this.replace(/<\/?[^>]+>/gi, ''); - }, - - stripScripts: function() { - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - }, - - extractScripts: function() { - var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); - var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); - return (this.match(matchAll) || []).map(function(scriptTag) { - return (scriptTag.match(matchOne) || ['', ''])[1]; - }); - }, - - evalScripts: function() { - return this.extractScripts().map(function(script) { return eval(script) }); - }, - - escapeHTML: function() { - var self = arguments.callee; - self.text.data = this; - return self.div.innerHTML; - }, - - unescapeHTML: function() { - var div = new Element('div'); - div.innerHTML = this.stripTags(); - return div.childNodes[0] ? (div.childNodes.length > 1 ? - $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : - div.childNodes[0].nodeValue) : ''; - }, - - toQueryParams: function(separator) { - var match = this.strip().match(/([^?#]*)(#.*)?$/); - if (!match) return { }; - - return match[1].split(separator || '&').inject({ }, function(hash, pair) { - if ((pair = pair.split('='))[0]) { - var key = decodeURIComponent(pair.shift()); - var value = pair.length > 1 ? pair.join('=') : pair[0]; - if (value != undefined) value = decodeURIComponent(value); - - if (key in hash) { - if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; - hash[key].push(value); - } - else hash[key] = value; - } - return hash; - }); - }, - - toArray: function() { - return this.split(''); - }, - - succ: function() { - return this.slice(0, this.length - 1) + - String.fromCharCode(this.charCodeAt(this.length - 1) + 1); - }, - - times: function(count) { - return count < 1 ? '' : new Array(count + 1).join(this); - }, - - camelize: function() { - var parts = this.split('-'), len = parts.length; - if (len == 1) return parts[0]; - - var camelized = this.charAt(0) == '-' - ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) - : parts[0]; - - for (var i = 1; i < len; i++) - camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); - - return camelized; - }, - - capitalize: function() { - return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); - }, - - underscore: function() { - return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); - }, - - dasherize: function() { - return this.gsub(/_/,'-'); - }, - - inspect: function(useDoubleQuotes) { - var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { - var character = String.specialChar[match[0]]; - return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); - }); - if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; - return "'" + escapedString.replace(/'/g, '\\\'') + "'"; - }, - - toJSON: function() { - return this.inspect(true); - }, - - unfilterJSON: function(filter) { - return this.sub(filter || Prototype.JSONFilter, '#{1}'); - }, - - isJSON: function() { - var str = this; - if (str.blank()) return false; - str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); - return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); - }, - - evalJSON: function(sanitize) { - var json = this.unfilterJSON(); - try { - if (!sanitize || json.isJSON()) return eval('(' + json + ')'); - } catch (e) { } - throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); - }, - - include: function(pattern) { - return this.indexOf(pattern) > -1; - }, - - startsWith: function(pattern) { - return this.indexOf(pattern) === 0; - }, - - endsWith: function(pattern) { - var d = this.length - pattern.length; - return d >= 0 && this.lastIndexOf(pattern) === d; - }, - - empty: function() { - return this == ''; - }, - - blank: function() { - return /^\s*$/.test(this); - }, - - interpolate: function(object, pattern) { - return new Template(this, pattern).evaluate(object); - } -}); - -if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { - escapeHTML: function() { - return this.replace(/&/g,'&').replace(//g,'>'); - }, - unescapeHTML: function() { - return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); - } -}); - -String.prototype.gsub.prepareReplacement = function(replacement) { - if (Object.isFunction(replacement)) return replacement; - var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; -}; - -String.prototype.parseQuery = String.prototype.toQueryParams; - -Object.extend(String.prototype.escapeHTML, { - div: document.createElement('div'), - text: document.createTextNode('') -}); - -with (String.prototype.escapeHTML) div.appendChild(text); - -var Template = Class.create({ - initialize: function(template, pattern) { - this.template = template.toString(); - this.pattern = pattern || Template.Pattern; - }, - - evaluate: function(object) { - if (Object.isFunction(object.toTemplateReplacements)) - object = object.toTemplateReplacements(); - - return this.template.gsub(this.pattern, function(match) { - if (object == null) return ''; - - var before = match[1] || ''; - if (before == '\\') return match[2]; - - var ctx = object, expr = match[3]; - var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; - match = pattern.exec(expr); - if (match == null) return before; - - while (match != null) { - var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; - ctx = ctx[comp]; - if (null == ctx || '' == match[3]) break; - expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); - match = pattern.exec(expr); - } - - return before + String.interpret(ctx); - }); - } -}); -Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; - -var $break = { }; - -var Enumerable = { - each: function(iterator, context) { - var index = 0; - iterator = iterator.bind(context); - try { - this._each(function(value) { - iterator(value, index++); - }); - } catch (e) { - if (e != $break) throw e; - } - return this; - }, - - eachSlice: function(number, iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var index = -number, slices = [], array = this.toArray(); - while ((index += number) < array.length) - slices.push(array.slice(index, index+number)); - return slices.collect(iterator, context); - }, - - all: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result = true; - this.each(function(value, index) { - result = result && !!iterator(value, index); - if (!result) throw $break; - }); - return result; - }, - - any: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result = false; - this.each(function(value, index) { - if (result = !!iterator(value, index)) - throw $break; - }); - return result; - }, - - collect: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var results = []; - this.each(function(value, index) { - results.push(iterator(value, index)); - }); - return results; - }, - - detect: function(iterator, context) { - iterator = iterator.bind(context); - var result; - this.each(function(value, index) { - if (iterator(value, index)) { - result = value; - throw $break; - } - }); - return result; - }, - - findAll: function(iterator, context) { - iterator = iterator.bind(context); - var results = []; - this.each(function(value, index) { - if (iterator(value, index)) - results.push(value); - }); - return results; - }, - - grep: function(filter, iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var results = []; - - if (Object.isString(filter)) - filter = new RegExp(filter); - - this.each(function(value, index) { - if (filter.match(value)) - results.push(iterator(value, index)); - }); - return results; - }, - - include: function(object) { - if (Object.isFunction(this.indexOf)) - if (this.indexOf(object) != -1) return true; - - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - }, - - inGroupsOf: function(number, fillWith) { - fillWith = Object.isUndefined(fillWith) ? null : fillWith; - return this.eachSlice(number, function(slice) { - while(slice.length < number) slice.push(fillWith); - return slice; - }); - }, - - inject: function(memo, iterator, context) { - iterator = iterator.bind(context); - this.each(function(value, index) { - memo = iterator(memo, value, index); - }); - return memo; - }, - - invoke: function(method) { - var args = $A(arguments).slice(1); - return this.map(function(value) { - return value[method].apply(value, args); - }); - }, - - max: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result; - this.each(function(value, index) { - value = iterator(value, index); - if (result == null || value >= result) - result = value; - }); - return result; - }, - - min: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result; - this.each(function(value, index) { - value = iterator(value, index); - if (result == null || value < result) - result = value; - }); - return result; - }, - - partition: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var trues = [], falses = []; - this.each(function(value, index) { - (iterator(value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - }, - - pluck: function(property) { - var results = []; - this.each(function(value) { - results.push(value[property]); - }); - return results; - }, - - reject: function(iterator, context) { - iterator = iterator.bind(context); - var results = []; - this.each(function(value, index) { - if (!iterator(value, index)) - results.push(value); - }); - return results; - }, - - sortBy: function(iterator, context) { - iterator = iterator.bind(context); - return this.map(function(value, index) { - return {value: value, criteria: iterator(value, index)}; - }).sort(function(left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }).pluck('value'); - }, - - toArray: function() { - return this.map(); - }, - - zip: function() { - var iterator = Prototype.K, args = $A(arguments); - if (Object.isFunction(args.last())) - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - return iterator(collections.pluck(index)); - }); - }, - - size: function() { - return this.toArray().length; - }, - - inspect: function() { - return '#'; - } -}; - -Object.extend(Enumerable, { - map: Enumerable.collect, - find: Enumerable.detect, - select: Enumerable.findAll, - filter: Enumerable.findAll, - member: Enumerable.include, - entries: Enumerable.toArray, - every: Enumerable.all, - some: Enumerable.any -}); -function $A(iterable) { - if (!iterable) return []; - if (iterable.toArray) return iterable.toArray(); - var length = iterable.length || 0, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; -} - -if (Prototype.Browser.WebKit) { - $A = function(iterable) { - if (!iterable) return []; - if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && - iterable.toArray) return iterable.toArray(); - var length = iterable.length || 0, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; - }; -} - -Array.from = $A; - -Object.extend(Array.prototype, Enumerable); - -if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; - -Object.extend(Array.prototype, { - _each: function(iterator) { - for (var i = 0, length = this.length; i < length; i++) - iterator(this[i]); - }, - - clear: function() { - this.length = 0; - return this; - }, - - first: function() { - return this[0]; - }, - - last: function() { - return this[this.length - 1]; - }, - - compact: function() { - return this.select(function(value) { - return value != null; - }); - }, - - flatten: function() { - return this.inject([], function(array, value) { - return array.concat(Object.isArray(value) ? - value.flatten() : [value]); - }); - }, - - without: function() { - var values = $A(arguments); - return this.select(function(value) { - return !values.include(value); - }); - }, - - reverse: function(inline) { - return (inline !== false ? this : this.toArray())._reverse(); - }, - - reduce: function() { - return this.length > 1 ? this : this[0]; - }, - - uniq: function(sorted) { - return this.inject([], function(array, value, index) { - if (0 == index || (sorted ? array.last() != value : !array.include(value))) - array.push(value); - return array; - }); - }, - - intersect: function(array) { - return this.uniq().findAll(function(item) { - return array.detect(function(value) { return item === value }); - }); - }, - - clone: function() { - return [].concat(this); - }, - - size: function() { - return this.length; - }, - - inspect: function() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - }, - - toJSON: function() { - var results = []; - this.each(function(object) { - var value = Object.toJSON(object); - if (!Object.isUndefined(value)) results.push(value); - }); - return '[' + results.join(', ') + ']'; - } -}); - -// use native browser JS 1.6 implementation if available -if (Object.isFunction(Array.prototype.forEach)) - Array.prototype._each = Array.prototype.forEach; - -if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { - i || (i = 0); - var length = this.length; - if (i < 0) i = length + i; - for (; i < length; i++) - if (this[i] === item) return i; - return -1; -}; - -if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { - i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; - var n = this.slice(0, i).reverse().indexOf(item); - return (n < 0) ? n : i - n - 1; -}; - -Array.prototype.toArray = Array.prototype.clone; - -function $w(string) { - if (!Object.isString(string)) return []; - string = string.strip(); - return string ? string.split(/\s+/) : []; -} - -if (Prototype.Browser.Opera){ - Array.prototype.concat = function() { - var array = []; - for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); - for (var i = 0, length = arguments.length; i < length; i++) { - if (Object.isArray(arguments[i])) { - for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) - array.push(arguments[i][j]); - } else { - array.push(arguments[i]); - } - } - return array; - }; -} -Object.extend(Number.prototype, { - toColorPart: function() { - return this.toPaddedString(2, 16); - }, - - succ: function() { - return this + 1; - }, - - times: function(iterator) { - $R(0, this, true).each(iterator); - return this; - }, - - toPaddedString: function(length, radix) { - var string = this.toString(radix || 10); - return '0'.times(length - string.length) + string; - }, - - toJSON: function() { - return isFinite(this) ? this.toString() : 'null'; - } -}); - -$w('abs round ceil floor').each(function(method){ - Number.prototype[method] = Math[method].methodize(); -}); -function $H(object) { - return new Hash(object); -}; - -var Hash = Class.create(Enumerable, (function() { - - function toQueryPair(key, value) { - if (Object.isUndefined(value)) return key; - return key + '=' + encodeURIComponent(String.interpret(value)); - } - - return { - initialize: function(object) { - this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); - }, - - _each: function(iterator) { - for (var key in this._object) { - var value = this._object[key], pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - }, - - set: function(key, value) { - return this._object[key] = value; - }, - - get: function(key) { - return this._object[key]; - }, - - unset: function(key) { - var value = this._object[key]; - delete this._object[key]; - return value; - }, - - toObject: function() { - return Object.clone(this._object); - }, - - keys: function() { - return this.pluck('key'); - }, - - values: function() { - return this.pluck('value'); - }, - - index: function(value) { - var match = this.detect(function(pair) { - return pair.value === value; - }); - return match && match.key; - }, - - merge: function(object) { - return this.clone().update(object); - }, - - update: function(object) { - return new Hash(object).inject(this, function(result, pair) { - result.set(pair.key, pair.value); - return result; - }); - }, - - toQueryString: function() { - return this.map(function(pair) { - var key = encodeURIComponent(pair.key), values = pair.value; - - if (values && typeof values == 'object') { - if (Object.isArray(values)) - return values.map(toQueryPair.curry(key)).join('&'); - } - return toQueryPair(key, values); - }).join('&'); - }, - - inspect: function() { - return '#'; - }, - - toJSON: function() { - return Object.toJSON(this.toObject()); - }, - - clone: function() { - return new Hash(this); - } - } -})()); - -Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; -Hash.from = $H; -var ObjectRange = Class.create(Enumerable, { - initialize: function(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - }, - - _each: function(iterator) { - var value = this.start; - while (this.include(value)) { - iterator(value); - value = value.succ(); - } - }, - - include: function(value) { - if (value < this.start) - return false; - if (this.exclusive) - return value < this.end; - return value <= this.end; - } -}); - -var $R = function(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -}; - -var Ajax = { - getTransport: function() { - return Try.these( - function() {return new XMLHttpRequest()}, - function() {return new ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')} - ) || false; - }, - - activeRequestCount: 0 -}; - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responder) { - if (!this.include(responder)) - this.responders.push(responder); - }, - - unregister: function(responder) { - this.responders = this.responders.without(responder); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (Object.isFunction(responder[callback])) { - try { - responder[callback].apply(responder, [request, transport, json]); - } catch (e) { } - } - }); - } -}; - -Object.extend(Ajax.Responders, Enumerable); - -Ajax.Responders.register({ - onCreate: function() { Ajax.activeRequestCount++ }, - onComplete: function() { Ajax.activeRequestCount-- } -}); - -Ajax.Base = Class.create({ - initialize: function(options) { - this.options = { - method: 'post', - asynchronous: true, - contentType: 'application/x-www-form-urlencoded', - encoding: 'UTF-8', - parameters: '', - evalJSON: true, - evalJS: true - }; - Object.extend(this.options, options || { }); - - this.options.method = this.options.method.toLowerCase(); - - if (Object.isString(this.options.parameters)) - this.options.parameters = this.options.parameters.toQueryParams(); - else if (Object.isHash(this.options.parameters)) - this.options.parameters = this.options.parameters.toObject(); - } -}); - -Ajax.Request = Class.create(Ajax.Base, { - _complete: false, - - initialize: function($super, url, options) { - $super(options); - this.transport = Ajax.getTransport(); - this.request(url); - }, - - request: function(url) { - this.url = url; - this.method = this.options.method; - var params = Object.clone(this.options.parameters); - - if (!['get', 'post'].include(this.method)) { - // simulate other verbs over post - params['_method'] = this.method; - this.method = 'post'; - } - - this.parameters = params; - - if (params = Object.toQueryString(params)) { - // when GET, append parameters to URL - if (this.method == 'get') - this.url += (this.url.include('?') ? '&' : '?') + params; - else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) - params += '&_='; - } - - try { - var response = new Ajax.Response(this); - if (this.options.onCreate) this.options.onCreate(response); - Ajax.Responders.dispatch('onCreate', this, response); - - this.transport.open(this.method.toUpperCase(), this.url, - this.options.asynchronous); - - if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); - - this.transport.onreadystatechange = this.onStateChange.bind(this); - this.setRequestHeaders(); - - this.body = this.method == 'post' ? (this.options.postBody || params) : null; - this.transport.send(this.body); - - /* Force Firefox to handle ready state 4 for synchronous requests */ - if (!this.options.asynchronous && this.transport.overrideMimeType) - this.onStateChange(); - - } - catch (e) { - this.dispatchException(e); - } - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState > 1 && !((readyState == 4) && this._complete)) - this.respondToReadyState(this.transport.readyState); - }, - - setRequestHeaders: function() { - var headers = { - 'X-Requested-With': 'XMLHttpRequest', - 'X-Prototype-Version': Prototype.Version, - 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' - }; - - if (this.method == 'post') { - headers['Content-type'] = this.options.contentType + - (this.options.encoding ? '; charset=' + this.options.encoding : ''); - - /* Force "Connection: close" for older Mozilla browsers to work - * around a bug where XMLHttpRequest sends an incorrect - * Content-length header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType && - (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) - headers['Connection'] = 'close'; - } - - // user-defined headers - if (typeof this.options.requestHeaders == 'object') { - var extras = this.options.requestHeaders; - - if (Object.isFunction(extras.push)) - for (var i = 0, length = extras.length; i < length; i += 2) - headers[extras[i]] = extras[i+1]; - else - $H(extras).each(function(pair) { headers[pair.key] = pair.value }); - } - - for (var name in headers) - this.transport.setRequestHeader(name, headers[name]); - }, - - success: function() { - var status = this.getStatus(); - return !status || (status >= 200 && status < 300); - }, - - getStatus: function() { - try { - return this.transport.status || 0; - } catch (e) { return 0 } - }, - - respondToReadyState: function(readyState) { - var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); - - if (state == 'Complete') { - try { - this._complete = true; - (this.options['on' + response.status] - || this.options['on' + (this.success() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - var contentType = response.getHeader('Content-type'); - if (this.options.evalJS == 'force' - || (this.options.evalJS && this.isSameOrigin() && contentType - && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) - this.evalResponse(); - } - - try { - (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); - Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - if (state == 'Complete') { - // avoid memory leak in MSIE: clean up - this.transport.onreadystatechange = Prototype.emptyFunction; - } - }, - - isSameOrigin: function() { - var m = this.url.match(/^\s*https?:\/\/[^\/]*/); - return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ - protocol: location.protocol, - domain: document.domain, - port: location.port ? ':' + location.port : '' - })); - }, - - getHeader: function(name) { - try { - return this.transport.getResponseHeader(name) || null; - } catch (e) { return null } - }, - - evalResponse: function() { - try { - return eval((this.transport.responseText || '').unfilterJSON()); - } catch (e) { - this.dispatchException(e); - } - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - -Ajax.Response = Class.create({ - initialize: function(request){ - this.request = request; - var transport = this.transport = request.transport, - readyState = this.readyState = transport.readyState; - - if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { - this.status = this.getStatus(); - this.statusText = this.getStatusText(); - this.responseText = String.interpret(transport.responseText); - this.headerJSON = this._getHeaderJSON(); - } - - if(readyState == 4) { - var xml = transport.responseXML; - this.responseXML = Object.isUndefined(xml) ? null : xml; - this.responseJSON = this._getResponseJSON(); - } - }, - - status: 0, - statusText: '', - - getStatus: Ajax.Request.prototype.getStatus, - - getStatusText: function() { - try { - return this.transport.statusText || ''; - } catch (e) { return '' } - }, - - getHeader: Ajax.Request.prototype.getHeader, - - getAllHeaders: function() { - try { - return this.getAllResponseHeaders(); - } catch (e) { return null } - }, - - getResponseHeader: function(name) { - return this.transport.getResponseHeader(name); - }, - - getAllResponseHeaders: function() { - return this.transport.getAllResponseHeaders(); - }, - - _getHeaderJSON: function() { - var json = this.getHeader('X-JSON'); - if (!json) return null; - json = decodeURIComponent(escape(json)); - try { - return json.evalJSON(this.request.options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - }, - - _getResponseJSON: function() { - var options = this.request.options; - if (!options.evalJSON || (options.evalJSON != 'force' && - !(this.getHeader('Content-type') || '').include('application/json')) || - this.responseText.blank()) - return null; - try { - return this.responseText.evalJSON(options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - } -}); - -Ajax.Updater = Class.create(Ajax.Request, { - initialize: function($super, container, url, options) { - this.container = { - success: (container.success || container), - failure: (container.failure || (container.success ? null : container)) - }; - - options = Object.clone(options); - var onComplete = options.onComplete; - options.onComplete = (function(response, json) { - this.updateContent(response.responseText); - if (Object.isFunction(onComplete)) onComplete(response, json); - }).bind(this); - - $super(url, options); - }, - - updateContent: function(responseText) { - var receiver = this.container[this.success() ? 'success' : 'failure'], - options = this.options; - - if (!options.evalScripts) responseText = responseText.stripScripts(); - - if (receiver = $(receiver)) { - if (options.insertion) { - if (Object.isString(options.insertion)) { - var insertion = { }; insertion[options.insertion] = responseText; - receiver.insert(insertion); - } - else options.insertion(receiver, responseText); - } - else receiver.update(responseText); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { - initialize: function($super, container, url, options) { - $super(options); - this.onComplete = this.options.onComplete; - - this.frequency = (this.options.frequency || 2); - this.decay = (this.options.decay || 1); - - this.updater = { }; - this.container = container; - this.url = url; - - this.start(); - }, - - start: function() { - this.options.onComplete = this.updateComplete.bind(this); - this.onTimerEvent(); - }, - - stop: function() { - this.updater.options.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(response) { - if (this.options.decay) { - this.decay = (response.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = response.responseText; - } - this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); -function $(element) { - if (arguments.length > 1) { - for (var i = 0, elements = [], length = arguments.length; i < length; i++) - elements.push($(arguments[i])); - return elements; - } - if (Object.isString(element)) - element = document.getElementById(element); - return Element.extend(element); -} - -if (Prototype.BrowserFeatures.XPath) { - document._getElementsByXPath = function(expression, parentElement) { - var results = []; - var query = document.evaluate(expression, $(parentElement) || document, - null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - for (var i = 0, length = query.snapshotLength; i < length; i++) - results.push(Element.extend(query.snapshotItem(i))); - return results; - }; -} - -/*--------------------------------------------------------------------------*/ - -if (!window.Node) var Node = { }; - -if (!Node.ELEMENT_NODE) { - // DOM level 2 ECMAScript Language Binding - Object.extend(Node, { - ELEMENT_NODE: 1, - ATTRIBUTE_NODE: 2, - TEXT_NODE: 3, - CDATA_SECTION_NODE: 4, - ENTITY_REFERENCE_NODE: 5, - ENTITY_NODE: 6, - PROCESSING_INSTRUCTION_NODE: 7, - COMMENT_NODE: 8, - DOCUMENT_NODE: 9, - DOCUMENT_TYPE_NODE: 10, - DOCUMENT_FRAGMENT_NODE: 11, - NOTATION_NODE: 12 - }); -} - -(function() { - var element = this.Element; - this.Element = function(tagName, attributes) { - attributes = attributes || { }; - tagName = tagName.toLowerCase(); - var cache = Element.cache; - if (Prototype.Browser.IE && attributes.name) { - tagName = '<' + tagName + ' name="' + attributes.name + '">'; - delete attributes.name; - return Element.writeAttribute(document.createElement(tagName), attributes); - } - if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); - return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); - }; - Object.extend(this.Element, element || { }); -}).call(window); - -Element.cache = { }; - -Element.Methods = { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function(element) { - element = $(element); - Element[Element.visible(element) ? 'hide' : 'show'](element); - return element; - }, - - hide: function(element) { - $(element).style.display = 'none'; - return element; - }, - - show: function(element) { - $(element).style.display = ''; - return element; - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - return element; - }, - - update: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) return element.update().insert(content); - content = Object.toHTML(content); - element.innerHTML = content.stripScripts(); - content.evalScripts.bind(content).defer(); - return element; - }, - - replace: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - else if (!Object.isElement(content)) { - content = Object.toHTML(content); - var range = element.ownerDocument.createRange(); - range.selectNode(element); - content.evalScripts.bind(content).defer(); - content = range.createContextualFragment(content.stripScripts()); - } - element.parentNode.replaceChild(content, element); - return element; - }, - - insert: function(element, insertions) { - element = $(element); - - if (Object.isString(insertions) || Object.isNumber(insertions) || - Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) - insertions = {bottom:insertions}; - - var content, insert, tagName, childNodes; - - for (var position in insertions) { - content = insertions[position]; - position = position.toLowerCase(); - insert = Element._insertionTranslations[position]; - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - insert(element, content); - continue; - } - - content = Object.toHTML(content); - - tagName = ((position == 'before' || position == 'after') - ? element.parentNode : element).tagName.toUpperCase(); - - childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - - if (position == 'top' || position == 'after') childNodes.reverse(); - childNodes.each(insert.curry(element)); - - content.evalScripts.bind(content).defer(); - } - - return element; - }, - - wrap: function(element, wrapper, attributes) { - element = $(element); - if (Object.isElement(wrapper)) - $(wrapper).writeAttribute(attributes || { }); - else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); - else wrapper = new Element('div', wrapper); - if (element.parentNode) - element.parentNode.replaceChild(wrapper, element); - wrapper.appendChild(element); - return wrapper; - }, - - inspect: function(element) { - element = $(element); - var result = '<' + element.tagName.toLowerCase(); - $H({'id': 'id', 'className': 'class'}).each(function(pair) { - var property = pair.first(), attribute = pair.last(); - var value = (element[property] || '').toString(); - if (value) result += ' ' + attribute + '=' + value.inspect(true); - }); - return result + '>'; - }, - - recursivelyCollect: function(element, property) { - element = $(element); - var elements = []; - while (element = element[property]) - if (element.nodeType == 1) - elements.push(Element.extend(element)); - return elements; - }, - - ancestors: function(element) { - return $(element).recursivelyCollect('parentNode'); - }, - - descendants: function(element) { - return $(element).select("*"); - }, - - firstDescendant: function(element) { - element = $(element).firstChild; - while (element && element.nodeType != 1) element = element.nextSibling; - return $(element); - }, - - immediateDescendants: function(element) { - if (!(element = $(element).firstChild)) return []; - while (element && element.nodeType != 1) element = element.nextSibling; - if (element) return [element].concat($(element).nextSiblings()); - return []; - }, - - previousSiblings: function(element) { - return $(element).recursivelyCollect('previousSibling'); - }, - - nextSiblings: function(element) { - return $(element).recursivelyCollect('nextSibling'); - }, - - siblings: function(element) { - element = $(element); - return element.previousSiblings().reverse().concat(element.nextSiblings()); - }, - - match: function(element, selector) { - if (Object.isString(selector)) - selector = new Selector(selector); - return selector.match($(element)); - }, - - up: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(element.parentNode); - var ancestors = element.ancestors(); - return Object.isNumber(expression) ? ancestors[expression] : - Selector.findElement(ancestors, expression, index); - }, - - down: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return element.firstDescendant(); - return Object.isNumber(expression) ? element.descendants()[expression] : - element.select(expression)[index || 0]; - }, - - previous: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); - var previousSiblings = element.previousSiblings(); - return Object.isNumber(expression) ? previousSiblings[expression] : - Selector.findElement(previousSiblings, expression, index); - }, - - next: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); - var nextSiblings = element.nextSiblings(); - return Object.isNumber(expression) ? nextSiblings[expression] : - Selector.findElement(nextSiblings, expression, index); - }, - - select: function() { - var args = $A(arguments), element = $(args.shift()); - return Selector.findChildElements(element, args); - }, - - adjacent: function() { - var args = $A(arguments), element = $(args.shift()); - return Selector.findChildElements(element.parentNode, args).without(element); - }, - - identify: function(element) { - element = $(element); - var id = element.readAttribute('id'), self = arguments.callee; - if (id) return id; - do { id = 'anonymous_element_' + self.counter++ } while ($(id)); - element.writeAttribute('id', id); - return id; - }, - - readAttribute: function(element, name) { - element = $(element); - if (Prototype.Browser.IE) { - var t = Element._attributeTranslations.read; - if (t.values[name]) return t.values[name](element, name); - if (t.names[name]) name = t.names[name]; - if (name.include(':')) { - return (!element.attributes || !element.attributes[name]) ? null : - element.attributes[name].value; - } - } - return element.getAttribute(name); - }, - - writeAttribute: function(element, name, value) { - element = $(element); - var attributes = { }, t = Element._attributeTranslations.write; - - if (typeof name == 'object') attributes = name; - else attributes[name] = Object.isUndefined(value) ? true : value; - - for (var attr in attributes) { - name = t.names[attr] || attr; - value = attributes[attr]; - if (t.values[attr]) name = t.values[attr](element, value); - if (value === false || value === null) - element.removeAttribute(name); - else if (value === true) - element.setAttribute(name, name); - else element.setAttribute(name, value); - } - return element; - }, - - getHeight: function(element) { - return $(element).getDimensions().height; - }, - - getWidth: function(element) { - return $(element).getDimensions().width; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - var elementClassName = element.className; - return (elementClassName.length > 0 && (elementClassName == className || - new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - if (!element.hasClassName(className)) - element.className += (element.className ? ' ' : '') + className; - return element; - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - element.className = element.className.replace( - new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); - return element; - }, - - toggleClassName: function(element, className) { - if (!(element = $(element))) return; - return element[element.hasClassName(className) ? - 'removeClassName' : 'addClassName'](className); - }, - - // removes whitespace-only text node children - cleanWhitespace: function(element) { - element = $(element); - var node = element.firstChild; - while (node) { - var nextNode = node.nextSibling; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - element.removeChild(node); - node = nextNode; - } - return element; - }, - - empty: function(element) { - return $(element).innerHTML.blank(); - }, - - descendantOf: function(element, ancestor) { - element = $(element), ancestor = $(ancestor); - var originalAncestor = ancestor; - - if (element.compareDocumentPosition) - return (element.compareDocumentPosition(ancestor) & 8) === 8; - - if (element.sourceIndex && !Prototype.Browser.Opera) { - var e = element.sourceIndex, a = ancestor.sourceIndex, - nextAncestor = ancestor.nextSibling; - if (!nextAncestor) { - do { ancestor = ancestor.parentNode; } - while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode); - } - if (nextAncestor && nextAncestor.sourceIndex) - return (e > a && e < nextAncestor.sourceIndex); - } - - while (element = element.parentNode) - if (element == originalAncestor) return true; - return false; - }, - - scrollTo: function(element) { - element = $(element); - var pos = element.cumulativeOffset(); - window.scrollTo(pos[0], pos[1]); - return element; - }, - - getStyle: function(element, style) { - element = $(element); - style = style == 'float' ? 'cssFloat' : style.camelize(); - var value = element.style[style]; - if (!value) { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css[style] : null; - } - if (style == 'opacity') return value ? parseFloat(value) : 1.0; - return value == 'auto' ? null : value; - }, - - getOpacity: function(element) { - return $(element).getStyle('opacity'); - }, - - setStyle: function(element, styles) { - element = $(element); - var elementStyle = element.style, match; - if (Object.isString(styles)) { - element.style.cssText += ';' + styles; - return styles.include('opacity') ? - element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; - } - for (var property in styles) - if (property == 'opacity') element.setOpacity(styles[property]); - else - elementStyle[(property == 'float' || property == 'cssFloat') ? - (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : - property] = styles[property]; - - return element; - }, - - setOpacity: function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - return element; - }, - - getDimensions: function(element) { - element = $(element); - var display = $(element).getStyle('display'); - if (display != 'none' && display != null) // Safari bug - return {width: element.offsetWidth, height: element.offsetHeight}; - - // All *Width and *Height properties give 0 on elements with display none, - // so enable the element temporarily - var els = element.style; - var originalVisibility = els.visibility; - var originalPosition = els.position; - var originalDisplay = els.display; - els.visibility = 'hidden'; - els.position = 'absolute'; - els.display = 'block'; - var originalWidth = element.clientWidth; - var originalHeight = element.clientHeight; - els.display = originalDisplay; - els.position = originalPosition; - els.visibility = originalVisibility; - return {width: originalWidth, height: originalHeight}; - }, - - makePositioned: function(element) { - element = $(element); - var pos = Element.getStyle(element, 'position'); - if (pos == 'static' || !pos) { - element._madePositioned = true; - element.style.position = 'relative'; - // Opera returns the offset relative to the positioning context, when an - // element is position relative but top and left have not been defined - if (window.opera) { - element.style.top = 0; - element.style.left = 0; - } - } - return element; - }, - - undoPositioned: function(element) { - element = $(element); - if (element._madePositioned) { - element._madePositioned = undefined; - element.style.position = - element.style.top = - element.style.left = - element.style.bottom = - element.style.right = ''; - } - return element; - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return element; - element._overflow = Element.getStyle(element, 'overflow') || 'auto'; - if (element._overflow !== 'hidden') - element.style.overflow = 'hidden'; - return element; - }, - - undoClipping: function(element) { - element = $(element); - if (!element._overflow) return element; - element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; - element._overflow = null; - return element; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - positionedOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - if (element.tagName == 'BODY') break; - var p = Element.getStyle(element, 'position'); - if (p !== 'static') break; - } - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - absolutize: function(element) { - element = $(element); - if (element.getStyle('position') == 'absolute') return; - // Position.prepare(); // To be done manually by Scripty when it needs it. - - var offsets = element.positionedOffset(); - var top = offsets[1]; - var left = offsets[0]; - var width = element.clientWidth; - var height = element.clientHeight; - - element._originalLeft = left - parseFloat(element.style.left || 0); - element._originalTop = top - parseFloat(element.style.top || 0); - element._originalWidth = element.style.width; - element._originalHeight = element.style.height; - - element.style.position = 'absolute'; - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.width = width + 'px'; - element.style.height = height + 'px'; - return element; - }, - - relativize: function(element) { - element = $(element); - if (element.getStyle('position') == 'relative') return; - // Position.prepare(); // To be done manually by Scripty when it needs it. - - element.style.position = 'relative'; - var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); - var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); - - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.height = element._originalHeight; - element.style.width = element._originalWidth; - return element; - }, - - cumulativeScrollOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - getOffsetParent: function(element) { - if (element.offsetParent) return $(element.offsetParent); - if (element == document.body) return $(element); - - while ((element = element.parentNode) && element != document.body) - if (Element.getStyle(element, 'position') != 'static') - return $(element); - - return $(document.body); - }, - - viewportOffset: function(forElement) { - var valueT = 0, valueL = 0; - - var element = forElement; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - - // Safari fix - if (element.offsetParent == document.body && - Element.getStyle(element, 'position') == 'absolute') break; - - } while (element = element.offsetParent); - - element = forElement; - do { - if (!Prototype.Browser.Opera || element.tagName == 'BODY') { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } - } while (element = element.parentNode); - - return Element._returnOffset(valueL, valueT); - }, - - clonePosition: function(element, source) { - var options = Object.extend({ - setLeft: true, - setTop: true, - setWidth: true, - setHeight: true, - offsetTop: 0, - offsetLeft: 0 - }, arguments[2] || { }); - - // find page position of source - source = $(source); - var p = source.viewportOffset(); - - // find coordinate system to use - element = $(element); - var delta = [0, 0]; - var parent = null; - // delta [0,0] will do fine with position: fixed elements, - // position:absolute needs offsetParent deltas - if (Element.getStyle(element, 'position') == 'absolute') { - parent = element.getOffsetParent(); - delta = parent.viewportOffset(); - } - - // correct by body offsets (fixes Safari) - if (parent == document.body) { - delta[0] -= document.body.offsetLeft; - delta[1] -= document.body.offsetTop; - } - - // set position - if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if (options.setWidth) element.style.width = source.offsetWidth + 'px'; - if (options.setHeight) element.style.height = source.offsetHeight + 'px'; - return element; - } -}; - -Element.Methods.identify.counter = 1; - -Object.extend(Element.Methods, { - getElementsBySelector: Element.Methods.select, - childElements: Element.Methods.immediateDescendants -}); - -Element._attributeTranslations = { - write: { - names: { - className: 'class', - htmlFor: 'for' - }, - values: { } - } -}; - -if (Prototype.Browser.Opera) { - Element.Methods.getStyle = Element.Methods.getStyle.wrap( - function(proceed, element, style) { - switch (style) { - case 'left': case 'top': case 'right': case 'bottom': - if (proceed(element, 'position') === 'static') return null; - case 'height': case 'width': - // returns '0px' for hidden elements; we want it to return null - if (!Element.visible(element)) return null; - - // returns the border-box dimensions rather than the content-box - // dimensions, so we subtract padding and borders from the value - var dim = parseInt(proceed(element, style), 10); - - if (dim !== element['offset' + style.capitalize()]) - return dim + 'px'; - - var properties; - if (style === 'height') { - properties = ['border-top-width', 'padding-top', - 'padding-bottom', 'border-bottom-width']; - } - else { - properties = ['border-left-width', 'padding-left', - 'padding-right', 'border-right-width']; - } - return properties.inject(dim, function(memo, property) { - var val = proceed(element, property); - return val === null ? memo : memo - parseInt(val, 10); - }) + 'px'; - default: return proceed(element, style); - } - } - ); - - Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( - function(proceed, element, attribute) { - if (attribute === 'title') return element.title; - return proceed(element, attribute); - } - ); -} - -else if (Prototype.Browser.IE) { - // IE doesn't report offsets correctly for static elements, so we change them - // to "relative" to get the values, then change them back. - Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( - function(proceed, element) { - element = $(element); - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - } - ); - - $w('positionedOffset viewportOffset').each(function(method) { - Element.Methods[method] = Element.Methods[method].wrap( - function(proceed, element) { - element = $(element); - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - // Trigger hasLayout on the offset parent so that IE6 reports - // accurate offsetTop and offsetLeft values for position: fixed. - var offsetParent = element.getOffsetParent(); - if (offsetParent && offsetParent.getStyle('position') === 'fixed') - offsetParent.setStyle({ zoom: 1 }); - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - } - ); - }); - - Element.Methods.getStyle = function(element, style) { - element = $(element); - style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); - var value = element.style[style]; - if (!value && element.currentStyle) value = element.currentStyle[style]; - - if (style == 'opacity') { - if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) - if (value[1]) return parseFloat(value[1]) / 100; - return 1.0; - } - - if (value == 'auto') { - if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) - return element['offset' + style.capitalize()] + 'px'; - return null; - } - return value; - }; - - Element.Methods.setOpacity = function(element, value) { - function stripAlpha(filter){ - return filter.replace(/alpha\([^\)]*\)/gi,''); - } - element = $(element); - var currentStyle = element.currentStyle; - if ((currentStyle && !currentStyle.hasLayout) || - (!currentStyle && element.style.zoom == 'normal')) - element.style.zoom = 1; - - var filter = element.getStyle('filter'), style = element.style; - if (value == 1 || value === '') { - (filter = stripAlpha(filter)) ? - style.filter = filter : style.removeAttribute('filter'); - return element; - } else if (value < 0.00001) value = 0; - style.filter = stripAlpha(filter) + - 'alpha(opacity=' + (value * 100) + ')'; - return element; - }; - - Element._attributeTranslations = { - read: { - names: { - 'class': 'className', - 'for': 'htmlFor' - }, - values: { - _getAttr: function(element, attribute) { - return element.getAttribute(attribute, 2); - }, - _getAttrNode: function(element, attribute) { - var node = element.getAttributeNode(attribute); - return node ? node.value : ""; - }, - _getEv: function(element, attribute) { - attribute = element.getAttribute(attribute); - return attribute ? attribute.toString().slice(23, -2) : null; - }, - _flag: function(element, attribute) { - return $(element).hasAttribute(attribute) ? attribute : null; - }, - style: function(element) { - return element.style.cssText.toLowerCase(); - }, - title: function(element) { - return element.title; - } - } - } - }; - - Element._attributeTranslations.write = { - names: Object.extend({ - cellpadding: 'cellPadding', - cellspacing: 'cellSpacing' - }, Element._attributeTranslations.read.names), - values: { - checked: function(element, value) { - element.checked = !!value; - }, - - style: function(element, value) { - element.style.cssText = value ? value : ''; - } - } - }; - - Element._attributeTranslations.has = {}; - - $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + - 'encType maxLength readOnly longDesc').each(function(attr) { - Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; - Element._attributeTranslations.has[attr.toLowerCase()] = attr; - }); - - (function(v) { - Object.extend(v, { - href: v._getAttr, - src: v._getAttr, - type: v._getAttr, - action: v._getAttrNode, - disabled: v._flag, - checked: v._flag, - readonly: v._flag, - multiple: v._flag, - onload: v._getEv, - onunload: v._getEv, - onclick: v._getEv, - ondblclick: v._getEv, - onmousedown: v._getEv, - onmouseup: v._getEv, - onmouseover: v._getEv, - onmousemove: v._getEv, - onmouseout: v._getEv, - onfocus: v._getEv, - onblur: v._getEv, - onkeypress: v._getEv, - onkeydown: v._getEv, - onkeyup: v._getEv, - onsubmit: v._getEv, - onreset: v._getEv, - onselect: v._getEv, - onchange: v._getEv - }); - })(Element._attributeTranslations.read.values); -} - -else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1) ? 0.999999 : - (value === '') ? '' : (value < 0.00001) ? 0 : value; - return element; - }; -} - -else if (Prototype.Browser.WebKit) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - - if (value == 1) - if(element.tagName == 'IMG' && element.width) { - element.width++; element.width--; - } else try { - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch (e) { } - - return element; - }; - - // Safari returns margins on body which is incorrect if the child is absolutely - // positioned. For performance reasons, redefine Element#cumulativeOffset for - // KHTML/WebKit only. - Element.Methods.cumulativeOffset = function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == document.body) - if (Element.getStyle(element, 'position') == 'absolute') break; - - element = element.offsetParent; - } while (element); - - return Element._returnOffset(valueL, valueT); - }; -} - -if (Prototype.Browser.IE || Prototype.Browser.Opera) { - // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements - Element.Methods.update = function(element, content) { - element = $(element); - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) return element.update().insert(content); - - content = Object.toHTML(content); - var tagName = element.tagName.toUpperCase(); - - if (tagName in Element._insertionTranslations.tags) { - $A(element.childNodes).each(function(node) { element.removeChild(node) }); - Element._getContentFromAnonymousElement(tagName, content.stripScripts()) - .each(function(node) { element.appendChild(node) }); - } - else element.innerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - -if ('outerHTML' in document.createElement('div')) { - Element.Methods.replace = function(element, content) { - element = $(element); - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - element.parentNode.replaceChild(content, element); - return element; - } - - content = Object.toHTML(content); - var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); - - if (Element._insertionTranslations.tags[tagName]) { - var nextSibling = element.next(); - var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - parent.removeChild(element); - if (nextSibling) - fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); - else - fragments.each(function(node) { parent.appendChild(node) }); - } - else element.outerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - -Element._returnOffset = function(l, t) { - var result = [l, t]; - result.left = l; - result.top = t; - return result; -}; - -Element._getContentFromAnonymousElement = function(tagName, html) { - var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]; - if (t) { - div.innerHTML = t[0] + html + t[1]; - t[2].times(function() { div = div.firstChild }); - } else div.innerHTML = html; - return $A(div.childNodes); -}; - -Element._insertionTranslations = { - before: function(element, node) { - element.parentNode.insertBefore(node, element); - }, - top: function(element, node) { - element.insertBefore(node, element.firstChild); - }, - bottom: function(element, node) { - element.appendChild(node); - }, - after: function(element, node) { - element.parentNode.insertBefore(node, element.nextSibling); - }, - tags: { - TABLE: ['', '
', 1], - TBODY: ['', '
', 2], - TR: ['', '
', 3], - TD: ['
', '
', 4], - SELECT: ['', 1] - } -}; - -(function() { - Object.extend(this.tags, { - THEAD: this.tags.TBODY, - TFOOT: this.tags.TBODY, - TH: this.tags.TD - }); -}).call(Element._insertionTranslations); - -Element.Methods.Simulated = { - hasAttribute: function(element, attribute) { - attribute = Element._attributeTranslations.has[attribute] || attribute; - var node = $(element).getAttributeNode(attribute); - return node && node.specified; - } -}; - -Element.Methods.ByTag = { }; - -Object.extend(Element, Element.Methods); - -if (!Prototype.BrowserFeatures.ElementExtensions && - document.createElement('div').__proto__) { - window.HTMLElement = { }; - window.HTMLElement.prototype = document.createElement('div').__proto__; - Prototype.BrowserFeatures.ElementExtensions = true; -} - -Element.extend = (function() { - if (Prototype.BrowserFeatures.SpecificElementExtensions) - return Prototype.K; - - var Methods = { }, ByTag = Element.Methods.ByTag; - - var extend = Object.extend(function(element) { - if (!element || element._extendedByPrototype || - element.nodeType != 1 || element == window) return element; - - var methods = Object.clone(Methods), - tagName = element.tagName, property, value; - - // extend methods for specific tags - if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); - - for (property in methods) { - value = methods[property]; - if (Object.isFunction(value) && !(property in element)) - element[property] = value.methodize(); - } - - element._extendedByPrototype = Prototype.emptyFunction; - return element; - - }, { - refresh: function() { - // extend methods for all tags (Safari doesn't need this) - if (!Prototype.BrowserFeatures.ElementExtensions) { - Object.extend(Methods, Element.Methods); - Object.extend(Methods, Element.Methods.Simulated); - } - } - }); - - extend.refresh(); - return extend; -})(); - -Element.hasAttribute = function(element, attribute) { - if (element.hasAttribute) return element.hasAttribute(attribute); - return Element.Methods.Simulated.hasAttribute(element, attribute); -}; - -Element.addMethods = function(methods) { - var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; - - if (!methods) { - Object.extend(Form, Form.Methods); - Object.extend(Form.Element, Form.Element.Methods); - Object.extend(Element.Methods.ByTag, { - "FORM": Object.clone(Form.Methods), - "INPUT": Object.clone(Form.Element.Methods), - "SELECT": Object.clone(Form.Element.Methods), - "TEXTAREA": Object.clone(Form.Element.Methods) - }); - } - - if (arguments.length == 2) { - var tagName = methods; - methods = arguments[1]; - } - - if (!tagName) Object.extend(Element.Methods, methods || { }); - else { - if (Object.isArray(tagName)) tagName.each(extend); - else extend(tagName); - } - - function extend(tagName) { - tagName = tagName.toUpperCase(); - if (!Element.Methods.ByTag[tagName]) - Element.Methods.ByTag[tagName] = { }; - Object.extend(Element.Methods.ByTag[tagName], methods); - } - - function copy(methods, destination, onlyIfAbsent) { - onlyIfAbsent = onlyIfAbsent || false; - for (var property in methods) { - var value = methods[property]; - if (!Object.isFunction(value)) continue; - if (!onlyIfAbsent || !(property in destination)) - destination[property] = value.methodize(); - } - } - - function findDOMClass(tagName) { - var klass; - var trans = { - "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", - "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", - "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", - "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", - "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": - "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": - "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": - "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": - "FrameSet", "IFRAME": "IFrame" - }; - if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName.capitalize() + 'Element'; - if (window[klass]) return window[klass]; - - window[klass] = { }; - window[klass].prototype = document.createElement(tagName).__proto__; - return window[klass]; - } - - if (F.ElementExtensions) { - copy(Element.Methods, HTMLElement.prototype); - copy(Element.Methods.Simulated, HTMLElement.prototype, true); - } - - if (F.SpecificElementExtensions) { - for (var tag in Element.Methods.ByTag) { - var klass = findDOMClass(tag); - if (Object.isUndefined(klass)) continue; - copy(T[tag], klass.prototype); - } - } - - Object.extend(Element, Element.Methods); - delete Element.ByTag; - - if (Element.extend.refresh) Element.extend.refresh(); - Element.cache = { }; -}; - -document.viewport = { - getDimensions: function() { - var dimensions = { }; - var B = Prototype.Browser; - $w('width height').each(function(d) { - var D = d.capitalize(); - dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] : - (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D]; - }); - return dimensions; - }, - - getWidth: function() { - return this.getDimensions().width; - }, - - getHeight: function() { - return this.getDimensions().height; - }, - - getScrollOffsets: function() { - return Element._returnOffset( - window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); - } -}; -/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, - * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style - * license. Please see http://www.yui-ext.com/ for more information. */ - -var Selector = Class.create({ - initialize: function(expression) { - this.expression = expression.strip(); - this.compileMatcher(); - }, - - shouldUseXPath: function() { - if (!Prototype.BrowserFeatures.XPath) return false; - - var e = this.expression; - - // Safari 3 chokes on :*-of-type and :empty - if (Prototype.Browser.WebKit && - (e.include("-of-type") || e.include(":empty"))) - return false; - - // XPath can't do namespaced attributes, nor can it read - // the "checked" property from DOM nodes - if ((/(\[[\w-]*?:|:checked)/).test(this.expression)) - return false; - - return true; - }, - - compileMatcher: function() { - if (this.shouldUseXPath()) - return this.compileXPathMatcher(); - - var e = this.expression, ps = Selector.patterns, h = Selector.handlers, - c = Selector.criteria, le, p, m; - - if (Selector._cache[e]) { - this.matcher = Selector._cache[e]; - return; - } - - this.matcher = ["this.matcher = function(root) {", - "var r = root, h = Selector.handlers, c = false, n;"]; - - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i in ps) { - p = ps[i]; - if (m = e.match(p)) { - this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : - new Template(c[i]).evaluate(m)); - e = e.replace(m[0], ''); - break; - } - } - } - - this.matcher.push("return h.unique(n);\n}"); - eval(this.matcher.join('\n')); - Selector._cache[this.expression] = this.matcher; - }, - - compileXPathMatcher: function() { - var e = this.expression, ps = Selector.patterns, - x = Selector.xpath, le, m; - - if (Selector._cache[e]) { - this.xpath = Selector._cache[e]; return; - } - - this.matcher = ['.//*']; - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i in ps) { - if (m = e.match(ps[i])) { - this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : - new Template(x[i]).evaluate(m)); - e = e.replace(m[0], ''); - break; - } - } - } - - this.xpath = this.matcher.join(''); - Selector._cache[this.expression] = this.xpath; - }, - - findElements: function(root) { - root = root || document; - if (this.xpath) return document._getElementsByXPath(this.xpath, root); - return this.matcher(root); - }, - - match: function(element) { - this.tokens = []; - - var e = this.expression, ps = Selector.patterns, as = Selector.assertions; - var le, p, m; - - while (e && le !== e && (/\S/).test(e)) { - le = e; - for (var i in ps) { - p = ps[i]; - if (m = e.match(p)) { - // use the Selector.assertions methods unless the selector - // is too complex. - if (as[i]) { - this.tokens.push([i, Object.clone(m)]); - e = e.replace(m[0], ''); - } else { - // reluctantly do a document-wide search - // and look for a match in the array - return this.findElements(document).include(element); - } - } - } - } - - var match = true, name, matches; - for (var i = 0, token; token = this.tokens[i]; i++) { - name = token[0], matches = token[1]; - if (!Selector.assertions[name](element, matches)) { - match = false; break; - } - } - - return match; - }, - - toString: function() { - return this.expression; - }, - - inspect: function() { - return "#"; - } -}); - -Object.extend(Selector, { - _cache: { }, - - xpath: { - descendant: "//*", - child: "/*", - adjacent: "/following-sibling::*[1]", - laterSibling: '/following-sibling::*', - tagName: function(m) { - if (m[1] == '*') return ''; - return "[local-name()='" + m[1].toLowerCase() + - "' or local-name()='" + m[1].toUpperCase() + "']"; - }, - className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", - id: "[@id='#{1}']", - attrPresence: function(m) { - m[1] = m[1].toLowerCase(); - return new Template("[@#{1}]").evaluate(m); - }, - attr: function(m) { - m[1] = m[1].toLowerCase(); - m[3] = m[5] || m[6]; - return new Template(Selector.xpath.operators[m[2]]).evaluate(m); - }, - pseudo: function(m) { - var h = Selector.xpath.pseudos[m[1]]; - if (!h) return ''; - if (Object.isFunction(h)) return h(m); - return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); - }, - operators: { - '=': "[@#{1}='#{3}']", - '!=': "[@#{1}!='#{3}']", - '^=': "[starts-with(@#{1}, '#{3}')]", - '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", - '*=': "[contains(@#{1}, '#{3}')]", - '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", - '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" - }, - pseudos: { - 'first-child': '[not(preceding-sibling::*)]', - 'last-child': '[not(following-sibling::*)]', - 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', - 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", - 'checked': "[@checked]", - 'disabled': "[@disabled]", - 'enabled': "[not(@disabled)]", - 'not': function(m) { - var e = m[6], p = Selector.patterns, - x = Selector.xpath, le, v; - - var exclusion = []; - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i in p) { - if (m = e.match(p[i])) { - v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m); - exclusion.push("(" + v.substring(1, v.length - 1) + ")"); - e = e.replace(m[0], ''); - break; - } - } - } - return "[not(" + exclusion.join(" and ") + ")]"; - }, - 'nth-child': function(m) { - return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); - }, - 'nth-last-child': function(m) { - return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); - }, - 'nth-of-type': function(m) { - return Selector.xpath.pseudos.nth("position() ", m); - }, - 'nth-last-of-type': function(m) { - return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); - }, - 'first-of-type': function(m) { - m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); - }, - 'last-of-type': function(m) { - m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); - }, - 'only-of-type': function(m) { - var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); - }, - nth: function(fragment, m) { - var mm, formula = m[6], predicate; - if (formula == 'even') formula = '2n+0'; - if (formula == 'odd') formula = '2n+1'; - if (mm = formula.match(/^(\d+)$/)) // digit only - return '[' + fragment + "= " + mm[1] + ']'; - if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b - if (mm[1] == "-") mm[1] = -1; - var a = mm[1] ? Number(mm[1]) : 1; - var b = mm[2] ? Number(mm[2]) : 0; - predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + - "((#{fragment} - #{b}) div #{a} >= 0)]"; - return new Template(predicate).evaluate({ - fragment: fragment, a: a, b: b }); - } - } - } - }, - - criteria: { - tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', - className: 'n = h.className(n, r, "#{1}", c); c = false;', - id: 'n = h.id(n, r, "#{1}", c); c = false;', - attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;', - attr: function(m) { - m[3] = (m[5] || m[6]); - return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m); - }, - pseudo: function(m) { - if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); - return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); - }, - descendant: 'c = "descendant";', - child: 'c = "child";', - adjacent: 'c = "adjacent";', - laterSibling: 'c = "laterSibling";' - }, - - patterns: { - // combinators must be listed first - // (and descendant needs to be last combinator) - laterSibling: /^\s*~\s*/, - child: /^\s*>\s*/, - adjacent: /^\s*\+\s*/, - descendant: /^\s/, - - // selectors follow - tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, - id: /^#([\w\-\*]+)(\b|$)/, - className: /^\.([\w\-\*]+)(\b|$)/, - pseudo: -/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/, - attrPresence: /^\[([\w]+)\]/, - attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ - }, - - // for Selector.match and Element#match - assertions: { - tagName: function(element, matches) { - return matches[1].toUpperCase() == element.tagName.toUpperCase(); - }, - - className: function(element, matches) { - return Element.hasClassName(element, matches[1]); - }, - - id: function(element, matches) { - return element.id === matches[1]; - }, - - attrPresence: function(element, matches) { - return Element.hasAttribute(element, matches[1]); - }, - - attr: function(element, matches) { - var nodeValue = Element.readAttribute(element, matches[1]); - return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]); - } - }, - - handlers: { - // UTILITY FUNCTIONS - // joins two collections - concat: function(a, b) { - for (var i = 0, node; node = b[i]; i++) - a.push(node); - return a; - }, - - // marks an array of nodes for counting - mark: function(nodes) { - var _true = Prototype.emptyFunction; - for (var i = 0, node; node = nodes[i]; i++) - node._countedByPrototype = _true; - return nodes; - }, - - unmark: function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node._countedByPrototype = undefined; - return nodes; - }, - - // mark each child node with its position (for nth calls) - // "ofType" flag indicates whether we're indexing for nth-of-type - // rather than nth-child - index: function(parentNode, reverse, ofType) { - parentNode._countedByPrototype = Prototype.emptyFunction; - if (reverse) { - for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { - var node = nodes[i]; - if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; - } - } else { - for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) - if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; - } - }, - - // filters out duplicates and extends all nodes - unique: function(nodes) { - if (nodes.length == 0) return nodes; - var results = [], n; - for (var i = 0, l = nodes.length; i < l; i++) - if (!(n = nodes[i])._countedByPrototype) { - n._countedByPrototype = Prototype.emptyFunction; - results.push(Element.extend(n)); - } - return Selector.handlers.unmark(results); - }, - - // COMBINATOR FUNCTIONS - descendant: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - h.concat(results, node.getElementsByTagName('*')); - return results; - }, - - child: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) { - for (var j = 0, child; child = node.childNodes[j]; j++) - if (child.nodeType == 1 && child.tagName != '!') results.push(child); - } - return results; - }, - - adjacent: function(nodes) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - var next = this.nextElementSibling(node); - if (next) results.push(next); - } - return results; - }, - - laterSibling: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - h.concat(results, Element.nextSiblings(node)); - return results; - }, - - nextElementSibling: function(node) { - while (node = node.nextSibling) - if (node.nodeType == 1) return node; - return null; - }, - - previousElementSibling: function(node) { - while (node = node.previousSibling) - if (node.nodeType == 1) return node; - return null; - }, - - // TOKEN FUNCTIONS - tagName: function(nodes, root, tagName, combinator) { - var uTagName = tagName.toUpperCase(); - var results = [], h = Selector.handlers; - if (nodes) { - if (combinator) { - // fastlane for ordinary descendant combinators - if (combinator == "descendant") { - for (var i = 0, node; node = nodes[i]; i++) - h.concat(results, node.getElementsByTagName(tagName)); - return results; - } else nodes = this[combinator](nodes); - if (tagName == "*") return nodes; - } - for (var i = 0, node; node = nodes[i]; i++) - if (node.tagName.toUpperCase() === uTagName) results.push(node); - return results; - } else return root.getElementsByTagName(tagName); - }, - - id: function(nodes, root, id, combinator) { - var targetNode = $(id), h = Selector.handlers; - if (!targetNode) return []; - if (!nodes && root == document) return [targetNode]; - if (nodes) { - if (combinator) { - if (combinator == 'child') { - for (var i = 0, node; node = nodes[i]; i++) - if (targetNode.parentNode == node) return [targetNode]; - } else if (combinator == 'descendant') { - for (var i = 0, node; node = nodes[i]; i++) - if (Element.descendantOf(targetNode, node)) return [targetNode]; - } else if (combinator == 'adjacent') { - for (var i = 0, node; node = nodes[i]; i++) - if (Selector.handlers.previousElementSibling(targetNode) == node) - return [targetNode]; - } else nodes = h[combinator](nodes); - } - for (var i = 0, node; node = nodes[i]; i++) - if (node == targetNode) return [targetNode]; - return []; - } - return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; - }, - - className: function(nodes, root, className, combinator) { - if (nodes && combinator) nodes = this[combinator](nodes); - return Selector.handlers.byClassName(nodes, root, className); - }, - - byClassName: function(nodes, root, className) { - if (!nodes) nodes = Selector.handlers.descendant([root]); - var needle = ' ' + className + ' '; - for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { - nodeClassName = node.className; - if (nodeClassName.length == 0) continue; - if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) - results.push(node); - } - return results; - }, - - attrPresence: function(nodes, root, attr, combinator) { - if (!nodes) nodes = root.getElementsByTagName("*"); - if (nodes && combinator) nodes = this[combinator](nodes); - var results = []; - for (var i = 0, node; node = nodes[i]; i++) - if (Element.hasAttribute(node, attr)) results.push(node); - return results; - }, - - attr: function(nodes, root, attr, value, operator, combinator) { - if (!nodes) nodes = root.getElementsByTagName("*"); - if (nodes && combinator) nodes = this[combinator](nodes); - var handler = Selector.operators[operator], results = []; - for (var i = 0, node; node = nodes[i]; i++) { - var nodeValue = Element.readAttribute(node, attr); - if (nodeValue === null) continue; - if (handler(nodeValue, value)) results.push(node); - } - return results; - }, - - pseudo: function(nodes, name, value, root, combinator) { - if (nodes && combinator) nodes = this[combinator](nodes); - if (!nodes) nodes = root.getElementsByTagName("*"); - return Selector.pseudos[name](nodes, value, root); - } - }, - - pseudos: { - 'first-child': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - if (Selector.handlers.previousElementSibling(node)) continue; - results.push(node); - } - return results; - }, - 'last-child': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - if (Selector.handlers.nextElementSibling(node)) continue; - results.push(node); - } - return results; - }, - 'only-child': function(nodes, value, root) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) - results.push(node); - return results; - }, - 'nth-child': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root); - }, - 'nth-last-child': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, true); - }, - 'nth-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, false, true); - }, - 'nth-last-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, true, true); - }, - 'first-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, "1", root, false, true); - }, - 'last-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, "1", root, true, true); - }, - 'only-of-type': function(nodes, formula, root) { - var p = Selector.pseudos; - return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); - }, - - // handles the an+b logic - getIndices: function(a, b, total) { - if (a == 0) return b > 0 ? [b] : []; - return $R(1, total).inject([], function(memo, i) { - if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); - return memo; - }); - }, - - // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type - nth: function(nodes, formula, root, reverse, ofType) { - if (nodes.length == 0) return []; - if (formula == 'even') formula = '2n+0'; - if (formula == 'odd') formula = '2n+1'; - var h = Selector.handlers, results = [], indexed = [], m; - h.mark(nodes); - for (var i = 0, node; node = nodes[i]; i++) { - if (!node.parentNode._countedByPrototype) { - h.index(node.parentNode, reverse, ofType); - indexed.push(node.parentNode); - } - } - if (formula.match(/^\d+$/)) { // just a number - formula = Number(formula); - for (var i = 0, node; node = nodes[i]; i++) - if (node.nodeIndex == formula) results.push(node); - } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b - if (m[1] == "-") m[1] = -1; - var a = m[1] ? Number(m[1]) : 1; - var b = m[2] ? Number(m[2]) : 0; - var indices = Selector.pseudos.getIndices(a, b, nodes.length); - for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { - for (var j = 0; j < l; j++) - if (node.nodeIndex == indices[j]) results.push(node); - } - } - h.unmark(nodes); - h.unmark(indexed); - return results; - }, - - 'empty': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - // IE treats comments as element nodes - if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; - results.push(node); - } - return results; - }, - - 'not': function(nodes, selector, root) { - var h = Selector.handlers, selectorType, m; - var exclusions = new Selector(selector).findElements(root); - h.mark(exclusions); - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!node._countedByPrototype) results.push(node); - h.unmark(exclusions); - return results; - }, - - 'enabled': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!node.disabled) results.push(node); - return results; - }, - - 'disabled': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (node.disabled) results.push(node); - return results; - }, - - 'checked': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (node.checked) results.push(node); - return results; - } - }, - - operators: { - '=': function(nv, v) { return nv == v; }, - '!=': function(nv, v) { return nv != v; }, - '^=': function(nv, v) { return nv.startsWith(v); }, - '$=': function(nv, v) { return nv.endsWith(v); }, - '*=': function(nv, v) { return nv.include(v); }, - '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, - '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } - }, - - split: function(expression) { - var expressions = []; - expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { - expressions.push(m[1].strip()); - }); - return expressions; - }, - - matchElements: function(elements, expression) { - var matches = $$(expression), h = Selector.handlers; - h.mark(matches); - for (var i = 0, results = [], element; element = elements[i]; i++) - if (element._countedByPrototype) results.push(element); - h.unmark(matches); - return results; - }, - - findElement: function(elements, expression, index) { - if (Object.isNumber(expression)) { - index = expression; expression = false; - } - return Selector.matchElements(elements, expression || '*')[index || 0]; - }, - - findChildElements: function(element, expressions) { - expressions = Selector.split(expressions.join(',')); - var results = [], h = Selector.handlers; - for (var i = 0, l = expressions.length, selector; i < l; i++) { - selector = new Selector(expressions[i].strip()); - h.concat(results, selector.findElements(element)); - } - return (l > 1) ? h.unique(results) : results; - } -}); - -if (Prototype.Browser.IE) { - Object.extend(Selector.handlers, { - // IE returns comment nodes on getElementsByTagName("*"). - // Filter them out. - concat: function(a, b) { - for (var i = 0, node; node = b[i]; i++) - if (node.tagName !== "!") a.push(node); - return a; - }, - - // IE improperly serializes _countedByPrototype in (inner|outer)HTML. - unmark: function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node.removeAttribute('_countedByPrototype'); - return nodes; - } - }); -} - -function $$() { - return Selector.findChildElements(document, $A(arguments)); -} -var Form = { - reset: function(form) { - $(form).reset(); - return form; - }, - - serializeElements: function(elements, options) { - if (typeof options != 'object') options = { hash: !!options }; - else if (Object.isUndefined(options.hash)) options.hash = true; - var key, value, submitted = false, submit = options.submit; - - var data = elements.inject({ }, function(result, element) { - if (!element.disabled && element.name) { - key = element.name; value = $(element).getValue(); - if (value != null && (element.type != 'submit' || (!submitted && - submit !== false && (!submit || key == submit) && (submitted = true)))) { - if (key in result) { - // a key is already present; construct an array of values - if (!Object.isArray(result[key])) result[key] = [result[key]]; - result[key].push(value); - } - else result[key] = value; - } - } - return result; - }); - - return options.hash ? data : Object.toQueryString(data); - } -}; - -Form.Methods = { - serialize: function(form, options) { - return Form.serializeElements(Form.getElements(form), options); - }, - - getElements: function(form) { - return $A($(form).getElementsByTagName('*')).inject([], - function(elements, child) { - if (Form.Element.Serializers[child.tagName.toLowerCase()]) - elements.push(Element.extend(child)); - return elements; - } - ); - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) return $A(inputs).map(Element.extend); - - for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || (name && input.name != name)) - continue; - matchingInputs.push(Element.extend(input)); - } - - return matchingInputs; - }, - - disable: function(form) { - form = $(form); - Form.getElements(form).invoke('disable'); - return form; - }, - - enable: function(form) { - form = $(form); - Form.getElements(form).invoke('enable'); - return form; - }, - - findFirstElement: function(form) { - var elements = $(form).getElements().findAll(function(element) { - return 'hidden' != element.type && !element.disabled; - }); - var firstByIndex = elements.findAll(function(element) { - return element.hasAttribute('tabIndex') && element.tabIndex >= 0; - }).sortBy(function(element) { return element.tabIndex }).first(); - - return firstByIndex ? firstByIndex : elements.find(function(element) { - return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); - }); - }, - - focusFirstElement: function(form) { - form = $(form); - form.findFirstElement().activate(); - return form; - }, - - request: function(form, options) { - form = $(form), options = Object.clone(options || { }); - - var params = options.parameters, action = form.readAttribute('action') || ''; - if (action.blank()) action = window.location.href; - options.parameters = form.serialize(true); - - if (params) { - if (Object.isString(params)) params = params.toQueryParams(); - Object.extend(options.parameters, params); - } - - if (form.hasAttribute('method') && !options.method) - options.method = form.method; - - return new Ajax.Request(action, options); - } -}; - -/*--------------------------------------------------------------------------*/ - -Form.Element = { - focus: function(element) { - $(element).focus(); - return element; - }, - - select: function(element) { - $(element).select(); - return element; - } -}; - -Form.Element.Methods = { - serialize: function(element) { - element = $(element); - if (!element.disabled && element.name) { - var value = element.getValue(); - if (value != undefined) { - var pair = { }; - pair[element.name] = value; - return Object.toQueryString(pair); - } - } - return ''; - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - return Form.Element.Serializers[method](element); - }, - - setValue: function(element, value) { - element = $(element); - var method = element.tagName.toLowerCase(); - Form.Element.Serializers[method](element, value); - return element; - }, - - clear: function(element) { - $(element).value = ''; - return element; - }, - - present: function(element) { - return $(element).value != ''; - }, - - activate: function(element) { - element = $(element); - try { - element.focus(); - if (element.select && (element.tagName.toLowerCase() != 'input' || - !['button', 'reset', 'submit'].include(element.type))) - element.select(); - } catch (e) { } - return element; - }, - - disable: function(element) { - element = $(element); - element.blur(); - element.disabled = true; - return element; - }, - - enable: function(element) { - element = $(element); - element.disabled = false; - return element; - } -}; - -/*--------------------------------------------------------------------------*/ - -var Field = Form.Element; -var $F = Form.Element.Methods.getValue; - -/*--------------------------------------------------------------------------*/ - -Form.Element.Serializers = { - input: function(element, value) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element, value); - default: - return Form.Element.Serializers.textarea(element, value); - } - }, - - inputSelector: function(element, value) { - if (Object.isUndefined(value)) return element.checked ? element.value : null; - else element.checked = !!value; - }, - - textarea: function(element, value) { - if (Object.isUndefined(value)) return element.value; - else element.value = value; - }, - - select: function(element, index) { - if (Object.isUndefined(index)) - return this[element.type == 'select-one' ? - 'selectOne' : 'selectMany'](element); - else { - var opt, value, single = !Object.isArray(index); - for (var i = 0, length = element.length; i < length; i++) { - opt = element.options[i]; - value = this.optionValue(opt); - if (single) { - if (value == index) { - opt.selected = true; - return; - } - } - else opt.selected = index.include(value); - } - } - }, - - selectOne: function(element) { - var index = element.selectedIndex; - return index >= 0 ? this.optionValue(element.options[index]) : null; - }, - - selectMany: function(element) { - var values, length = element.length; - if (!length) return null; - - for (var i = 0, values = []; i < length; i++) { - var opt = element.options[i]; - if (opt.selected) values.push(this.optionValue(opt)); - } - return values; - }, - - optionValue: function(opt) { - // extend element because hasAttribute may not be native - return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; - } -}; - -/*--------------------------------------------------------------------------*/ - -Abstract.TimedObserver = Class.create(PeriodicalExecuter, { - initialize: function($super, element, frequency, callback) { - $super(callback, frequency); - this.element = $(element); - this.lastValue = this.getValue(); - }, - - execute: function() { - var value = this.getValue(); - if (Object.isString(this.lastValue) && Object.isString(value) ? - this.lastValue != value : String(this.lastValue) != String(value)) { - this.callback(this.element, value); - this.lastValue = value; - } - } -}); - -Form.Element.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = Class.create({ - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - if (this.element.tagName.toLowerCase() == 'form') - this.registerFormCallbacks(); - else - this.registerCallback(this.element); - }, - - onElementEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - }, - - registerFormCallbacks: function() { - Form.getElements(this.element).each(this.registerCallback, this); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - default: - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -}); - -Form.Element.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); -if (!window.Event) var Event = { }; - -Object.extend(Event, { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - KEY_HOME: 36, - KEY_END: 35, - KEY_PAGEUP: 33, - KEY_PAGEDOWN: 34, - KEY_INSERT: 45, - - cache: { }, - - relatedTarget: function(event) { - var element; - switch(event.type) { - case 'mouseover': element = event.fromElement; break; - case 'mouseout': element = event.toElement; break; - default: return null; - } - return Element.extend(element); - } -}); - -Event.Methods = (function() { - var isButton; - - if (Prototype.Browser.IE) { - var buttonMap = { 0: 1, 1: 4, 2: 2 }; - isButton = function(event, code) { - return event.button == buttonMap[code]; - }; - - } else if (Prototype.Browser.WebKit) { - isButton = function(event, code) { - switch (code) { - case 0: return event.which == 1 && !event.metaKey; - case 1: return event.which == 1 && event.metaKey; - default: return false; - } - }; - - } else { - isButton = function(event, code) { - return event.which ? (event.which === code + 1) : (event.button === code); - }; - } - - return { - isLeftClick: function(event) { return isButton(event, 0) }, - isMiddleClick: function(event) { return isButton(event, 1) }, - isRightClick: function(event) { return isButton(event, 2) }, - - element: function(event) { - var node = Event.extend(event).target; - return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node); - }, - - findElement: function(event, expression) { - var element = Event.element(event); - if (!expression) return element; - var elements = [element].concat(element.ancestors()); - return Selector.findElement(elements, expression, 0); - }, - - pointer: function(event) { - return { - x: event.pageX || (event.clientX + - (document.documentElement.scrollLeft || document.body.scrollLeft)), - y: event.pageY || (event.clientY + - (document.documentElement.scrollTop || document.body.scrollTop)) - }; - }, - - pointerX: function(event) { return Event.pointer(event).x }, - pointerY: function(event) { return Event.pointer(event).y }, - - stop: function(event) { - Event.extend(event); - event.preventDefault(); - event.stopPropagation(); - event.stopped = true; - } - }; -})(); - -Event.extend = (function() { - var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { - m[name] = Event.Methods[name].methodize(); - return m; - }); - - if (Prototype.Browser.IE) { - Object.extend(methods, { - stopPropagation: function() { this.cancelBubble = true }, - preventDefault: function() { this.returnValue = false }, - inspect: function() { return "[object Event]" } - }); - - return function(event) { - if (!event) return false; - if (event._extendedByPrototype) return event; - - event._extendedByPrototype = Prototype.emptyFunction; - var pointer = Event.pointer(event); - Object.extend(event, { - target: event.srcElement, - relatedTarget: Event.relatedTarget(event), - pageX: pointer.x, - pageY: pointer.y - }); - return Object.extend(event, methods); - }; - - } else { - Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__; - Object.extend(Event.prototype, methods); - return Prototype.K; - } -})(); - -Object.extend(Event, (function() { - var cache = Event.cache; - - function getEventID(element) { - if (element._prototypeEventID) return element._prototypeEventID[0]; - arguments.callee.id = arguments.callee.id || 1; - return element._prototypeEventID = [++arguments.callee.id]; - } - - function getDOMEventName(eventName) { - if (eventName && eventName.include(':')) return "dataavailable"; - return eventName; - } - - function getCacheForID(id) { - return cache[id] = cache[id] || { }; - } - - function getWrappersForEventName(id, eventName) { - var c = getCacheForID(id); - return c[eventName] = c[eventName] || []; - } - - function createWrapper(element, eventName, handler) { - var id = getEventID(element); - var c = getWrappersForEventName(id, eventName); - if (c.pluck("handler").include(handler)) return false; - - var wrapper = function(event) { - if (!Event || !Event.extend || - (event.eventName && event.eventName != eventName)) - return false; - - Event.extend(event); - handler.call(element, event); - }; - - wrapper.handler = handler; - c.push(wrapper); - return wrapper; - } - - function findWrapper(id, eventName, handler) { - var c = getWrappersForEventName(id, eventName); - return c.find(function(wrapper) { return wrapper.handler == handler }); - } - - function destroyWrapper(id, eventName, handler) { - var c = getCacheForID(id); - if (!c[eventName]) return false; - c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); - } - - function destroyCache() { - for (var id in cache) - for (var eventName in cache[id]) - cache[id][eventName] = null; - } - - if (window.attachEvent) { - window.attachEvent("onunload", destroyCache); - } - - return { - observe: function(element, eventName, handler) { - element = $(element); - var name = getDOMEventName(eventName); - - var wrapper = createWrapper(element, eventName, handler); - if (!wrapper) return element; - - if (element.addEventListener) { - element.addEventListener(name, wrapper, false); - } else { - element.attachEvent("on" + name, wrapper); - } - - return element; - }, - - stopObserving: function(element, eventName, handler) { - element = $(element); - var id = getEventID(element), name = getDOMEventName(eventName); - - if (!handler && eventName) { - getWrappersForEventName(id, eventName).each(function(wrapper) { - element.stopObserving(eventName, wrapper.handler); - }); - return element; - - } else if (!eventName) { - Object.keys(getCacheForID(id)).each(function(eventName) { - element.stopObserving(eventName); - }); - return element; - } - - var wrapper = findWrapper(id, eventName, handler); - if (!wrapper) return element; - - if (element.removeEventListener) { - element.removeEventListener(name, wrapper, false); - } else { - element.detachEvent("on" + name, wrapper); - } - - destroyWrapper(id, eventName, handler); - - return element; - }, - - fire: function(element, eventName, memo) { - element = $(element); - if (element == document && document.createEvent && !element.dispatchEvent) - element = document.documentElement; - - var event; - if (document.createEvent) { - event = document.createEvent("HTMLEvents"); - event.initEvent("dataavailable", true, true); - } else { - event = document.createEventObject(); - event.eventType = "ondataavailable"; - } - - event.eventName = eventName; - event.memo = memo || { }; - - if (document.createEvent) { - element.dispatchEvent(event); - } else { - element.fireEvent(event.eventType, event); - } - - return Event.extend(event); - } - }; -})()); - -Object.extend(Event, Event.Methods); - -Element.addMethods({ - fire: Event.fire, - observe: Event.observe, - stopObserving: Event.stopObserving -}); - -Object.extend(document, { - fire: Element.Methods.fire.methodize(), - observe: Element.Methods.observe.methodize(), - stopObserving: Element.Methods.stopObserving.methodize(), - loaded: false -}); - -(function() { - /* Support for the DOMContentLoaded event is based on work by Dan Webb, - Matthias Miller, Dean Edwards and John Resig. */ - - var timer; - - function fireContentLoadedEvent() { - if (document.loaded) return; - if (timer) window.clearInterval(timer); - document.fire("dom:loaded"); - document.loaded = true; - } - - if (document.addEventListener) { - if (Prototype.Browser.WebKit) { - timer = window.setInterval(function() { - if (/loaded|complete/.test(document.readyState)) - fireContentLoadedEvent(); - }, 0); - - Event.observe(window, "load", fireContentLoadedEvent); - - } else { - document.addEventListener("DOMContentLoaded", - fireContentLoadedEvent, false); - } - - } else { - document.write("' ); - - iframe_doc.close(); - - // Update the Iframe's hash, for great justice. - iframe.location.hash = hash; - } - }; - - })(); - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - // ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^ - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - return self; - })(); - -})(jQuery,this); -/* -* jQuery Mobile Framework : "page" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { - -$.widget( "mobile.page", $.mobile.widget, { - options: { - backBtnText: "Back", - addBackBtn: false, - backBtnTheme: null, - degradeInputs: { - color: false, - date: false, - datetime: false, - "datetime-local": false, - email: false, - month: false, - number: false, - range: "number", - search: true, - tel: false, - time: false, - url: false, - week: false - }, - keepNative: null - }, - - _create: function() { - var $elem = this.element, - o = this.options; - - this.keepNative = ":jqmData(role='none'), :jqmData(role='nojs')" + (o.keepNative ? ", " + o.keepNative : ""); - - if ( this._trigger( "beforeCreate" ) === false ) { - return; - } - - //some of the form elements currently rely on the presence of ui-page and ui-content - // classes so we'll handle page and content roles outside of the main role processing - // loop below. - $elem.find( ":jqmData(role='page'), :jqmData(role='content')" ).andSelf().each(function() { - $(this).addClass( "ui-" + $(this).jqmData( "role" ) ); - }); - - $elem.find( ":jqmData(role='nojs')" ).addClass( "ui-nojs" ); - - // pre-find data els - var $dataEls = $elem.find( ":jqmData(role)" ).andSelf().each(function() { - var $this = $( this ), - role = $this.jqmData( "role" ), - theme = $this.jqmData( "theme" ); - - //apply theming and markup modifications to page,header,content,footer - if ( role === "header" || role === "footer" ) { - $this.addClass( "ui-bar-" + (theme || $this.parent( ":jqmData(role='page')" ).jqmData( "theme" ) || "a") ); - - // add ARIA role - $this.attr( "role", role === "header" ? "banner" : "contentinfo" ); - - //right,left buttons - var $headeranchors = $this.children( "a" ), - leftbtn = $headeranchors.hasClass( "ui-btn-left" ), - rightbtn = $headeranchors.hasClass( "ui-btn-right" ); - - if ( !leftbtn ) { - leftbtn = $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length; - } - - if ( !rightbtn ) { - rightbtn = $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length; - } - - // auto-add back btn on pages beyond first view - if ( o.addBackBtn && role === "header" && - $( ".ui-page" ).length > 1 && - $elem.jqmData( "url" ) !== $.mobile.path.stripHash( location.hash ) && - !leftbtn && $this.jqmData( "backbtn" ) !== false ) { - - var backBtn = $( ""+ o.backBtnText +"" ).prependTo( $this ); - - //if theme is provided, override default inheritance - if( o.backBtnTheme ){ - backBtn.attr( "data-"+ $.mobile.ns +"theme", o.backBtnTheme ); - } - } - - //page title - $this.children( "h1, h2, h3, h4, h5, h6" ) - .addClass( "ui-title" ) - //regardless of h element number in src, it becomes h1 for the enhanced page - .attr({ "tabindex": "0", "role": "heading", "aria-level": "1" }); - - } else if ( role === "content" ) { - if ( theme ) { - $this.addClass( "ui-body-" + theme ); - } - - // add ARIA role - $this.attr( "role", "main" ); - - } else if ( role === "page" ) { - $this.addClass( "ui-body-" + (theme || "c") ); - } - - switch(role) { - case "header": - case "footer": - case "page": - case "content": - $this.addClass( "ui-" + role ); - break; - case "collapsible": - case "fieldcontain": - case "navbar": - case "listview": - case "dialog": - $this[ role ](); - break; - } - }); - - //enhance form controls - this._enhanceControls(); - - //links in bars, or those with data-role become buttons - $elem.find( ":jqmData(role='button'), .ui-bar > a, .ui-header > a, .ui-footer > a" ) - .not( ".ui-btn" ) - .not(this.keepNative) - .buttonMarkup(); - - $elem - .find(":jqmData(role='controlgroup')") - .controlgroup(); - - //links within content areas - $elem.find( "a:not(.ui-btn):not(.ui-link-inherit)" ) - .not(this.keepNative) - .addClass( "ui-link" ); - - //fix toolbars - $elem.fixHeaderFooter(); - }, - - _typeAttributeRegex: /\s+type=["']?\w+['"]?/, - - _enhanceControls: function() { - var o = this.options, self = this; - - // degrade inputs to avoid poorly implemented native functionality - this.element.find( "input" ).not(this.keepNative).each(function() { - var type = this.getAttribute( "type" ), - optType = o.degradeInputs[ type ] || "text"; - - if ( o.degradeInputs[ type ] ) { - $( this ).replaceWith( - $( "
" ).html( $(this).clone() ).html() - .replace( self._typeAttributeRegex, " type=\""+ optType +"\" data-" + $.mobile.ns + "type=\""+type+"\" " ) ); - } - }); - - // We re-find form elements since the degredation code above - // may have injected new elements. We cache the non-native control - // query to reduce the number of times we search through the entire page. - - var allControls = this.element.find("input, textarea, select, button"), - nonNativeControls = allControls.not(this.keepNative); - - // XXX: Temporary workaround for issue 785. Turn off autocorrect and - // autocomplete since the popup they use can't be dismissed by - // the user. Note that we test for the presence of the feature - // by looking for the autocorrect property on the input element. - - var textInputs = allControls.filter( "input[type=text]" ); - if (textInputs.length && typeof textInputs[0].autocorrect !== "undefined") { - textInputs.each(function(){ - // Set the attribute instead of the property just in case there - // is code that attempts to make modifications via HTML. - this.setAttribute("autocorrect", "off"); - this.setAttribute("autocomplete", "off"); - }); - } - - // enchance form controls - nonNativeControls - .filter( "[type='radio'], [type='checkbox']" ) - .checkboxradio(); - - nonNativeControls - .filter( "button, [type='button'], [type='submit'], [type='reset'], [type='image']" ) - .button(); - - nonNativeControls - .filter( "input, textarea" ) - .not( "[type='radio'], [type='checkbox'], [type='button'], [type='submit'], [type='reset'], [type='image'], [type='hidden']" ) - .textinput(); - - nonNativeControls - .filter( "input, select" ) - .filter( ":jqmData(role='slider'), :jqmData(type='range')" ) - .slider(); - - nonNativeControls - .filter( "select:not(:jqmData(role='slider'))" ) - .selectmenu(); - } -}); - -})( jQuery ); -/*! - * jQuery Mobile v@VERSION - * http://jquerymobile.com/ - * - * Copyright 2010, jQuery Project - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - */ - -(function( $, window, undefined ) { - - //jQuery.mobile configurable options - $.extend( $.mobile, { - - //namespace used framework-wide for data-attrs. Default is no namespace - ns: "", - - //define the url parameter used for referencing widget-generated sub-pages. - //Translates to to example.html&ui-page=subpageIdentifier - //hash segment before &ui-page= is used to make Ajax request - subPageUrlKey: "ui-page", - - //anchor links with a data-rel, or pages with a data-role, that match these selectors will be untrackable in history - //(no change in URL, not bookmarkable) - nonHistorySelectors: "dialog", - - //class assigned to page currently in view, and during transitions - activePageClass: "ui-page-active", - - //class used for "active" button state, from CSS framework - activeBtnClass: "ui-btn-active", - - //automatically handle clicks and form submissions through Ajax, when same-domain - ajaxEnabled: true, - - //When enabled, clicks and taps that result in Ajax page changes will happen slightly sooner on touch devices. - //Also, it will prevent the address bar from appearing on platforms like iOS during page transitions. - //This option has no effect on non-touch devices, but enabling it may interfere with jQuery plugins that bind to click events - useFastClick: true, - - //automatically load and show pages based on location.hash - hashListeningEnabled: true, - - //set default page transition - 'none' for no transitions - defaultPageTransition: "slide", - - //minimum scroll distance that will be remembered when returning to a page - minScrollBack: screen.height / 2, - - //set default dialog transition - 'none' for no transitions - defaultDialogTransition: "pop", - - //show loading message during Ajax requests - //if false, message will not appear, but loading classes will still be toggled on html el - loadingMessage: "loading", - - //error response message - appears when an Ajax page request fails - pageLoadErrorMessage: "Error Loading Page", - - //support conditions that must be met in order to proceed - //default enhanced qualifications are media query support OR IE 7+ - gradeA: function(){ - return $.support.mediaquery || $.mobile.browser.ie && $.mobile.browser.ie >= 7; - }, - - //TODO might be useful upstream in jquery itself ? - keyCode: { - ALT: 18, - BACKSPACE: 8, - CAPS_LOCK: 20, - COMMA: 188, - COMMAND: 91, - COMMAND_LEFT: 91, // COMMAND - COMMAND_RIGHT: 93, - CONTROL: 17, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - INSERT: 45, - LEFT: 37, - MENU: 93, // COMMAND_RIGHT - 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 // COMMAND - }, - - //scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value - silentScroll: function( ypos ) { - if( $.type( ypos ) !== "number" ){ - ypos = $.mobile.defaultHomeScroll; - } - - // prevent scrollstart and scrollstop events - $.event.special.scrollstart.enabled = false; - - setTimeout(function() { - window.scrollTo( 0, ypos ); - $(document).trigger( "silentscroll", { x: 0, y: ypos }); - },20); - - setTimeout(function() { - $.event.special.scrollstart.enabled = true; - }, 150 ); - }, - - // compile the namespace normalization regex once - normalizeRegex: /-([a-z])/g, - - // take a data attribute property, prepend the namespace - // and then camel case the attribute string - nsNormalize: function(prop){ - if(!prop) return; - - return $.camelCase( $.mobile.ns + prop ); - } - }); - - //mobile version of data and removeData and hasData methods - //ensures all data is set and retrieved using jQuery Mobile's data namespace - $.fn.jqmData = function( prop, value ){ - return this.data( prop ? $.mobile.nsNormalize(prop) : prop, value ); - }; - - $.jqmData = function( elem, prop, value ){ - return $.data( elem, $.mobile.nsNormalize(prop), value ); - }; - - $.fn.jqmRemoveData = function( prop ){ - return this.removeData( $.mobile.nsNormalize(prop) ); - }; - - $.jqmRemoveData = function( elem, prop ){ - return $.removeData( elem, $.mobile.nsNormalize(prop) ); - }; - - $.jqmHasData = function( elem, prop ){ - return $.hasData( elem, $.mobile.nsNormalize(prop) ); - }; - - // Monkey-patching Sizzle to filter the :jqmData selector - var oldFind = $.find; - - $.find = function( selector, context, ret, extra ) { - selector = selector.replace(/:jqmData\(([^)]*)\)/g, "[data-" + ($.mobile.ns || "") + "$1]"); - - return oldFind.call( this, selector, context, ret, extra ); - }; - - $.extend( $.find, oldFind ); - - $.find.matches = function( expr, set ) { - return $.find( expr, null, null, set ); - }; - - $.find.matchesSelector = function( node, expr ) { - return $.find( expr, null, null, [node] ).length > 0; - }; -})( jQuery, this ); -/* -* jQuery Mobile Framework : core utilities for auto ajax navigation, base tag mgmt, -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -( function( $, undefined ) { - - //define vars for interal use - var $window = $( window ), - $html = $( 'html' ), - $head = $( 'head' ), - - //url path helpers for use in relative url management - path = { - - // This scary looking regular expression parses an absolute URL or its relative - // variants (protocol, site, document, query, and hash), into the various - // components (protocol, host, path, query, fragment, etc that make up the - // URL as well as some other commonly used sub-parts. When used with RegExp.exec() - // or String.match, it parses the URL into a results array that looks like this: - // - // [0]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content - // [1]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread - // [2]: http://jblas:password@mycompany.com:8080/mail/inbox - // [3]: http://jblas:password@mycompany.com:8080 - // [4]: http: - // [5]: jblas:password@mycompany.com:8080 - // [6]: jblas:password - // [7]: jblas - // [8]: password - // [9]: mycompany.com:8080 - // [10]: mycompany.com - // [11]: 8080 - // [12]: /mail/inbox - // [13]: /mail/ - // [14]: inbox - // [15]: ?msg=1234&type=unread - // [16]: #msg-content - // - urlParseRE: /^(((([^:\/#\?]+:)?(?:\/\/((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?]+)(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/, - - //Parse a URL into a structure that allows easy access to - //all of the URL components by name. - parseUrl: function( url ) { - // If we're passed an object, we'll assume that it is - // a parsed url object and just return it back to the caller. - if ( typeof url === "object" ) { - return url; - } - - var u = url || "", - matches = path.urlParseRE.exec( url ), - results; - if ( matches ) { - // Create an object that allows the caller to access the sub-matches - // by name. Note that IE returns an empty string instead of undefined, - // like all other browsers do, so we normalize everything so its consistent - // no matter what browser we're running on. - results = { - href: matches[0] || "", - hrefNoHash: matches[1] || "", - hrefNoSearch: matches[2] || "", - domain: matches[3] || "", - protocol: matches[4] || "", - authority: matches[5] || "", - username: matches[7] || "", - password: matches[8] || "", - host: matches[9] || "", - hostname: matches[10] || "", - port: matches[11] || "", - pathname: matches[12] || "", - directory: matches[13] || "", - filename: matches[14] || "", - search: matches[15] || "", - hash: matches[16] || "" - }; - } - return results || {}; - }, - - //Turn relPath into an asbolute path. absPath is - //an optional absolute path which describes what - //relPath is relative to. - makePathAbsolute: function( relPath, absPath ) { - if ( relPath && relPath.charAt( 0 ) === "/" ) { - return relPath; - } - - relPath = relPath || ""; - absPath = absPath ? absPath.replace( /^\/|\/?[^\/]*$/g, "" ) : ""; - - var absStack = absPath ? absPath.split( "/" ) : [], - relStack = relPath.split( "/" ); - for ( var i = 0; i < relStack.length; i++ ) { - var d = relStack[ i ]; - switch ( d ) { - case ".": - break; - case "..": - if ( absStack.length ) { - absStack.pop(); - } - break; - default: - absStack.push( d ); - break; - } - } - return "/" + absStack.join( "/" ); - }, - - //Returns true if both urls have the same domain. - isSameDomain: function( absUrl1, absUrl2 ) { - return path.parseUrl( absUrl1 ).domain === path.parseUrl( absUrl2 ).domain; - }, - - //Returns true for any relative variant. - isRelativeUrl: function( url ) { - // All relative Url variants have one thing in common, no protocol. - return path.parseUrl( url ).protocol === ""; - }, - - //Returns true for an absolute url. - isAbsoluteUrl: function( url ) { - return path.parseUrl( url ).protocol !== ""; - }, - - //Turn the specified realtive URL into an absolute one. This function - //can handle all relative variants (protocol, site, document, query, fragment). - makeUrlAbsolute: function( relUrl, absUrl ) { - if ( !path.isRelativeUrl( relUrl ) ) { - return relUrl; - } - - var relObj = path.parseUrl( relUrl ), - absObj = path.parseUrl( absUrl ), - protocol = relObj.protocol || absObj.protocol, - authority = relObj.authority || absObj.authority, - hasPath = relObj.pathname !== "", - pathname = path.makePathAbsolute( relObj.pathname || absObj.filename, absObj.pathname ), - search = relObj.search || ( !hasPath && absObj.search ) || "", - hash = relObj.hash; - - return protocol + "//" + authority + pathname + search + hash; - }, - - //Add search (aka query) params to the specified url. - addSearchParams: function( url, params ) { - var u = path.parseUrl( url ), - p = ( typeof params === "object" ) ? $.param( params ) : params, - s = u.search || "?"; - return u.hrefNoSearch + s + ( s.charAt( s.length - 1 ) !== "?" ? "&" : "" ) + p + ( u.hash || "" ); - }, - - convertUrlToDataUrl: function( absUrl ) { - var u = path.parseUrl( absUrl ); - if ( path.isEmbeddedPage( u ) ) { - return u.hash.replace( /^#/, "" ); - } else if ( path.isSameDomain( u, documentBase ) ) { - return u.hrefNoHash.replace( documentBase.domain, "" ); - } - return absUrl; - }, - - //get path from current hash, or from a file path - get: function( newPath ) { - if( newPath === undefined ) { - newPath = location.hash; - } - return path.stripHash( newPath ).replace( /[^\/]*\.[^\/*]+$/, '' ); - }, - - //return the substring of a filepath before the sub-page key, for making a server request - getFilePath: function( path ) { - var splitkey = '&' + $.mobile.subPageUrlKey; - return path && path.split( splitkey )[0].split( dialogHashKey )[0]; - }, - - //set location hash to path - set: function( path ) { - location.hash = path; - }, - - //test if a given url (string) is a path - //NOTE might be exceptionally naive - isPath: function( url ) { - return ( /\// ).test( url ); - }, - - //return a url path with the window's location protocol/hostname/pathname removed - clean: function( url ) { - return url.replace( documentBase.domain, "" ); - }, - - //just return the url without an initial # - stripHash: function( url ) { - return url.replace( /^#/, "" ); - }, - - //remove the preceding hash, any query params, and dialog notations - cleanHash: function( hash ) { - return path.stripHash( hash.replace( /\?.*$/, "" ).replace( dialogHashKey, "" ) ); - }, - - //check whether a url is referencing the same domain, or an external domain or different protocol - //could be mailto, etc - isExternal: function( url ) { - var u = path.parseUrl( url ); - return u.protocol && u.domain !== documentUrl.domain ? true : false; - }, - - hasProtocol: function( url ) { - return ( /^(:?\w+:)/ ).test( url ); - }, - - isEmbeddedPage: function( url ) { - var u = path.parseUrl( url ); - - //if the path is absolute, then we need to compare the url against - //both the documentUrl and the documentBase. The main reason for this - //is that links embedded within external documents will refer to the - //application document, whereas links embedded within the application - //document will be resolved against the document base. - if ( u.protocol !== "" ) { - return ( u.hash && ( u.hrefNoHash === documentUrl.hrefNoHash || ( documentBaseDiffers && u.hrefNoHash === documentBase.hrefNoHash ) ) ); - } - return (/^#/).test( u.href ); - } - }, - - //will be defined when a link is clicked and given an active class - $activeClickedLink = null, - - //urlHistory is purely here to make guesses at whether the back or forward button was clicked - //and provide an appropriate transition - urlHistory = { - //array of pages that are visited during a single page load. each has a url and optional transition - stack: [], - - //maintain an index number for the active page in the stack - activeIndex: 0, - - //get active - getActive: function() { - return urlHistory.stack[ urlHistory.activeIndex ]; - }, - - getPrev: function() { - return urlHistory.stack[ urlHistory.activeIndex - 1 ]; - }, - - getNext: function() { - return urlHistory.stack[ urlHistory.activeIndex + 1 ]; - }, - - // addNew is used whenever a new page is added - addNew: function( url, transition, title, storedTo ) { - //if there's forward history, wipe it - if( urlHistory.getNext() ) { - urlHistory.clearForward(); - } - - urlHistory.stack.push( {url : url, transition: transition, title: title, page: storedTo } ); - - urlHistory.activeIndex = urlHistory.stack.length - 1; - }, - - //wipe urls ahead of active index - clearForward: function() { - urlHistory.stack = urlHistory.stack.slice( 0, urlHistory.activeIndex + 1 ); - }, - - directHashChange: function( opts ) { - var back , forward, newActiveIndex; - - // check if url isp in history and if it's ahead or behind current page - $.each( urlHistory.stack, function( i, historyEntry ) { - - //if the url is in the stack, it's a forward or a back - if( opts.currentUrl === historyEntry.url ) { - //define back and forward by whether url is older or newer than current page - back = i < urlHistory.activeIndex; - forward = !back; - newActiveIndex = i; - } - }); - - // save new page index, null check to prevent falsey 0 result - this.activeIndex = newActiveIndex !== undefined ? newActiveIndex : this.activeIndex; - - if( back ) { - opts.isBack(); - } else if( forward ) { - opts.isForward(); - } - }, - - //disable hashchange event listener internally to ignore one change - //toggled internally when location.hash is updated to match the url of a successful page load - ignoreNextHashChange: false - }, - - //define first selector to receive focus when a page is shown - focusable = "[tabindex],a,button:visible,select:visible,input", - - //queue to hold simultanious page transitions - pageTransitionQueue = [], - - //indicates whether or not page is in process of transitioning - isPageTransitioning = false, - - //nonsense hash change key for dialogs, so they create a history entry - dialogHashKey = "&ui-state=dialog", - - //existing base tag? - $base = $head.children( "base" ), - - //tuck away the original document URL minus any fragment. - documentUrl = path.parseUrl( location.href ), - - //if the document has an embedded base tag, documentBase is set to its - //initial value. If a base tag does not exist, then we default to the documentUrl. - documentBase = $base.length ? path.parseUrl( path.makeUrlAbsolute( $base.attr( "href" ), documentUrl.href ) ) : documentUrl, - - //cache the comparison once. - documentBaseDiffers = ( documentUrl.hrefNoHash !== documentBase.hrefNoHash ); - - //base element management, defined depending on dynamic base tag support - var base = $.support.dynamicBaseTag ? { - - //define base element, for use in routing asset urls that are referenced in Ajax-requested markup - element: ( $base.length ? $base : $( "", { href: documentBase.hrefNoHash } ).prependTo( $head ) ), - - //set the generated BASE element's href attribute to a new page's base path - set: function( href ) { - base.element.attr( "href", path.makeUrlAbsolute( href, documentBase ) ); - }, - - //set the generated BASE element's href attribute to a new page's base path - reset: function() { - base.element.attr( "href", documentBase.hrefNoHash ); - } - - } : undefined; - -/* - internal utility functions ---------------------------------------*/ - - - //direct focus to the page title, or otherwise first focusable element - function reFocus( page ) { - var lastClicked = page.jqmData( "lastClicked" ); - - if( lastClicked && lastClicked.length ) { - lastClicked.focus(); - } - else { - var pageTitle = page.find( ".ui-title:eq(0)" ); - - if( pageTitle.length ) { - pageTitle.focus(); - } - else{ - page.find( focusable ).eq( 0 ).focus(); - } - } - } - - //remove active classes after page transition or error - function removeActiveLinkClass( forceRemoval ) { - if( !!$activeClickedLink && ( !$activeClickedLink.closest( '.ui-page-active' ).length || forceRemoval ) ) { - $activeClickedLink.removeClass( $.mobile.activeBtnClass ); - } - $activeClickedLink = null; - } - - function releasePageTransitionLock() { - isPageTransitioning = false; - if( pageTransitionQueue.length > 0 ) { - $.mobile.changePage.apply( null, pageTransitionQueue.pop() ); - } - } - - //function for transitioning between two existing pages - function transitionPages( toPage, fromPage, transition, reverse ) { - - //get current scroll distance - var currScroll = $.support.scrollTop ? $window.scrollTop() : true, - toScroll = toPage.data( "lastScroll" ) || $.mobile.defaultHomeScroll, - screenHeight = getScreenHeight(); - - //if scrolled down, scroll to top - if( currScroll ){ - window.scrollTo( 0, $.mobile.defaultHomeScroll ); - } - - //if the Y location we're scrolling to is less than 10px, let it go for sake of smoothness - if( toScroll < $.mobile.minScrollBack ){ - toScroll = 0; - } - - if( fromPage ) { - //set as data for returning to that spot - fromPage - .height( screenHeight + currScroll ) - .jqmData( "lastScroll", currScroll ) - .jqmData( "lastClicked", $activeClickedLink ); - - //trigger before show/hide events - fromPage.data( "page" )._trigger( "beforehide", null, { nextPage: toPage } ); - } - toPage - .height( screenHeight + toScroll ) - .data( "page" )._trigger( "beforeshow", null, { prevPage: fromPage || $( "" ) } ); - - //clear page loader - $.mobile.hidePageLoadingMsg(); - - //find the transition handler for the specified transition. If there - //isn't one in our transitionHandlers dictionary, use the default one. - //call the handler immediately to kick-off the transition. - var th = $.mobile.transitionHandlers[transition || "none"] || $.mobile.defaultTransitionHandler, - promise = th( transition, reverse, toPage, fromPage ); - - promise.done(function() { - //reset toPage height bac - toPage.height( "" ); - - //jump to top or prev scroll, sometimes on iOS the page has not rendered yet. - if( toScroll ){ - $.mobile.silentScroll( toScroll ); - $( document ).one( "silentscroll", function() { reFocus( toPage ); } ); - } - else{ - reFocus( toPage ); - } - - //trigger show/hide events - if( fromPage ) { - fromPage.height("").data( "page" )._trigger( "hide", null, { nextPage: toPage } ); - } - - //trigger pageshow, define prevPage as either fromPage or empty jQuery obj - toPage.data( "page" )._trigger( "show", null, { prevPage: fromPage || $( "" ) } ); - }); - - return promise; - } - - //simply set the active page's minimum height to screen height, depending on orientation - function getScreenHeight(){ - var orientation = jQuery.event.special.orientationchange.orientation(), - port = orientation === "portrait", - winMin = port ? 480 : 320, - screenHeight = port ? screen.availHeight : screen.availWidth, - winHeight = Math.max( winMin, $( window ).height() ), - pageMin = Math.min( screenHeight, winHeight ); - - return pageMin; - } - - //simply set the active page's minimum height to screen height, depending on orientation - function resetActivePageHeight(){ - $( "." + $.mobile.activePageClass ).css( "min-height", getScreenHeight() ); - } - - //shared page enhancements - function enhancePage( $page, role ) { - // If a role was specified, make sure the data-role attribute - // on the page element is in sync. - if( role ) { - $page.attr( "data-" + $.mobile.ns + "role", role ); - } - - //run page plugin - $page.page(); - } - -/* exposed $.mobile methods */ - - //animation complete callback - $.fn.animationComplete = function( callback ) { - if( $.support.cssTransitions ) { - return $( this ).one( 'webkitAnimationEnd', callback ); - } - else{ - // defer execution for consistency between webkit/non webkit - setTimeout( callback, 0 ); - return $( this ); - } - }; - - //update location.hash, with or without triggering hashchange event - //TODO - deprecate this one at 1.0 - $.mobile.updateHash = path.set; - - //expose path object on $.mobile - $.mobile.path = path; - - //expose base object on $.mobile - $.mobile.base = base; - - //url stack, useful when plugins need to be aware of previous pages viewed - //TODO: deprecate this one at 1.0 - $.mobile.urlstack = urlHistory.stack; - - //history stack - $.mobile.urlHistory = urlHistory; - - //default non-animation transition handler - $.mobile.noneTransitionHandler = function( name, reverse, $toPage, $fromPage ) { - if ( $fromPage ) { - $fromPage.removeClass( $.mobile.activePageClass ); - } - $toPage.addClass( $.mobile.activePageClass ); - - return $.Deferred().resolve( name, reverse, $toPage, $fromPage ).promise(); - }; - - //default handler for unknown transitions - $.mobile.defaultTransitionHandler = $.mobile.noneTransitionHandler; - - //transition handler dictionary for 3rd party transitions - $.mobile.transitionHandlers = { - none: $.mobile.defaultTransitionHandler - }; - - //enable cross-domain page support - $.mobile.allowCrossDomainPages = false; - - //return the original document url - $.mobile.getDocumentUrl = function(asParsedObject) { - return asParsedObject ? $.extend( {}, documentUrl ) : documentUrl.href; - }; - - //return the original document base url - $.mobile.getDocumentBase = function(asParsedObject) { - return asParsedObject ? $.extend( {}, documentBase ) : documentBase.href; - }; - - // Load a page into the DOM. - $.mobile.loadPage = function( url, options ) { - // This function uses deferred notifications to let callers - // know when the page is done loading, or if an error has occurred. - var deferred = $.Deferred(), - - // The default loadPage options with overrides specified by - // the caller. - settings = $.extend( {}, $.mobile.loadPage.defaults, options ), - - // The DOM element for the page after it has been loaded. - page = null, - - // If the reloadPage option is true, and the page is already - // in the DOM, dupCachedPage will be set to the page element - // so that it can be removed after the new version of the - // page is loaded off the network. - dupCachedPage = null, - - // The absolute version of the URL passed into the function. This - // version of the URL may contain dialog/subpage params in it. - absUrl = path.makeUrlAbsolute( url, documentBase.hrefNoHash ); - - - // If the caller provided data, and we're using "get" request, - // append the data to the URL. - if ( settings.data && settings.type === "get" ) { - absUrl = path.addSearchParams( absUrl, settings.data ); - settings.data = undefined; - } - - // The absolute version of the URL minus any dialog/subpage params. - // In otherwords the real URL of the page to be loaded. - var fileUrl = path.getFilePath( absUrl ), - - // The version of the Url actually stored in the data-url attribute of - // the page. For embedded pages, it is just the id of the page. For pages - // within the same domain as the document base, it is the site relative - // path. For cross-domain pages (Phone Gap only) the entire absolute Url - // used to load the page. - dataUrl = path.convertUrlToDataUrl( absUrl ); - - // Make sure we have a pageContainer to work with. - settings.pageContainer = settings.pageContainer || $.mobile.pageContainer; - - // Check to see if the page already exists in the DOM. - page = settings.pageContainer.children( ":jqmData(url='" + dataUrl + "')" ); - - // Reset base to the default document base. - if ( base ) { - base.reset(); - } - - // If the page we are interested in is already in the DOM, - // and the caller did not indicate that we should force a - // reload of the file, we are done. Otherwise, track the - // existing page as a duplicated. - if ( page.length ) { - if ( !settings.reloadPage ) { - enhancePage( page, settings.role ); - deferred.resolve( absUrl, options, page ); - return deferred.promise(); - } - dupCachedPage = page; - } - - if ( settings.showLoadMsg ) { - $.mobile.showPageLoadingMsg(); - } - - // Load the new page. - $.ajax({ - url: fileUrl, - type: settings.type, - data: settings.data, - dataType: "html", - success: function( html ) { - //pre-parse html to check for a data-url, - //use it as the new fileUrl, base path, etc - var all = $( "
" ), - - //page title regexp - newPageTitle = html.match( /]*>([^<]*)/ ) && RegExp.$1, - - // TODO handle dialogs again - pageElemRegex = new RegExp( ".*(<[^>]+\\bdata-" + $.mobile.ns + "role=[\"']?page[\"']?[^>]*>).*" ), - dataUrlRegex = new RegExp( "\\bdata-" + $.mobile.ns + "url=[\"']?([^\"'>]*)[\"']?" ); - - - // data-url must be provided for the base tag so resource requests can be directed to the - // correct url. loading into a temprorary element makes these requests immediately - if( pageElemRegex.test( html ) - && RegExp.$1 - && dataUrlRegex.test( RegExp.$1 ) - && RegExp.$1 ) { - url = fileUrl = path.getFilePath( RegExp.$1 ); - } - - if ( base ) { - base.set( fileUrl ); - } - - //workaround to allow scripts to execute when included in page divs - all.get( 0 ).innerHTML = html; - page = all.find( ":jqmData(role='page'), :jqmData(role='dialog')" ).first(); - - if ( newPageTitle && !page.jqmData( "title" ) ) { - page.jqmData( "title", newPageTitle ); - } - - //rewrite src and href attrs to use a base url - if( !$.support.dynamicBaseTag ) { - var newPath = path.get( fileUrl ); - page.find( "[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]" ).each(function() { - var thisAttr = $( this ).is( '[href]' ) ? 'href' : - $(this).is('[src]') ? 'src' : 'action', - thisUrl = $( this ).attr( thisAttr ); - - // XXX_jblas: We need to fix this so that it removes the document - // base URL, and then prepends with the new page URL. - //if full path exists and is same, chop it - helps IE out - thisUrl = thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' ); - - if( !/^(\w+:|#|\/)/.test( thisUrl ) ) { - $( this ).attr( thisAttr, newPath + thisUrl ); - } - }); - } - - //append to page and enhance - page - .attr( "data-" + $.mobile.ns + "url", path.convertUrlToDataUrl( fileUrl ) ) - .appendTo( settings.pageContainer ); - - enhancePage( page, settings.role ); - - // Enhancing the page may result in new dialogs/sub pages being inserted - // into the DOM. If the original absUrl refers to a sub-page, that is the - // real page we are interested in. - if ( absUrl.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ) { - page = settings.pageContainer.children( ":jqmData(url='" + dataUrl + "')" ); - } - - // Remove loading message. - if ( settings.showLoadMsg ) { - $.mobile.hidePageLoadingMsg(); - } - - deferred.resolve( absUrl, options, page, dupCachedPage ); - }, - error: function() { - //set base back to current path - if( base ) { - base.set( path.get() ); - } - - // Remove loading message. - if ( settings.showLoadMsg ) { - $.mobile.hidePageLoadingMsg(); - - //show error message - $( "

"+ $.mobile.pageLoadErrorMessage +"

" ) - .css({ "display": "block", "opacity": 0.96, "top": $window.scrollTop() + 100 }) - .appendTo( settings.pageContainer ) - .delay( 800 ) - .fadeOut( 400, function() { - $( this ).remove(); - }); - } - - deferred.reject( absUrl, options ); - } - }); - - return deferred.promise(); - }; - - $.mobile.loadPage.defaults = { - type: "get", - data: undefined, - reloadPage: false, - role: undefined, // By default we rely on the role defined by the @data-role attribute. - showLoadMsg: true, - pageContainer: undefined - }; - - // Show a specific page in the page container. - $.mobile.changePage = function( toPage, options ) { - // XXX: REMOVE_BEFORE_SHIPPING_1.0 - // This is temporary code that makes changePage() compatible with previous alpha versions. - if ( typeof options !== "object" ) { - var opts = null; - - // Map old-style call signature for form submit to the new options object format. - if ( typeof toPage === "object" && toPage.url && toPage.type ) { - opts = { - type: toPage.type, - data: toPage.data, - forcePageLoad: true - }; - toPage = toPage.url; - } - - // The arguments passed into the function need to be re-mapped - // to the new options object format. - var len = arguments.length; - if ( len > 1 ) { - var argNames = [ "transition", "reverse", "changeHash", "fromHashChange" ], i; - for ( i = 1; i < len; i++ ) { - var a = arguments[ i ]; - if ( typeof a !== "undefined" ) { - opts = opts || {}; - opts[ argNames[ i - 1 ] ] = a; - } - } - } - - // If an options object was created, then we know changePage() was called - // with an old signature. - if ( opts ) { - return $.mobile.changePage( toPage, opts ); - } - } - // XXX: REMOVE_BEFORE_SHIPPING_1.0 - - // If we are in the midst of a transition, queue the current request. - // We'll call changePage() once we're done with the current transition to - // service the request. - if( isPageTransitioning ) { - pageTransitionQueue.unshift( arguments ); - return; - } - - // Set the isPageTransitioning flag to prevent any requests from - // entering this method while we are in the midst of loading a page - // or transitioning. - - isPageTransitioning = true; - - var settings = $.extend( {}, $.mobile.changePage.defaults, options ); - - // Make sure we have a pageContainer to work with. - settings.pageContainer = settings.pageContainer || $.mobile.pageContainer; - - // If the caller passed us a url, call loadPage() - // to make sure it is loaded into the DOM. We'll listen - // to the promise object it returns so we know when - // it is done loading or if an error ocurred. - if ( typeof toPage == "string" ) { - $.mobile.loadPage( toPage, settings ) - .done(function( url, options, newPage, dupCachedPage ) { - isPageTransitioning = false; - options.duplicateCachedPage = dupCachedPage; - $.mobile.changePage( newPage, options ); - }) - .fail(function( url, options ) { - // XXX_jblas: Fire off changepagefailed notificaiton. - isPageTransitioning = false; - - //clear out the active button state - removeActiveLinkClass( true ); - - //release transition lock so navigation is free again - releasePageTransitionLock(); - settings.pageContainer.trigger("changepagefailed"); - }); - return; - } - - // The caller passed us a real page DOM element. Update our - // internal state and then trigger a transition to the page. - var mpc = settings.pageContainer, - fromPage = $.mobile.activePage, - url = toPage.jqmData( "url" ), - fileUrl = path.getFilePath( url ), - active = urlHistory.getActive(), - activeIsInitialPage = urlHistory.activeIndex === 0, - historyDir = 0, - pageTitle = document.title, - isDialog = settings.role === "dialog" || toPage.jqmData( "role" ) === "dialog"; - - // Let listeners know we're about to change the current page. - mpc.trigger( "beforechangepage" ); - - // If we are trying to transition to the same page that we are currently on ignore the request. - // an illegal same page request is defined by the current page being the same as the url, as long as there's history - // and toPage is not an array or object (those are allowed to be "same") - // - // XXX_jblas: We need to remove this at some point when we allow for transitions - // to the same page. - if( fromPage && fromPage[0] === toPage[0] ) { - isPageTransitioning = false; - mpc.trigger( "changepage" ); - return; - } - - // We need to make sure the page we are given has already been enhanced. - enhancePage( toPage, settings.role ); - - // If the changePage request was sent from a hashChange event, check to see if the - // page is already within the urlHistory stack. If so, we'll assume the user hit - // the forward/back button and will try to match the transition accordingly. - if( settings.fromHashChange ) { - urlHistory.directHashChange({ - currentUrl: url, - isBack: function() { historyDir = -1; }, - isForward: function() { historyDir = 1; } - }); - } - - // Kill the keyboard. - // XXX_jblas: We need to stop crawling the entire document to kill focus. Instead, - // we should be tracking focus with a live() handler so we already have - // the element in hand at this point. - $( document.activeElement || "" ).add( "input:focus, textarea:focus, select:focus" ).blur(); - - // If we're displaying the page as a dialog, we don't want the url - // for the dialog content to be used in the hash. Instead, we want - // to append the dialogHashKey to the url of the current page. - if ( isDialog && active ) { - url = active.url + dialogHashKey; - } - - // Set the location hash. - if( settings.changeHash !== false && url ) { - //disable hash listening temporarily - urlHistory.ignoreNextHashChange = true; - //update hash and history - path.set( url ); - } - - //if title element wasn't found, try the page div data attr too - var newPageTitle = toPage.jqmData( "title" ) || toPage.children(":jqmData(role='header')").find(".ui-title" ).text(); - if( !!newPageTitle && pageTitle == document.title ) { - pageTitle = newPageTitle; - } - - //add page to history stack if it's not back or forward - if( !historyDir ) { - urlHistory.addNew( url, settings.transition, pageTitle, toPage ); - } - - //set page title - document.title = urlHistory.getActive().title; - - //set "toPage" as activePage - $.mobile.activePage = toPage; - - // Make sure we have a transition defined. - settings.transition = settings.transition - || ( ( historyDir && !activeIsInitialPage ) ? active.transition : undefined ) - || ( settings.role === "dialog" ? $.mobile.defaultDialogTransition : $.mobile.defaultPageTransition ); - - // If we're navigating back in the URL history, set reverse accordingly. - settings.reverse = settings.reverse || historyDir < 0; - - transitionPages( toPage, fromPage, settings.transition, settings.reverse ) - .done(function() { - removeActiveLinkClass(); - - //if there's a duplicateCachedPage, remove it from the DOM now that it's hidden - if ( settings.duplicateCachedPage ) { - settings.duplicateCachedPage.remove(); - } - - //remove initial build class (only present on first pageshow) - $html.removeClass( "ui-mobile-rendering" ); - - releasePageTransitionLock(); - - // Let listeners know we're all done changing the current page. - mpc.trigger( "changepage" ); - }); - }; - - $.mobile.changePage.defaults = { - transition: undefined, - reverse: false, - changeHash: true, - fromHashChange: false, - role: undefined, // By default we rely on the role defined by the @data-role attribute. - duplicateCachedPage: undefined, - pageContainer: undefined - }; - -/* Event Bindings - hashchange, submit, and click */ - - //bind to form submit events, handle with Ajax - $( "form" ).live('submit', function( event ) { - var $this = $( this ); - if( !$.mobile.ajaxEnabled || - $this.is( ":jqmData(ajax='false')" ) ) { - return; - } - - var type = $this.attr( "method" ), - url = path.makeUrlAbsolute( $this.attr( "action" ), getClosestBaseUrl($this) ), - target = $this.attr( "target" ); - - //external submits use regular HTTP - if( path.isExternal( url ) || target ) { - return; - } - - $.mobile.changePage( - url, - { - type: type.length && type.toLowerCase() || "get", - data: $this.serialize(), - transition: $this.jqmData( "transition" ), - direction: $this.jqmData( "direction" ), - reloadPage: true - } - ); - event.preventDefault(); - }); - - function findClosestLink( ele ) - { - while ( ele ) { - if ( ele.nodeName.toLowerCase() == "a" ) { - break; - } - ele = ele.parentNode; - } - return ele; - } - - // The base URL for any given element depends on the page it resides in. - function getClosestBaseUrl( ele ) - { - // Find the closest page and extract out its url. - var url = $( ele ).closest( ".ui-page" ).jqmData( "url" ), - base = documentBase.hrefNoHash; - - if ( !url || !path.isPath( url ) ) { - url = base; - } - - return path.makeUrlAbsolute( url, base); - } - - //add active state on vclick - $( document ).bind( "vclick", function( event ) { - var link = findClosestLink( event.target ); - if ( link ) { - if ( path.parseUrl( link.getAttribute( "href" ) || "#" ).hash !== "#" ) { - $( link ).closest( ".ui-btn" ).not( ".ui-disabled" ).addClass( $.mobile.activeBtnClass ); - $( "." + $.mobile.activePageClass + " .ui-btn" ).not( link ).blur(); - } - } - }); - - // click routing - direct to HTTP or Ajax, accordingly - // TODO: most of the time, vclick will be all we need for fastClick bulletproofing. - // However, it seems that in Android 2.1, a click event - // will occasionally arrive independently of the bound vclick - // binding to click as well seems to help in this edge case - // we'll dig into this further in the next release cycle - $( document ).bind( $.mobile.useFastClick ? "vclick click" : "click", function( event ) { - var link = findClosestLink( event.target ); - if ( !link ) { - return; - } - - var $link = $( link ), - //remove active link class if external (then it won't be there if you come back) - httpCleanup = function(){ - window.setTimeout( function() { removeActiveLinkClass( true ); }, 200 ); - }; - - //if there's a data-rel=back attr, go back in history - if( $link.is( ":jqmData(rel='back')" ) ) { - window.history.back(); - return false; - } - - //if ajax is disabled, exit early - if( !$.mobile.ajaxEnabled ){ - httpCleanup(); - //use default click handling - return; - } - - var baseUrl = getClosestBaseUrl( $link ), - - //get href, if defined, otherwise default to empty hash - href = path.makeUrlAbsolute( $link.attr( "href" ) || "#", baseUrl ); - - // XXX_jblas: Ideally links to application pages should be specified as - // an url to the application document with a hash that is either - // the site relative path or id to the page. But some of the - // internal code that dynamically generates sub-pages for nested - // lists and select dialogs, just write a hash in the link they - // create. This means the actual URL path is based on whatever - // the current value of the base tag is at the time this code - // is called. For now we are just assuming that any url with a - // hash in it is an application page reference. - if ( href.search( "#" ) != -1 ) { - href = href.replace( /[^#]*#/, "" ); - if ( !href ) { - //link was an empty hash meant purely - //for interaction, so we ignore it. - event.preventDefault(); - return; - } else if ( path.isPath( href ) ) { - //we have apath so make it the href we want to load. - href = path.makeUrlAbsolute( href, baseUrl ); - } else { - //we have a simple id so use the documentUrl as its base. - href = path.makeUrlAbsolute( "#" + href, documentUrl.hrefNoHash ); - } - } - - // Should we handle this link, or let the browser deal with it? - var useDefaultUrlHandling = $link.is( "[rel='external']" ) || $link.is( ":jqmData(ajax='false')" ) || $link.is( "[target]" ), - - // Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR - // requests if the document doing the request was loaded via the file:// protocol. - // This is usually to allow the application to "phone home" and fetch app specific - // data. We normally let the browser handle external/cross-domain urls, but if the - // allowCrossDomainPages option is true, we will allow cross-domain http/https - // requests to go through our page loading logic. - isCrossDomainPageLoad = ( $.mobile.allowCrossDomainPages && documentUrl.protocol === "file:" && href.search( /^https?:/ ) != -1 ), - - //check for protocol or rel and its not an embedded page - //TODO overlap in logic from isExternal, rel=external check should be - // moved into more comprehensive isExternalLink - isExternal = useDefaultUrlHandling || ( path.isExternal( href ) && !isCrossDomainPageLoad ); - - $activeClickedLink = $link.closest( ".ui-btn" ); - - if( isExternal ) { - httpCleanup(); - //use default click handling - return; - } - - //use ajax - var transition = $link.jqmData( "transition" ), - direction = $link.jqmData( "direction" ), - reverse = ( direction && direction === "reverse" ) || - // deprecated - remove by 1.0 - $link.jqmData( "back" ), - - //this may need to be more specific as we use data-rel more - role = $link.attr( "data-" + $.mobile.ns + "rel" ) || undefined; - - $.mobile.changePage( href, { transition: transition, reverse: reverse, role: role } ); - event.preventDefault(); - }); - - //hashchange event handler - $window.bind( "hashchange", function( e, triggered ) { - //find first page via hash - var to = path.stripHash( location.hash ), - //transition is false if it's the first page, undefined otherwise (and may be overridden by default) - transition = $.mobile.urlHistory.stack.length === 0 ? "none" : undefined; - - //if listening is disabled (either globally or temporarily), or it's a dialog hash - if( !$.mobile.hashListeningEnabled || urlHistory.ignoreNextHashChange ) { - urlHistory.ignoreNextHashChange = false; - return; - } - - // special case for dialogs - if( urlHistory.stack.length > 1 && - to.indexOf( dialogHashKey ) > -1 ) { - - // If current active page is not a dialog skip the dialog and continue - // in the same direction - if(!$.mobile.activePage.is( ".ui-dialog" )) { - //determine if we're heading forward or backward and continue accordingly past - //the current dialog - urlHistory.directHashChange({ - currentUrl: to, - isBack: function() { window.history.back(); }, - isForward: function() { window.history.forward(); } - }); - - // prevent changepage - return; - } else { - var setTo = function() { to = $.mobile.urlHistory.getActive().page; }; - // if the current active page is a dialog and we're navigating - // to a dialog use the dialog objected saved in the stack - urlHistory.directHashChange({ currentUrl: to, isBack: setTo, isForward: setTo }); - } - } - - //if to is defined, load it - if ( to ) { - to = ( typeof to === "string" && !path.isPath( to ) ) ? ( '#' + to ) : to; - $.mobile.changePage( to, { transition: transition, changeHash: false, fromHashChange: true } ); - } - //there's no hash, go to the first page in the dom - else { - $.mobile.changePage( $.mobile.firstPage, { transition: transition, changeHash: false, fromHashChange: true } ); - } - }); - - //set page min-heights to be device specific - $( document ).bind( "pageshow", resetActivePageHeight ); - $( window ).bind( "throttledresize", resetActivePageHeight ); - -})( jQuery ); -/*! - * jQuery Mobile v@VERSION - * http://jquerymobile.com/ - * - * Copyright 2010, jQuery Project - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - */ - -( function( $, window, undefined ) { - -function css3TransitionHandler( name, reverse, $to, $from ) -{ - var deferred = new $.Deferred(), - reverseClass = reverse ? " reverse" : "", - viewportClass = "ui-mobile-viewport-transitioning viewport-" + name, - doneFunc = function() { - $to.add( $from ).removeClass( "out in reverse " + name ); - if ( $from ) { - $from.removeClass( $.mobile.activePageClass ); - } - $to.parent().removeClass( viewportClass ); - - deferred.resolve( name, reverse, $to, $from ); - }; - - $to.animationComplete( doneFunc ); - - $to.parent().addClass( viewportClass ); - if ( $from ) { - $from.addClass( name + " out" + reverseClass ); - } - $to.addClass( $.mobile.activePageClass + " " + name + " in" + reverseClass ); - - return deferred.promise(); -} - -// Make our transition handler public. -$.mobile.css3TransitionHandler = css3TransitionHandler; - -// If the default transition handler is the 'none' handler, replace it with our handler. -if ( $.mobile.defaultTransitionHandler === $.mobile.noneTransitionHandler ) { - $.mobile.defaultTransitionHandler = css3TransitionHandler; -} - -})( jQuery, this ); -/* -* jQuery Mobile Framework : "fixHeaderFooter" plugin - on-demand positioning for headers,footers -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.fn.fixHeaderFooter = function(options){ - if( !$.support.scrollTop ){ return this; } - - return this.each(function(){ - var $this = $(this); - - if( $this.jqmData('fullscreen') ){ $this.addClass('ui-page-fullscreen'); } - $this.find( ".ui-header:jqmData(position='fixed')" ).addClass('ui-header-fixed ui-fixed-inline fade'); //should be slidedown - $this.find( ".ui-footer:jqmData(position='fixed')" ).addClass('ui-footer-fixed ui-fixed-inline fade'); //should be slideup - }); -}; - -//single controller for all showing,hiding,toggling -$.fixedToolbars = (function(){ - if( !$.support.scrollTop ){ return; } - var currentstate = 'inline', - autoHideMode = false, - showDelay = 100, - delayTimer, - ignoreTargets = 'a,input,textarea,select,button,label,.ui-header-fixed,.ui-footer-fixed', - toolbarSelector = '.ui-header-fixed:first, .ui-footer-fixed:not(.ui-footer-duplicate):last', - stickyFooter, //for storing quick references to duplicate footers - supportTouch = $.support.touch, - touchStartEvent = supportTouch ? "touchstart" : "mousedown", - touchStopEvent = supportTouch ? "touchend" : "mouseup", - stateBefore = null, - scrollTriggered = false, - touchToggleEnabled = true; - - function showEventCallback(event) - { - // An event that affects the dimensions of the visual viewport has - // been triggered. If the header and/or footer for the current page are in overlay - // mode, we want to hide them, and then fire off a timer to show them at a later - // point. Events like a resize can be triggered continuously during a scroll, on - // some platforms, so the timer is used to delay the actual positioning until the - // flood of events have subsided. - // - // If we are in autoHideMode, we don't do anything because we know the scroll - // callbacks for the plugin will fire off a show when the scrolling has stopped. - if (!autoHideMode && currentstate == 'overlay') { - if (!delayTimer) - $.fixedToolbars.hide(true); - $.fixedToolbars.startShowTimer(); - } - } - - $(function() { - $(document) - .bind( "vmousedown",function(event){ - if( touchToggleEnabled ) { - stateBefore = currentstate; - } - }) - .bind( "vclick",function(event){ - if( touchToggleEnabled ) { - if( $(event.target).closest(ignoreTargets).length ){ return; } - if( !scrollTriggered ){ - $.fixedToolbars.toggle(stateBefore); - stateBefore = null; - } - } - }) - .bind('silentscroll', showEventCallback); - -/* - The below checks first for a $(document).scrollTop() value, and if zero, binds scroll events to $(window) instead. If the scrollTop value is actually zero, both will return zero anyway. - - Works with $(document), not $(window) : Opera Mobile (WinMO phone; kinda broken anyway) - Works with $(window), not $(document) : IE 7/8 - Works with either $(window) or $(document) : Chrome, FF 3.6/4, Android 1.6/2.1, iOS - Needs work either way : BB5, Opera Mobile (iOS) - -*/ - - (( $(document).scrollTop() == 0 ) ? $(window) : $(document)) - .bind('scrollstart',function(event){ - scrollTriggered = true; - if(stateBefore == null){ stateBefore = currentstate; } - - // We only enter autoHideMode if the headers/footers are in - // an overlay state or the show timer was started. If the - // show timer is set, clear it so the headers/footers don't - // show up until after we're done scrolling. - var isOverlayState = stateBefore == 'overlay'; - autoHideMode = isOverlayState || !!delayTimer; - if (autoHideMode){ - $.fixedToolbars.clearShowTimer(); - if (isOverlayState) { - $.fixedToolbars.hide(true); - } - } - }) - .bind('scrollstop',function(event){ - if( $(event.target).closest(ignoreTargets).length ){ return; } - scrollTriggered = false; - if (autoHideMode) { - autoHideMode = false; - $.fixedToolbars.startShowTimer(); - } - stateBefore = null; - }); - - $(window).bind('resize', showEventCallback); - }); - - //before page is shown, check for duplicate footer - $('.ui-page').live('pagebeforeshow', function(event, ui){ - var page = $(event.target), - footer = page.find( ":jqmData(role='footer')" ), - id = footer.data('id'), - prevPage = ui.prevPage, - prevFooter = prevPage && prevPage.find( ":jqmData(role='footer')" ), - prevFooterMatches = prevFooter.length && prevFooter.jqmData( "id" ) === id; - - if( id && prevFooterMatches ){ - stickyFooter = footer; - setTop( stickyFooter.removeClass( "fade in out" ).appendTo( $.mobile.pageContainer ) ); - } - }); - - //after page is shown, append footer to new page - $('.ui-page').live('pageshow', function(event, ui){ - var $this = $(this); - - if( stickyFooter && stickyFooter.length ){ - - setTimeout(function(){ - setTop( stickyFooter.appendTo( $this ).addClass("fade") ); - stickyFooter = null; - }, 500); - } - - $.fixedToolbars.show(true, this); - }); - - //When a collapsiable is hidden or shown we need to trigger the fixed toolbar to reposition itself (#1635) - $( ".ui-collapsible-contain" ).live( "collapse expand", showEventCallback ); - - // element.getBoundingClientRect() is broken in iOS 3.2.1 on the iPad. The - // coordinates inside of the rect it returns don't have the page scroll position - // factored out of it like the other platforms do. To get around this, - // we'll just calculate the top offset the old fashioned way until core has - // a chance to figure out how to handle this situation. - // - // TODO: We'll need to get rid of getOffsetTop() once a fix gets folded into core. - - function getOffsetTop(ele) - { - var top = 0; - if (ele) - { - var op = ele.offsetParent, body = document.body; - top = ele.offsetTop; - while (ele && ele != body) - { - top += ele.scrollTop || 0; - if (ele == op) - { - top += op.offsetTop; - op = ele.offsetParent; - } - ele = ele.parentNode; - } - } - return top; - } - - function setTop(el){ - var fromTop = $(window).scrollTop(), - thisTop = getOffsetTop(el[0]), // el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead. - thisCSStop = el.css('top') == 'auto' ? 0 : parseFloat(el.css('top')), - screenHeight = window.innerHeight, - thisHeight = el.outerHeight(), - useRelative = el.parents('.ui-page:not(.ui-page-fullscreen)').length, - relval; - if( el.is('.ui-header-fixed') ){ - relval = fromTop - thisTop + thisCSStop; - if( relval < thisTop){ relval = 0; } - return el.css('top', ( useRelative ) ? relval : fromTop); - } - else{ - //relval = -1 * (thisTop - (fromTop + screenHeight) + thisCSStop + thisHeight); - //if( relval > thisTop ){ relval = 0; } - relval = fromTop + screenHeight - thisHeight - (thisTop - thisCSStop); - return el.css('top', ( useRelative ) ? relval : fromTop + screenHeight - thisHeight ); - } - } - - //exposed methods - return { - show: function(immediately, page){ - $.fixedToolbars.clearShowTimer(); - currentstate = 'overlay'; - var $ap = page ? $(page) : ($.mobile.activePage ? $.mobile.activePage : $(".ui-page-active")); - return $ap.children( toolbarSelector ).each(function(){ - var el = $(this), - fromTop = $(window).scrollTop(), - thisTop = getOffsetTop(el[0]), // el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead. - screenHeight = window.innerHeight, - thisHeight = el.outerHeight(), - alreadyVisible = (el.is('.ui-header-fixed') && fromTop <= thisTop + thisHeight) || (el.is('.ui-footer-fixed') && thisTop <= fromTop + screenHeight); - - //add state class - el.addClass('ui-fixed-overlay').removeClass('ui-fixed-inline'); - - if( !alreadyVisible && !immediately ){ - el.animationComplete(function(){ - el.removeClass('in'); - }).addClass('in'); - } - setTop(el); - }); - }, - hide: function(immediately){ - currentstate = 'inline'; - var $ap = $.mobile.activePage ? $.mobile.activePage : $(".ui-page-active"); - return $ap.children( toolbarSelector ).each(function(){ - var el = $(this); - - var thisCSStop = el.css('top'); thisCSStop = thisCSStop == 'auto' ? 0 : parseFloat(thisCSStop); - - //add state class - el.addClass('ui-fixed-inline').removeClass('ui-fixed-overlay'); - - if (thisCSStop < 0 || (el.is('.ui-header-fixed') && thisCSStop != 0)) - { - if(immediately){ - el.css('top',0); - } - else{ - if( el.css('top') !== 'auto' && parseFloat(el.css('top')) !== 0 ){ - var classes = 'out reverse'; - el.animationComplete(function(){ - el.removeClass(classes); - el.css('top',0); - }).addClass(classes); - } - } - } - }); - }, - startShowTimer: function(){ - $.fixedToolbars.clearShowTimer(); - var args = $.makeArray(arguments); - delayTimer = setTimeout(function(){ - delayTimer = undefined; - $.fixedToolbars.show.apply(null, args); - }, showDelay); - }, - clearShowTimer: function() { - if (delayTimer) { - clearTimeout(delayTimer); - } - delayTimer = undefined; - }, - toggle: function(from){ - if(from){ currentstate = from; } - return (currentstate == 'overlay') ? $.fixedToolbars.hide() : $.fixedToolbars.show(); - }, - setTouchToggleEnabled: function(enabled) { - touchToggleEnabled = enabled; - } - }; -})(); - -})(jQuery); -/* -* jQuery Mobile Framework : "checkboxradio" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.checkboxradio", $.mobile.widget, { - options: { - theme: null - }, - _create: function(){ - var self = this, - input = this.element, - //NOTE: Windows Phone could not find the label through a selector - //filter works though. - label = input.closest("form,fieldset,:jqmData(role='page')").find("label").filter('[for="' + input[0].id + '"]'), - inputtype = input.attr( "type" ), - checkedicon = "ui-icon-" + inputtype + "-on", - uncheckedicon = "ui-icon-" + inputtype + "-off"; - - if ( inputtype != "checkbox" && inputtype != "radio" ) { return; } - - //expose for other methods - $.extend( this,{ - label : label, - inputtype : inputtype, - checkedicon : checkedicon, - uncheckedicon : uncheckedicon - }); - - // If there's no selected theme... - if( !this.options.theme ) { - this.options.theme = this.element.jqmData( "theme" ); - } - - label - .buttonMarkup({ - theme: this.options.theme, - icon: this.element.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedicon, - shadow: false - }); - - // wrap the input + label in a div - input - .add( label ) - .wrapAll( "
" ); - - label.bind({ - vmouseover: function() { - if( $(this).parent().is('.ui-disabled') ){ return false; } - }, - - vclick: function( event ){ - if ( input.is( ":disabled" ) ){ - event.preventDefault(); - return; - } - - self._cacheVals(); - - input.prop( "checked", inputtype === "radio" && true || !(input.prop("checked")) ); - - // input set for common radio buttons will contain all the radio - // buttons, but will not for checkboxes. clearing the checked status - // of other radios ensures the active button state is applied properly - self._getInputSet().not(input).prop('checked', false); - - self._updateAll(); - return false; - } - - }); - - input - .bind({ - vmousedown: function(){ - this._cacheVals(); - }, - - vclick: function(){ - // adds checked attribute to checked input when keyboard is used - if ($(this).is(":checked")) { - $(this).prop( "checked", true); - self._getInputSet().not($(this)).prop('checked', false); - } else { - $(this).prop("checked", false); - } - self._updateAll(); - }, - - focus: function() { - label.addClass( "ui-focus" ); - }, - - blur: function() { - label.removeClass( "ui-focus" ); - } - }); - - this.refresh(); - - }, - - _cacheVals: function(){ - this._getInputSet().each(function(){ - $(this).jqmData("cacheVal", $(this).is(":checked") ); - }); - }, - - //returns either a set of radios with the same name attribute, or a single checkbox - _getInputSet: function(){ - return this.element.closest( "form,fieldset,:jqmData(role='page')" ) - .find( "input[name='"+ this.element.attr( "name" ) +"'][type='"+ this.inputtype +"']" ); - }, - - _updateAll: function(){ - var self = this; - - this._getInputSet().each(function(){ - if( $(this).is(":checked") || self.inputtype === "checkbox" ){ - $(this).trigger("change"); - } - }) - .checkboxradio( "refresh" ); - }, - - refresh: function( ){ - var input = this.element, - label = this.label, - icon = label.find( ".ui-icon" ); - - // input[0].checked expando doesn't always report the proper value - // for checked='checked' - if ( $(input[0]).prop('checked') ) { - label.addClass( $.mobile.activeBtnClass ); - icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon ); - - } else { - label.removeClass( $.mobile.activeBtnClass ); - icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon ); - } - - if( input.is( ":disabled" ) ){ - this.disable(); - } - else { - this.enable(); - } - }, - - disable: function(){ - this.element.prop("disabled",true).parent().addClass("ui-disabled"); - }, - - enable: function(){ - this.element.prop("disabled",false).parent().removeClass("ui-disabled"); - } -}); -})( jQuery ); -/* -* jQuery Mobile Framework : "textinput" plugin for text inputs, textareas -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.textinput", $.mobile.widget, { - options: { - theme: null - }, - _create: function(){ - var input = this.element, - o = this.options, - theme = o.theme, - themeclass; - - if ( !theme ) { - var themedParent = this.element.closest("[class*='ui-bar-'],[class*='ui-body-']"), - themeLetter = themedParent.length && /ui-(bar|body)-([a-z])/.exec( themedParent.attr("class") ), - theme = themeLetter && themeLetter[2] || "c"; - } - - themeclass = " ui-body-" + theme; - - $('label[for="'+input.attr('id')+'"]').addClass('ui-input-text'); - - input.addClass('ui-input-text ui-body-'+ o.theme); - - var focusedEl = input; - - //"search" input widget - if( input.is( "[type='search'],:jqmData(type='search')" ) ){ - focusedEl = input.wrap('').parent(); - var clearbtn = $('clear text') - .tap(function( e ){ - input.val('').focus(); - input.trigger('change'); - clearbtn.addClass('ui-input-clear-hidden'); - e.preventDefault(); - }) - .appendTo(focusedEl) - .buttonMarkup({icon: 'delete', iconpos: 'notext', corners:true, shadow:true}); - - function toggleClear(){ - if(input.val() == ''){ - clearbtn.addClass('ui-input-clear-hidden'); - } - else{ - clearbtn.removeClass('ui-input-clear-hidden'); - } - } - - toggleClear(); - input.keyup(toggleClear); - input.focus(toggleClear); - } - else{ - input.addClass('ui-corner-all ui-shadow-inset' + themeclass); - } - - input - .focus(function(){ - focusedEl.addClass('ui-focus'); - }) - .blur(function(){ - focusedEl.removeClass('ui-focus'); - }); - - //autogrow - if ( input.is('textarea') ) { - var extraLineHeight = 15, - keyupTimeoutBuffer = 100, - keyup = function() { - var scrollHeight = input[0].scrollHeight, - clientHeight = input[0].clientHeight; - if ( clientHeight < scrollHeight ) { - input.css({ height: (scrollHeight + extraLineHeight) }); - } - }, - keyupTimeout; - input.keyup(function() { - clearTimeout( keyupTimeout ); - keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer ); - }); - } - }, - - disable: function(){ - ( this.element.attr("disabled",true).is( "[type='search'],:jqmData(type='search')" ) ? this.element.parent() : this.element ).addClass("ui-disabled"); - }, - - enable: function(){ - ( this.element.attr("disabled", false).is( "[type='search'],:jqmData(type='search')" ) ? this.element.parent() : this.element ).removeClass("ui-disabled"); - } -}); -})( jQuery ); -/* -* jQuery Mobile Framework : "selectmenu" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.selectmenu", $.mobile.widget, { - options: { - theme: null, - disabled: false, - icon: 'arrow-d', - iconpos: 'right', - inline: null, - corners: true, - shadow: true, - iconshadow: true, - menuPageTheme: 'b', - overlayTheme: 'a', - hidePlaceholderMenuItems: true, - closeText: 'Close', - nativeMenu: true - }, - _create: function(){ - - var self = this, - - o = this.options, - - select = this.element - .wrap( "
" ), - - selectID = select.attr( "id" ), - - label = $( 'label[for="'+ selectID +'"]' ).addClass( "ui-select" ), - - //IE throws an exception at options.item() function when - //there is no selected item - //select first in this case - selectedIndex = select[0].selectedIndex == -1 ? 0 : select[0].selectedIndex, - - button = ( self.options.nativeMenu ? $( "
" ) : $( "", { - "href": "#", - "role": "button", - "id": buttonId, - "aria-haspopup": "true", - "aria-owns": menuId - }) ) - .text( $( select[0].options.item( selectedIndex ) ).text() ) - .insertBefore( select ) - .buttonMarkup({ - theme: o.theme, - icon: o.icon, - iconpos: o.iconpos, - inline: o.inline, - corners: o.corners, - shadow: o.shadow, - iconshadow: o.iconshadow - }), - - //multi select or not - isMultiple = self.isMultiple = select[0].multiple; - - //Opera does not properly support opacity on select elements - //In Mini, it hides the element, but not its text - //On the desktop,it seems to do the opposite - //for these reasons, using the nativeMenu option results in a full native select in Opera - if( o.nativeMenu && window.opera && window.opera.version ){ - select.addClass( "ui-select-nativeonly" ); - } - - //vars for non-native menus - if( !o.nativeMenu ){ - var options = select.find("option"), - - buttonId = selectID + "-button", - - menuId = selectID + "-menu", - - thisPage = select.closest( ".ui-page" ), - - //button theme - theme = /ui-btn-up-([a-z])/.exec( button.attr("class") )[1], - - menuPage = $( "
" + - "
" + - "
" + label.text() + "
"+ - "
"+ - "
"+ - "
" ) - .appendTo( $.mobile.pageContainer ) - .page(), - - menuPageContent = menuPage.find( ".ui-content" ), - - menuPageClose = menuPage.find( ".ui-header a" ), - - screen = $( "
", {"class": "ui-selectmenu-screen ui-screen-hidden"}) - .appendTo( thisPage ), - - listbox = $( "
", { "class": "ui-selectmenu ui-selectmenu-hidden ui-overlay-shadow ui-corner-all pop ui-body-" + o.overlayTheme } ) - .insertAfter(screen), - - list = $( "
    ", { - "class": "ui-selectmenu-list", - "id": menuId, - "role": "listbox", - "aria-labelledby": buttonId - }) - .attr( "data-" + $.mobile.ns + "theme", theme ) - .appendTo( listbox ), - - header = $( "
    ", { - "class": "ui-header ui-bar-" + theme - }) - .prependTo( listbox ), - - headerTitle = $( "

    ", { - "class": "ui-title" - }) - .appendTo( header ), - - headerClose = $( "", { - "text": o.closeText, - "href": "#", - "class": "ui-btn-left" - }) - .attr( "data-" + $.mobile.ns + "iconpos", "notext" ) - .attr( "data-" + $.mobile.ns + "icon", "delete" ) - .appendTo( header ) - .buttonMarkup(), - - menuType; - } //end non native vars - - // add counter for multi selects - if( isMultiple ){ - self.buttonCount = $('') - .addClass( 'ui-li-count ui-btn-up-c ui-btn-corner-all' ) - .hide() - .appendTo( button ); - } - - //disable if specified - if( o.disabled ){ this.disable(); } - - //events on native select - select - .change(function(){ - self.refresh(); - }); - - //expose to other methods - $.extend(self, { - select: select, - optionElems: options, - selectID: selectID, - label: label, - buttonId:buttonId, - menuId:menuId, - thisPage:thisPage, - button:button, - menuPage:menuPage, - menuPageContent:menuPageContent, - screen:screen, - listbox:listbox, - list:list, - menuType:menuType, - header:header, - headerClose:headerClose, - headerTitle:headerTitle, - placeholder: '' - }); - - //support for using the native select menu with a custom button - if( o.nativeMenu ){ - - select - .appendTo(button) - .bind( "vmousedown", function( e ){ - //add active class to button - button.addClass( $.mobile.activeBtnClass ); - }) - .bind( "focus vmouseover", function(){ - button.trigger( "vmouseover" ); - }) - .bind( "vmousemove", function(){ - //remove active class on scroll/touchmove - button.removeClass( $.mobile.activeBtnClass ); - }) - .bind( "change blur vmouseout", function(){ - button - .trigger( "vmouseout" ) - .removeClass( $.mobile.activeBtnClass ); - }); - - - } else { - - //create list from select, update state - self.refresh(); - - select - .attr( "tabindex", "-1" ) - .focus(function(){ - $(this).blur(); - button.focus(); - }); - - //button events - button - .bind( "vclick keydown" , function( event ){ - if( event.type == "vclick" || - event.keyCode && ( event.keyCode === $.mobile.keyCode.ENTER || event.keyCode === $.mobile.keyCode.SPACE ) ){ - self.open(); - event.preventDefault(); - } - }); - - //events for list items - list - .attr( "role", "listbox" ) - .delegate( ".ui-li>a", "focusin", function() { - $( this ).attr( "tabindex", "0" ); - }) - .delegate( ".ui-li>a", "focusout", function() { - $( this ).attr( "tabindex", "-1" ); - }) - .delegate("li:not(.ui-disabled, .ui-li-divider)", "vclick", function(event){ - - // index of option tag to be selected - var oldIndex = select[0].selectedIndex, - newIndex = list.find( "li:not(.ui-li-divider)" ).index( this ), - option = self.optionElems.eq( newIndex )[0]; - - // toggle selected status on the tag for multi selects - option.selected = isMultiple ? !option.selected : true; - - // toggle checkbox class for multiple selects - if( isMultiple ){ - $(this) - .find('.ui-icon') - .toggleClass('ui-icon-checkbox-on', option.selected) - .toggleClass('ui-icon-checkbox-off', !option.selected); - } - - // trigger change if value changed - if( isMultiple || oldIndex !== newIndex ){ - select.trigger( "change" ); - } - - //hide custom select for single selects only - if( !isMultiple ){ - self.close(); - } - - event.preventDefault(); - }) - //keyboard events for menu items - .keydown(function( e ) { - var target = $( e.target ), - li = target.closest( "li" ); - - // switch logic based on which key was pressed - switch ( e.keyCode ) { - // up or left arrow keys - case 38: - var prev = li.prev(); - - // if there's a previous option, focus it - if ( prev.length ) { - target - .blur() - .attr( "tabindex", "-1" ); - - prev.find( "a" ).first().focus(); - } - - return false; - break; - - // down or right arrow keys - case 40: - var next = li.next(); - - // if there's a next option, focus it - if ( next.length ) { - target - .blur() - .attr( "tabindex", "-1" ); - - next.find( "a" ).first().focus(); - } - - return false; - break; - - // if enter or space is pressed, trigger click - case 13: - case 32: - target.trigger( "vclick" ); - - return false; - break; - } - }); - - //events on "screen" overlay - screen.bind("vclick", function( event ){ - self.close(); - }); - - //close button on small overlays - self.headerClose.click(function(){ - if( self.menuType == "overlay" ){ - self.close(); - return false; - } - }) - } - }, - - _buildList: function(){ - var self = this, - o = this.options, - placeholder = this.placeholder, - optgroups = [], - lis = [], - dataIcon = self.isMultiple ? "checkbox-off" : "false"; - - self.list.empty().filter('.ui-listview').listview('destroy'); - - //populate menu with options from select element - self.select.find( "option" ).each(function( i ){ - var $this = $(this), - $parent = $this.parent(), - text = $this.text(), - anchor = ""+ text +"", - classes = [], - extraAttrs = []; - - // are we inside an optgroup? - if( $parent.is("optgroup") ){ - var optLabel = $parent.attr("label"); - - // has this optgroup already been built yet? - if( $.inArray(optLabel, optgroups) === -1 ){ - lis.push( "
  • "+ optLabel +"
  • " ); - optgroups.push( optLabel ); - } - } - - //find placeholder text - if( !this.getAttribute('value') || text.length == 0 || $this.jqmData('placeholder') ){ - if( o.hidePlaceholderMenuItems ){ - classes.push( "ui-selectmenu-placeholder" ); - } - placeholder = self.placeholder = text; - } - - // support disabled option tags - if( this.disabled ){ - classes.push( "ui-disabled" ); - extraAttrs.push( "aria-disabled='true'" ); - } - - lis.push( "
  • "+ anchor +"
  • " ) - }); - - self.list.html( lis.join(" ") ); - - self.list.find( "li" ) - .attr({ "role": "option", "tabindex": "-1" }) - .first().attr( "tabindex", "0" ); - - // hide header close link for single selects - if( !this.isMultiple ){ - this.headerClose.hide(); - } - - // hide header if it's not a multiselect and there's no placeholder - if( !this.isMultiple && !placeholder.length ){ - this.header.hide(); - } else { - this.headerTitle.text( this.placeholder ); - } - - //now populated, create listview - self.list.listview(); - }, - - refresh: function( forceRebuild ){ - var self = this, - select = this.element, - isMultiple = this.isMultiple, - options = this.optionElems = select.find("option"), - selected = options.filter(":selected"), - - // return an array of all selected index's - indicies = selected.map(function(){ - return options.index( this ); - }).get(); - - if( !self.options.nativeMenu && ( forceRebuild || select[0].options.length != self.list.find('li').length )){ - self._buildList(); - } - - self.button - .find( ".ui-btn-text" ) - .text(function(){ - if( !isMultiple ){ - return selected.text(); - } - - return selected.length ? - selected.map(function(){ return $(this).text(); }).get().join(', ') : - self.placeholder; - }); - - // multiple count inside button - if( isMultiple ){ - self.buttonCount[ selected.length > 1 ? 'show' : 'hide' ]().text( selected.length ); - } - - if( !self.options.nativeMenu ){ - self.list - .find( 'li:not(.ui-li-divider)' ) - .removeClass( $.mobile.activeBtnClass ) - .attr( 'aria-selected', false ) - .each(function( i ){ - if( $.inArray(i, indicies) > -1 ){ - var item = $(this).addClass( $.mobile.activeBtnClass ); - - // aria selected attr - item.find( 'a' ).attr( 'aria-selected', true ); - - // multiple selects: add the "on" checkbox state to the icon - if( isMultiple ){ - item.find('.ui-icon').removeClass('ui-icon-checkbox-off').addClass('ui-icon-checkbox-on'); - } - } - }); - } - }, - - open: function(){ - if( this.options.disabled || this.options.nativeMenu ){ return; } - - var self = this, - menuHeight = self.list.parent().outerHeight(), - menuWidth = self.list.parent().outerWidth(), - scrollTop = $(window).scrollTop(), - btnOffset = self.button.offset().top, - screenHeight = window.innerHeight, - screenWidth = window.innerWidth; - - //add active class to button - self.button.addClass( $.mobile.activeBtnClass ); - - //remove after delay - setTimeout(function(){ - self.button.removeClass( $.mobile.activeBtnClass ); - }, 300); - - function focusMenuItem(){ - self.list.find( ".ui-btn-active" ).focus(); - } - - if( menuHeight > screenHeight - 80 || !$.support.scrollTop ){ - - //for webos (set lastscroll using button offset) - if( scrollTop == 0 && btnOffset > screenHeight ){ - self.thisPage.one('pagehide',function(){ - $(this).jqmData('lastScroll', btnOffset); - }); - } - - self.menuPage.one('pageshow', function() { - // silentScroll() is called whenever a page is shown to restore - // any previous scroll position the page may have had. We need to - // wait for the "silentscroll" event before setting focus to avoid - // the browser's "feature" which offsets rendering to make sure - // whatever has focus is in view. - $(window).one("silentscroll", function(){ focusMenuItem(); }); - }); - - self.menuType = "page"; - self.menuPageContent.append( self.list ); - $.mobile.changePage( self.menuPage, { transition: 'pop' } ); - } - else { - self.menuType = "overlay"; - - self.screen - .height( $(document).height() ) - .removeClass('ui-screen-hidden'); - - //try and center the overlay over the button - var roomtop = btnOffset - scrollTop, - roombot = scrollTop + screenHeight - btnOffset, - halfheight = menuHeight / 2, - maxwidth = parseFloat(self.list.parent().css('max-width')), - newtop, newleft; - - if( roomtop > menuHeight / 2 && roombot > menuHeight / 2 ){ - newtop = btnOffset + ( self.button.outerHeight() / 2 ) - halfheight; - } - else{ - //30px tolerance off the edges - newtop = roomtop > roombot ? scrollTop + screenHeight - menuHeight - 30 : scrollTop + 30; - } - - // if the menuwidth is smaller than the screen center is - if (menuWidth < maxwidth) { - newleft = (screenWidth - menuWidth) / 2; - } else { //otherwise insure a >= 30px offset from the left - newleft = self.button.offset().left + self.button.outerWidth() / 2 - menuWidth / 2; - // 30px tolerance off the edges - if (newleft < 30) { - newleft = 30; - } else if ((newleft + menuWidth) > screenWidth) { - newleft = screenWidth - menuWidth - 30; - } - } - - self.listbox - .append( self.list ) - .removeClass( "ui-selectmenu-hidden" ) - .css({ - top: newtop, - left: newleft - }) - .addClass("in"); - - focusMenuItem(); - } - - // wait before the dialog can be closed - setTimeout(function(){ - self.isOpen = true; - }, 400); - }, - - close: function(){ - if( this.options.disabled || !this.isOpen || this.options.nativeMenu ){ return; } - var self = this; - - function focusButton(){ - setTimeout(function(){ - self.button.focus(); - }, 40); - - self.listbox.removeAttr('style').append( self.list ); - } - - if(self.menuType == "page"){ - // button refocus ensures proper height calculation - // by removing the inline style and ensuring page inclusion - self.menuPage.one("pagehide", focusButton); - - // doesn't solve the possible issue with calling change page - // where the objects don't define data urls which prevents dialog key - // stripping - changePage has incoming refactor - window.history.back(); - } - else{ - self.screen.addClass( "ui-screen-hidden" ); - self.listbox.addClass( "ui-selectmenu-hidden" ).removeAttr( "style" ).removeClass("in"); - focusButton(); - } - - // allow the dialog to be closed again - this.isOpen = false; - }, - - disable: function(){ - this.element.attr("disabled",true); - this.button.addClass('ui-disabled').attr("aria-disabled", true); - return this._setOption( "disabled", true ); - }, - - enable: function(){ - this.element.attr("disabled",false); - this.button.removeClass('ui-disabled').attr("aria-disabled", false); - return this._setOption( "disabled", false ); - } -}); -})( jQuery ); - -/* -* jQuery Mobile Framework : plugin for making button-like links -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -( function( $, undefined ) { - -$.fn.buttonMarkup = function( options ) { - return this.each( function() { - var el = $( this ), - o = $.extend( {}, $.fn.buttonMarkup.defaults, el.jqmData(), options ), - - // Classes Defined - buttonClass, - innerClass = "ui-btn-inner", - iconClass; - - if ( attachEvents ) { - attachEvents(); - } - - // if not, try to find closest theme container - if ( !o.theme ) { - var themedParent = el.closest( "[class*='ui-bar-'],[class*='ui-body-']" ); - o.theme = themedParent.length ? - /ui-(bar|body)-([a-z])/.exec( themedParent.attr( "class" ) )[2] : - "c"; - } - - buttonClass = "ui-btn ui-btn-up-" + o.theme; - - if ( o.inline ) { - buttonClass += " ui-btn-inline"; - } - - if ( o.icon ) { - o.icon = "ui-icon-" + o.icon; - o.iconpos = o.iconpos || "left"; - - iconClass = "ui-icon " + o.icon; - - if ( o.shadow ) { - iconClass += " ui-icon-shadow"; - } - } - - if ( o.iconpos ) { - buttonClass += " ui-btn-icon-" + o.iconpos; - - if ( o.iconpos == "notext" && !el.attr( "title" ) ) { - el.attr( "title", el.text() ); - } - } - - if ( o.corners ) { - buttonClass += " ui-btn-corner-all"; - innerClass += " ui-btn-corner-all"; - } - - if ( o.shadow ) { - buttonClass += " ui-shadow"; - } - - el - .attr( "data-" + $.mobile.ns + "theme", o.theme ) - .addClass( buttonClass ); - - var wrap = ( "" + - ( o.icon ? "" : "" ) + - "" ).replace( /D/g, o.wrapperEls ); - - el.wrapInner( wrap ); - }); -}; - -$.fn.buttonMarkup.defaults = { - corners: true, - shadow: true, - iconshadow: true, - wrapperEls: "span" -}; - -function closestEnabledButton( element ) -{ - while ( element ) { - var $ele = $( element ); - if ( $ele.hasClass( "ui-btn" ) && !$ele.hasClass( "ui-disabled" ) ) { - break; - } - element = element.parentNode; - } - return element; -} - -var attachEvents = function() { - $( document ).bind( { - "vmousedown": function( event ) { - var btn = closestEnabledButton( event.target ); - if ( btn ) { - var $btn = $( btn ), - theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); - $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme ); - } - }, - "vmousecancel vmouseup": function( event ) { - var btn = closestEnabledButton( event.target ); - if ( btn ) { - var $btn = $( btn ), - theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); - $btn.removeClass( "ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme ); - } - }, - "vmouseover focus": function( event ) { - var btn = closestEnabledButton( event.target ); - if ( btn ) { - var $btn = $( btn ), - theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); - $btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme ); - } - }, - "vmouseout blur": function( event ) { - var btn = closestEnabledButton( event.target ); - if ( btn ) { - var $btn = $( btn ), - theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); - $btn.removeClass( "ui-btn-hover-" + theme ).addClass( "ui-btn-up-" + theme ); - } - } - }); - - attachEvents = null; -}; - -})( jQuery ); -/* -* jQuery Mobile Framework : "button" plugin - links that proxy to native input/buttons -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.button", $.mobile.widget, { - options: { - theme: null, - icon: null, - iconpos: null, - inline: null, - corners: true, - shadow: true, - iconshadow: true - }, - _create: function(){ - var $el = this.element, - o = this.options; - - //add ARIA role - this.button = $( "
    " ) - .text( $el.text() || $el.val() ) - .buttonMarkup({ - theme: o.theme, - icon: o.icon, - iconpos: o.iconpos, - inline: o.inline, - corners: o.corners, - shadow: o.shadow, - iconshadow: o.iconshadow - }) - .insertBefore( $el ) - .append( $el.addClass('ui-btn-hidden') ); - - //add hidden input during submit - var type = $el.attr('type'); - if( type !== 'button' && type !== 'reset' ){ - $el.bind("vclick", function(){ - var $buttonPlaceholder = $("", - {type: "hidden", name: $el.attr("name"), value: $el.attr("value")}) - .insertBefore($el); - - //bind to doc to remove after submit handling - $(document).submit(function(){ - $buttonPlaceholder.remove(); - }); - }); - } - this.refresh(); - - }, - - enable: function(){ - this.element.attr("disabled", false); - this.button.removeClass("ui-disabled").attr("aria-disabled", false); - return this._setOption("disabled", false); - }, - - disable: function(){ - this.element.attr("disabled", true); - this.button.addClass("ui-disabled").attr("aria-disabled", true); - return this._setOption("disabled", true); - }, - - refresh: function(){ - if( this.element.attr('disabled') ){ - this.disable(); - } - else{ - this.enable(); - } - } -}); -})( jQuery );/* -* jQuery Mobile Framework : "slider" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.slider", $.mobile.widget, { - options: { - theme: null, - trackTheme: null, - disabled: false - }, - _create: function(){ - var self = this, - - control = this.element, - - parentTheme = control.parents('[class*=ui-bar-],[class*=ui-body-]').eq(0), - - parentTheme = parentTheme.length ? parentTheme.attr('class').match(/ui-(bar|body)-([a-z])/)[2] : 'c', - - theme = this.options.theme ? this.options.theme : parentTheme, - - trackTheme = this.options.trackTheme ? this.options.trackTheme : parentTheme, - - cType = control[0].nodeName.toLowerCase(), - selectClass = (cType == 'select') ? 'ui-slider-switch' : '', - controlID = control.attr('id'), - labelID = controlID + '-label', - label = $('[for="'+ controlID +'"]').attr('id',labelID), - val = function(){ - return (cType == 'input') ? parseFloat(control.val()) : control[0].selectedIndex; - }, - min = (cType == 'input') ? parseFloat(control.attr('min')) : 0, - max = (cType == 'input') ? parseFloat(control.attr('max')) : control.find('option').length-1, - step = window.parseFloat(control.attr('step') || 1), - slider = $('
    '), - handle = $('') - .appendTo(slider) - .buttonMarkup({corners: true, theme: theme, shadow: true}) - .attr({ - 'role': 'slider', - 'aria-valuemin': min, - 'aria-valuemax': max, - 'aria-valuenow': val(), - 'aria-valuetext': val(), - 'title': val(), - 'aria-labelledby': labelID - }); - - $.extend(this, { - slider: slider, - handle: handle, - dragging: false, - beforeStart: null - }); - - if(cType == 'select'){ - slider.wrapInner('
    '); - var options = control.find('option'); - - control.find('option').each(function(i){ - var side = (i==0) ?'b':'a', - corners = (i==0) ? 'right' :'left', - theme = (i==0) ? ' ui-btn-down-' + trackTheme :' ui-btn-active'; - $('
    ').prependTo(slider); - $(''+$(this).text()+'').prependTo(handle); - }); - - } - - label.addClass('ui-slider'); - - // monitor the input for updated values - control - .addClass((cType == 'input') ? 'ui-slider-input' : 'ui-slider-switch') - .change(function(){ - self.refresh( val(), true ); - }) - .keyup(function(){ // necessary? - self.refresh( val(), true, true ); - }) - .blur(function(){ - self.refresh( val(), true ); - }); - - // prevent screen drag when slider activated - $(document).bind( "vmousemove", function(event){ - if ( self.dragging ) { - self.refresh( event ); - return false; - } - }); - - slider - .bind( "vmousedown", function(event){ - self.dragging = true; - if ( cType === "select" ) { - self.beforeStart = control[0].selectedIndex; - } - self.refresh( event ); - return false; - }); - - slider - .add(document) - .bind( "vmouseup", function(){ - if ( self.dragging ) { - self.dragging = false; - if ( cType === "select" ) { - if ( self.beforeStart === control[0].selectedIndex ) { - //tap occurred, but value didn't change. flip it! - self.refresh( self.beforeStart === 0 ? 1 : 0 ); - } - var curval = val(); - var snapped = Math.round( curval / (max - min) * 100 ); - handle - .addClass("ui-slider-handle-snapping") - .css("left", snapped + "%") - .animationComplete(function(){ - handle.removeClass("ui-slider-handle-snapping"); - }); - } - return false; - } - }); - - slider.insertAfter(control); - - // NOTE force focus on handle - this.handle - .bind( "vmousedown", function(){ - $(this).focus(); - }) - .bind( "vclick", false ); - - this.handle - .bind( "keydown", function( event ) { - var index = val(); - - if ( self.options.disabled ) { - return; - } - - // In all cases prevent the default and mark the handle as active - switch ( event.keyCode ) { - case $.mobile.keyCode.HOME: - case $.mobile.keyCode.END: - case $.mobile.keyCode.PAGE_UP: - case $.mobile.keyCode.PAGE_DOWN: - case $.mobile.keyCode.UP: - case $.mobile.keyCode.RIGHT: - case $.mobile.keyCode.DOWN: - case $.mobile.keyCode.LEFT: - event.preventDefault(); - - if ( !self._keySliding ) { - self._keySliding = true; - $( this ).addClass( "ui-state-active" ); - } - break; - } - - // move the slider according to the keypress - switch ( event.keyCode ) { - case $.mobile.keyCode.HOME: - self.refresh(min); - break; - case $.mobile.keyCode.END: - self.refresh(max); - break; - case $.mobile.keyCode.PAGE_UP: - case $.mobile.keyCode.UP: - case $.mobile.keyCode.RIGHT: - self.refresh(index + step); - break; - case $.mobile.keyCode.PAGE_DOWN: - case $.mobile.keyCode.DOWN: - case $.mobile.keyCode.LEFT: - self.refresh(index - step); - break; - } - }) // remove active mark - .keyup(function( event ) { - if ( self._keySliding ) { - self._keySliding = false; - $( this ).removeClass( "ui-state-active" ); - } - }); - - this.refresh(); - }, - - refresh: function(val, isfromControl, preventInputUpdate){ - if ( this.options.disabled ) { return; } - - var control = this.element, percent, - cType = control[0].nodeName.toLowerCase(), - min = (cType === "input") ? parseFloat(control.attr("min")) : 0, - max = (cType === "input") ? parseFloat(control.attr("max")) : control.find("option").length - 1; - - if ( typeof val === "object" ) { - var data = val, - // a slight tolerance helped get to the ends of the slider - tol = 8; - if ( !this.dragging - || data.pageX < this.slider.offset().left - tol - || data.pageX > this.slider.offset().left + this.slider.width() + tol ) { - return; - } - percent = Math.round( ((data.pageX - this.slider.offset().left) / this.slider.width() ) * 100 ); - } else { - if ( val == null ) { - val = (cType === "input") ? parseFloat(control.val()) : control[0].selectedIndex; - } - percent = (parseFloat(val) - min) / (max - min) * 100; - } - - if ( isNaN(percent) ) { return; } - if ( percent < 0 ) { percent = 0; } - if ( percent > 100 ) { percent = 100; } - - var newval = Math.round( (percent / 100) * (max - min) ) + min; - if ( newval < min ) { newval = min; } - if ( newval > max ) { newval = max; } - - //flip the stack of the bg colors - if ( percent > 60 && cType === "select" ) { - - } - this.handle.css("left", percent + "%"); - this.handle.attr({ - "aria-valuenow": (cType === "input") ? newval : control.find("option").eq(newval).attr("value"), - "aria-valuetext": (cType === "input") ? newval : control.find("option").eq(newval).text(), - title: newval - }); - - // add/remove classes for flip toggle switch - if ( cType === "select" ) { - if ( newval === 0 ) { - this.slider.addClass("ui-slider-switch-a") - .removeClass("ui-slider-switch-b"); - } else { - this.slider.addClass("ui-slider-switch-b") - .removeClass("ui-slider-switch-a"); - } - } - - if(!preventInputUpdate){ - // update control's value - if ( cType === "input" ) { - control.val(newval); - } else { - control[ 0 ].selectedIndex = newval; - } - if (!isfromControl) { control.trigger("change"); } - } - }, - - enable: function(){ - this.element.attr("disabled", false); - this.slider.removeClass("ui-disabled").attr("aria-disabled", false); - return this._setOption("disabled", false); - }, - - disable: function(){ - this.element.attr("disabled", true); - this.slider.addClass("ui-disabled").attr("aria-disabled", true); - return this._setOption("disabled", true); - } - -}); -})( jQuery ); - -/* -* jQuery Mobile Framework : "collapsible" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -( function( $, undefined ) { -$.widget( "mobile.collapsible", $.mobile.widget, { - options: { - expandCueText: " click to expand contents", - collapseCueText: " click to collapse contents", - collapsed: false, - heading: ">:header,>legend", - theme: null, - iconTheme: "d" - }, - _create: function() { - - var $el = this.element, - o = this.options, - collapsibleContain = $el.addClass( "ui-collapsible-contain" ), - collapsibleHeading = $el.find( o.heading ).eq( 0 ), - collapsibleContent = collapsibleContain.wrapInner( '
    ' ).find( ".ui-collapsible-content" ), - collapsibleParent = $el.closest( ":jqmData(role='collapsible-set')" ).addClass( "ui-collapsible-set" ); - - //replace collapsibleHeading if it's a legend - if ( collapsibleHeading.is( "legend" ) ) { - collapsibleHeading = $( '
    '+ collapsibleHeading.html() +"
    " ).insertBefore( collapsibleHeading ); - collapsibleHeading.next().remove(); - } - - collapsibleHeading - //drop heading in before content - .insertBefore( collapsibleContent ) - //modify markup & attributes - .addClass( "ui-collapsible-heading" ) - .append( '' ) - .wrapInner( '' ) - .find( "a:eq(0)" ) - .buttonMarkup( { - shadow: !collapsibleParent.length, - corners: false, - iconPos: "left", - icon: "plus", - theme: o.theme - } ) - .find( ".ui-icon" ) - .removeAttr( "class" ) - .buttonMarkup( { - shadow: true, - corners: true, - iconPos: "notext", - icon: "plus", - theme: o.iconTheme - } ); - - if ( ! collapsibleParent.length ) { - collapsibleHeading - .find( "a:eq(0)" ) - .addClass( "ui-corner-all" ) - .find( ".ui-btn-inner" ) - .addClass( "ui-corner-all" ); - } - else { - if ( collapsibleContain.jqmData( "collapsible-last" ) ) { - collapsibleHeading - .find( "a:eq(0), .ui-btn-inner" ) - .addClass( "ui-corner-bottom" ); - } - } - - //events - collapsibleContain - .bind( "collapse", function( event ) { - if ( ! event.isDefaultPrevented() && $( event.target ).closest( ".ui-collapsible-contain" ).is( collapsibleContain ) ) { - event.preventDefault(); - collapsibleHeading - .addClass( "ui-collapsible-heading-collapsed" ) - .find( ".ui-collapsible-heading-status" ) - .text( o.expandCueText ) - .end() - .find( ".ui-icon" ) - .removeClass( "ui-icon-minus" ) - .addClass( "ui-icon-plus" ); - collapsibleContent.addClass( "ui-collapsible-content-collapsed" ).attr( "aria-hidden", true ); - - if ( collapsibleContain.jqmData( "collapsible-last" ) ) { - collapsibleHeading - .find( "a:eq(0), .ui-btn-inner" ) - .addClass( "ui-corner-bottom" ); - } - } - - } ) - .bind( "expand", function( event ) { - if ( ! event.isDefaultPrevented() ) { - event.preventDefault(); - collapsibleHeading - .removeClass( "ui-collapsible-heading-collapsed" ) - .find( ".ui-collapsible-heading-status" ).text( o.collapseCueText ); - - collapsibleHeading.find( ".ui-icon" ).removeClass( "ui-icon-plus" ).addClass( "ui-icon-minus" ); - collapsibleContent.removeClass( "ui-collapsible-content-collapsed" ).attr( "aria-hidden", false ); - - if ( collapsibleContain.jqmData( "collapsible-last" ) ) { - collapsibleHeading - .find( "a:eq(0), .ui-btn-inner" ) - .removeClass( "ui-corner-bottom" ); - } - } - } ) - .trigger( o.collapsed ? "collapse" : "expand" ); - - - //close others in a set - if ( collapsibleParent.length && !collapsibleParent.jqmData( "collapsiblebound" ) ) { - collapsibleParent - .jqmData( "collapsiblebound", true ) - .bind( "expand", function( event ){ - - $( event.target ) - .closest( ".ui-collapsible-contain" ) - .siblings( ".ui-collapsible-contain" ) - .trigger( "collapse" ); - - } ); - - - var set = collapsibleParent.find( ":jqmData(role='collapsible'):first" ); - - set.first() - .find( "a:eq(0)" ) - .addClass( "ui-corner-top" ) - .find( ".ui-btn-inner" ) - .addClass( "ui-corner-top" ); - - set.last().jqmData( "collapsible-last", true ); - } - - collapsibleHeading - .bind( "vclick", function( e ) { - if ( collapsibleHeading.is( ".ui-collapsible-heading-collapsed" ) ) { - collapsibleContain.trigger( "expand" ); - } - else { - collapsibleContain.trigger( "collapse" ); - } - e.preventDefault(); - } ); - } -} ); -} )( jQuery ); -/* -* jQuery Mobile Framework: "controlgroup" plugin - corner-rounding for groups of buttons, checks, radios, etc -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.fn.controlgroup = function(options){ - - return this.each(function(){ - var o = $.extend({ - direction: $( this ).jqmData( "type" ) || "vertical", - shadow: false - },options); - var groupheading = $(this).find('>legend'), - flCorners = o.direction == 'horizontal' ? ['ui-corner-left', 'ui-corner-right'] : ['ui-corner-top', 'ui-corner-bottom'], - type = $(this).find('input:eq(0)').attr('type'); - - //replace legend with more stylable replacement div - if( groupheading.length ){ - $(this).wrapInner('
    '); - $('
    '+ groupheading.html() +'
    ').insertBefore( $(this).children(0) ); - groupheading.remove(); - } - - $(this).addClass('ui-corner-all ui-controlgroup ui-controlgroup-'+o.direction); - - function flipClasses(els){ - els - .removeClass('ui-btn-corner-all ui-shadow') - .eq(0).addClass(flCorners[0]) - .end() - .filter(':last').addClass(flCorners[1]).addClass('ui-controlgroup-last'); - } - flipClasses($(this).find('.ui-btn')); - flipClasses($(this).find('.ui-btn-inner')); - if(o.shadow){ - $(this).addClass('ui-shadow'); - } - }); -}; -})(jQuery);/* -* jQuery Mobile Framework : "fieldcontain" plugin - simple class additions to make form row separators -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.fn.fieldcontain = function(options){ - return this.addClass('ui-field-contain ui-body ui-br'); -}; -})(jQuery);/* -* jQuery Mobile Framework : "listview" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -//Keeps track of the number of lists per page UID -//This allows support for multiple nested list in the same page -//https://github.com/jquery/jquery-mobile/issues/1617 -var listCountPerPage = {}; - -$.widget( "mobile.listview", $.mobile.widget, { - options: { - theme: "c", - countTheme: "c", - headerTheme: "b", - dividerTheme: "b", - splitIcon: "arrow-r", - splitTheme: "b", - inset: false - }, - - _create: function() { - var t = this; - - // create listview markup - t.element.addClass(function( i, orig ) { - return orig + " ui-listview " + ( t.options.inset ? " ui-listview-inset ui-corner-all ui-shadow " : "" ); - }); - - t.refresh(); - }, - - _itemApply: function( $list, item ) { - // TODO class has to be defined in markup - item.find( ".ui-li-count" ) - .addClass( "ui-btn-up-" + ($list.jqmData( "counttheme" ) || this.options.countTheme) + " ui-btn-corner-all" ).end() - .find( "h1, h2, h3, h4, h5, h6" ).addClass( "ui-li-heading" ).end() - .find( "p, dl" ).addClass( "ui-li-desc" ).end() - .find( ">img:eq(0), .ui-link-inherit>img:eq(0)" ).addClass( "ui-li-thumb" ).each(function() { - item.addClass( $(this).is( ".ui-li-icon" ) ? "ui-li-has-icon" : "ui-li-has-thumb" ); - }).end() - .find( ".ui-li-aside" ).each(function() { - var $this = $(this); - $this.prependTo( $this.parent() ); //shift aside to front for css float - }); - }, - - _removeCorners: function( li ) { - li - .add( li.find(".ui-btn-inner, .ui-li-link-alt, .ui-li-thumb") ) - .removeClass( "ui-corner-top ui-corner-bottom ui-corner-br ui-corner-bl ui-corner-tr ui-corner-tl" ); - }, - - refresh: function( create ) { - this._createSubPages(); - - var o = this.options, - $list = this.element, - self = this, - dividertheme = $list.jqmData( "dividertheme" ) || o.dividerTheme, - listsplittheme = $list.jqmData( "splittheme" ), - listspliticon = $list.jqmData( "spliticon" ), - li = $list.children( "li" ), - counter = $.support.cssPseudoElement || !$.nodeName( $list[0], "ol" ) ? 0 : 1; - - if ( counter ) { - $list.find( ".ui-li-dec" ).remove(); - } - - for (var pos = 0, numli = li.length; pos < numli; pos++) { - var item = li.eq(pos), - itemClass = "ui-li"; - - // If we're creating the element, we update it regardless - if ( create || !item.hasClass( "ui-li" ) ) { - var itemTheme = item.jqmData("theme") || o.theme, - a = item.children( "a" ); - - if ( a.length ) { - var icon = item.jqmData("icon"); - - item - .buttonMarkup({ - wrapperEls: "div", - shadow: false, - corners: false, - iconpos: "right", - icon: a.length > 1 || icon === false ? false : icon || "arrow-r", - theme: itemTheme - }); - - a.first().addClass( "ui-link-inherit" ); - - if ( a.length > 1 ) { - itemClass += " ui-li-has-alt"; - - var last = a.last(), - splittheme = listsplittheme || last.jqmData( "theme" ) || o.splitTheme; - - last - .appendTo(item) - .attr( "title", last.text() ) - .addClass( "ui-li-link-alt" ) - .empty() - .buttonMarkup({ - shadow: false, - corners: false, - theme: itemTheme, - icon: false, - iconpos: false - }) - .find( ".ui-btn-inner" ) - .append( $( "" ).buttonMarkup({ - shadow: true, - corners: true, - theme: splittheme, - iconpos: "notext", - icon: listspliticon || last.jqmData( "icon" ) || o.splitIcon - } ) ); - } - - } else if ( item.jqmData( "role" ) === "list-divider" ) { - itemClass += " ui-li-divider ui-btn ui-bar-" + dividertheme; - item.attr( "role", "heading" ); - - //reset counter when a divider heading is encountered - if ( counter ) { - counter = 1; - } - - } else { - itemClass += " ui-li-static ui-body-" + itemTheme; - } - } - - - if( o.inset ){ - if ( pos === 0 ) { - itemClass += " ui-corner-top"; - - item - .add( item.find( ".ui-btn-inner" ) ) - .find( ".ui-li-link-alt" ) - .addClass( "ui-corner-tr" ) - .end() - .find( ".ui-li-thumb" ) - .addClass( "ui-corner-tl" ); - if(item.next().next().length){ - self._removeCorners( item.next() ); - } - - } - if ( pos === li.length - 1 ) { - itemClass += " ui-corner-bottom"; - - item - .add( item.find( ".ui-btn-inner" ) ) - .find( ".ui-li-link-alt" ) - .addClass( "ui-corner-br" ) - .end() - .find( ".ui-li-thumb" ) - .addClass( "ui-corner-bl" ); - - if(item.prev().prev().length){ - self._removeCorners( item.prev() ); - } - } - } - - - if ( counter && itemClass.indexOf( "ui-li-divider" ) < 0 ) { - - var countParent = item.is(".ui-li-static:first") ? item : item.find( ".ui-link-inherit" ); - - countParent - .addClass( "ui-li-jsnumbering" ) - .prepend( "" + (counter++) + ". " ); - } - - item.add( item.children( ".ui-btn-inner" ) ).addClass( itemClass ); - - if ( !create ) { - self._itemApply( $list, item ); - } - } - }, - - //create a string for ID/subpage url creation - _idStringEscape: function( str ){ - return str.replace(/[^a-zA-Z0-9]/g, '-'); - }, - - _createSubPages: function() { - var parentList = this.element, - parentPage = parentList.closest( ".ui-page" ), - parentUrl = parentPage.jqmData( "url" ), - parentId = parentUrl || parentPage[ 0 ][ $.expando ], - parentListId = parentList.attr( "id" ), - o = this.options, - dns = "data-" + $.mobile.ns, - self = this, - persistentFooterID = parentPage.find( ":jqmData(role='footer')" ).jqmData( "id" ); - - if ( typeof( listCountPerPage[ parentId ] ) === 'undefined' ) { - listCountPerPage[ parentId ] = -1; - } - parentListId = parentListId || ++listCountPerPage[ parentId ]; - - $( parentList.find( "li>ul, li>ol" ).toArray().reverse() ).each(function( i ) { - var list = $( this ), - listId = list.attr( "id" ) || parentListId + "-" + i, - parent = list.parent(), - nodeEls = $( list.prevAll().toArray().reverse() ), - nodeEls = nodeEls.length ? nodeEls : $( "" + $.trim(parent.contents()[ 0 ].nodeValue) + "" ), - title = nodeEls.first().text(),//url limits to first 30 chars of text - id = ( parentUrl || "" ) + "&" + $.mobile.subPageUrlKey + "=" + listId; - theme = list.jqmData( "theme" ) || o.theme, - countTheme = list.jqmData( "counttheme" ) || parentList.jqmData( "counttheme" ) || o.countTheme, - newPage = list.detach() - .wrap( "
    " ) - .parent() - .before( "
    " + title + "
    " ) - .after( persistentFooterID ? $( "
    ") : "" ) - .parent() - .appendTo( $.mobile.pageContainer ); - - newPage.page(); - var anchor = parent.find('a:first'); - if ( !anchor.length ) { - anchor = $("").html( nodeEls || title ).prependTo( parent.empty() ); - } - anchor.attr('href','#' + id); - }).listview(); - } -}); - -})( jQuery ); -/* -* jQuery Mobile Framework : "listview" filter extension -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { - -$.mobile.listview.prototype.options.filter = false; -$.mobile.listview.prototype.options.filterPlaceholder = "Filter items..."; -$.mobile.listview.prototype.options.filterTheme = "c"; - -$( ":jqmData(role='listview')" ).live( "listviewcreate", function() { - var list = $( this ), - listview = list.data( "listview" ); - - if ( !listview.options.filter ) { - return; - } - - var wrapper = $( "
    ", { "class": "ui-listview-filter ui-bar-" + listview.options.filterTheme, "role": "search" } ), - - search = $( "", { - placeholder: listview.options.filterPlaceholder - }) - .attr( "data-" + $.mobile.ns + "type", "search" ) - .jqmData( 'lastval', "" ) - .bind( "keyup change", function() { - - var val = this.value.toLowerCase(), - listItems=null, - lastval = $( this ).jqmData('lastval')+""; - - //change val as lastval for next execution - $(this).jqmData( 'lastval' , val ); - - change = val.replace( new RegExp( "^" + lastval ) , "" ); - - if( val.length < lastval.length || change.length != ( val.length - lastval.length ) ){ - - //removed chars or pasted something totaly different, check all items - listItems = list.children(); - } else { - - //only chars added, not removed, only use visible subset - listItems = list.children( ':not(.ui-screen-hidden)' ); - } - - if ( val ) { - - // This handles hiding regular rows without the text we search for - // and any list dividers without regular rows shown under it - var item, - childItems = false, - itemtext=""; - - for ( var i = listItems.length - 1; i >= 0; i-- ) { - item = $( listItems[i] ); - itemtext = item.jqmData( 'filtertext' ) || item.text(); - - if ( item.is( "li:jqmData(role=list-divider)" ) ) { - - item.toggleClass( 'ui-filter-hidequeue' , !childItems ); - - // New bucket! - childItems = false; - - } else if ( itemtext.toLowerCase().indexOf( val ) === -1) { - - //mark to be hidden - item.toggleClass( 'ui-filter-hidequeue' , true ); - } else { - - // There's a shown item in the bucket - childItems = true; - } - } - - // show items, not marked to be hidden - listItems - .filter( ':not(.ui-filter-hidequeue)' ) - .toggleClass('ui-screen-hidden',false); - - // hide items, marked to be hidden - listItems - .filter( '.ui-filter-hidequeue' ) - .toggleClass('ui-screen-hidden',true) - .toggleClass( 'ui-filter-hidequeue' , false ); - - }else{ - - //filtervalue is empty => show all - listItems.toggleClass('ui-screen-hidden',false); - } - }) - .appendTo( wrapper ) - .textinput(); - - if ($( this ).jqmData( "inset" ) ) { - wrapper.addClass( "ui-listview-filter-inset" ); - } - - wrapper.insertBefore( list ); -}); - -})( jQuery );/* -* jQuery Mobile Framework : "dialog" plugin. -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. -* Note: Code is in draft form and is subject to change -*/ -( function( $, undefined ) { -$.widget( "mobile.dialog", $.mobile.widget, { - options: { - closeBtnText: "Close" - }, - _create: function() { - var $el = this.element; - - /* class the markup for dialog styling */ - $el - //add ARIA role - .attr( "role", "dialog" ) - .addClass( "ui-page ui-dialog ui-body-a" ) - .find( ":jqmData(role=header)" ) - .addClass( "ui-corner-top ui-overlay-shadow" ) - .prepend( ""+ this.options.closeBtnText +"" ) - .end() - .find( '.ui-content:not([class*="ui-body-"])' ) - .addClass( 'ui-body-c' ) - .end() - .find( ".ui-content,:jqmData(role='footer')" ) - .last() - .addClass( "ui-corner-bottom ui-overlay-shadow" ); - - /* bind events - - clicks and submits should use the closing transition that the dialog opened with - unless a data-transition is specified on the link/form - - if the click was on the close button, or the link has a data-rel="back" it'll go back in history naturally - */ - $el - .bind( "vclick submit", function( e ) { - var $target = $( e.target ).closest( e.type === "vclick" ? "a" : "form" ); - - if( $target.length && ! $target.jqmData( "transition" ) ) { - var active = $.mobile.urlHistory.getActive() || {}; - $target - .attr( "data-" + $.mobile.ns + "transition", ( active.transition || $.mobile.defaultDialogTransition ) ) - .attr( "data-" + $.mobile.ns + "direction", "reverse" ); - } - }) - .bind( "pagehide", function() { - $( this ).find( "." + $.mobile.activeBtnClass ).removeClass( $.mobile.activeBtnClass ); - }); - }, - - //close method goes back in history - close: function() { - window.history.back(); - } -}); -})( jQuery ); -/* -* jQuery Mobile Framework : "navbar" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.navbar", $.mobile.widget, { - options: { - iconpos: 'top', - grid: null - }, - _create: function(){ - var $navbar = this.element, - $navbtns = $navbar.find("a"), - iconpos = $navbtns.filter( ":jqmData(icon)").length ? this.options.iconpos : undefined; - - $navbar - .addClass('ui-navbar') - .attr("role","navigation") - .find("ul") - .grid({grid: this.options.grid }); - - if( !iconpos ){ - $navbar.addClass("ui-navbar-noicons"); - } - - $navbtns - .buttonMarkup({ - corners: false, - shadow: false, - iconpos: iconpos - }); - - $navbar.delegate("a", "vclick",function(event){ - $navbtns.not( ".ui-state-persist" ).removeClass( $.mobile.activeBtnClass ); - $( this ).addClass( $.mobile.activeBtnClass ); - }); - } -}); -})( jQuery ); -/* -* jQuery Mobile Framework : plugin for creating CSS grids -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.fn.grid = function(options){ - return this.each(function(){ - var o = $.extend({ - grid: null - },options); - - - var $kids = $(this).children(), - gridCols = {solo:1, a:2, b:3, c:4, d:5}, - grid = o.grid, - iterator; - - if( !grid ){ - if( $kids.length <= 5 ){ - for(var letter in gridCols){ - if(gridCols[letter] == $kids.length){ grid = letter; } - } - } - else{ - grid = 'a'; - } - } - iterator = gridCols[grid]; - - $(this).addClass('ui-grid-' + grid); - - $kids.filter(':nth-child(' + iterator + 'n+1)').addClass('ui-block-a'); - if(iterator > 1){ - $kids.filter(':nth-child(' + iterator + 'n+2)').addClass('ui-block-b'); - } - if(iterator > 2){ - $kids.filter(':nth-child(3n+3)').addClass('ui-block-c'); - } - if(iterator > 3){ - $kids.filter(':nth-child(4n+4)').addClass('ui-block-d'); - } - if(iterator > 4){ - $kids.filter(':nth-child(5n+5)').addClass('ui-block-e'); - } - - }); -}; -})(jQuery);/*! - * jQuery Mobile v@VERSION - * http://jquerymobile.com/ - * - * Copyright 2010, jQuery Project - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - */ - -(function( $, window, undefined ) { - var $html = $( "html" ), - $head = $( "head" ), - $window = $( window ); - - //trigger mobileinit event - useful hook for configuring $.mobile settings before they're used - $( window.document ).trigger( "mobileinit" ); - - //support conditions - //if device support condition(s) aren't met, leave things as they are -> a basic, usable experience, - //otherwise, proceed with the enhancements - if ( !$.mobile.gradeA() ) { - return; - } - - // override ajaxEnabled on platforms that have known conflicts with hash history updates - // or generally work better browsing in regular http for full page refreshes (BB5, Opera Mini) - if( window.blackberry && !window.WebKitPoint || window.operamini && Object.prototype.toString.call( window.operamini ) === "[object OperaMini]" ){ - $.mobile.ajaxEnabled = false; - } - - //add mobile, initial load "rendering" classes to docEl - $html.addClass( "ui-mobile ui-mobile-rendering" ); - - //loading div which appears during Ajax requests - //will not appear if $.mobile.loadingMessage is false - var $loader = $.mobile.loadingMessage ? $( "
    " + "" + "

    " + $.mobile.loadingMessage + "

    " + "
    " ) : undefined; - - $.extend($.mobile, { - // turn on/off page loading message. - showPageLoadingMsg: function() { - if( $.mobile.loadingMessage ){ - var activeBtn = $( "." + $.mobile.activeBtnClass ).first(); - - $loader - .appendTo( $.mobile.pageContainer ) - //position at y center (if scrollTop supported), above the activeBtn (if defined), or just 100px from top - .css( { - top: $.support.scrollTop && $(window).scrollTop() + $(window).height() / 2 || - activeBtn.length && activeBtn.offset().top || 100 - } ); - } - - $html.addClass( "ui-loading" ); - }, - - hidePageLoadingMsg: function() { - $html.removeClass( "ui-loading" ); - }, - - // XXX: deprecate for 1.0 - pageLoading: function ( done ) { - if ( done ) { - $.mobile.hidePageLoadingMsg(); - } else { - $.mobile.showPageLoadingMsg(); - } - }, - - // find and enhance the pages in the dom and transition to the first page. - initializePage: function(){ - //find present pages - var $pages = $( ":jqmData(role='page')" ); - - //add dialogs, set data-url attrs - $pages.add( ":jqmData(role='dialog')" ).each(function(){ - var $this = $(this); - - // unless the data url is already set set it to the id - if( !$this.jqmData('url') ){ - $this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) ); - } - }); - - //define first page in dom case one backs out to the directory root (not always the first page visited, but defined as fallback) - $.mobile.firstPage = $pages.first(); - - //define page container - $.mobile.pageContainer = $pages.first().parent().addClass( "ui-mobile-viewport" ); - - //cue page loading message - $.mobile.showPageLoadingMsg(); - - // if hashchange listening is disabled or there's no hash deeplink, change to the first page in the DOM - if( !$.mobile.hashListeningEnabled || !$.mobile.path.stripHash( location.hash ) ){ - $.mobile.changePage( $.mobile.firstPage, { transition: "none", reverse: true, changeHash: false, fromHashChange: true } ); - } - // otherwise, trigger a hashchange to load a deeplink - else { - $window.trigger( "hashchange", [ true ] ); - } - } - }); - - //check which scrollTop value should be used by scrolling to 1 immediately at domready - //then check what the scroll top is. Android will report 0... others 1 - //note that this initial scroll won't hide the address bar. It's just for the check. - $(function(){ - window.scrollTo( 0, 1 ); - - //if defaultHomeScroll hasn't been set yet, see if scrollTop is 1 - //it should be 1 in most browsers, but android treats 1 as 0 (for hiding addr bar) - //so if it's 1, use 0 from now on - $.mobile.defaultHomeScroll = ( !$.support.scrollTop || $(window).scrollTop() === 1 ) ? 0 : 1; - - //dom-ready inits - $( $.mobile.initializePage ); - - //window load event - //hide iOS browser chrome on load - $window.load( $.mobile.silentScroll ); - }); -})( jQuery, this ); - --- /dev/null +++ b/js/yepnope --- a/labs/OpenStreetMap.js +++ /dev/null @@ -1,165 +1,1 @@ -/** - * Namespace: Util.OSM - */ -OpenLayers.Util.OSM = {}; -/** - * Constant: MISSING_TILE_URL - * {String} URL of image to display for missing tiles - */ -OpenLayers.Util.OSM.MISSING_TILE_URL = "/404.php"; - -/** - * Property: originalOnImageLoadError - * {Function} Original onImageLoadError function. - */ -OpenLayers.Util.OSM.originalOnImageLoadError = OpenLayers.Util.onImageLoadError; - -/** - * Function: onImageLoadError - */ -OpenLayers.Util.onImageLoadError = function() { - if (this.src.match(/^http:\/\/[abc]\.[a-z]+\.openstreetmap\.org\//)) { - this.src = OpenLayers.Util.OSM.MISSING_TILE_URL; - } else if (this.src.match(/^http:\/\/[def]\.tah\.openstreetmap\.org\//)) { - // do nothing - this layer is transparent - } else { - OpenLayers.Util.OSM.originalOnImageLoadError; - } -}; - -/** - * Class: OpenLayers.Layer.OSM.Mapnik - * - * Inherits from: - * - - */ -OpenLayers.Layer.OSM.Mapnik = OpenLayers.Class(OpenLayers.Layer.OSM, { - /** - * Constructor: OpenLayers.Layer.OSM.Mapnik - * - * Parameters: - * name - {String} - * options - {Object} Hashtable of extra options to tag onto the layer - */ - initialize: function(name, options) { - var url = [ - "http://a.tiles.bigtincan.com/${z}/${x}/${y}.png", - "http://b.tiles.bigtincan.com/${z}/${x}/${y}.png", - "http://c.tiles.bigtincan.com/${z}/${x}/${y}.png" - ]; - options = OpenLayers.Util.extend({ numZoomLevels: 19 }, options); - var newArguments = [name, url, options]; - OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments); - }, - - CLASS_NAME: "OpenLayers.Layer.OSM.Mapnik" -}); - -OpenLayers.Layer.OSM.NearMap = OpenLayers.Class(OpenLayers.Layer.OSM, { - /** - * Constructor: OpenLayers.Layer.OSM.Mapnik - * - * Parameters: - * name - {String} - * options - {Object} Hashtable of extra options to tag onto the layer - */ - initialize: function(name, options) { - var url = [ - "http://nearmap:findreality@web0.nearmap.com/maps/hl=en&nml=Vert&x=${x}&y=${y}&z=${z}", - "http://nearmap:findreality@web1.nearmap.com/maps/hl=en&nml=Vert&x=${x}&y=${y}&z=${z}", - "http://nearmap:findreality@web2.nearmap.com/maps/hl=en&nml=Vert&x=${x}&y=${y}&z=${z}", - "http://nearmap:findreality@web3.nearmap.com/maps/hl=en&nml=Vert&x=${x}&y=${y}&z=${z}" - ]; - options = OpenLayers.Util.extend({ numZoomLevels: 22 }, options); - var newArguments = [name, url, options]; - OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments); - }, - - CLASS_NAME: "OpenLayers.Layer.OSM.NearMap" -}); - -/** - * Class: OpenLayers.Layer.OSM.Osmarender - * - * Inherits from: - * - - */ -OpenLayers.Layer.OSM.Osmarender = OpenLayers.Class(OpenLayers.Layer.OSM, { - /** - * Constructor: OpenLayers.Layer.OSM.Osmarender - * - * Parameters: - * name - {String} - * options - {Object} Hashtable of extra options to tag onto the layer - */ - initialize: function(name, options) { - var url = [ - "http://a.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png", - "http://b.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png", - "http://c.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png" - ]; - options = OpenLayers.Util.extend({ numZoomLevels: 18 }, options); - var newArguments = [name, url, options]; - OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments); - }, - - CLASS_NAME: "OpenLayers.Layer.OSM.Osmarender" -}); - -/** - * Class: OpenLayers.Layer.OSM.CycleMap - * - * Inherits from: - * - - */ -OpenLayers.Layer.OSM.CycleMap = OpenLayers.Class(OpenLayers.Layer.OSM, { - /** - * Constructor: OpenLayers.Layer.OSM.CycleMap - * - * Parameters: - * name - {String} - * options - {Object} Hashtable of extra options to tag onto the layer - */ - initialize: function(name, options) { - var url = [ - "http://a.andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png", - "http://b.andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png", - "http://c.andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png" - ]; - options = OpenLayers.Util.extend({ numZoomLevels: 19 }, options); - var newArguments = [name, url, options]; - OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments); - }, - - CLASS_NAME: "OpenLayers.Layer.OSM.CycleMap" -}); - -/** - * Class: OpenLayers.Layer.OSM.Maplint - * - * Inherits from: - * - - */ -OpenLayers.Layer.OSM.Maplint = OpenLayers.Class(OpenLayers.Layer.OSM, { - /** - * Constructor: OpenLayers.Layer.OSM.Maplint - * - * Parameters: - * name - {String} - * options - {Object} Hashtable of extra options to tag onto the layer - */ - initialize: function(name, options) { - var url = [ - "http://d.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png", - "http://e.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png", - "http://f.tah.openstreetmap.org/Tiles/maplint/${z}/${x}/${y}.png" - ]; - options = OpenLayers.Util.extend({ numZoomLevels: 18, isBaseLayer: false, visibility: false }, options); - var newArguments = [name, url, options]; - OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments); - }, - - CLASS_NAME: "OpenLayers.Layer.OSM.Maplint" -}); - --- a/labs/about.php +++ /dev/null @@ -1,1 +1,1 @@ -../about.php + --- a/labs/busstopdensity.php +++ /dev/null @@ -1,78 +1,1 @@ - - - -
    -
    - Status:  progess bar -
    - - - - - --- a/labs/busstopdensity.tile.php +++ /dev/null @@ -1,124 +1,1 @@ - -* @version: 1.0 -* @history: -* 1.0 creation -*/ - set_time_limit(120);//2mn - ini_set('memory_limit', '256M'); -error_reporting(E_ALL ^ E_DEPRECATED); - require_once ('lib/GoogleMapUtility.php'); - require_once ('lib/HeatMap.php'); - - //Root folder to store generated tiles - define('TILE_DIR', 'tiles/'); - //Covered geographic areas - define('MIN_LAT', -35.48); - define('MAX_LAT', -35.15); - define('MIN_LNG', 148.98); - define('MAX_LNG', 149.25); - define('TILE_SIZE_FACTOR', 0.5); - define('SPOT_RADIUS', 30); - define('SPOT_DIMMING_LEVEL', 50); - - //Input parameters - if(isset($_GET['x'])) - $X = (int)$_GET['x']; - else - exit("x missing"); - if(isset($_GET['y'])) - $Y = (int)$_GET['y']; - else - exit("y missing"); - if(isset($_GET['zoom'])) - $zoom = (int)$_GET['zoom']; - else - 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; - $tilename = $dir.'/'.$X.'_'.$Y.'.png'; - //HTTP headers (data type and caching rule) - header("Cache-Control: must-revalidate"); - header("Expires: " . gmdate("D, d M Y H:i:s", time() + 86400) . " GMT"); - if(!file_exists($tilename)){ - $rect = GoogleMapUtility::getTileRect($X, $Y, $zoom); - //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. - $extend_X = $rect->width * TILE_SIZE_FACTOR;//in decimal degrees - $extend_Y = $rect->height * TILE_SIZE_FACTOR;//in decimal degrees - $swlat = $rect->y - $extend_Y; - $swlng = $rect->x - $extend_X; - $nelat = $swlat + $rect->height + 2 * $extend_Y; - $nelng = $swlng + $rect->width + 2 * $extend_X; - - if( ($nelat <= MIN_LAT) || ($swlat >= MAX_LAT) || ($nelng <= MIN_LNG) || ($swlng >= MAX_LNG)){ - //No geodata so return generic empty tile - echo file_get_contents(TILE_DIR.'empty.png'); - exit(); - } - - //Get McDonald's spots - $spots = fGetPOI('Select * from stops where - (stop_lon > '.$swlng.' AND stop_lon < '.$nelng.') - AND (stop_lat < '.$nelat.' AND stop_lat > '.$swlat.')', $im, $X, $Y, $zoom, SPOT_RADIUS); - - - if(empty($spots)){ - //No geodata so return generic empty tile - header('Content-type: image/png'); - echo file_get_contents(TILE_DIR.'empty.png'); - }else{ - if(!file_exists($dir)){ - mkdir($dir, 0705); - } - //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); - //Store tile for reuse and output it - header('content-type:image/png;'); - imagepng($im, $tilename); - echo file_get_contents($tilename); - imagedestroy($im); - unset($im); - } - }else{ - //Output stored tile - header('content-type:image/png;'); - echo file_get_contents($tilename); - } - ///////////// - //Functions// - ///////////// - function fGetPOI($query, &$im, $X, $Y, $zoom, $offset){ - global $conn; - $nbPOIInsideTile = 0; - - $result = pg_query($conn, $query); - $spots = Array(); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - foreach( pg_fetch_all($result) as $row){ - $point = GoogleMapUtility::getOffsetPixelCoords($row['stop_lat'], $row['stop_lon'], $zoom, $X, $Y); - //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))){ - $spots[] = new HeatMapPoint($point->x, $point->y); - } - - }//while - return $spots; - }//fAddPOI -?> - - --- a/labs/css +++ /dev/null @@ -1,1 +1,1 @@ -../css/ + --- a/labs/feedback.php +++ /dev/null @@ -1,1 +1,1 @@ -../feedback.php + --- a/labs/googlemaps.php +++ /dev/null @@ -1,29 +1,1 @@ - - - - - - - - - -
    - - + --- a/labs/index.php +++ b/labs/index.php @@ -1,20 +1,16 @@ -
    +

    --- a/labs/js +++ /dev/null @@ -1,1 +1,1 @@ -../js + --- a/labs/lib +++ /dev/null @@ -1,1 +1,1 @@ -../lib + --- a/labs/myway_api.json.php +++ /dev/null @@ -1,129 +1,1 @@ - "SRNO", - "DOBmonth" => "month", - "DOBday" => "day", - "DOByear" => "year", - "secret_answer" => "pwrd", - "button" => "Submit" -); -foreach (Array( - "card_number", - "DOBday", - "DOBmonth", - "DOByear" -) as $field_name) { - if (isset($_REQUEST[$field_name])) { - $fields[$field_name] = filter_var($_REQUEST[$field_name], FILTER_SANITIZE_NUMBER_INT); - } - else { - $return["error"][] = $field_name. " parameter invalid or unspecified"; - } -} -if (isset($_REQUEST['secret_answer'])) { - $fields['secret_answer'] = filter_var($_REQUEST['secret_answer'], FILTER_SANITIZE_STRING, Array( - FILTER_FLAG_NO_ENCODE_QUOTES, - FILTER_FLAG_STRIP_HIGH, - FILTER_FLAG_STRIP_LOW - )); -} -else { - $return["error"][] = "secret_answer parameter invalid or unspecified"; -} -$fields['button'] = 'Submit'; -$fields_string = ""; -//url-ify the data for the POST -foreach ($fields as $key => $value) { - if (sizeof($value) === 0) $return['error'][] = $key . " parameter invalid or unspecified"; - $fields_string.= $field_mapping[$key] . '=' . $value . '&'; -} -$fields_string = rtrim($fields_string, '&'); -if (!isset($return['error'])) { - //open connection - $ch = curl_init(); - //set the url, number of POST vars, POST data - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_POST, count($fields)); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - 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_TIMEOUT, 30); - //execute post - $pageHTML = curl_exec($ch); - if (curl_errno($ch)) $return["error"][] = "Network error " . curl_errno($ch) . " " . curl_error($ch) . " " . $url . $fields_string; - //close connection - curl_close($ch); -} -if (!isset($return['error'])) { - include_once ('lib/simple_html_dom.php'); - //print_r($pageHTML); - $page = str_get_html($pageHTML); - $pageAlerts = $page->find(".smartCardAlert"); - if (sizeof($pageAlerts) > 0) { - $return['error'][] = $pageAlerts[0]->plaintext; - } - if (!isset($return['error'])) { - $tableNum = 0; - $tableName = Array( - 1 => "myway_carddetails", - 2 => "myway_transactions" - ); - foreach ($page->find("table") as $table) { - $tableNum++; - $tableColumns = Array(); - $tableColumnNum = 0; - foreach ($table->find("th") as $th) { - $tableColumns[$tableColumnNum] = cleanString($th->plaintext); - $tableColumnNum++; - } - //print_r($tableColumns); - $tableRowNum = 0; - foreach ($table->find("tr") as $tr) { - $tableColumnNum = 0; - foreach ($tr->find("td") as $td) { - if ($tableNum == 1) $return[$tableName[$tableNum]][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext); - else $return[$tableName[$tableNum]][$tableRowNum][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext); - //print_r($return); - $tableColumnNum++; - } - $tableRowNum++; - } - } - } -} -if (sizeof($return) == 0) { -$return['error'][] = "No data extracted from MyWay website - API may be out of date"; -} - -header('Content-Type: text/javascript; charset=utf8'); -// header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/'); -header('Access-Control-Max-Age: 3628800'); -header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); -if (isset($_GET['callback'])) { - $json = '(' . json_encode($return) . ');'; //must wrap in parens and end with semicolon - print_r($_GET['callback'] . $json); //callback is prepended for json-p - -} -else echo json_encode($return); -?> - --- a/labs/mywaybalance.php +++ /dev/null @@ -1,87 +1,1 @@ - -
    - Back -

    MyWay Balance

    - Logout -
    - -
    '; - -$return = Array(); -function logout() { - setcookie("card_number", "", time() - 60 * 60 * 24 * 100, "/"); - setcookie("date", "", time() - 60 * 60 * 24 * 100, "/"); - setcookie("secret_answer", "", time() - 60 * 60 * 24 * 100, "/"); -} -function printBalance($cardNumber, $date, $pwrd) -{ - global $return; - $return = json_decode(getPage(curPageURL() . "/myway_api.json.php?card_number=$cardNumber&DOBday={$date[0]}&DOBmonth={$date[1]}&DOByear={$date[2]}&secret_answer=$pwrd") , true); - if (isset($return['error'])) { - logout(); - echo '

    ' . $return['error'][0] . "

    "; - } - else { - echo "

    Balance: " . $return['myway_carddetails']['Card Balance'] . "

    "; - echo '
    • Recent Transactions
    • '; - $txCount=0; - foreach ($return['myway_transactions'] as $transaction) { - echo "
    • "; - if ($transaction["Deduction Type"] == "DEFAULT") echo 'Failed to tap off: '; - echo"" . $transaction["Date / Time"] . ""; - echo "
      " .$transaction["Route"] ." at " . $transaction["Stop Name"]. "
      ". $transaction["TX Reference No / Type"] . "
      "; - echo '

      ' . $transaction["TX Amount"] . '

      '; - echo "
    • "; - $txCount++; - if ($txCount > 10) break; - } - echo "
    "; - } -} -if (isset($_REQUEST['card_number']) && isset($_REQUEST['date']) && isset($_REQUEST['secret_answer'])) { - $cardNumber = $_REQUEST['card_number']; - $date = explode("/", $_REQUEST['date']); - $pwrd = $_REQUEST['secret_answer']; - if ($_REQUEST['remember'] == "on") { - setcookie("card_number", $cardNumber, time() + 60 * 60 * 24 * 100, "/"); - setcookie("date", $_REQUEST['date'], time() + 60 * 60 * 24 * 100, "/"); - setcookie("secret_answer", $pwrd, time() + 60 * 60 * 24 * 100, "/"); - } - printBalance($cardNumber, $date, $pwrd); -} -else if (isset($_REQUEST['logout'])) { - echo '

    Logged out of MyWay balance

    Back to main menu...
    '; -} -else if (isset($_COOKIE['card_number']) && isset($_COOKIE['date']) && isset($_COOKIE['secret_answer'])) { - $cardNumber = $_COOKIE['card_number']; - $date = explode("/", $_COOKIE['date']); - $pwrd = $_COOKIE['secret_answer']; - printBalance($cardNumber, $date, $pwrd); -} -else { - $date = (isset($_REQUEST['date']) ? filter_var($_REQUEST['date'], FILTER_SANITIZE_STRING) : date("m/d/Y")); - echo ' -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    - '; -} -include_footer(); -?> --- a/labs/networkstats.php +++ /dev/null @@ -1,147 +1,1 @@ - - - - - - - - - -
    - - -
    - -{$route['route_short_name']} {$route['route_long_name']}"; -foreach (getRouteTrips($routeid) as $key => $trip) { - $dLabel[$key] = $trip['arrival_time']; - if ($key == 0) { - $time = strtotime($trip['arrival_time']); - $adjustFactor = (date("G", $time) * 3600); - } - $tripStops = viaPoints($trip['trip_id']); - foreach ($tripStops as $i => $stop) { - if ($key == 0) { - $dTicks[$i] = $stop['stop_name']; - } - $time = strtotime($stop['arrival_time']); - $d[$key][$i] = (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time) - $adjustFactor; - - } -} - -?> -
    - - -
    - - - - - - --- a/labs/openlayers/OpenLayers.js +++ /dev/null @@ -1,2553 +1,1 @@ -/* - OpenLayers.js -- OpenLayers Map Viewer Library - - Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD - license. Please see http://svn.openlayers.org/trunk/openlayers/license.txt - for the full text of the license. - - Includes compressed code under the following licenses: - - (For uncompressed versions of the code used please see the - OpenLayers SVN repository: ) - -*/ - -/* Contains portions of Prototype.js: - * - * Prototype JavaScript framework, version 1.4.0 - * (c) 2005 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://prototype.conio.net/ - * - *--------------------------------------------------------------------------*/ - -/** -* -* Contains portions of Rico -* -* Copyright 2005 Sabre Airline Solutions -* -* Licensed under the Apache License, Version 2.0 (the "License"); you -* may not use this file except in compliance with the License. You -* may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -* implied. See the License for the specific language governing -* permissions and limitations under the License. -* -**/ - -/** - * Contains XMLHttpRequest.js - * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - */ - -/** - * Contains portions of Gears - * - * Copyright 2007, Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of Google Inc. nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * 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. - * - * Sets up google.gears.*, which is *the only* supported way to access Gears. - * - * Circumvent this file at your own risk! - * - * In the future, Gears may automatically define google.gears.* without this - * file. Gears may use these objects to transparently fix bugs and compatibility - * issues. Applications that use the code below will continue to work seamlessly - * when that happens. - */ -var OpenLayers={singleFile:true};(function(){var singleFile=(typeof OpenLayers=="object"&&OpenLayers.singleFile);var scriptLocation;window.OpenLayers={_scriptName:(!singleFile)?"lib/OpenLayers.js":"OpenLayers.js",_getScriptLocation:function(){if(scriptLocation!=undefined){return scriptLocation;} -scriptLocation="";var isOL=new RegExp("(^|(.*?\\/))("+OpenLayers._scriptName+")(\\?|$)");var scripts=document.getElementsByTagName('script');for(var i=0,len=scripts.length;i";}else{var s=document.createElement("script");s.src=host+jsfiles[i];var h=document.getElementsByTagName("head").length?document.getElementsByTagName("head")[0]:document.body;h.appendChild(s);}} -if(docWrite){document.write(allScriptTags.join(""));}}})();OpenLayers.VERSION_NUMBER="OpenLayers 2.10 -- $Revision: 10721 $";OpenLayers.String={startsWith:function(str,sub){return(str.indexOf(sub)==0);},contains:function(str,sub){return(str.indexOf(sub)!=-1);},trim:function(str){return str.replace(/^\s\s*/,'').replace(/\s\s*$/,'');},camelize:function(str){var oStringList=str.split('-');var camelizedString=oStringList[0];for(var i=1,len=oStringList.length;i0){fig=parseFloat(num.toPrecision(sig));} -return fig;},format:function(num,dec,tsep,dsep){dec=(typeof dec!="undefined")?dec:0;tsep=(typeof tsep!="undefined")?tsep:OpenLayers.Number.thousandsSeparator;dsep=(typeof dsep!="undefined")?dsep:OpenLayers.Number.decimalSeparator;if(dec!=null){num=parseFloat(num.toFixed(dec));} -var parts=num.toString().split(".");if(parts.length==1&&dec==null){dec=0;} -var integer=parts[0];if(tsep){var thousands=/(-?[0-9]+)([0-9]{3})/;while(thousands.test(integer)){integer=integer.replace(thousands,"$1"+tsep+"$2");}} -var str;if(dec==0){str=integer;}else{var rem=parts.length>1?parts[1]:"0";if(dec!=null){rem=rem+new Array(dec-rem.length+1).join("0");} -str=integer+dsep+rem;} -return str;}};if(!Number.prototype.limitSigDigs){Number.prototype.limitSigDigs=function(sig){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Number.limitSigDigs'}));return OpenLayers.Number.limitSigDigs(this,sig);};} -OpenLayers.Function={bind:function(func,object){var args=Array.prototype.slice.apply(arguments,[2]);return function(){var newArgs=args.concat(Array.prototype.slice.apply(arguments,[0]));return func.apply(object,newArgs);};},bindAsEventListener:function(func,object){return function(event){return func.call(object,event||window.event);};},False:function(){return false;},True:function(){return true;}};if(!Function.prototype.bind){Function.prototype.bind=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Function.bind'}));Array.prototype.unshift.apply(arguments,[this]);return OpenLayers.Function.bind.apply(null,arguments);};} -if(!Function.prototype.bindAsEventListener){Function.prototype.bindAsEventListener=function(object){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Function.bindAsEventListener'}));return OpenLayers.Function.bindAsEventListener(this,object);};} -OpenLayers.Array={filter:function(array,callback,caller){var selected=[];if(Array.prototype.filter){selected=array.filter(callback,caller);}else{var len=array.length;if(typeof callback!="function"){throw new TypeError();} -for(var i=0;i1){initialize=Type.prototype.initialize;Type.prototype.initialize=function(){};extended=new Type();if(initialize===undefined){delete Type.prototype.initialize;}else{Type.prototype.initialize=initialize;}} -parent=Type.prototype;}else{parent=Type;} -OpenLayers.Util.extend(extended,parent);} -Class.prototype=extended;return Class;};OpenLayers.Class.isPrototype=function(){};OpenLayers.Class.create=function(){return function(){if(arguments&&arguments[0]!=OpenLayers.Class.isPrototype){this.initialize.apply(this,arguments);}};};OpenLayers.Class.inherit=function(){var superClass=arguments[0];var proto=new superClass(OpenLayers.Class.isPrototype);for(var i=1,len=arguments.length;i=0;i--){if(array[i]==item){array.splice(i,1);}} -return array;};OpenLayers.Util.clearArray=function(array){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'array = []'}));array.length=0;};OpenLayers.Util.indexOf=function(array,obj){if(typeof array.indexOf=="function"){return array.indexOf(obj);}else{for(var i=0,len=array.length;i=0.0&&parseFloat(opacity)<1.0){element.style.filter='alpha(opacity='+(opacity*100)+')';element.style.opacity=opacity;}else if(parseFloat(opacity)==1.0){element.style.filter='';element.style.opacity='';}};OpenLayers.Util.createDiv=function(id,px,sz,imgURL,position,border,overflow,opacity){var dom=document.createElement('div');if(imgURL){dom.style.backgroundImage='url('+imgURL+')';} -if(!id){id=OpenLayers.Util.createUniqueID("OpenLayersDiv");} -if(!position){position="absolute";} -OpenLayers.Util.modifyDOMElement(dom,id,px,sz,position,border,overflow,opacity);return dom;};OpenLayers.Util.createImage=function(id,px,sz,imgURL,position,border,opacity,delayDisplay){var image=document.createElement("img");if(!id){id=OpenLayers.Util.createUniqueID("OpenLayersDiv");} -if(!position){position="relative";} -OpenLayers.Util.modifyDOMElement(image,id,px,sz,position,border,null,opacity);if(delayDisplay){image.style.display="none";OpenLayers.Event.observe(image,"load",OpenLayers.Function.bind(OpenLayers.Util.onImageLoad,image));OpenLayers.Event.observe(image,"error",OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError,image));} -image.style.alt=id;image.galleryImg="no";if(imgURL){image.src=imgURL;} -return image;};OpenLayers.Util.setOpacity=function(element,opacity){OpenLayers.Util.modifyDOMElement(element,null,null,null,null,null,null,opacity);};OpenLayers.Util.onImageLoad=function(){if(!this.viewRequestID||(this.map&&this.viewRequestID==this.map.viewRequestID)){this.style.display="";} -OpenLayers.Element.removeClass(this,"olImageLoadError");};OpenLayers.IMAGE_RELOAD_ATTEMPTS=0;OpenLayers.Util.onImageLoadError=function(){this._attempts=(this._attempts)?(this._attempts+1):1;if(this._attempts<=OpenLayers.IMAGE_RELOAD_ATTEMPTS){var urls=this.urls;if(urls&&urls instanceof Array&&urls.length>1){var src=this.src.toString();var current_url,k;for(k=0;current_url=urls[k];k++){if(src.indexOf(current_url)!=-1){break;}} -var guess=Math.floor(urls.length*Math.random());var new_url=urls[guess];k=0;while(new_url==current_url&&k++<4){guess=Math.floor(urls.length*Math.random());new_url=urls[guess];} -this.src=src.replace(current_url,new_url);}else{this.src=this.src;}}else{OpenLayers.Element.addClass(this,"olImageLoadError");} -this.style.display="";};OpenLayers.Util.alphaHackNeeded=null;OpenLayers.Util.alphaHack=function(){if(OpenLayers.Util.alphaHackNeeded==null){var arVersion=navigator.appVersion.split("MSIE");var version=parseFloat(arVersion[1]);var filter=false;try{filter=!!(document.body.filters);}catch(e){} -OpenLayers.Util.alphaHackNeeded=(filter&&(version>=5.5)&&(version<7));} -return OpenLayers.Util.alphaHackNeeded;};OpenLayers.Util.modifyAlphaImageDiv=function(div,id,px,sz,imgURL,position,border,sizing,opacity){OpenLayers.Util.modifyDOMElement(div,id,px,sz,position,null,null,opacity);var img=div.childNodes[0];if(imgURL){img.src=imgURL;} -OpenLayers.Util.modifyDOMElement(img,div.id+"_innerImage",null,sz,"relative",border);if(OpenLayers.Util.alphaHack()){if(div.style.display!="none"){div.style.display="inline-block";} -if(sizing==null){sizing="scale";} -div.style.filter="progid:DXImageTransform.Microsoft"+".AlphaImageLoader(src='"+img.src+"', "+"sizingMethod='"+sizing+"')";if(parseFloat(div.style.opacity)>=0.0&&parseFloat(div.style.opacity)<1.0){div.style.filter+=" alpha(opacity="+div.style.opacity*100+")";} -img.style.filter="alpha(opacity=0)";}};OpenLayers.Util.createAlphaImageDiv=function(id,px,sz,imgURL,position,border,sizing,opacity,delayDisplay){var div=OpenLayers.Util.createDiv();var img=OpenLayers.Util.createImage(null,null,null,null,null,null,null,false);div.appendChild(img);if(delayDisplay){img.style.display="none";OpenLayers.Event.observe(img,"load",OpenLayers.Function.bind(OpenLayers.Util.onImageLoad,div));OpenLayers.Event.observe(img,"error",OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError,div));} -OpenLayers.Util.modifyAlphaImageDiv(div,id,px,sz,imgURL,position,border,sizing,opacity);return div;};OpenLayers.Util.upperCaseObject=function(object){var uObject={};for(var key in object){uObject[key.toUpperCase()]=object[key];} -return uObject;};OpenLayers.Util.applyDefaults=function(to,from){to=to||{};var fromIsEvt=typeof window.Event=="function"&&from instanceof window.Event;for(var key in from){if(to[key]===undefined||(!fromIsEvt&&from.hasOwnProperty&&from.hasOwnProperty(key)&&!to.hasOwnProperty(key))){to[key]=from[key];}} -if(!fromIsEvt&&from&&from.hasOwnProperty&&from.hasOwnProperty('toString')&&!to.hasOwnProperty('toString')){to.toString=from.toString;} -return to;};OpenLayers.Util.getParameterString=function(params){var paramsArray=[];for(var key in params){var value=params[key];if((value!=null)&&(typeof value!='function')){var encodedValue;if(typeof value=='object'&&value.constructor==Array){var encodedItemArray=[];var item;for(var itemIndex=0,len=value.length;itemIndex0)) -{if(!index){index=0;} -if(result[index].childNodes.length>1){return result.childNodes[1].nodeValue;} -else if(result[index].childNodes.length==1){return result[index].firstChild.nodeValue;}}else{return"";}};OpenLayers.Util.getXmlNodeValue=function(node){var val=null;OpenLayers.Util.Try(function(){val=node.text;if(!val){val=node.textContent;} -if(!val){val=node.firstChild.nodeValue;}},function(){val=node.textContent;});return val;};OpenLayers.Util.mouseLeft=function(evt,div){var target=(evt.relatedTarget)?evt.relatedTarget:evt.toElement;while(target!=div&&target!=null){target=target.parentNode;} -return(target!=div);};OpenLayers.Util.DEFAULT_PRECISION=14;OpenLayers.Util.toFloat=function(number,precision){if(precision==null){precision=OpenLayers.Util.DEFAULT_PRECISION;} -var number;if(precision==0){number=parseFloat(number);}else{number=parseFloat(parseFloat(number).toPrecision(precision));} -return number;};OpenLayers.Util.rad=function(x){return x*Math.PI/180;};OpenLayers.Util.deg=function(x){return x*180/Math.PI;};OpenLayers.Util.VincentyConstants={a:6378137,b:6356752.3142,f:1/298.257223563};OpenLayers.Util.distVincenty=function(p1,p2){var ct=OpenLayers.Util.VincentyConstants;var a=ct.a,b=ct.b,f=ct.f;var L=OpenLayers.Util.rad(p2.lon-p1.lon);var U1=Math.atan((1-f)*Math.tan(OpenLayers.Util.rad(p1.lat)));var U2=Math.atan((1-f)*Math.tan(OpenLayers.Util.rad(p2.lat)));var sinU1=Math.sin(U1),cosU1=Math.cos(U1);var sinU2=Math.sin(U2),cosU2=Math.cos(U2);var lambda=L,lambdaP=2*Math.PI;var iterLimit=20;while(Math.abs(lambda-lambdaP)>1e-12&&--iterLimit>0){var sinLambda=Math.sin(lambda),cosLambda=Math.cos(lambda);var sinSigma=Math.sqrt((cosU2*sinLambda)*(cosU2*sinLambda)+ -(cosU1*sinU2-sinU1*cosU2*cosLambda)*(cosU1*sinU2-sinU1*cosU2*cosLambda));if(sinSigma==0){return 0;} -var cosSigma=sinU1*sinU2+cosU1*cosU2*cosLambda;var sigma=Math.atan2(sinSigma,cosSigma);var alpha=Math.asin(cosU1*cosU2*sinLambda/sinSigma);var cosSqAlpha=Math.cos(alpha)*Math.cos(alpha);var cos2SigmaM=cosSigma-2*sinU1*sinU2/cosSqAlpha;var C=f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));lambdaP=lambda;lambda=L+(1-C)*f*Math.sin(alpha)*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));} -if(iterLimit==0){return NaN;} -var uSq=cosSqAlpha*(a*a-b*b)/(b*b);var A=1+uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));var B=uSq/1024*(256+uSq*(-128+uSq*(74-47*uSq)));var deltaSigma=B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)- -B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));var s=b*A*(sigma-deltaSigma);var d=s.toFixed(3)/1000;return d;};OpenLayers.Util.destinationVincenty=function(lonlat,brng,dist){var u=OpenLayers.Util;var ct=u.VincentyConstants;var a=ct.a,b=ct.b,f=ct.f;var lon1=lonlat.lon;var lat1=lonlat.lat;var s=dist;var alpha1=u.rad(brng);var sinAlpha1=Math.sin(alpha1);var cosAlpha1=Math.cos(alpha1);var tanU1=(1-f)*Math.tan(u.rad(lat1));var cosU1=1/Math.sqrt((1+tanU1*tanU1)),sinU1=tanU1*cosU1;var sigma1=Math.atan2(tanU1,cosAlpha1);var sinAlpha=cosU1*sinAlpha1;var cosSqAlpha=1-sinAlpha*sinAlpha;var uSq=cosSqAlpha*(a*a-b*b)/(b*b);var A=1+uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));var B=uSq/1024*(256+uSq*(-128+uSq*(74-47*uSq)));var sigma=s/(b*A),sigmaP=2*Math.PI;while(Math.abs(sigma-sigmaP)>1e-12){var cos2SigmaM=Math.cos(2*sigma1+sigma);var sinSigma=Math.sin(sigma);var cosSigma=Math.cos(sigma);var deltaSigma=B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)- -B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));sigmaP=sigma;sigma=s/(b*A)+deltaSigma;} -var tmp=sinU1*sinSigma-cosU1*cosSigma*cosAlpha1;var lat2=Math.atan2(sinU1*cosSigma+cosU1*sinSigma*cosAlpha1,(1-f)*Math.sqrt(sinAlpha*sinAlpha+tmp*tmp));var lambda=Math.atan2(sinSigma*sinAlpha1,cosU1*cosSigma-sinU1*sinSigma*cosAlpha1);var C=f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));var L=lambda-(1-C)*f*sinAlpha*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));var revAz=Math.atan2(sinAlpha,-tmp);return new OpenLayers.LonLat(lon1+u.deg(L),u.deg(lat2));};OpenLayers.Util.getParameters=function(url){url=url||window.location.href;var paramsString="";if(OpenLayers.String.contains(url,'?')){var start=url.indexOf('?')+1;var end=OpenLayers.String.contains(url,"#")?url.indexOf('#'):url.length;paramsString=url.substring(start,end);} -var parameters={};var pairs=paramsString.split(/[&;]/);for(var i=0,len=pairs.length;i1.0)?(1.0/scale):scale;return normScale;};OpenLayers.Util.getResolutionFromScale=function(scale,units){var resolution;if(scale){if(units==null){units="degrees";} -var normScale=OpenLayers.Util.normalizeScale(scale);resolution=1/(normScale*OpenLayers.INCHES_PER_UNIT[units]*OpenLayers.DOTS_PER_INCH);} -return resolution;};OpenLayers.Util.getScaleFromResolution=function(resolution,units){if(units==null){units="degrees";} -var scale=resolution*OpenLayers.INCHES_PER_UNIT[units]*OpenLayers.DOTS_PER_INCH;return scale;};OpenLayers.Util.safeStopPropagation=function(evt){OpenLayers.Event.stop(evt,true);};OpenLayers.Util.pagePosition=function(forElement){var valueT=0,valueL=0;var element=forElement;var child=forElement;while(element){if(element==document.body){if(OpenLayers.Element.getStyle(child,'position')=='absolute'){break;}} -valueT+=element.offsetTop||0;valueL+=element.offsetLeft||0;child=element;try{element=element.offsetParent;}catch(e){OpenLayers.Console.error(OpenLayers.i18n("pagePositionFailed",{'elemId':element.id}));break;}} -element=forElement;while(element){valueT-=element.scrollTop||0;valueL-=element.scrollLeft||0;element=element.parentNode;} -return[valueL,valueT];};OpenLayers.Util.isEquivalentUrl=function(url1,url2,options){options=options||{};OpenLayers.Util.applyDefaults(options,{ignoreCase:true,ignorePort80:true,ignoreHash:true});var urlObj1=OpenLayers.Util.createUrlObject(url1,options);var urlObj2=OpenLayers.Util.createUrlObject(url2,options);for(var key in urlObj1){if(key!=="args"){if(urlObj1[key]!=urlObj2[key]){return false;}}} -for(var key in urlObj1.args){if(urlObj1.args[key]!=urlObj2.args[key]){return false;} -delete urlObj2.args[key];} -for(var key in urlObj2.args){return false;} -return true;};OpenLayers.Util.createUrlObject=function(url,options){options=options||{};if(!(/^\w+:\/\//).test(url)){var loc=window.location;var port=loc.port?":"+loc.port:"";var fullUrl=loc.protocol+"//"+loc.host.split(":").shift()+port;if(url.indexOf("/")===0){url=fullUrl+url;}else{var parts=loc.pathname.split("/");parts.pop();url=fullUrl+parts.join("/")+"/"+url;}} -if(options.ignoreCase){url=url.toLowerCase();} -var a=document.createElement('a');a.href=url;var urlObject={};urlObject.host=a.host.split(":").shift();urlObject.protocol=a.protocol;if(options.ignorePort80){urlObject.port=(a.port=="80"||a.port=="0")?"":a.port;}else{urlObject.port=(a.port==""||a.port=="0")?"80":a.port;} -urlObject.hash=(options.ignoreHash||a.hash==="#")?"":a.hash;var queryString=a.search;if(!queryString){var qMark=url.indexOf("?");queryString=(qMark!=-1)?url.substr(qMark):"";} -urlObject.args=OpenLayers.Util.getParameters(queryString);urlObject.pathname=(a.pathname.charAt(0)=="/")?a.pathname:"/"+a.pathname;return urlObject;};OpenLayers.Util.removeTail=function(url){var head=null;var qMark=url.indexOf("?");var hashMark=url.indexOf("#");if(qMark==-1){head=(hashMark!=-1)?url.substr(0,hashMark):url;}else{head=(hashMark!=-1)?url.substr(0,Math.min(qMark,hashMark)):url.substr(0,qMark);} -return head;};OpenLayers.Util.getBrowserName=function(){var browserName="";var ua=navigator.userAgent.toLowerCase();if(ua.indexOf("opera")!=-1){browserName="opera";}else if(ua.indexOf("msie")!=-1){browserName="msie";}else if(ua.indexOf("safari")!=-1){browserName="safari";}else if(ua.indexOf("mozilla")!=-1){if(ua.indexOf("firefox")!=-1){browserName="firefox";}else{browserName="mozilla";}} -return browserName;};OpenLayers.Util.getRenderedDimensions=function(contentHTML,size,options){var w,h;var container=document.createElement("div");container.style.visibility="hidden";var containerElement=(options&&options.containerElement)?options.containerElement:document.body;if(size){if(size.w){w=size.w;container.style.width=w+"px";}else if(size.h){h=size.h;container.style.height=h+"px";}} -if(options&&options.displayClass){container.className=options.displayClass;} -var content=document.createElement("div");content.innerHTML=contentHTML;content.style.overflow="visible";if(content.childNodes){for(var i=0,l=content.childNodes.length;i=0){if(coordinateminutes<10){coordinateminutes="0"+coordinateminutes;} -str+=coordinateminutes+"'";if(dmsOption.indexOf('dms')>=0){if(coordinateseconds<10){coordinateseconds="0"+coordinateseconds;} -str+=coordinateseconds+'"';}} -if(axis=="lon"){str+=coordinate<0?OpenLayers.i18n("W"):OpenLayers.i18n("E");}else{str+=coordinate<0?OpenLayers.i18n("S"):OpenLayers.i18n("N");} -return str;};OpenLayers.Rico=new Object();OpenLayers.Rico.Corner={round:function(e,options){e=OpenLayers.Util.getElement(e);this._setOptions(options);var color=this.options.color;if(this.options.color=="fromElement"){color=this._background(e);} -var bgColor=this.options.bgColor;if(this.options.bgColor=="fromParent"){bgColor=this._background(e.offsetParent);} -this._roundCornersImpl(e,color,bgColor);},changeColor:function(theDiv,newColor){theDiv.style.backgroundColor=newColor;var spanElements=theDiv.parentNode.getElementsByTagName("span");for(var currIdx=0;currIdx"+el.innerHTML+"
";},_roundTopCorners:function(el,color,bgColor){var corner=this._createCorner(bgColor);for(var i=0;i=0;i--){corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));} -el.style.paddingBottom=0;el.appendChild(corner);},_createCorner:function(bgColor){var corner=document.createElement("div");corner.style.backgroundColor=(this._isTransparent()?"transparent":bgColor);return corner;},_createCornerSlice:function(color,bgColor,n,position){var slice=document.createElement("span");var inStyle=slice.style;inStyle.backgroundColor=color;inStyle.display="block";inStyle.height="1px";inStyle.overflow="hidden";inStyle.fontSize="1px";var borderColor=this._borderColor(color,bgColor);if(this.options.border&&n==0){inStyle.borderTopStyle="solid";inStyle.borderTopWidth="1px";inStyle.borderLeftWidth="0px";inStyle.borderRightWidth="0px";inStyle.borderBottomWidth="0px";inStyle.height="0px";inStyle.borderColor=borderColor;} -else if(borderColor){inStyle.borderColor=borderColor;inStyle.borderStyle="solid";inStyle.borderWidth="0px 1px";} -if(!this.options.compact&&(n==(this.options.numSlices-1))){inStyle.height="2px";} -this._setMargin(slice,n,position);this._setBorder(slice,n,position);return slice;},_setOptions:function(options){this.options={corners:"all",color:"fromElement",bgColor:"fromParent",blend:true,border:false,compact:false};OpenLayers.Util.extend(this.options,options||{});this.options.numSlices=this.options.compact?2:4;if(this._isTransparent()){this.options.blend=false;}},_whichSideTop:function(){if(this._hasString(this.options.corners,"all","top")){return"";} -if(this.options.corners.indexOf("tl")>=0&&this.options.corners.indexOf("tr")>=0){return"";} -if(this.options.corners.indexOf("tl")>=0){return"left";}else if(this.options.corners.indexOf("tr")>=0){return"right";} -return"";},_whichSideBottom:function(){if(this._hasString(this.options.corners,"all","bottom")){return"";} -if(this.options.corners.indexOf("bl")>=0&&this.options.corners.indexOf("br")>=0){return"";} -if(this.options.corners.indexOf("bl")>=0){return"left";}else if(this.options.corners.indexOf("br")>=0){return"right";} -return"";},_borderColor:function(color,bgColor){if(color=="transparent"){return bgColor;}else if(this.options.border){return this.options.border;}else if(this.options.blend){return this._blend(bgColor,color);}else{return"";}},_setMargin:function(el,n,corners){var marginSize=this._marginSize(n);var whichSide=corners=="top"?this._whichSideTop():this._whichSideBottom();if(whichSide=="left"){el.style.marginLeft=marginSize+"px";el.style.marginRight="0px";} -else if(whichSide=="right"){el.style.marginRight=marginSize+"px";el.style.marginLeft="0px";} -else{el.style.marginLeft=marginSize+"px";el.style.marginRight=marginSize+"px";}},_setBorder:function(el,n,corners){var borderSize=this._borderSize(n);var whichSide=corners=="top"?this._whichSideTop():this._whichSideBottom();if(whichSide=="left"){el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth="0px";} -else if(whichSide=="right"){el.style.borderRightWidth=borderSize+"px";el.style.borderLeftWidth="0px";} -else{el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth=borderSize+"px";} -if(this.options.border!=false){el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth=borderSize+"px";}},_marginSize:function(n){if(this._isTransparent()){return 0;} -var marginSizes=[5,3,2,1];var blendedMarginSizes=[3,2,1,0];var compactMarginSizes=[2,1];var smBlendedMarginSizes=[1,0];if(this.options.compact&&this.options.blend){return smBlendedMarginSizes[n];}else if(this.options.compact){return compactMarginSizes[n];}else if(this.options.blend){return blendedMarginSizes[n];}else{return marginSizes[n];}},_borderSize:function(n){var transparentBorderSizes=[5,3,2,1];var blendedBorderSizes=[2,1,1,1];var compactBorderSizes=[1,0];var actualBorderSizes=[0,2,0,0];if(this.options.compact&&(this.options.blend||this._isTransparent())){return 1;}else if(this.options.compact){return compactBorderSizes[n];}else if(this.options.blend){return blendedBorderSizes[n];}else if(this.options.border){return actualBorderSizes[n];}else if(this._isTransparent()){return transparentBorderSizes[n];} -return 0;},_hasString:function(str){for(var i=1;i=0){return true;}return false;},_blend:function(c1,c2){var cc1=OpenLayers.Rico.Color.createFromHex(c1);cc1.blend(OpenLayers.Rico.Color.createFromHex(c2));return cc1;},_background:function(el){try{return OpenLayers.Rico.Color.createColorFromBackground(el).asHex();}catch(err){return"#ffffff";}},_isTransparent:function(){return this.options.color=="transparent";},_isTopRounded:function(){return this._hasString(this.options.corners,"all","top","tl","tr");},_isBottomRounded:function(){return this._hasString(this.options.corners,"all","bottom","bl","br");},_hasSingleTextChild:function(el){return el.childNodes.length==1&&el.childNodes[0].nodeType==3;}};(function(){if(window.google&&google.gears){return;} -var factory=null;if(typeof GearsFactory!='undefined'){factory=new GearsFactory();}else{try{factory=new ActiveXObject('Gears.Factory');if(factory.getBuildInfo().indexOf('ie_mobile')!=-1){factory.privateSetGlobalObject(this);}}catch(e){if((typeof navigator.mimeTypes!='undefined')&&navigator.mimeTypes["application/x-googlegears"]){factory=document.createElement("object");factory.style.display="none";factory.width=0;factory.height=0;factory.type="application/x-googlegears";document.documentElement.appendChild(factory);}}} -if(!factory){return;} -if(!window.google){google={};} -if(!google.gears){google.gears={factory:factory};}})();OpenLayers.Element={visible:function(element){return OpenLayers.Util.getElement(element).style.display!='none';},toggle:function(){for(var i=0,len=arguments.length;i"+ -this.contentDiv.innerHTML+"
";var containerElement=(this.map)?this.map.layerContainerDiv:document.body;var realSize=OpenLayers.Util.getRenderedDimensions(preparedHTML,null,{displayClass:this.displayClass,containerElement:containerElement});var safeSize=this.getSafeContentSize(realSize);var newSize=null;if(safeSize.equals(realSize)){newSize=realSize;}else{var fixedSize=new OpenLayers.Size();fixedSize.w=(safeSize.w(mapSize.w-this.map.paddingForPopups.right)){newTL.x=mapSize.w-this.map.paddingForPopups.right-this.size.w;} -if(origTL.y(mapSize.h-this.map.paddingForPopups.bottom)){newTL.y=mapSize.h-this.map.paddingForPopups.bottom-this.size.h;} -var dx=origTL.x-newTL.x;var dy=origTL.y-newTL.y;this.map.pan(dx,dy);},registerEvents:function(){this.events=new OpenLayers.Events(this,this.div,null,true);this.events.on({"mousedown":this.onmousedown,"mousemove":this.onmousemove,"mouseup":this.onmouseup,"click":this.onclick,"mouseout":this.onmouseout,"dblclick":this.ondblclick,scope:this});},onmousedown:function(evt){this.mousedown=true;OpenLayers.Event.stop(evt,true);},onmousemove:function(evt){if(this.mousedown){OpenLayers.Event.stop(evt,true);}},onmouseup:function(evt){if(this.mousedown){this.mousedown=false;OpenLayers.Event.stop(evt,true);}},onclick:function(evt){OpenLayers.Event.stop(evt,true);},onmouseout:function(evt){this.mousedown=false;},ondblclick:function(evt){OpenLayers.Event.stop(evt,true);},CLASS_NAME:"OpenLayers.Popup"});OpenLayers.Popup.WIDTH=200;OpenLayers.Popup.HEIGHT=200;OpenLayers.Popup.COLOR="white";OpenLayers.Popup.OPACITY=1;OpenLayers.Popup.BORDER="0px";OpenLayers.Protocol=OpenLayers.Class({format:null,options:null,autoDestroy:true,defaultFilter:null,initialize:function(options){options=options||{};OpenLayers.Util.extend(this,options);this.options=options;},mergeWithDefaultFilter:function(filter){var merged;if(filter&&this.defaultFilter){merged=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,filters:[this.defaultFilter,filter]});}else{merged=filter||this.defaultFilter||undefined;} -return merged;},destroy:function(){this.options=null;this.format=null;},read:function(options){options=options||{};options.filter=this.mergeWithDefaultFilter(options.filter);},create:function(){},update:function(){},"delete":function(){},commit:function(){},abort:function(response){},createCallback:function(method,response,options){return OpenLayers.Function.bind(function(){method.apply(this,[response,options]);},this);},CLASS_NAME:"OpenLayers.Protocol"});OpenLayers.Protocol.Response=OpenLayers.Class({code:null,requestType:null,last:true,features:null,reqFeatures:null,priv:null,initialize:function(options){OpenLayers.Util.extend(this,options);},success:function(){return this.code>0;},CLASS_NAME:"OpenLayers.Protocol.Response"});OpenLayers.Protocol.Response.SUCCESS=1;OpenLayers.Protocol.Response.FAILURE=0;OpenLayers.Renderer=OpenLayers.Class({container:null,root:null,extent:null,locked:false,size:null,resolution:null,map:null,initialize:function(containerID,options){this.container=OpenLayers.Util.getElement(containerID);},destroy:function(){this.container=null;this.extent=null;this.size=null;this.resolution=null;this.map=null;},supported:function(){return false;},setExtent:function(extent,resolutionChanged){this.extent=extent.clone();if(resolutionChanged){this.resolution=null;}},setSize:function(size){this.size=size.clone();this.resolution=null;},getResolution:function(){this.resolution=this.resolution||this.map.getResolution();return this.resolution;},drawFeature:function(feature,style){if(style==null){style=feature.style;} -if(feature.geometry){var bounds=feature.geometry.getBounds();if(bounds){if(!bounds.intersectsBounds(this.extent)){style={display:"none"};} -var rendered=this.drawGeometry(feature.geometry,style,feature.id);if(style.display!="none"&&style.label&&rendered!==false){var location=feature.geometry.getCentroid();if(style.labelXOffset||style.labelYOffset){xOffset=isNaN(style.labelXOffset)?0:style.labelXOffset;yOffset=isNaN(style.labelYOffset)?0:style.labelYOffset;var res=this.getResolution();location.move(xOffset*res,yOffset*res);} -this.drawText(feature.id,style,location);}else{this.removeText(feature.id);} -return rendered;}}},drawGeometry:function(geometry,style,featureId){},drawText:function(featureId,style,location){},removeText:function(featureId){},clear:function(){},getFeatureIdFromEvent:function(evt){},eraseFeatures:function(features){if(!(features instanceof Array)){features=[features];} -for(var i=0,len=features.length;i0.5;},isDark:function(){return!this.isBright();},asRGB:function(){return"rgb("+this.rgb.r+","+this.rgb.g+","+this.rgb.b+")";},asHex:function(){return"#"+this.rgb.r.toColorPart()+this.rgb.g.toColorPart()+this.rgb.b.toColorPart();},asHSB:function(){return OpenLayers.Rico.Color.RGBtoHSB(this.rgb.r,this.rgb.g,this.rgb.b);},toString:function(){return this.asHex();}});OpenLayers.Rico.Color.createFromHex=function(hexCode){if(hexCode.length==4){var shortHexCode=hexCode;var hexCode='#';for(var i=1;i<4;i++){hexCode+=(shortHexCode.charAt(i)+ -shortHexCode.charAt(i));}} -if(hexCode.indexOf('#')==0){hexCode=hexCode.substring(1);} -var red=hexCode.substring(0,2);var green=hexCode.substring(2,4);var blue=hexCode.substring(4,6);return new OpenLayers.Rico.Color(parseInt(red,16),parseInt(green,16),parseInt(blue,16));};OpenLayers.Rico.Color.createColorFromBackground=function(elem){var actualColor=RicoUtil.getElementsComputedStyle(OpenLayers.Util.getElement(elem),"backgroundColor","background-color");if(actualColor=="transparent"&&elem.parentNode){return OpenLayers.Rico.Color.createColorFromBackground(elem.parentNode);} -if(actualColor==null){return new OpenLayers.Rico.Color(255,255,255);} -if(actualColor.indexOf("rgb(")==0){var colors=actualColor.substring(4,actualColor.length-1);var colorArray=colors.split(",");return new OpenLayers.Rico.Color(parseInt(colorArray[0]),parseInt(colorArray[1]),parseInt(colorArray[2]));} -else if(actualColor.indexOf("#")==0){return OpenLayers.Rico.Color.createFromHex(actualColor);} -else{return new OpenLayers.Rico.Color(255,255,255);}};OpenLayers.Rico.Color.HSBtoRGB=function(hue,saturation,brightness){var red=0;var green=0;var blue=0;if(saturation==0){red=parseInt(brightness*255.0+0.5);green=red;blue=red;} -else{var h=(hue-Math.floor(hue))*6.0;var f=h-Math.floor(h);var p=brightness*(1.0-saturation);var q=brightness*(1.0-saturation*f);var t=brightness*(1.0-(saturation*(1.0-f)));switch(parseInt(h)){case 0:red=(brightness*255.0+0.5);green=(t*255.0+0.5);blue=(p*255.0+0.5);break;case 1:red=(q*255.0+0.5);green=(brightness*255.0+0.5);blue=(p*255.0+0.5);break;case 2:red=(p*255.0+0.5);green=(brightness*255.0+0.5);blue=(t*255.0+0.5);break;case 3:red=(p*255.0+0.5);green=(q*255.0+0.5);blue=(brightness*255.0+0.5);break;case 4:red=(t*255.0+0.5);green=(p*255.0+0.5);blue=(brightness*255.0+0.5);break;case 5:red=(brightness*255.0+0.5);green=(p*255.0+0.5);blue=(q*255.0+0.5);break;}} -return{r:parseInt(red),g:parseInt(green),b:parseInt(blue)};};OpenLayers.Rico.Color.RGBtoHSB=function(r,g,b){var hue;var saturation;var brightness;var cmax=(r>g)?r:g;if(b>cmax){cmax=b;} -var cmin=(rthis.right)){this.right=bounds.right;} -if((this.top==null)||(bounds.top>this.top)){this.top=bounds.top;}}}},containsLonLat:function(ll,inclusive){return this.contains(ll.lon,ll.lat,inclusive);},containsPixel:function(px,inclusive){return this.contains(px.x,px.y,inclusive);},contains:function(x,y,inclusive){if(inclusive==null){inclusive=true;} -if(x==null||y==null){return false;} -x=OpenLayers.Util.toFloat(x);y=OpenLayers.Util.toFloat(y);var contains=false;if(inclusive){contains=((x>=this.left)&&(x<=this.right)&&(y>=this.bottom)&&(y<=this.top));}else{contains=((x>this.left)&&(xthis.bottom)&&(y=this.bottom)&&(bounds.bottom<=this.top))||((this.bottom>=bounds.bottom)&&(this.bottom<=bounds.top)));var inTop=(((bounds.top>=this.bottom)&&(bounds.top<=this.top))||((this.top>bounds.bottom)&&(this.top=this.left)&&(bounds.left<=this.right))||((this.left>=bounds.left)&&(this.left<=bounds.right)));var inRight=(((bounds.right>=this.left)&&(bounds.right<=this.right))||((this.right>=bounds.left)&&(this.right<=bounds.right)));intersects=((inBottom||inTop)&&(inLeft||inRight));} -return intersects;},containsBounds:function(bounds,partial,inclusive){if(partial==null){partial=false;} -if(inclusive==null){inclusive=true;} -var bottomLeft=this.contains(bounds.left,bounds.bottom,inclusive);var bottomRight=this.contains(bounds.right,bounds.bottom,inclusive);var topLeft=this.contains(bounds.left,bounds.top,inclusive);var topRight=this.contains(bounds.right,bounds.top,inclusive);return(partial)?(bottomLeft||bottomRight||topLeft||topRight):(bottomLeft&&bottomRight&&topLeft&&topRight);},determineQuadrant:function(lonlat){var quadrant="";var center=this.getCenterLonLat();quadrant+=(lonlat.lat=maxExtent.right&&newBounds.right>maxExtent.right){newBounds=newBounds.add(-maxExtent.getWidth(),0);}} -return newBounds;},CLASS_NAME:"OpenLayers.Bounds"});OpenLayers.Bounds.fromString=function(str){var bounds=str.split(",");return OpenLayers.Bounds.fromArray(bounds);};OpenLayers.Bounds.fromArray=function(bbox){return new OpenLayers.Bounds(parseFloat(bbox[0]),parseFloat(bbox[1]),parseFloat(bbox[2]),parseFloat(bbox[3]));};OpenLayers.Bounds.fromSize=function(size){return new OpenLayers.Bounds(0,size.h,size.w,0);};OpenLayers.Bounds.oppositeQuadrant=function(quadrant){var opp="";opp+=(quadrant.charAt(0)=='t')?'b':'t';opp+=(quadrant.charAt(1)=='l')?'r':'l';return opp;};OpenLayers.LonLat=OpenLayers.Class({lon:0.0,lat:0.0,initialize:function(lon,lat){this.lon=OpenLayers.Util.toFloat(lon);this.lat=OpenLayers.Util.toFloat(lat);},toString:function(){return("lon="+this.lon+",lat="+this.lat);},toShortString:function(){return(this.lon+", "+this.lat);},clone:function(){return new OpenLayers.LonLat(this.lon,this.lat);},add:function(lon,lat){if((lon==null)||(lat==null)){var msg=OpenLayers.i18n("lonlatAddError");OpenLayers.Console.error(msg);return null;} -return new OpenLayers.LonLat(this.lon+OpenLayers.Util.toFloat(lon),this.lat+OpenLayers.Util.toFloat(lat));},equals:function(ll){var equals=false;if(ll!=null){equals=((this.lon==ll.lon&&this.lat==ll.lat)||(isNaN(this.lon)&&isNaN(this.lat)&&isNaN(ll.lon)&&isNaN(ll.lat)));} -return equals;},transform:function(source,dest){var point=OpenLayers.Projection.transform({'x':this.lon,'y':this.lat},source,dest);this.lon=point.x;this.lat=point.y;return this;},wrapDateLine:function(maxExtent){var newLonLat=this.clone();if(maxExtent){while(newLonLat.lonmaxExtent.right){newLonLat.lon-=maxExtent.getWidth();}} -return newLonLat;},CLASS_NAME:"OpenLayers.LonLat"});OpenLayers.LonLat.fromString=function(str){var pair=str.split(",");return new OpenLayers.LonLat(pair[0],pair[1]);};OpenLayers.Pixel=OpenLayers.Class({x:0.0,y:0.0,initialize:function(x,y){this.x=parseFloat(x);this.y=parseFloat(y);},toString:function(){return("x="+this.x+",y="+this.y);},clone:function(){return new OpenLayers.Pixel(this.x,this.y);},equals:function(px){var equals=false;if(px!=null){equals=((this.x==px.x&&this.y==px.y)||(isNaN(this.x)&&isNaN(this.y)&&isNaN(px.x)&&isNaN(px.y)));} -return equals;},add:function(x,y){if((x==null)||(y==null)){var msg=OpenLayers.i18n("pixelAddError");OpenLayers.Console.error(msg);return null;} -return new OpenLayers.Pixel(this.x+x,this.y+y);},offset:function(px){var newPx=this.clone();if(px){newPx=this.add(px.x,px.y);} -return newPx;},CLASS_NAME:"OpenLayers.Pixel"});OpenLayers.Control=OpenLayers.Class({id:null,map:null,div:null,type:null,allowSelection:false,displayClass:"",title:"",autoActivate:false,active:null,handler:null,eventListeners:null,events:null,EVENT_TYPES:["activate","deactivate"],initialize:function(options){this.displayClass=this.CLASS_NAME.replace("OpenLayers.","ol").replace(/\./g,"");OpenLayers.Util.extend(this,options);this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);} -if(this.id==null){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");}},destroy:function(){if(this.events){if(this.eventListeners){this.events.un(this.eventListeners);} -this.events.destroy();this.events=null;} -this.eventListeners=null;if(this.handler){this.handler.destroy();this.handler=null;} -if(this.handlers){for(var key in this.handlers){if(this.handlers.hasOwnProperty(key)&&typeof this.handlers[key].destroy=="function"){this.handlers[key].destroy();}} -this.handlers=null;} -if(this.map){this.map.removeControl(this);this.map=null;}},setMap:function(map){this.map=map;if(this.handler){this.handler.setMap(map);}},draw:function(px){if(this.div==null){this.div=OpenLayers.Util.createDiv(this.id);this.div.className=this.displayClass;if(!this.allowSelection){this.div.className+=" olControlNoSelect";this.div.setAttribute("unselectable","on",0);this.div.onselectstart=OpenLayers.Function.False;} -if(this.title!=""){this.div.title=this.title;}} -if(px!=null){this.position=px.clone();} -this.moveTo(this.position);return this.div;},moveTo:function(px){if((px!=null)&&(this.div!=null)){this.div.style.left=px.x+"px";this.div.style.top=px.y+"px";}},activate:function(){if(this.active){return false;} -if(this.handler){this.handler.activate();} -this.active=true;if(this.map){OpenLayers.Element.addClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active");} -this.events.triggerEvent("activate");return true;},deactivate:function(){if(this.active){if(this.handler){this.handler.deactivate();} -this.active=false;if(this.map){OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active");} -this.events.triggerEvent("deactivate");return true;} -return false;},CLASS_NAME:"OpenLayers.Control"});OpenLayers.Control.TYPE_BUTTON=1;OpenLayers.Control.TYPE_TOGGLE=2;OpenLayers.Control.TYPE_TOOL=3;OpenLayers.Lang={code:null,defaultCode:"en",getCode:function(){if(!OpenLayers.Lang.code){OpenLayers.Lang.setCode();} -return OpenLayers.Lang.code;},setCode:function(code){var lang;if(!code){code=(OpenLayers.Util.getBrowserName()=="msie")?navigator.userLanguage:navigator.language;} -var parts=code.split('-');parts[0]=parts[0].toLowerCase();if(typeof OpenLayers.Lang[parts[0]]=="object"){lang=parts[0];} -if(parts[1]){var testLang=parts[0]+'-'+parts[1].toUpperCase();if(typeof OpenLayers.Lang[testLang]=="object"){lang=testLang;}} -if(!lang){OpenLayers.Console.warn('Failed to find OpenLayers.Lang.'+parts.join("-")+' dictionary, falling back to default language');lang=OpenLayers.Lang.defaultCode;} -OpenLayers.Lang.code=lang;},translate:function(key,context){var dictionary=OpenLayers.Lang[OpenLayers.Lang.getCode()];var message=dictionary[key];if(!message){message=key;} -if(context){message=OpenLayers.String.format(message,context);} -return message;}};OpenLayers.i18n=OpenLayers.Lang.translate;OpenLayers.Popup.Anchored=OpenLayers.Class(OpenLayers.Popup,{relativePosition:null,keepInMap:true,anchor:null,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){var newArguments=[id,lonlat,contentSize,contentHTML,closeBox,closeBoxCallback];OpenLayers.Popup.prototype.initialize.apply(this,newArguments);this.anchor=(anchor!=null)?anchor:{size:new OpenLayers.Size(0,0),offset:new OpenLayers.Pixel(0,0)};},destroy:function(){this.anchor=null;this.relativePosition=null;OpenLayers.Popup.prototype.destroy.apply(this,arguments);},show:function(){this.updatePosition();OpenLayers.Popup.prototype.show.apply(this,arguments);},moveTo:function(px){var oldRelativePosition=this.relativePosition;this.relativePosition=this.calculateRelativePosition(px);var newPx=this.calculateNewPx(px);var newArguments=new Array(newPx);OpenLayers.Popup.prototype.moveTo.apply(this,newArguments);if(this.relativePosition!=oldRelativePosition){this.updateRelativePosition();}},setSize:function(contentSize){OpenLayers.Popup.prototype.setSize.apply(this,arguments);if((this.lonlat)&&(this.map)){var px=this.map.getLayerPxFromLonLat(this.lonlat);this.moveTo(px);}},calculateRelativePosition:function(px){var lonlat=this.map.getLonLatFromLayerPx(px);var extent=this.map.getExtent();var quadrant=extent.determineQuadrant(lonlat);return OpenLayers.Bounds.oppositeQuadrant(quadrant);},updateRelativePosition:function(){},calculateNewPx:function(px){var newPx=px.offset(this.anchor.offset);var size=this.size||this.contentSize;var top=(this.relativePosition.charAt(0)=='t');newPx.y+=(top)?-(size.h+this.anchor.size.h):this.anchor.size.h;var left=(this.relativePosition.charAt(1)=='l');newPx.x+=(left)?-(size.w+this.anchor.size.w):this.anchor.size.w;return newPx;},CLASS_NAME:"OpenLayers.Popup.Anchored"});OpenLayers.Protocol.SOS=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Protocol.SOS.DEFAULTS);var cls=OpenLayers.Protocol.SOS["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported SOS version: "+options.version;} -return new cls(options);};OpenLayers.Protocol.SOS.DEFAULTS={"version":"1.0.0"};OpenLayers.Protocol.SQL=OpenLayers.Class(OpenLayers.Protocol,{databaseName:'ol',tableName:"ol_vector_features",postReadFiltering:true,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);},destroy:function(){OpenLayers.Protocol.prototype.destroy.apply(this);},supported:function(){return false;},evaluateFilter:function(feature,filter){return filter&&this.postReadFiltering?filter.evaluate(feature):true;},CLASS_NAME:"OpenLayers.Protocol.SQL"});OpenLayers.Protocol.WFS=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Protocol.WFS.DEFAULTS);var cls=OpenLayers.Protocol.WFS["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported WFS version: "+options.version;} -return new cls(options);};OpenLayers.Protocol.WFS.fromWMSLayer=function(layer,options){var typeName,featurePrefix;var param=layer.params["LAYERS"];var parts=(param instanceof Array?param[0]:param).split(":");if(parts.length>1){featurePrefix=parts[0];} -typeName=parts.pop();var protocolOptions={url:layer.url,featureType:typeName,featurePrefix:featurePrefix,srsName:layer.projection&&layer.projection.getCode()||layer.map&&layer.map.getProjectionObject().getCode(),version:"1.1.0"};return new OpenLayers.Protocol.WFS(OpenLayers.Util.applyDefaults(options,protocolOptions));};OpenLayers.Protocol.WFS.DEFAULTS={"version":"1.0.0"};OpenLayers.Renderer.Canvas=OpenLayers.Class(OpenLayers.Renderer,{canvas:null,features:null,initialize:function(containerID){OpenLayers.Renderer.prototype.initialize.apply(this,arguments);this.root=document.createElement("canvas");this.container.appendChild(this.root);this.canvas=this.root.getContext("2d");this.features={};},eraseGeometry:function(geometry,featureId){this.eraseFeatures(this.features[featureId][0]);},supported:function(){var canvas=document.createElement("canvas");return!!canvas.getContext;},setExtent:function(extent){this.extent=extent.clone();this.resolution=null;this.redraw();},setSize:function(size){this.size=size.clone();this.root.style.width=size.w+"px";this.root.style.height=size.h+"px";this.root.width=size.w;this.root.height=size.h;this.resolution=null;},drawFeature:function(feature,style){style=style||feature.style;style=this.applyDefaultSymbolizer(style);this.features[feature.id]=[feature,style];this.redraw();},drawGeometry:function(geometry,style){var className=geometry.CLASS_NAME;if((className=="OpenLayers.Geometry.Collection")||(className=="OpenLayers.Geometry.MultiPoint")||(className=="OpenLayers.Geometry.MultiLineString")||(className=="OpenLayers.Geometry.MultiPolygon")){for(var i=0;i1){middle=parseInt((leftIndex+rightIndex)/2);var placement=this.compare(this,newNode,OpenLayers.Util.getElement(this.order[middle]));if(placement>0){leftIndex=middle;}else{rightIndex=middle;}} -this.order.splice(rightIndex,0,nodeId);this.indices[nodeId]=this.getZIndex(newNode);return this.getNextElement(rightIndex);},remove:function(node){var nodeId=node.id;var arrayIndex=OpenLayers.Util.indexOf(this.order,nodeId);if(arrayIndex>=0){this.order.splice(arrayIndex,1);delete this.indices[nodeId];if(this.order.length>0){var lastId=this.order[this.order.length-1];this.maxZIndex=this.indices[lastId];}else{this.maxZIndex=0;}}},clear:function(){this.order=[];this.indices={};this.maxZIndex=0;},exists:function(node){return(this.indices[node.id]!=null);},getZIndex:function(node){return node._style.graphicZIndex;},determineZIndex:function(node){var zIndex=node._style.graphicZIndex;if(zIndex==null){zIndex=this.maxZIndex;node._style.graphicZIndex=zIndex;}else if(zIndex>this.maxZIndex){this.maxZIndex=zIndex;}},getNextElement:function(index){var nextIndex=index+1;if(nextIndex=0;--j){cluster=clusters[j];if(this.shouldCluster(cluster,feature)){this.addToCluster(cluster,feature);clustered=true;break;}} -if(!clustered){clusters.push(this.createCluster(this.features[i]));}}} -this.layer.removeAllFeatures();if(clusters.length>0){if(this.threshold>1){var clone=clusters.slice();clusters=[];var candidate;for(var i=0,len=clone.length;i0&&this.clusters.length==this.layer.features.length){exist=true;for(var i=0;i0){var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var geom;for(var i=0,len=features.length;i0){this.length=newLength;} -return this.length;},pageNext:function(event){var changed=false;if(this.features){if(this.num===null){this.num=-1;} -var start=(this.num+1)*this.length;changed=this.page(start,event);} -return changed;},pagePrevious:function(){var changed=false;if(this.features){if(this.num===null){this.num=this.pageCount();} -var start=(this.num-1)*this.length;changed=this.page(start);} -return changed;},page:function(start,event){var changed=false;if(this.features){if(start>=0&&start0){this.timer=window.setInterval(OpenLayers.Function.bind(this.refresh,this),this.interval);}},refresh:function(){if(this.layer&&this.layer.refresh&&typeof this.layer.refresh=="function"){this.layer.refresh({force:this.force});}},stop:function(){if(this.timer!==null){window.clearInterval(this.timer);this.timer=null;}},CLASS_NAME:"OpenLayers.Strategy.Refresh"});OpenLayers.Strategy.Save=OpenLayers.Class(OpenLayers.Strategy,{EVENT_TYPES:["start","success","fail"],events:null,auto:false,timer:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){if(this.auto){if(typeof this.auto==="number"){this.timer=window.setInterval(OpenLayers.Function.bind(this.save,this),this.auto*1000);}else{this.layer.events.on({"featureadded":this.triggerSave,"afterfeaturemodified":this.triggerSave,scope:this});}}} -return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){if(this.auto){if(typeof this.auto==="number"){window.clearInterval(this.timer);}else{this.layer.events.un({"featureadded":this.triggerSave,"afterfeaturemodified":this.triggerSave,scope:this});}}} -return deactivated;},triggerSave:function(event){var feature=event.feature;if(feature.state===OpenLayers.State.INSERT||feature.state===OpenLayers.State.UPDATE||feature.state===OpenLayers.State.DELETE){this.save([event.feature]);}},save:function(features){if(!features){features=this.layer.features;} -this.events.triggerEvent("start",{features:features});var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var len=features.length;var clones=new Array(len);var orig,clone;for(var i=0;i0){this.layer.destroyFeatures(destroys);} -this.events.triggerEvent("success",evt);}else{this.events.triggerEvent("fail",evt);}},CLASS_NAME:"OpenLayers.Strategy.Save"});OpenLayers.Symbolizer.Line=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Line"});OpenLayers.Symbolizer.Point=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,fillColor:null,fillOpacity:null,pointRadius:null,externalGraphic:null,graphicWidth:null,graphicHeight:null,graphicOpacity:null,graphicXOffset:null,graphicYOffset:null,rotation:null,graphicName:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Point"});OpenLayers.Symbolizer.Polygon=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,fillColor:null,fillOpacity:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Polygon"});OpenLayers.Symbolizer.Raster=OpenLayers.Class(OpenLayers.Symbolizer,{initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Raster"});OpenLayers.Symbolizer.Text=OpenLayers.Class(OpenLayers.Symbolizer,{label:null,fontFamily:null,fontSize:null,fontWeight:null,fontStyle:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Text"});OpenLayers.Tween=OpenLayers.Class({INTERVAL:10,easing:null,begin:null,finish:null,duration:null,callbacks:null,time:null,interval:null,playing:false,initialize:function(easing){this.easing=(easing)?easing:OpenLayers.Easing.Expo.easeOut;},start:function(begin,finish,duration,options){this.playing=true;this.begin=begin;this.finish=finish;this.duration=duration;this.callbacks=options.callbacks;this.time=0;if(this.interval){window.clearInterval(this.interval);this.interval=null;} -if(this.callbacks&&this.callbacks.start){this.callbacks.start.call(this,this.begin);} -this.interval=window.setInterval(OpenLayers.Function.bind(this.play,this),this.INTERVAL);},stop:function(){if(!this.playing){return;} -if(this.callbacks&&this.callbacks.done){this.callbacks.done.call(this,this.finish);} -window.clearInterval(this.interval);this.interval=null;this.playing=false;},play:function(){var value={};for(var i in this.begin){var b=this.begin[i];var f=this.finish[i];if(b==null||f==null||isNaN(b)||isNaN(f)){OpenLayers.Console.error('invalid value for Tween');} -var c=f-b;value[i]=this.easing.apply(this,[this.time,b,c,this.duration]);} -this.time++;if(this.callbacks&&this.callbacks.eachStep){this.callbacks.eachStep.call(this,value);} -if(this.time>this.duration){this.stop();}},CLASS_NAME:"OpenLayers.Tween"});OpenLayers.Easing={CLASS_NAME:"OpenLayers.Easing"};OpenLayers.Easing.Linear={easeIn:function(t,b,c,d){return c*t/d+b;},easeOut:function(t,b,c,d){return c*t/d+b;},easeInOut:function(t,b,c,d){return c*t/d+b;},CLASS_NAME:"OpenLayers.Easing.Linear"};OpenLayers.Easing.Expo={easeIn:function(t,b,c,d){return(t==0)?b:c*Math.pow(2,10*(t/d-1))+b;},easeOut:function(t,b,c,d){return(t==d)?b+c:c*(-Math.pow(2,-10*t/d)+1)+b;},easeInOut:function(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;},CLASS_NAME:"OpenLayers.Easing.Expo"};OpenLayers.Easing.Quad={easeIn:function(t,b,c,d){return c*(t/=d)*t+b;},easeOut:function(t,b,c,d){return-c*(t/=d)*(t-2)+b;},easeInOut:function(t,b,c,d){if((t/=d/2)<1)return c/2*t*t+b;return-c/2*((--t)*(t-2)-1)+b;},CLASS_NAME:"OpenLayers.Easing.Quad"};OpenLayers.Control.ArgParser=OpenLayers.Class(OpenLayers.Control,{center:null,zoom:null,layers:null,displayProjection:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);for(var i=0,len=this.map.controls.length;i=mapBounds.bottom&&!labelPoint){labelPoint=gridPoint;}} -if(this.labelled){var labelPos=new OpenLayers.Geometry.Point(labelPoint.x,mapBounds.bottom);var labelAttrs={value:lon,label:this.labelled?OpenLayers.Util.getFormattedLonLat(lon,"lon",this.labelFormat):"",labelAlign:"cb",xOffset:0,yOffset:2};this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(labelPos,labelAttrs));} -var geom=new OpenLayers.Geometry.LineString(pointList);lines.push(new OpenLayers.Feature.Vector(geom));} -for(var j=0;j90){continue;} -var pointList=[];var lonStart=centerLatPoints[0].x;var lonEnd=centerLatPoints[centerLatPoints.length-1].x;var lonDelta=(lonEnd-lonStart)/this.numPoints;var lon=lonStart;var labelPoint=null;for(var i=0;i<=this.numPoints;++i){var gridPoint=new OpenLayers.Geometry.Point(lon,lat);gridPoint.transform(llProj,mapProj);pointList.push(gridPoint);lon+=lonDelta;if(gridPoint.x0){this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),this.map.getZoom()-1);}},zoomBoxEnd:function(evt){if(this.mouseDragStart!=null){if(Math.abs(this.mouseDragStart.x-evt.xy.x)>5||Math.abs(this.mouseDragStart.y-evt.xy.y)>5){var start=this.map.getLonLatFromViewPortPx(this.mouseDragStart);var end=this.map.getLonLatFromViewPortPx(evt.xy);var top=Math.max(start.lat,end.lat);var bottom=Math.min(start.lat,end.lat);var left=Math.min(start.lon,end.lon);var right=Math.max(start.lon,end.lon);var bounds=new OpenLayers.Bounds(left,bottom,right,top);this.map.zoomToExtent(bounds);}else{var end=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(new OpenLayers.LonLat((end.lon),(end.lat)),this.map.getZoom()+1);} -this.removeZoomBox();}},removeZoomBox:function(){this.map.viewPortDiv.removeChild(this.zoomBox);this.zoomBox=null;},onWheelEvent:function(e){var inMap=false;var elem=OpenLayers.Event.element(e);while(elem!=null){if(this.map&&elem==this.map.div){inMap=true;break;} -elem=elem.parentNode;} -if(inMap){var delta=0;if(!e){e=window.event;} -if(e.wheelDelta){delta=e.wheelDelta/120;if(window.opera&&window.opera.version()<9.2){delta=-delta;}}else if(e.detail){delta=-e.detail/3;} -if(delta){e.xy=this.mousePosition;if(delta<0){this.defaultWheelDown(e);}else{this.defaultWheelUp(e);}} -OpenLayers.Event.stop(e);}},CLASS_NAME:"OpenLayers.Control.MouseDefaults"});OpenLayers.Control.MousePosition=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,element:null,prefix:'',separator:', ',suffix:'',numDigits:5,granularity:10,emptyString:null,lastXy:null,displayProjection:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.map.events.register('mousemove',this,this.redraw);this.map.events.register('mouseout',this,this.reset);this.redraw();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.map.events.unregister('mousemove',this,this.redraw);this.map.events.unregister('mouseout',this,this.reset);this.element.innerHTML="";return true;}else{return false;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.div.left="";this.div.top="";this.element=this.div;} -return this.div;},redraw:function(evt){var lonLat;if(evt==null){this.reset();return;}else{if(this.lastXy==null||Math.abs(evt.xy.x-this.lastXy.x)>this.granularity||Math.abs(evt.xy.y-this.lastXy.y)>this.granularity) -{this.lastXy=evt.xy;return;} -lonLat=this.map.getLonLatFromPixel(evt.xy);if(!lonLat){return;} -if(this.displayProjection){lonLat.transform(this.map.getProjectionObject(),this.displayProjection);} -this.lastXy=evt.xy;} -var newHtml=this.formatOutput(lonLat);if(newHtml!=this.element.innerHTML){this.element.innerHTML=newHtml;}},reset:function(evt){if(this.emptyString!=null){this.element.innerHTML=this.emptyString;}},formatOutput:function(lonLat){var digits=parseInt(this.numDigits);var newHtml=this.prefix+ -lonLat.lon.toFixed(digits)+ -this.separator+ -lonLat.lat.toFixed(digits)+ -this.suffix;return newHtml;},CLASS_NAME:"OpenLayers.Control.MousePosition"});OpenLayers.Control.Pan=OpenLayers.Class(OpenLayers.Control,{slideFactor:50,direction:null,type:OpenLayers.Control.TYPE_BUTTON,initialize:function(direction,options){this.direction=direction;this.CLASS_NAME+=this.direction;OpenLayers.Control.prototype.initialize.apply(this,[options]);},trigger:function(){switch(this.direction){case OpenLayers.Control.Pan.NORTH:this.map.pan(0,-this.slideFactor);break;case OpenLayers.Control.Pan.SOUTH:this.map.pan(0,this.slideFactor);break;case OpenLayers.Control.Pan.WEST:this.map.pan(-this.slideFactor,0);break;case OpenLayers.Control.Pan.EAST:this.map.pan(this.slideFactor,0);break;}},CLASS_NAME:"OpenLayers.Control.Pan"});OpenLayers.Control.Pan.NORTH="North";OpenLayers.Control.Pan.SOUTH="South";OpenLayers.Control.Pan.EAST="East";OpenLayers.Control.Pan.WEST="West";OpenLayers.Control.PanZoom=OpenLayers.Class(OpenLayers.Control,{slideFactor:50,slideRatio:null,buttons:null,position:null,initialize:function(options){this.position=new OpenLayers.Pixel(OpenLayers.Control.PanZoom.X,OpenLayers.Control.PanZoom.Y);OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this,arguments);this.removeButtons();this.buttons=null;this.position=null;},draw:function(px){OpenLayers.Control.prototype.draw.apply(this,arguments);px=this.position;this.buttons=[];var sz=new OpenLayers.Size(18,18);var centered=new OpenLayers.Pixel(px.x+sz.w/2,px.y);this._addButton("panup","north-mini.png",centered,sz);px.y=centered.y+sz.h;this._addButton("panleft","west-mini.png",px,sz);this._addButton("panright","east-mini.png",px.add(sz.w,0),sz);this._addButton("pandown","south-mini.png",centered.add(0,sz.h*2),sz);this._addButton("zoomin","zoom-plus-mini.png",centered.add(0,sz.h*3+5),sz);this._addButton("zoomworld","zoom-world-mini.png",centered.add(0,sz.h*4+5),sz);this._addButton("zoomout","zoom-minus-mini.png",centered.add(0,sz.h*5+5),sz);return this.div;},_addButton:function(id,img,xy,sz){var imgLocation=OpenLayers.Util.getImagesLocation()+img;var btn=OpenLayers.Util.createAlphaImageDiv(this.id+"_"+id,xy,sz,imgLocation,"absolute");this.div.appendChild(btn);OpenLayers.Event.observe(btn,"mousedown",OpenLayers.Function.bindAsEventListener(this.buttonDown,btn));OpenLayers.Event.observe(btn,"dblclick",OpenLayers.Function.bindAsEventListener(this.doubleClick,btn));OpenLayers.Event.observe(btn,"click",OpenLayers.Function.bindAsEventListener(this.doubleClick,btn));btn.action=id;btn.map=this.map;if(!this.slideRatio){var slideFactorPixels=this.slideFactor;var getSlideFactor=function(){return slideFactorPixels;};}else{var slideRatio=this.slideRatio;var getSlideFactor=function(dim){return this.map.getSize()[dim]*slideRatio;};} -btn.getSlideFactor=getSlideFactor;this.buttons.push(btn);return btn;},_removeButton:function(btn){OpenLayers.Event.stopObservingElement(btn);btn.map=null;btn.getSlideFactor=null;this.div.removeChild(btn);OpenLayers.Util.removeItem(this.buttons,btn);},removeButtons:function(){for(var i=this.buttons.length-1;i>=0;--i){this._removeButton(this.buttons[i]);}},doubleClick:function(evt){OpenLayers.Event.stop(evt);return false;},buttonDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;} -switch(this.action){case"panup":this.map.pan(0,-this.getSlideFactor("h"));break;case"pandown":this.map.pan(0,this.getSlideFactor("h"));break;case"panleft":this.map.pan(-this.getSlideFactor("w"),0);break;case"panright":this.map.pan(this.getSlideFactor("w"),0);break;case"zoomin":this.map.zoomIn();break;case"zoomout":this.map.zoomOut();break;case"zoomworld":this.map.zoomToMaxExtent();break;} -OpenLayers.Event.stop(evt);},CLASS_NAME:"OpenLayers.Control.PanZoom"});OpenLayers.Control.PanZoom.X=4;OpenLayers.Control.PanZoom.Y=4;OpenLayers.Control.Panel=OpenLayers.Class(OpenLayers.Control,{controls:null,autoActivate:true,defaultControl:null,saveState:false,activeState:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.controls=[];this.activeState={};},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this,arguments);for(var i=this.controls.length-1;i>=0;i--){if(this.controls[i].events){this.controls[i].events.un({"activate":this.redraw,"deactivate":this.redraw,scope:this});} -OpenLayers.Event.stopObservingElement(this.controls[i].panel_div);this.controls[i].panel_div=null;} -this.activeState=null;},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){var control;for(var i=0,len=this.controls.length;i0){for(var l=this.div.children.length,i=l-1;i>=0;i--){this.div.removeChild(this.div.children[i]);}} -this.div.innerHTML="";if(this.active){for(var i=0,len=this.controls.length;i=9500&&scale<=950000){scale=Math.round(scale/1000)+"K";}else if(scale>=950000){scale=Math.round(scale/1000000)+"M";}else{scale=Math.round(scale);} -this.element.innerHTML=OpenLayers.i18n("scale",{'scaleDenom':scale});},CLASS_NAME:"OpenLayers.Control.Scale"});OpenLayers.Control.ScaleLine=OpenLayers.Class(OpenLayers.Control,{maxWidth:100,topOutUnits:"km",topInUnits:"m",bottomOutUnits:"mi",bottomInUnits:"ft",eTop:null,eBottom:null,geodesic:false,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.eTop){this.eTop=document.createElement("div");this.eTop.className=this.displayClass+"Top";var theLen=this.topInUnits.length;this.div.appendChild(this.eTop);if((this.topOutUnits=="")||(this.topInUnits=="")){this.eTop.style.visibility="hidden";}else{this.eTop.style.visibility="visible";} -this.eBottom=document.createElement("div");this.eBottom.className=this.displayClass+"Bottom";this.div.appendChild(this.eBottom);if((this.bottomOutUnits=="")||(this.bottomInUnits=="")){this.eBottom.style.visibility="hidden";}else{this.eBottom.style.visibility="visible";}} -this.map.events.register('moveend',this,this.update);this.update();return this.div;},getBarLen:function(maxLen){var digits=parseInt(Math.log(maxLen)/Math.log(10));var pow10=Math.pow(10,digits);var firstChar=parseInt(maxLen/pow10);var barLen;if(firstChar>5){barLen=5;}else if(firstChar>2){barLen=2;}else{barLen=1;} -return barLen*pow10;},update:function(){var res=this.map.getResolution();if(!res){return;} -var curMapUnits=this.map.getUnits();var inches=OpenLayers.INCHES_PER_UNIT;var maxSizeData=this.maxWidth*res*inches[curMapUnits];var geodesicRatio=1;if(this.geodesic===true){var maxSizeGeodesic=(this.map.getGeodesicPixelSize().w||0.000001)*this.maxWidth;var maxSizeKilometers=maxSizeData/inches["km"];geodesicRatio=maxSizeGeodesic/maxSizeKilometers;maxSizeData*=geodesicRatio;} -var topUnits;var bottomUnits;if(maxSizeData>100000){topUnits=this.topOutUnits;bottomUnits=this.bottomOutUnits;}else{topUnits=this.topInUnits;bottomUnits=this.bottomInUnits;} -var topMax=maxSizeData/inches[topUnits];var bottomMax=maxSizeData/inches[bottomUnits];var topRounded=this.getBarLen(topMax);var bottomRounded=this.getBarLen(bottomMax);topMax=topRounded/inches[curMapUnits]*inches[topUnits];bottomMax=bottomRounded/inches[curMapUnits]*inches[bottomUnits];var topPx=topMax/res/geodesicRatio;var bottomPx=bottomMax/res/geodesicRatio;if(this.eBottom.style.visibility=="visible"){this.eBottom.style.width=Math.round(bottomPx)+"px";this.eBottom.innerHTML=bottomRounded+" "+bottomUnits;} -if(this.eTop.style.visibility=="visible"){this.eTop.style.width=Math.round(topPx)+"px";this.eTop.innerHTML=topRounded+" "+topUnits;}},CLASS_NAME:"OpenLayers.Control.ScaleLine"});OpenLayers.Control.ZoomIn=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomIn();},CLASS_NAME:"OpenLayers.Control.ZoomIn"});OpenLayers.Control.ZoomOut=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomOut();},CLASS_NAME:"OpenLayers.Control.ZoomOut"});OpenLayers.Control.ZoomToMaxExtent=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){if(this.map){this.map.zoomToMaxExtent();}},CLASS_NAME:"OpenLayers.Control.ZoomToMaxExtent"});OpenLayers.Event={observers:false,KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,element:function(event){return event.target||event.srcElement;},isLeftClick:function(event){return(((event.which)&&(event.which==1))||((event.button)&&(event.button==1)));},isRightClick:function(event){return(((event.which)&&(event.which==3))||((event.button)&&(event.button==2)));},stop:function(event,allowDefault){if(!allowDefault){if(event.preventDefault){event.preventDefault();}else{event.returnValue=false;}} -if(event.stopPropagation){event.stopPropagation();}else{event.cancelBubble=true;}},findElement:function(event,tagName){var element=OpenLayers.Event.element(event);while(element.parentNode&&(!element.tagName||(element.tagName.toUpperCase()!=tagName.toUpperCase()))){element=element.parentNode;} -return element;},observe:function(elementParam,name,observer,useCapture){var element=OpenLayers.Util.getElement(elementParam);useCapture=useCapture||false;if(name=='keypress'&&(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||element.attachEvent)){name='keydown';} -if(!this.observers){this.observers={};} -if(!element._eventCacheID){var idPrefix="eventCacheID_";if(element.id){idPrefix=element.id+"_"+idPrefix;} -element._eventCacheID=OpenLayers.Util.createUniqueID(idPrefix);} -var cacheID=element._eventCacheID;if(!this.observers[cacheID]){this.observers[cacheID]=[];} -this.observers[cacheID].push({'element':element,'name':name,'observer':observer,'useCapture':useCapture});if(element.addEventListener){element.addEventListener(name,observer,useCapture);}else if(element.attachEvent){element.attachEvent('on'+name,observer);}},stopObservingElement:function(elementParam){var element=OpenLayers.Util.getElement(elementParam);var cacheID=element._eventCacheID;this._removeElementObservers(OpenLayers.Event.observers[cacheID]);},_removeElementObservers:function(elementObservers){if(elementObservers){for(var i=elementObservers.length-1;i>=0;i--){var entry=elementObservers[i];var args=new Array(entry.element,entry.name,entry.observer,entry.useCapture);var removed=OpenLayers.Event.stopObserving.apply(this,args);}}},stopObserving:function(elementParam,name,observer,useCapture){useCapture=useCapture||false;var element=OpenLayers.Util.getElement(elementParam);var cacheID=element._eventCacheID;if(name=='keypress'){if(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||element.detachEvent){name='keydown';}} -var foundEntry=false;var elementObservers=OpenLayers.Event.observers[cacheID];if(elementObservers){var i=0;while(!foundEntry&&i
"+"To get rid of this message, select a new BaseLayer "+"in the layer switcher in the upper-right corner.

"+"Most likely, this is because the Google Maps library "+"script was either not included, or does not contain the "+"correct API key for your site.

"+"Developers: For help getting this working correctly, "+"click here",'getLayerWarning':"The ${layerType} Layer was unable to load correctly.

"+"To get rid of this message, select a new BaseLayer "+"in the layer switcher in the upper-right corner.

"+"Most likely, this is because the ${layerLib} library "+"script was not correctly included.

"+"Developers: For help getting this working correctly, "+"click here",'scale':"Scale = 1 : ${scaleDenom}",'W':'W','E':'E','N':'N','S':'S','graticule':'Graticule','layerAlreadyAdded':"You tried to add the layer: ${layerName} to the map, but it has already been added",'reprojectDeprecated':"You are using the 'reproject' option "+"on the ${layerName} layer. This option is deprecated: "+"its use was designed to support displaying data over commercial "+"basemaps, but that functionality should now be achieved by using "+"Spherical Mercator support. More information is available from "+"http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"This method has been deprecated and will be removed in 3.0. "+"Please use ${newMethod} instead.",'boundsAddError':"You must pass both x and y values to the add function.",'lonlatAddError':"You must pass both lon and lat values to the add function.",'pixelAddError':"You must pass both x and y values to the add function.",'unsupportedGeometryType':"Unsupported geometry type: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: element with id ${elemId} may be misplaced.",'filterEvaluateNotImplemented':"evaluate is not implemented for this filter type.",'end':''};OpenLayers.Lang["fi"]=OpenLayers.Util.applyDefaults({'permalink':"Ikilinkki",'overlays':"Kerrokset",'baseLayer':"Peruskerros",'sameProjection':"Yleiskuvakarttaa voi käyttää vain, kun sillä on sama projektio kuin pääkartalla.",'W':"L",'E':"I",'N':"P",'S':"E"});OpenLayers.Lang["fur"]=OpenLayers.Util.applyDefaults({'permalink':"Leam Permanent",'overlays':"Livei parsore",'baseLayer':"Livel di base",'browserNotSupported':"Il to sgarfadôr nol supuarte la renderizazion vetoriâl. Al moment a son supuartâts:\n${renderers}",'scale':"Scjale = 1 : ${scaleDenom}",'W':"O",'E':"E",'N':"N",'S':"S"});OpenLayers.Lang["gl"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Solicitude non xerada; a resposta foi: ${statusText}",'permalink':"Ligazón permanente",'overlays':"Capas superpostas",'baseLayer':"Capa base",'sameProjection':"A vista xeral do mapa só funciona cando está na mesma proxección có mapa principal",'readNotImplemented':"Lectura non implementada.",'writeNotImplemented':"Escritura non implementada.",'noFID':"Non se pode actualizar a funcionalidade para a que non hai FID.",'errorLoadingGML':"Erro ao cargar o ficheiro GML ${url}",'browserNotSupported':"O seu navegador non soporta a renderización de vectores. Os renderizadores soportados actualmente son:\n${renderers}",'componentShouldBe':"addFeatures: o compoñente debera ser de tipo ${geomType}",'getFeatureError':"getFeatureFromEvent ten sido chamado a unha capa sen renderizador. Isto normalmente significa que destruíu unha capa, mais non o executador que está asociado con ela.",'minZoomLevelError':"A propiedade minZoomLevel é só para uso conxuntamente coas capas FixedZoomLevels-descendent. O feito de que esa capa wfs verifique o minZoomLevel é unha reliquia do pasado. Non podemos, con todo, eliminala sen a posibilidade de non romper as aplicacións baseadas en OL que poidan depender dela. Por iso a estamos deixando obsoleta (a comprobación minZoomLevel de embaixo será eliminada na versión 3.0). Por favor, no canto diso use o axuste de resolución mín/máx tal e como está descrito aquí: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transacción WFS: ÉXITO ${response}",'commitFailed':"Transacción WFS: FALLIDA ${response}",'googleWarning':"A capa do Google non puido cargarse correctamente.\x3cbr\x3e\x3cbr\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\x3cbr\x3e\x3cbr\x3eProbablemente, isto acontece porque a escritura da libraría do Google Maps ou ben non foi incluída ou ben non contén a clave API correcta para o seu sitio.\x3cbr\x3e\x3cbr\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3epremede aquí\x3c/a\x3e",'getLayerWarning':"A capa ${layerType} foi incapaz de cargarse correctamente.\x3cbr\x3e\x3cbr\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\x3cbr\x3e\x3cbr\x3eProbablemente, isto acontece porque a escritura da libraría ${layerLib} non foi ben incluída.\x3cbr\x3e\x3cbr\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3epremede aquí\x3c/a\x3e",'scale':"Escala = 1 : ${scaleDenom}",'W':"O",'E':"L",'N':"N",'S':"S",'layerAlreadyAdded':"Intentou engadir a capa: ${layerName} ao mapa, pero xa fora engadida",'reprojectDeprecated':"Está usando a opción \"reproject\" na capa ${layerName}. Esta opción está obsoleta: o seu uso foi deseñado para a visualización de datos sobre mapas base comerciais, pero esta funcionalidade debera agora ser obtida utilizando a proxección Spherical Mercator. Hai dispoñible máis información en http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Este método está obsoleto e será eliminado na versión 3.0. Por favor, no canto deste use ${newMethod}.",'boundsAddError':"Debe achegar os valores x e y á función add.",'lonlatAddError':"Debe achegar tanto o valor lon coma o lat á función add.",'pixelAddError':"Debe achegar os valores x e y á función add.",'unsupportedGeometryType':"Tipo xeométrico non soportado: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition fallou: o elemento con id ${elemId} pode non estar na súa posición.",'filterEvaluateNotImplemented':"avaliar non está implementado para este tipo de filtro."});OpenLayers.Lang["gsw"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nit behandleti Aafrogsruckmäldig ${statusText}",'permalink':"Permalink",'overlays':"Iberlagerige",'baseLayer':"Grundcharte",'sameProjection':"D Ibersichts-Charte funktioniert nume, wänn si di glych Projäktion brucht wie d Hauptcharte",'readNotImplemented':"Läse nit implementiert.",'writeNotImplemented':"Schrybe nit implementiert.",'noFID':"E Feature, wu s kei FID derfir git, cha nit aktualisiert wäre.",'errorLoadingGML':"Fähler bim Lade vu dr GML-Datei ${url}",'browserNotSupported':"Dyy Browser unterstitzt kei Vektordarstellig. Aktuäll unterstitzti Renderer:\n${renderers}",'componentShouldBe':"addFeatures : Komponänt sott dr Typ ${geomType} syy",'getFeatureError':"getFeatureFromEvent isch uf eme Layer ohni Renderer ufgruefe wore. Des heisst normalerwys, ass Du e Layer kaputt gmacht hesch, aber nit dr Handler, wu derzue ghert.",'minZoomLevelError':"D minZoomLevel-Eigeschaft isch nume dänk fir d Layer, wu vu dr FixedZoomLevels abstamme. Ass dää wfs-Layer minZoomLevel prieft, scih e Relikt us dr Vergangeheit. Mir chenne s aber nit ändere ohni OL_basierti Aawändige villicht kaputt gehn, wu dervu abhänge. Us däm Grund het die Funktion d Eigeschaft \'deprecated\' iberchuu. D minZoomLevel-Priefig unte wird in dr Version 3.0 usegnuu. Bitte verwänd statt däm e min/max-Uflesig wie s do bschriben isch: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-Transaktion: ERFOLGRYCH ${response}",'commitFailed':"WFS-Transaktion: FÄHLGSCHLAA ${response}",'googleWarning':"Dr Google-Layer het nit korräkt chenne glade wäre.\x3cbr\x3e\x3cbr\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\x3cbr\x3e\x3cbr\x3eDää Fähler git s seli hyfig, wel s Skript vu dr Google-Maps-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\x3cbr\x3e\x3cbr\x3eEntwickler: Fir Hilf zum korräkte Yybinde vum Google-Layer \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3edoo drucke\x3c/a\x3e",'getLayerWarning':"Dr ${layerType}-Layer het nit korräkt chenne glade wäre.\x3cbr\x3e\x3cbr\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\x3cbr\x3e\x3cbr\x3eDää Fähler git s seli hyfig, wel s Skript vu dr \'${layerLib}\'-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\x3cbr\x3e\x3cbr\x3eEntwickler: Fir Hilf zum korräkte Yybinde vu Layer \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3edoo drucke\x3c/a\x3e",'scale':"Maßstab = 1 : ${scaleDenom}",'W':"W",'E':"O",'N':"N",'S':"S",'layerAlreadyAdded':"Du hesch versuecht dää Layer in d Charte yyzfiege: ${layerName}, aber är isch schoi yygfiegt",'reprojectDeprecated':"Du bruchsch d \'reproject\'-Option bim ${layerName}-Layer. Die Option isch nimi giltig: si isch aagleit wore go Date iber kommerziälli Grundcharte lege, aber des sott mer jetz mache mit dr Unterstitzig vu Spherical Mercator. Meh Informatione git s uf http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Die Methode isch veraltet un wird us dr Version 3.0 usegnuu. Bitte verwäbnd statt däm ${newMethod}.",'boundsAddError':"Du muesch e x-Wärt un e y-Wärt yygee bi dr Zuefieg-Funktion",'lonlatAddError':"Du meusch e Lengi- un e Breiti-Grad yygee bi dr Zuefieg-Funktion.",'pixelAddError':"Du muesch x- un y-Wärt aagee bi dr Zuefieg-Funktion.",'unsupportedGeometryType':"Nit unterstitze Geometrii-Typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition fählgschlaa: Elemänt mit ID ${elemId} isch villicht falsch gsetzt.",'filterEvaluateNotImplemented':"evaluiere isch nit implemäntiert in däm Filtertyp."});OpenLayers.Lang["hr"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nepodržani zahtjev ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Osnovna karta",'sameProjection':"Pregledna karta radi jedino kao je u istoj projekciji kao i glava karta",'readNotImplemented':"ÄŒitanje nije implementirano.",'writeNotImplemented':"Pisanje nije implementirano.",'noFID':"Ne mogu ažurirati znaÄajku za koju ne postoji FID.",'errorLoadingGML':"GreÅ¡ka u uÄitavanju GML datoteke ${url}",'browserNotSupported':"VaÅ¡ preglednik ne podržava vektorsko renderiranje. Trenutno podržani rendereri su: ${renderers}",'componentShouldBe':"addFeatures : komponenta bi trebala biti ${geomType}",'getFeatureError':"getFeatureFromEvent je pozvao Layer bez renderera. Ovo obiÄno znaÄi da ste uniÅ¡tiili Layer, a ne neki Handler koji je povezan s njim.",'commitSuccess':"WFS Transakcija: USPJEÅ NA ${response}",'commitFailed':"WFS Transakcija: NEUSPJEÅ NA ${response}",'scale':"Mjerilo = 1 : ${scaleDenom}",'layerAlreadyAdded':"PokuÅ¡ali ste dodati layer: ${layerName} na kartu, ali je već dodan",'methodDeprecated':"Ova metoda nije odobrena i biti će maknuta u 3.0. Koristite ${newMethod}.",'boundsAddError':"Morate dati obje vrijednosti , x i y da bi dodali funkciju.",'lonlatAddError':"Morate dati obje vrijednosti , (lon i lat) da bi dodali funkciju.",'pixelAddError':"Morate dati obje vrijednosti , x i y da bi dodali funkciju.",'unsupportedGeometryType':"Nepodržani tip geometrije: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition nije uspjelo: element sa id ${elemId} može biti krivo smjeÅ¡ten."});OpenLayers.Lang["hsb"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"WotmoÅ‚wa njewobdźěłaneho napraÅ¡owanja ${statusText}",'permalink':"Trajny wotkaz",'overlays':"NaworÅ¡towanja",'baseLayer':"ZakÅ‚adna runina",'sameProjection':"PÅ™ehladowa karta jenož funguje, hdyž je w samsnej projekciji kaž hÅ‚owna karta",'readNotImplemented':"ÄŒitanje njeimplementowane.",'writeNotImplemented':"Pisanje njeimplementowane.",'noFID':"Funkcija, za kotruž FID njeje, njeda so aktualizować.",'errorLoadingGML':"Zmylk pÅ™i zaÄitowanju dataje ${url}",'browserNotSupported':"Twój wobhladowak wektorowe rysowanje njepodpÄ›ruje. Tuchwilu podpÄ›rowane rysowaki su:\n${renderers}",'componentShouldBe':"addFeatures: komponenta měła ${geomType} być",'getFeatureError':"getFeatureFromEvent bu na woršće bjez rysowak zawoÅ‚any. To zwjetÅ¡a woznamjenja, zo sy worÅ¡tu zniÄiÅ‚, ale nic wobdźěłak, kotryž je z njej zwjazany.",'minZoomLevelError':"Kajkosć minZoomLevel je jenož za wužiwanje z worÅ¡tami myslena, kotrež wot FixedZoomLevels pochadźeja. Zo tuta worÅ¡ta wfs za minZoomLevel pÅ™epruwuje, je relikt zaÅ„dźenosće. Njemóžemy wÅ¡ak ju wotstronić, bjeztoho zo aplikacije, kotrež na OpenLayers bazÄ›ruja a snano tutu kajkosć wužiwaja, hižo njefunguja. Tohodla smy ju jako zestarjenu woznamjenili -- pÅ™epruwowanje za minZoomLevel budu so we wersiji 3.0 wotstronjeć. ProÅ¡u wužij mÄ›sto toho nastajenje min/max, kaž je tu wopisane: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-Transakcija: WUSPĚŠNA ${response}",'commitFailed':"WFS-Transakcija: NJEPORADŹENA ${response}",'googleWarning':"WorÅ¡ta Google njemóžeÅ¡e so korektnje zaÄitać.\x3cbr\x3e\x3cbr\x3eZo by tutu zdźělenku wotbyÅ‚, wubjer nowy BaseLayer z wubÄ›ra worÅ¡tow horjeka naprawo.\x3cbr\x3e\x3cbr\x3eNajskerje so to stawa, dokelž skript biblioteki Google Maps pak njebu zapÅ™ijaty pak njewobsahuje korektny kluÄ API za twoje sydÅ‚o.\x3cbr\x3e\x3cbr\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worÅ¡tow\n\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3etu kliknyć\x3c/a\x3e",'getLayerWarning':"WorÅ¡ta ${layerType} njemóžeÅ¡e so korektnje zaÄitać.\x3cbr\x3e\x3cbr\x3eZo by tutu zdźělenku wotbyÅ‚, wubjer nowy BaseLayer z wubÄ›ra worÅ¡tow horjeka naprawo.\x3cbr\x3e\x3cbr\x3eNajskerje so to stawa, dokelž skript biblioteki ${layerLib} njebu korektnje zapÅ™ijaty.\x3cbr\x3e\x3cbr\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worÅ¡tow\n\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3etu kliknyć\x3c/a\x3e",'scale':"MÄ›ritko = 1 : ${scaleDenom}",'W':"Z",'E':"W",'N':"S",'S':"J",'layerAlreadyAdded':"Sy spytaÅ‚ runinu ${layerName} karće dodać, ale je so hižo dodaÅ‚a",'reprojectDeprecated':"WužiwaÅ¡ opciju \"reproject\" wořšty ${layerName}. Tuta opcija je zestarjena: jeje wužiwanje bÄ› myslene, zo by zwobraznjenje datow nad komercielnymi bazowymi kartami podpÄ›raÅ‚o, ale funkcionalnosć měła so nÄ›tko z pomocu Sperical Mercator docpěć. DalÅ¡e informacije steja na http://trac.openlayers.org/wiki/SphericalMercator k dispoziciji.",'methodDeprecated':"Tuta metoda je so njeschwaliÅ‚a a budźe so w 3.0 wotstronjeć. ProÅ¡u wužij ${newMethod} mÄ›sto toho.",'boundsAddError':"DyrbiÅ¡ hódnotu x kaž tež y funkciji \"add\" pÅ™epodać.",'lonlatAddError':"DyrbiÅ¡ hódnotu lon kaž tež lat funkciji \"add\" pÅ™epodać.",'pixelAddError':"DyrbiÅ¡ hódnotu x kaž tež y funkciji \"add\" pÅ™epodać.",'unsupportedGeometryType':"NjepodpÄ›rowany geometrijowy typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition je so njeporadźiÅ‚: element z id ${elemId} bu snano wopak zamÄ›stnjeny.",'filterEvaluateNotImplemented':"wuhódnoćenje njeje za tutón filtrowy typ implementowany."});OpenLayers.Lang["hu"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nem kezelt kérés visszatérése ${statusText}",'permalink':"Permalink",'overlays':"Rávetítések",'baseLayer':"Alapréteg",'sameProjection':"Az áttekintÅ‘ térkép csak abban az esetben működik, ha ugyanazon a vetületen van, mint a fÅ‘ térkép.",'readNotImplemented':"Olvasás nincs végrehajtva.",'writeNotImplemented':"Ãrás nincs végrehajtva.",'noFID':"Nem frissíthetÅ‘ olyan jellemzÅ‘, amely nem rendelkezik FID-del.",'errorLoadingGML':"Hiba GML-fájl betöltésekor ${url}",'browserNotSupported':"A böngészÅ‘je nem támogatja a vektoros renderelést. A jelenleg támogatott renderelÅ‘k:\n${renderers}",'componentShouldBe':"addFeatures : az összetevÅ‘nek ilyen típusúnak kell lennie: ${geomType}",'getFeatureError':"getFeatureFromEvent réteget hívott meg renderelÅ‘ nélkül. Ez rendszerint azt jelenti, hogy megsemmisített egy fóliát, de néhány ahhoz társított kezelÅ‘t nem.",'minZoomLevelError':"A minZoomLevel tulajdonságot csak a következÅ‘vel való használatra szánták: FixedZoomLevels-leszármazott fóliák. Ez azt jelenti, hogy a minZoomLevel wfs fólia jelölÅ‘négyzetei már a múlté. Mi azonban nem távolíthatjuk el annak a veszélye nélkül, hogy az esetlegesen ettÅ‘l függÅ‘ OL alapú alkalmazásokat tönkretennénk. Ezért ezt érvénytelenítjük -- a minZoomLevel az alul levÅ‘ jelölÅ‘négyzet a 3.0-s verzióból el lesz távolítva. Kérjük, helyette használja a min/max felbontás beállítást, amelyrÅ‘l az alábbi helyen talál leírást: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS tranzakció: SIKERES ${response}",'commitFailed':"WFS tranzakció: SIKERTELEN ${response}",'googleWarning':"A Google fólia betöltése sikertelen.\x3cbr\x3e\x3cbr\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felsÅ‘ sarokban található fóliakapcsoló segítségével.\x3cbr\x3e\x3cbr\x3eNagy valószínűséggel ez azért van, mert a Google Maps könyvtár parancsfájlja nem található, vagy nem tartalmazza az Ön oldalához tartozó megfelelÅ‘ API-kulcsot.\x3cbr\x3e\x3cbr\x3eFejlesztÅ‘knek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhetÅ‘ el, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3ekattintson ide\x3c/a\x3e",'getLayerWarning':"A(z) ${layerType} fólia nem töltÅ‘dött be helyesen.\x3cbr\x3e\x3cbr\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felsÅ‘ sarokban található fóliakapcsoló segítségével.\x3cbr\x3e\x3cbr\x3eNagy valószínűséggel ez azért van, mert a(z) ${layerLib} könyvtár parancsfájlja helytelen.\x3cbr\x3e\x3cbr\x3eFejlesztÅ‘knek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhetÅ‘ el, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3ekattintson ide\x3c/a\x3e",'scale':"Lépték = 1 : ${scaleDenom}",'W':"Ny",'E':"K",'N':"É",'S':"D",'layerAlreadyAdded':"Megpróbálta hozzáadni a(z) ${layerName} fóliát a térképhez, de az már hozzá van adva",'reprojectDeprecated':"Ön a \'reproject\' beállítást használja a(z) ${layerName} fólián. Ez a beállítás érvénytelen: használata az üzleti alaptérképek fölötti adatok megjelenítésének támogatására szolgált, de ezt a funkció ezentúl a Gömbi Mercator használatával érhetÅ‘ el. További információ az alábbi helyen érhetÅ‘ el: http://trac.openlayers.org/wiki/SphericalMercator",'methodDeprecated':"Ez a módszer érvénytelenítve lett és a 3.0-s verzióból el lesz távolítva. Használja a(z) ${newMethod} módszert helyette.",'boundsAddError':"Az x és y értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'lonlatAddError':"A hossz. és szél. értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'pixelAddError':"Az x és y értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'unsupportedGeometryType':"Nem támogatott geometriatípus: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition sikertelen: lehetséges, hogy a(z) ${elemId} azonosítójú elem téves helyre került.",'filterEvaluateNotImplemented':"ennél a szűrÅ‘típusnál kiértékelés nem hajtódik végre."});OpenLayers.Lang["ia"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Le responsa a un requesta non esseva maneate: ${statusText}",'permalink':"Permaligamine",'overlays':"Superpositiones",'baseLayer':"Strato de base",'sameProjection':"Le mini-carta functiona solmente si illo es in le mesme projection que le carta principal",'readNotImplemented':"Lectura non implementate.",'writeNotImplemented':"Scriptura non implementate.",'noFID':"Non pote actualisar un elemento sin FID.",'errorLoadingGML':"Error al cargamento del file GML ${url}",'browserNotSupported':"Tu navigator non supporta le rendition de vectores. Le renditores actualmente supportate es:\n${renderers}",'componentShouldBe':"addFeatures: le componente debe esser del typo ${geomType}",'getFeatureError':"getFeatureFromEvent ha essite appellate in un strato sin renditor. Isto significa generalmente que tu ha destruite un strato, ma lassava un gestor associate con illo.",'minZoomLevelError':"Le proprietate minZoomLevel es solmente pro uso con le stratos descendente de FixedZoomLevels. Le facto que iste strato WFS verifica minZoomLevel es un reliquia del passato. Nonobstante, si nos lo remove immediatemente, nos pote rumper applicationes a base de OL que depende de illo. Ergo nos lo declara obsolete; le verification de minZoomLevel in basso essera removite in version 3.0. Per favor usa in su loco le configuration de resolutiones min/max como describite a: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transaction WFS: SUCCESSO ${response}",'commitFailed':"Transaction WFS: FALLEVA ${response}",'googleWarning':"Le strato Google non poteva esser cargate correctemente.\x3cbr\x3e\x3cbr\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\x3cbr\x3e\x3cbr\x3eMulto probabilemente, isto es proque le script del libreria de Google Maps non esseva includite o non contine le clave API correcte pro tu sito.\x3cbr\x3e\x3cbr\x3eDisveloppatores: Pro adjuta de corriger isto, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclicca hic\x3c/a",'getLayerWarning':"Le strato ${layerType} non poteva esser cargate correctemente.\x3cbr\x3e\x3cbr\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\x3cbr\x3e\x3cbr\x3eMulto probabilemente, isto es proque le script del libreria de ${layerLib} non esseva correctemente includite.\x3cbr\x3e\x3cbr\x3eDisveloppatores: Pro adjuta de corriger isto, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclicca hic\x3c/a\x3e",'scale':"Scala = 1 : ${scaleDenom}",'W':"W",'E':"E",'N':"N",'S':"S",'layerAlreadyAdded':"Tu tentava adder le strato: ${layerName} al carta, ma illo es ja presente",'reprojectDeprecated':"Tu usa le option \'reproject\' in le strato ${layerName} layer. Iste option es obsolescente: illo esseva pro poter monstrar datos super cartas de base commercial, ma iste functionalitate pote ora esser attingite con le uso de Spherical Mercator. Ulterior information es disponibile a http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Iste methodo ha essite declarate obsolescente e essera removite in version 3.0. Per favor usa ${newMethod} in su loco.",'boundsAddError':"Tu debe passar le duo valores x e y al function add.",'lonlatAddError':"Tu debe passar le duo valores lon e lat al function add.",'pixelAddError':"Tu debe passar le duo valores x e y al function add.",'unsupportedGeometryType':"Typo de geometria non supportate: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition falleva: le elemento con id ${elemId} pote esser mal placiate.",'filterEvaluateNotImplemented':"\"evaluate\" non es implementate pro iste typo de filtro."});OpenLayers.Lang["id"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Permintaan yang tak tertangani menghasilkan ${statusText}",'permalink':"Pranala permanen",'overlays':"Hamparan",'baseLayer':"Lapisan Dasar",'sameProjection':"Peta tinjauan hanya bekerja bila dalam proyeksi yang sama dengan peta utama",'readNotImplemented':"Membaca tidak diterapkan.",'writeNotImplemented':"Menyimpan tidak diterapkan.",'noFID':"Tidak dapat memperbarui fitur yang tidak memiliki FID.",'errorLoadingGML':"Kesalahan dalam memuat berkas GML ${url}",'browserNotSupported':"Peramban Anda tidak mendukung penggambaran vektor. Penggambar yang didukung saat ini adalah:\n${renderers}",'componentShouldBe':"addFeatures : komponen harus berupa ${geomType}",'getFeatureError':"getFeatureFromEvent diterapkan pada lapisan tanpa penggambar. Ini biasanya berarti Anda menghapus sebuah lapisan, tetapi tidak menghapus penangan yang terkait dengannya.",'minZoomLevelError':"Properti minZoomLevel hanya ditujukan bekerja dengan lapisan FixedZoomLevels-descendent. Pengecekan minZoomLevel oleh lapisan wfs adalah peninggalan masa lalu. Kami tidak dapat menghapusnya tanpa kemungkinan merusak aplikasi berbasis OL yang mungkin bergantung padanya. Karenanya, kami menganggapnya tidak berlaku -- Cek minZoomLevel di bawah ini akan dihapus pada 3.0. Silakan gunakan penyetelan resolusi min/maks seperti dijabarkan di sini: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS Transaksi: BERHASIL ${respon}",'commitFailed':"WFS Transaksi: GAGAL ${respon}",'googleWarning':"Lapisan Google tidak dapat dimuat dengan benar.\x3cbr\x3e\x3cbr\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\x3cbr\x3e\x3cbr\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan atau tidak mengandung kunci API yang tepat untuk situs Anda.\x3cbr\x3e\x3cbr\x3ePengembang: Untuk bantuan mengatasi masalah ini, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eklik di sini\x3c/a\x3e",'getLayerWarning':"Lapisan ${layerType} tidak dapat dimuat dengan benar.\x3cbr\x3e\x3cbr\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\x3cbr\x3e\x3cbr\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan dengan benar.\x3cbr\x3e\x3cbr\x3ePengembang: Untuk bantuan mengatasi masalah ini, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eklik di sini\x3c/a\x3e",'scale':"Sekala = 1 : ${scaleDenom}",'W':"B",'E':"T",'N':"U",'S':"S",'layerAlreadyAdded':"Anda mencoba menambahkan lapisan: ${layerName} ke dalam peta, tapi lapisan itu telah ditambahkan",'reprojectDeprecated':"Anda menggunakan opsi \'reproject\' pada lapisan ${layerName}. Opsi ini telah ditinggalkan: penggunaannya dirancang untuk mendukung tampilan data melalui peta dasar komersial, tapi fungsionalitas tersebut saat ini harus dilakukan dengan menggunakan dukungan Spherical Mercator. Informasi lebih lanjut tersedia di http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Metode ini telah usang dan akan dihapus di 3.0. Sebaliknya, harap gunakan ${newMethod}.",'boundsAddError':"Anda harus memberikan kedua nilai x dan y ke fungsi penambah.",'lonlatAddError':"Anda harus memberikan kedua nilai lon dan lat ke fungsi penambah.",'pixelAddError':"Anda harus memberikan kedua nilai x dan y ke fungsi penambah.",'unsupportedGeometryType':"Tipe geometri tak didukung: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition gagal: elemen dengan id ${elemId} mungkin salah tempat.",'filterEvaluateNotImplemented':"evaluasi tidak tersedia untuk tipe filter ini."});OpenLayers.Lang["io"]=OpenLayers.Util.applyDefaults({'scale':"Skalo = 1 : ${scaleDenom}"});OpenLayers.Lang["is"]=OpenLayers.Util.applyDefaults({'permalink':"Varanlegur tengill",'overlays':"Þekjur",'baseLayer':"Grunnlag",'sameProjection':"Yfirlitskortið virkar aðeins ef það er í sömu vörpun og aðalkortið",'readNotImplemented':"Skrifun er óútfærð.",'writeNotImplemented':"Lestur er óútfærður.",'errorLoadingGML':"Villa kom upp við að hlaða inn GML skránni ${url}",'scale':"Skali = 1 : ${scaleDenom}",'layerAlreadyAdded':"Þú reyndir að bæta laginu ${layerName} á kortið en það er þegar búið að bæta því við",'methodDeprecated':"Þetta fall hefur verið úrelt og verður fjarlægt í 3.0. Notaðu ${newMethod} í staðin."});OpenLayers.Lang["ja"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"未処ç†ã®è¦æ±‚㯠${statusText} ã‚’è¿”ã—ã¾ã™",'permalink':"パーマリンク",'overlays':"オーãƒãƒ¼ãƒ¬ã‚¤",'baseLayer':"基底レイヤー",'sameProjection':"概観地図ã¯ãƒ¡ã‚¤ãƒ³ã®åœ°å›³ã¨åŒã˜æŠ•å½±æ³•ã‚’ã¨ã‚‹å ´åˆã®ã¿æ©Ÿèƒ½ã—ã¾ã™",'readNotImplemented':"読ã¿è¾¼ã¿ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“。",'writeNotImplemented':"書ãè¾¼ã¿ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“。",'noFID':"FID ã®ãªã„地物ã¯æ›´æ–°ã§ãã¾ã›ã‚“。",'errorLoadingGML':"GML ファイル ${url} ã®èª­ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼",'browserNotSupported':"ã‚ãªãŸã®ãƒ–ラウザã¯ãƒ™ã‚¯ã‚¿ãƒ¼ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã‚¹ã®æ写ã«å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。ç¾æ™‚点ã§å¯¾å¿œã—ã¦ã„るソフトウェアã¯ä»¥ä¸‹ã®ã‚‚ã®ã§ã™ã€‚\n${renderers}",'componentShouldBe':"addFeatures: è¦ç´ ã¯ ${geomType} ã§ã‚ã‚‹ã¹ãã§ã™",'getFeatureError':"getFeatureFromEvent ãŒãƒ¬ãƒ³ãƒ€ãƒ©ãƒ¼ã®ãªã„レイヤーã‹ã‚‰å‘¼ã°ã‚Œã¾ã—ãŸã€‚通常ã€ã“ã‚Œã¯ã‚ãªãŸãŒãƒ¬ã‚¤ãƒ¤ãƒ¼ã‚’ã€ãã‚Œã«é–¢é€£ã¥ã‘られãŸã„ãã¤ã‹ã®ãƒãƒ³ãƒ‰ãƒ©ã‚’除ã„ã¦ã€ç ´å£Šã—ã¦ã—ã¾ã£ãŸã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚",'minZoomLevelError':"minZoomLevel プロパティ㯠FixedZoomLevels を継承ã™ã‚‹ãƒ¬ã‚¤ãƒ¤ãƒ¼ã§ã®ä½¿ç”¨ã®ã¿ã‚’想定ã—ã¦ã„ã¾ã™ã€‚ã“ã® minZoomLevel ã«å¯¾ã™ã‚‹ WFS レイヤーã®æ¤œæŸ»ã¯æ­´å²çš„ãªã‚‚ã®ã§ã™ã€‚ã—ã‹ã—ãªãŒã‚‰ã€ã“ã®æ¤œæŸ»ã‚’除去ã™ã‚‹ã¨ãã‚Œã«ä¾å­˜ã™ã‚‹ OpenLayers ベースã®ã‚¢ãƒ—リケーションを破壊ã—ã¦ã—ã¾ã†å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚よã£ã¦å»ƒæ­¢ãŒäºˆå®šã•ã‚Œã¦ãŠã‚Šã€ã“ã® minZoomLevel 検査ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³3.0ã§é™¤åŽ»ã•ã‚Œã¾ã™ã€‚代ã‚ã‚Šã«ã€http://trac.openlayers.org/wiki/SettingZoomLevels ã§è§£èª¬ã•ã‚Œã¦ã„ã‚‹ã€æœ€å°ãŠã‚ˆã³æœ€å¤§è§£åƒåº¦è¨­å®šã‚’使用ã—ã¦ãã ã•ã„。",'commitSuccess':"WFS トランザクション: æˆåŠŸ ${response}",'commitFailed':"WFS トランザクション: 失敗 ${response}",'googleWarning':"Google レイヤーãŒæ­£ã—ã読ã¿è¾¼ã¿ã‚’è¡Œãˆã¾ã›ã‚“ã§ã—ãŸã€‚\x3cbr\x3e\x3cbr\x3eã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’消ã™ã«ã¯ã€å³ä¸Šã®éš…ã«ã‚るレイヤー切り替ãˆéƒ¨åˆ†ã§æ–°ã—ã„基底レイヤーをé¸ã‚“ã§ãã ã•ã„。\x3cbr\x3e\x3cbr\x3eãŠãらãã€ã“れ㯠Google マップ用ライブラリã®ã‚¹ã‚¯ãƒªãƒ—トãŒçµ„ã¿è¾¼ã¾ã‚Œã¦ã„ãªã„ã‹ã€ã‚ãªãŸã®ã‚µã‚¤ãƒˆã«å¯¾å¿œã™ã‚‹æ­£ã—ã„ API キーãŒè¨­å®šã•ã‚Œã¦ã„ãªã„ãŸã‚ã§ã™ã€‚\x3cbr\x3e\x3cbr\x3e開発者ã®æ–¹ã¸: æ­£ã—ã„動作をã•ã›ã‚‹ãŸã‚ã«\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eã“ã¡ã‚‰ã®ã‚¦ã‚£ã‚­\x3c/a\x3eã‚’å‚ç…§ã—ã¦ãã ã•ã„。",'getLayerWarning':"${layerType} レイヤーãŒæ­£ã—ã読ã¿è¾¼ã¿ã‚’è¡Œãˆã¾ã›ã‚“ã§ã—ãŸã€‚\x3cbr\x3e\x3cbr\x3eã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’消ã™ã«ã¯ã€å³ä¸Šã®éš…ã«ã‚るレイヤー切り替ãˆéƒ¨åˆ†ã§æ–°ã—ã„基底レイヤーをé¸ã‚“ã§ãã ã•ã„。\x3cbr\x3e\x3cbr\x3eãŠãらãã€ã“れ㯠${layerLib} ライブラリã®ã‚¹ã‚¯ãƒªãƒ—トãŒæ­£ã—ã組ã¿è¾¼ã¾ã‚Œã¦ã„ãªã„ãŸã‚ã§ã™ã€‚\x3cbr\x3e\x3cbr\x3e開発者ã®æ–¹ã¸: æ­£ã—ã„動作をã•ã›ã‚‹ãŸã‚ã«\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eã“ã¡ã‚‰ã®ã‚¦ã‚£ã‚­\x3c/a\x3eã‚’å‚ç…§ã—ã¦ãã ã•ã„。",'scale':"縮尺 = 1 : ${scaleDenom}",'W':"西",'E':"æ±",'N':"北",'S':"å—",'layerAlreadyAdded':"ã‚ãªãŸã¯ã€Œ${layerName}ã€ã‚’地図ã«è¿½åŠ ã—よã†ã¨è©¦ã¿ã¾ã—ãŸãŒã€ãã®ãƒ¬ã‚¤ãƒ¤ãƒ¼ã¯æ—¢ã«è¿½åŠ ã•ã‚Œã¦ã„ã¾ã™",'reprojectDeprecated':"ã‚ãªãŸã¯ã€Œ${layerName}ã€ãƒ¬ã‚¤ãƒ¤ãƒ¼ã§ reproject オプションを使ã£ã¦ã„ã¾ã™ã€‚ã“ã®ã‚ªãƒ—ションã¯å•†ç”¨ã®åŸºåº•åœ°å›³ä¸Šã«æƒ…報を表示ã™ã‚‹ç›®çš„ã§è¨­è¨ˆã•ã‚Œã¾ã—ãŸãŒã€ç¾åœ¨ã§ã¯ãã®æ©Ÿèƒ½ã¯ Spherical Mercator サãƒãƒ¼ãƒˆã‚’利用ã—ã¦å®Ÿç¾ã•ã‚Œã¦ãŠã‚Šã€ã“ã®ã‚ªãƒ—ションã®ä½¿ç”¨ã¯éžæŽ¨å¥¨ã§ã™ã€‚追加ã®æƒ…報㯠http://trac.openlayers.org/wiki/SphericalMercator ã§å…¥æ‰‹ã§ãã¾ã™ã€‚",'methodDeprecated':"ã“ã®ãƒ¡ã‚½ãƒƒãƒ‰ã¯å»ƒæ­¢ãŒäºˆå®šã•ã‚Œã¦ãŠã‚Šã€ãƒãƒ¼ã‚¸ãƒ§ãƒ³3.0ã§é™¤åŽ»ã•ã‚Œã¾ã™ã€‚代ã‚ã‚Šã« ${newMethod} を使用ã—ã¦ãã ã•ã„。",'boundsAddError':"x 㨠y 両方ã®å€¤ã‚’ add 関数ã«æ¸¡ã•ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。",'lonlatAddError':"lon 㨠lat 両方ã®å€¤ã‚’ add 関数ã«æ¸¡ã•ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。",'pixelAddError':"x 㨠y ã®å€¤ä¸¡æ–¹ã‚’ add 関数ã«æ¸¡ã•ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。",'unsupportedGeometryType':"未対応ã®å½¢çŠ¶åž‹: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition ãŒå¤±æ•—ã—ã¾ã—ãŸ: id ${elemId} ã‚’ã‚‚ã¤è¦ç´ ãŒèª¤ã£ãŸä½ç½®ã«ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚",'filterEvaluateNotImplemented':"ã“ã®ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼åž‹ã«ã¤ã„㦠evaluate ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“。"});OpenLayers.Lang["km"]=OpenLayers.Util.applyDefaults({'permalink':"ážáŸ†ážŽáž—្ជាប់អចិន្ážáŸ’រៃយáŸ",'baseLayer':"ស្រទាប់បាážâ€‹",'errorLoadingGML':"កំហុសកំឡុងពáŸáž›áž•áŸ’ទុកឯកសារ GML ${url}",'scale':"មាážáŸ’រដ្ឋាន = ១ ៖ ${scaleDenom}"});OpenLayers.Lang["ksh"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Met dä Antwoot op en Aanfrooch ham_mer nix aanjefange: ${statusText}",'permalink':"Lengk op Duuer",'overlays':"Drövver jelaat",'baseLayer':"Jrund-Nivoh",'sameProjection':"De Övverseeschs_Kaat deiht et bloß, wann se de sälve Projäxjuhn bruche deiht, wi de Houp_Kaat",'readNotImplemented':"„\x3ccode lang=\"en\"\x3eread\x3c/code\x3e“ is em Projramm nit fürjesinn.",'writeNotImplemented':"„\x3ccode lang=\"en\"\x3ewrite\x3c/code\x3e“ is em Projramm nit fürjesinn.",'noFID':"En Saach, woh kein \x3ci lang=\"en\"\x3eFID\x3c/i\x3e för doh es, löht sesch nit ändere.",'errorLoadingGML':"Fähler beim \x3ci lang=\"en\"\x3eGML\x3c/i\x3e-Datei-Laade vun \x3ccode\x3e${url}\x3c/code\x3e",'browserNotSupported':"Dinge Brauser kann kein Väktore ußjävve. De Zoote Ußjaabe, di em Momang jon, sen:\n${renderers}",'componentShouldBe':"\x3ccode lang=\"en\"\x3eaddFeatures\x3c/code\x3e: dä Aandeil sullt vun dä Zoot „\x3ccode lang=\"en\"\x3e${geomType}\x3c/code\x3e“ sin.",'getFeatureError':"\x3ccode lang=\"en\"\x3egetFeatureFromEvent\x3c/code\x3e es vun enem Nivoh opjeroofe woode, woh et kei Projramm zom Ußjävve jit. Dat bedügg för jewöhnlesch, dat De e Nivoh kapott jemaat häs, ävver nit e Projramm för domet ömzejonn, wat domet verbonge es.",'minZoomLevelError':"De Eijeschaff „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“ es bloß doför jedaach, dat mer se met dä Nivvohß bruch, di vun \x3ccode lang=\"en\"\x3eFixedZoomLevels\x3c/code\x3e affhange don. Dat dat \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Nivvoh övverhoup de Eijeschaff „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“ pröhfe deiht, es noch övveresch vun fröhjer. Mer künne dat ävver jez nit fott lohße, oohne dat mer Jevaa loufe, dat Aanwendunge vun OpenLayers nit mieh loufe, di sesch doh velleijsch noch drop am verlohße sin. Dröm sare mer, dat mer et nit mieh han welle, un de „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“-Eijeschaff weed hee vun de Version 3.0 af nit mieh jeprööf wäde. Nemm doför de Enstellung för de hühßte un de kleinßte Oplöhsung, esu wi et en http://trac.openlayers.org/wiki/SettingZoomLevels opjeschrevve es.",'commitSuccess':"Dä \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Vörjang es joot jeloufe: ${response}",'commitFailed':"Dä \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Vörjang es scheif jejange: ${response}",'googleWarning':"Dat Nivvoh \x3ccode lang=\"en\"\x3eGoogle\x3c/code\x3e kunnt nit reschtesch jelaade wääde.\x3cbr /\x3e\x3cbr /\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhke, rähß bovve en de Äk.\x3cbr /\x3e\x3cbr /\x3eWascheinlesch es dat wiel dat \x3ci lang=\"en\"\x3eGoogle-Maps\x3c/i\x3e-Skrepp entweeder nit reschtesch enjebonge wood, udder nit dä reschtejje \x3ci lang=\"en\"\x3eAPI\x3c/i\x3e-Schlößel för Ding Web-ßait scheke deiht.\x3cbr /\x3e\x3cbr /\x3eFör Projrammierer jidd_et Hölp do_drövver, \x3ca href=\"http://trac.openlayers.org/wiki/Google\" target=\"_blank\"\x3ewi mer dat aan et Loufe brengk\x3c/a\x3e.",'getLayerWarning':"Dat Nivvoh \x3ccode\x3e${layerType}\x3c/code\x3e kunnt nit reschtesch jelaade wääde.\x3cbr /\x3e\x3cbr /\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhkre, rähß bovve en de Äk.\x3cbr /\x3e\x3cbr /\x3eWascheinlesch es dat, wiel dat Skrepp \x3ccode\x3e${layerLib}\x3c/code\x3e nit reschtesch enjebonge wood.\x3cbr /\x3e\x3cbr /\x3eFör Projrammierer jidd_Et Hölp do_drövver, \x3ca href=\"http://trac.openlayers.org/wiki/${layerLib}\" target=\"_blank\"\x3ewi mer dat aan et Loufe brengk\x3c/a\x3e.",'scale':"Mohßshtaab = 1 : ${scaleDenom}",'W':"W",'E':"O",'N':"N",'S':"S",'layerAlreadyAdded':"Do häß versöhk, dat Nivvoh \x3ccode\x3e${layerName}\x3c/code\x3e en di Kaat eren ze bränge, et wohr ävver ald do dren.",'reprojectDeprecated':"Do bruchs de Ußwahl \x3ccode\x3ereproject\x3c/code\x3e op däm Nivvoh \x3ccode\x3e${layerName}\x3c/code\x3e. Di Ußwahl es nit mieh jähn jesinn. Se wohr doför jedaach, öm Date op jeschääfsmäßesch eruß jejovve Kaate bovve drop ze moole, wat ävver enzwesche besser met dä Öngershtözung för de ßfääresche Mäkaator Beldscher jeiht. Doh kanns De mieh drövver fenge op dä Sigg: http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Hee di Metood es nim_mih aktoäll un et weed se en dä Version 3.0 nit mieh jävve. Nemm \x3ccode\x3e${newMethod}\x3c/code\x3e doföör.",'boundsAddError':"Do moß beeds vun de \x3ccode\x3ex\x3c/code\x3e un \x3ccode\x3ey\x3c/code\x3e Wääte aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'lonlatAddError':"Do moß beeds \x3ccode\x3elon\x3c/code\x3e un \x3ccode\x3elat\x3c/code\x3e aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'pixelAddError':"Do moß beeds \x3ccode\x3ex\x3c/code\x3e un \x3ccode\x3ey\x3c/code\x3e aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'unsupportedGeometryType':"De Zoot Jommetrii dom_mer nit ongershtöze: \x3ccode\x3e${geomType}\x3c/code\x3e",'pagePositionFailed':"\x3ccode lang=\"en\"\x3eOpenLayers.Util.pagePosition\x3c/code\x3e es donevve jejange: dat Denge met dä Kännong \x3ccode\x3e${elemId}\x3c/code\x3e künnt am verkeehte Plaz sin.",'filterEvaluateNotImplemented':"„\x3ccode lang=\"en\"\x3eevaluate\x3c/code\x3e“ es för di Zoot Fellter nit enjereschdt."});OpenLayers.Lang["nds"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Unbehannelt Trüchmellels för de Anfraag ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Achtergrundkoort",'sameProjection':"De Översichtskoort geiht blot, wenn de sülve Projekschoon as bi de Hööftkoort bruukt warrt",'readNotImplemented':"Lesen is nich inricht.",'writeNotImplemented':"Schrieven is nich inricht.",'noFID':"En Feature, dat keen FID hett, kann nich aktuell maakt warrn.",'errorLoadingGML':"Fehler bi’t Laden vun de GML-Datei ${url}",'browserNotSupported':"Dien Browser ünnerstütt keen Vektorbiller. Ãœnnerstütt Renderers:\n${renderers}",'componentShouldBe':"addFeatures : Kumponent schull man den Typ ${geomType} hebben",'getFeatureError':"getFeatureFromEvent is von en Laag ahn Render opropen worrn. Dat bedüüdt normalerwies, dat en Laag wegmaakt worrn is, aver nich de Handler, de dor op verwiest.",'commitSuccess':"WFS-Transakschoon: hett klappt ${response}",'commitFailed':"WFS-Transakschoon: hett nich klappt ${response}",'scale':"Skaal = 1 : ${scaleDenom}",'layerAlreadyAdded':"Du versöchst de Laag „${layerName}“ to de Koort totofögen, man de is al toföögt",'methodDeprecated':"Disse Methood is oold un schall dat in 3.0 nich mehr geven. Bruuk dor man beter ${newMethod} för.",'boundsAddError':"De Weert x un y, de mööt all beid an de add-Funkschoon övergeven warrn.",'lonlatAddError':"De Weert lon un lat, de mööt all beid an de add-Funkschoon övergeven warrn.",'pixelAddError':"De Weert x un y, de mööt all beid an de add-Funkschoon övergeven warrn.",'unsupportedGeometryType':"Nich ünnerstütt Geometrie-Typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition güng nich: Element mit de Id ${elemId} is villicht an’n verkehrten Platz."});OpenLayers.Lang["nn"]=OpenLayers.Util.applyDefaults({'scale':"Skala = 1 : ${scaleDenom}",'layerAlreadyAdded':"Du freista Ã¥ leggja til laget «${layerName}» pÃ¥ kartet, men det har alt vorte lagt til.",'boundsAddError':"Du er nøydd til Ã¥ gje bÃ¥de ein x- og ein y-verdi til «add»-funksjonen.",'lonlatAddError':"Du er nøydd til Ã¥ gje bÃ¥de lon- og lat-verdiar til «add»-funksjonen.",'pixelAddError':"Du er nøydd til Ã¥ gje bÃ¥de ein x- og ein y-verdi til «add»-funksjonen."});OpenLayers.Lang["oc"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Requèsta pas gerida, retorna ${statusText}",'permalink':"Permaligam",'overlays':"Calques",'baseLayer':"Calc de basa",'sameProjection':"La carta de situacion fonciona pas que quora sa projeccion es la meteissa que la de la carta principala",'readNotImplemented':"Lectura pas implementada.",'writeNotImplemented':"Escritura pas implementada.",'noFID':"Impossible de metre a jorn un objècte sens identificant (fid).",'errorLoadingGML':"Error al cargament del fichièr GML ${url}",'browserNotSupported':"Vòstre navegidor supòrta pas lo rendut vectorial. Los renderers actualament suportats son : \n${renderers}",'componentShouldBe':"addFeatures : lo compausant deuriá èsser de tipe ${geomType}",'getFeatureError':"getFeatureFromEvent es estat apelat sus un calc sens renderer. Aquò significa generalament qu\'avètz destruch aqueste jaç, mas qu\'avètz conservat un handler que li èra associat.",'minZoomLevelError':"La proprietat minZoomLevel deu èsser utilizada solament per de jaces FixedZoomLevels-descendent. Lo fach qu\'aqueste jaç WFS verifique la preséncia de minZoomLevel es una relica del passat. Çaquelà, la podèm suprimir sens copar d\'aplicacions que ne poirián dependre. Es per aquò que la depreciam -- la verificacion del minZoomLevel serà suprimida en version 3.0. A la plaça, mercés d\'utilizar los paramètres de resolucions min/max tal coma descrich sus : http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transaccion WFS : SUCCES ${response}",'commitFailed':"Transaccion WFS : FRACAS ${response}",'googleWarning':"Lo jaç Google es pas estat en mesura de se cargar corrèctament.\x3cbr\x3e\x3cbr\x3ePer suprimir aqueste messatge, causissètz una BaseLayer novèla dins lo selector de jaç en naut a drecha.\x3cbr\x3e\x3cbr\x3eAquò es possiblament causat par la non-inclusion de la librariá Google Maps, o alara perque que la clau de l\'API correspond pas a vòstre site.\x3cbr\x3e\x3cbr\x3eDesvolopaires : per saber cossí corregir aquò, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclicatz aicí\x3c/a\x3e",'getLayerWarning':"Lo jaç ${layerType} es pas en mesura de se cargar corrèctament.\x3cbr\x3e\x3cbr\x3ePer suprimir aqueste messatge, causissètz una BaseLayer novèla dins lo selector de jaç en naut a drecha.\x3cbr\x3e\x3cbr\x3eAquò es possiblament causat per la non-inclusion de la librariá ${layerLib}.\x3cbr\x3e\x3cbr\x3eDesvolopaires : per saber cossí corregir aquí, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclicatz aicí\x3c/a\x3e",'scale':"Escala ~ 1 : ${scaleDenom}",'W':"O",'E':"È",'N':"N",'S':"S",'layerAlreadyAdded':"Avètz ensajat d\'apondre a la carta lo calc : ${layerName}, mas ja es present",'reprojectDeprecated':"Utilizatz l\'opcion \'reproject\' sul jaç ${layerName}. Aquesta opcion es despreciada : Son usatge permetiá d\'afichar de donadas al dessús de jaces raster comercials. Aquesta foncionalitat ara es suportada en utilizant lo supòrt de la projeccion Mercator Esferica. Mai d\'informacion es disponibla sus http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Aqueste metòde es despreciada, e serà suprimida a la version 3.0. Mercés d\'utilizar ${newMethod} a la plaça.",'boundsAddError':"Vos cal passar las doas valors x e y a la foncion add.",'lonlatAddError':"Vos cal passar las doas valors lon e lat a la foncion add.",'pixelAddError':"Vos cal passar las doas valors x e y a la foncion add.",'unsupportedGeometryType':"Tipe de geometria pas suportat : ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition a fracassat : l\'element d\'id ${elemId} poiriá èsser mal posicionat.",'filterEvaluateNotImplemented':"evaluar es pas encara estat implementat per aqueste tipe de filtre."});OpenLayers.Lang["pt"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Servidor devolveu erro não contemplado ${statusText}",'permalink':"Ligação permanente",'overlays':"Sobreposições",'baseLayer':"Camada Base",'sameProjection':"O mapa panorâmico só funciona quando está na mesma projeção que o mapa principal",'readNotImplemented':"Leitura não implementada.",'writeNotImplemented':"Escrita não implementada.",'noFID':"Não é possível atualizar um elemento para a qual não há FID.",'errorLoadingGML':"Erro ao carregar ficheiro GML ${url}",'browserNotSupported':"O seu navegador não suporta renderização vetorial. Actualmente os renderizadores suportados são:\n${renderers}",'componentShouldBe':"addFeatures: componente deve ser um(a) ${geomType}",'getFeatureError':"getFeatureFromEvent foi chamado numa camada sem renderizador. Isto normalmente significa que destruiu uma camada, mas não um manipulador \'\'(handler)\'\' que lhe está associado.",'minZoomLevelError':"A propriedade minZoomLevel só deve ser usada com as camadas descendentes da FixedZoomLevels. A verificação da propriedade por esta camada wfs é uma relíquia do passado. No entanto, não podemos removê-la sem correr o risco de afectar aplicações OL que dependam dela. Portanto, estamos a torná-la obsoleta -- a verificação minZoomLevel será removida na versão 3.0. Em vez dela, por favor, use as opções de resolução min/max descritas aqui: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transacção WFS: SUCESSO ${response}",'commitFailed':"Transacção WFS: FALHOU ${response}",'googleWarning':"A Camada Google não foi correctamente carregada.\x3cbr\x3e\x3cbr\x3ePara deixar de receber esta mensagem, seleccione uma nova Camada-Base no \'\'switcher\'\' de camadas no canto superior direito.\x3cbr\x3e\x3cbr\x3eProvavelmente, isto acontece porque o \'\'script\'\' da biblioteca do Google Maps não foi incluído ou não contém a chave API correcta para o seu sítio.\x3cbr\x3e\x3cbr\x3eProgramadores: Para ajuda sobre como solucionar o problema \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclique aqui\x3c/a\x3e .",'getLayerWarning':"A camada ${layerType} não foi correctamente carregada.\x3cbr\x3e\x3cbr\x3ePara desactivar esta mensagem, seleccione uma nova Camada-Base no \'\'switcher\'\' de camadas no canto superior direito.\x3cbr\x3e\x3cbr\x3eProvavelmente, isto acontece porque o \'\'script\'\' da biblioteca ${layerLib} não foi incluído correctamente.\x3cbr\x3e\x3cbr\x3eProgramadores: Para ajuda sobre como solucionar o problema \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclique aqui\x3c/a\x3e .",'scale':"Escala = 1 : ${scaleDenom}",'W':"O",'E':"E",'N':"N",'S':"S",'layerAlreadyAdded':"Você tentou adicionar a camada: ${layerName} ao mapa, mas ela já tinha sido adicionada antes",'reprojectDeprecated':"Está usando a opção \'reproject\' na camada ${layerName}. Esta opção é obsoleta: foi concebida para permitir a apresentação de dados sobre mapas-base comerciais, mas esta funcionalidade é agora suportada pelo Mercator Esférico. Mais informação está disponível em http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Este método foi declarado obsoleto e será removido na versão 3.0. Por favor, use ${newMethod} em vez disso.",'boundsAddError':"Você deve passar tanto o valor x como o y à função de adição.",'lonlatAddError':"Você deve passar tanto o valor lon como o lat à função de adição.",'pixelAddError':"Você deve passar tanto o valor x como o y à função de adição.",'unsupportedGeometryType':"Tipo de geometria não suportado: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition falhou: o elemento com o id ${elemId} poderá estar mal-posicionado.",'filterEvaluateNotImplemented':"avaliar não está implementado para este tipo de filtro."});OpenLayers.Lang["ru"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Ðеобработанный Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð²ÐµÑ€Ð½ÑƒÐ» ${statusText}",'permalink':"ПоÑтоÑÐ½Ð½Ð°Ñ ÑÑылка",'overlays':"Слои",'baseLayer':"ОÑновной Ñлой",'sameProjection':"ÐžÐ±Ð·Ð¾Ñ€Ð½Ð°Ñ ÐºÐ°Ñ€Ñ‚Ð° работает только тогда, когда имеет ту же проекцию, что и оÑновнаÑ",'readNotImplemented':"Чтение не реализовано.",'writeNotImplemented':"ЗапиÑÑŒ не реализована.",'noFID':"Ðевозможно обновить объект, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ нет FID.",'errorLoadingGML':"Ошибка при загрузке файла GML ${url}",'browserNotSupported':"Ваш браузер не поддерживает векторную графику. Ðа данный момент поддерживаютÑÑ:\n${renderers}",'componentShouldBe':"addFeatures: компонент должен быть ${geomType}",'getFeatureError':"getFeatureFromEvent вызван Ð´Ð»Ñ ÑÐ»Ð¾Ñ Ð±ÐµÐ· рендерера. Обычно Ñто говорит о том, что вы уничтожили Ñлой, но оÑтавили ÑвÑзанный Ñ Ð½Ð¸Ð¼ обработчик.",'minZoomLevelError':"СвойÑтво minZoomLevel предназначено только Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñо ÑлоÑми, ÑвлÑющимиÑÑ Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ°Ð¼Ð¸ FixedZoomLevels. То, что Ñтот WFS-Ñлой проверÑетÑÑ Ð½Ð° minZoomLevel — реликт прошлого. Однако мы не можем удалить Ñту функцию, так как, возможно, от неё завиÑÑÑ‚ некоторые оÑнованные на OpenLayers приложениÑ. Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¾Ð±ÑŠÑвлена уÑтаревшей — проверка minZoomLevel будет удалена в 3.0. ПожалуйÑта, иÑпользуйте вмеÑто неё наÑтройку мин/Ð¼Ð°ÐºÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ, опиÑанную здеÑÑŒ: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Ð¢Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ WFS: УСПЕШÐО ${response}",'commitFailed':"Ð¢Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ WFS: ОШИБКР${response}",'googleWarning':"Слой Google не удалоÑÑŒ нормально загрузить.\x3cbr\x3e\x3cbr\x3eЧтобы избавитьÑÑ Ð¾Ñ‚ Ñтого ÑообщениÑ, выбите другой оÑновной Ñлой в переключателе в правом верхнем углу.\x3cbr\x3e\x3cbr\x3eСкорее вÑего, причина в том, что библиотека Google Maps не была включена или не Ñодержит корректного API-ключа Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ñайта.\x3cbr\x3e\x3cbr\x3eРазработчикам: чтобы узнать, как Ñделать, чтобы вÑÑ‘ заработало, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eщёлкните тут\x3c/a\x3e",'getLayerWarning':"Слой ${layerType} не удалоÑÑŒ нормально загрузить. \x3cbr\x3e\x3cbr\x3eЧтобы избавитьÑÑ Ð¾Ñ‚ Ñтого ÑообщениÑ, выбите другой оÑновной Ñлой в переключателе в правом верхнем углу.\x3cbr\x3e\x3cbr\x3eСкорее вÑего, причина в том, что библиотека ${layerLib} не была включена или была включена некорректно.\x3cbr\x3e\x3cbr\x3eРазработчикам: чтобы узнать, как Ñделать, чтобы вÑÑ‘ заработало, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eщёлкните тут\x3c/a\x3e",'scale':"МаÑштаб = 1 : ${scaleDenom}",'W':"З",'E':"Ð’",'N':"С",'S':"Ю",'layerAlreadyAdded':"Ð’Ñ‹ попыталиÑÑŒ добавить Ñлой «${layerName}» на карту, но он уже был добавлен",'reprojectDeprecated':"Ð’Ñ‹ иÑпользуете опцию \'reproject\' Ð´Ð»Ñ ÑÐ»Ð¾Ñ ${layerName}. Эта Ð¾Ð¿Ñ†Ð¸Ñ ÑвлÑетÑÑ ÑƒÑтаревшей: ее иÑпользование предполагалоÑÑŒ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ показа данных поверх коммерчеÑких базовых карт, но теперь Ñтот функционал неÑÑ‘Ñ‚ вÑÑ‚Ñ€Ð¾ÐµÐ½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ° ÑферичеÑкой проекции Меркатора. Больше Ñведений доÑтупно на http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Этот метод ÑчитаетÑÑ ÑƒÑтаревшим и будет удалён в верÑии 3.0. ПожалуйÑта, пользуйтеÑÑŒ ${newMethod}.",'boundsAddError':"Функции add надо передавать оба значениÑ, x и y.",'lonlatAddError':"Функции add надо передавать оба значениÑ, lon и lat.",'pixelAddError':"Функции add надо передавать оба значениÑ, x и y.",'unsupportedGeometryType':"Ðеподдерживаемый тип геометрии: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: Ñлемент Ñ id ${elemId} может находитьÑÑ Ð½Ðµ в нужном меÑте.",'filterEvaluateNotImplemented':"evaluate не реализовано Ð´Ð»Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð° данного типа."});OpenLayers.Lang["sk"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Neobslúžené požiadavky vracajú ${statusText}",'permalink':"Trvalý odkaz",'overlays':"Prekrytia",'baseLayer':"Základná vrstva",'sameProjection':"Prehľadová mapka funguje iba vtedy, keÄ je v rovnakej projekcii ako hlavná mapa",'readNotImplemented':"Čítanie nie je implementované.",'writeNotImplemented':"Zápis nie je implementovaný.",'noFID':"Nie je možné aktualizovaÅ¥ vlastnosÅ¥, pre ktorú neexistuje FID.",'errorLoadingGML':"Chyba pri naÄítaní súboru GML ${url}",'browserNotSupported':"Váš prehliadaÄ nepodporuje vykresľovanie vektorov. Momentálne podporované vykresľovaÄe sú:\n${renderers}",'componentShouldBe':"addFeatures: komponent by mal byÅ¥ ${geomType}",'getFeatureError':"getFeatureFromEvent bola zavolaná na vrstve bez vykresľovaÄa. To zvyÄajne znamená, že ste odstránili vrstvu, ale nie niektorú z obslúh, ktorá je s ňou asociovaná.",'minZoomLevelError':"VlastnosÅ¥ minZoomLevel je urÄený iba na použitie s vrstvami odvodenými od FixedZoomLevels. To, že táto wfs vrstva kontroluje minZoomLevel je pozostatok z minulosti. Nemôžeme ho vÅ¡ak odstrániÅ¥, aby sme sa vyhli možnému poruÅ¡eniu aplikácií založených na Open Layers, ktoré na tomto môže závisieÅ¥. Preto ho oznaÄujeme ako zavrhovaný - dolu uvedená kontrola minZoomLevel bude odstránená vo verzii 3.0. Použite prosím namiesto toho kontrolu min./max. rozlíšenia podľa tu uvedeného popisu: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transakcia WFS: ÚSPEÅ Nà ${response}",'commitFailed':"Transakcia WFS: ZLYHALA ${response}",'googleWarning':"Vrstvu Google nebolo možné správne naÄítaÅ¥.\x3cbr\x3e\x3cbr\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínaÄi vrstiev v pravom hornom rohu.\x3cbr\x3e\x3cbr\x3eToto sa stalo pravdepodobne preto, že skript knižnice Google Maps buÄ nebol naÄítaný alebo neobsahuje správny kÄ¾ÃºÄ API pre vaÅ¡u lokalitu.\x3cbr\x3e\x3cbr\x3eVývojári: Tu môžete získaÅ¥ \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3epomoc so sfunkÄnením\x3c/a\x3e",'getLayerWarning':"Vrstvu ${layerType} nebolo možné správne naÄítaÅ¥.\x3cbr\x3e\x3cbr\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínaÄi vrstiev v pravom hornom rohu.\x3cbr\x3e\x3cbr\x3eToto sa stalo pravdepodobne preto, že skript knižnice ${layerType} buÄ nebol naÄítaný alebo neobsahuje správny kÄ¾ÃºÄ API pre vaÅ¡u lokalitu.\x3cbr\x3e\x3cbr\x3eVývojári: Tu môžete získaÅ¥ \x3ca href=\'http://trac.openlayers.org/wiki/${layerType}\' target=\'_blank\'\x3epomoc so sfunkÄnením\x3c/a\x3e",'scale':"Mierka = 1 : ${scaleDenom}",'layerAlreadyAdded':"Pokúsili ste sa do mapy pridaÅ¥ vrstvu ${layerName}, ale tá už bola pridaná",'reprojectDeprecated':"Používate voľby „reproject“ vrstvy ${layerType}. Táto voľba je zzavrhovaná: jej použitie bolo navrhnuté na podporu zobrazovania údajov nad komerÄnými základovými mapami, ale túto funkcionalitu je teraz možné dosiahnuÅ¥ pomocou Spherical Mercator. ÄŽalÅ¡ie informácie získate na stránke http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Táto metóda je zavrhovaná a bude odstránená vo verzii 3.0. Použite prosím namiesto nej metódu ${newMethod}.",'boundsAddError':"SÄítacej funkcii musíte daÅ¥ hodnoty x aj y.",'lonlatAddError':"SÄítacej funkcii musíte daÅ¥ hodnoty lon (zem. dĺžka) aj lat (zem. šírka).",'pixelAddError':"SÄítacej funkcii musíte daÅ¥ hodnoty x aj y.",'unsupportedGeometryType':"Nepodporovaný typ geometrie: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition zlyhalo: prvok s id ${elemId} môže byÅ¥ zle umiestnený.",'filterEvaluateNotImplemented':"evaluate nie je implementovaný pre tento typ filtra"});OpenLayers.Lang["te"]=OpenLayers.Util.applyDefaults({'permalink':"à°¸à±à°¥à°¿à°°à°²à°¿à°‚à°•à±",'W':"à°ª",'E':"తూ",'N':"à°‰",'S':"à°¦"});OpenLayers.Lang["vi"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Không xá»­ lý được phản hồi ${statusText} cho yêu cầu",'permalink':"Liên kết thÆ°á»ng trá»±c",'overlays':"Lấp bản đồ",'baseLayer':"Lá»›p ná»n",'sameProjection':"Bản đồ toàn cảnh chỉ hoạt Ä‘á»™ng khi cùng phép chiếu vá»›i bản đồ chính",'readNotImplemented':"ChÆ°a há»— trợ chức năng Ä‘á»c.",'writeNotImplemented':"ChÆ°a há»— trợ chức năng viết.",'noFID':"Không thể cập nhật tính năng thiếu FID.",'errorLoadingGML':"Lá»—i tải tập tin GML tại ${url}",'browserNotSupported':"Trình duyệt của bạn không há»— trợ chức năng vẽ bằng vectÆ¡. Hiện há»— trợ các bá»™ kết xuất:\n${renderers}",'componentShouldBe':"addFeatures: bá»™ phận cần phải là ${geomType}",'getFeatureError':"getFeatureFromEvent được gá»i từ lá»›p không có bá»™ kết xuất. ThÆ°á»ng thì có lẽ lá»›p bị xóa nhÆ°ng má»™t phần xá»­ lý của nó vẫn còn.",'minZoomLevelError':"Chỉ nên sá»­ dụng thuá»™c tính minZoomLevel vá»›i các lá»›p FixedZoomLevels-descendent. Việc lá»›p wfs này tìm cho minZoomLevel là di tích còn lại từ xÆ°a. Tuy nhiên, nếu chúng tôi dá»i nó thì sẽ vỡ các chÆ°Æ¡ng trình OpenLayers mà dá»±a trên nó. Bởi vậy chúng tôi phản đối sá»­ dụng nó\x26nbsp;– bÆ°á»›c tìm cho minZoomLevel sẽ được dá»i vào phiên bản 3.0. Xin sá»­ dụng thiết lập Ä‘á»™ phân tích tối thiểu / tối Ä‘a thay thế, theo hÆ°á»›ng dẫn này: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Giao dịch WFS: THÀNH CÔNG ${response}",'commitFailed':"Giao dịch WFS: THẤT BẠI ${response}",'googleWarning':"Không thể tải lá»›p Google đúng đắn.\x3cbr\x3e\x3cbr\x3eÄể tránh thông báo này lần sau, hãy chá»n BaseLayer má»›i dùng Ä‘iá»u khiển chá»n lá»›p ở góc trên phải.\x3cbr\x3e\x3cbr\x3eChắc script thÆ° viện Google Maps hoặc không được bao gồm hoặc không chứa khóa API hợp vá»›i website của bạn.\x3cbr\x3e\x3cbr\x3e\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eTrợ giúp vá» tính năng này\x3c/a\x3e cho ngÆ°á»i phát triển.",'getLayerWarning':"Không thể tải lá»›p ${layerType} đúng đắn.\x3cbr\x3e\x3cbr\x3eÄể tránh thông báo này lần sau, hãy chá»n BaseLayer má»›i dùng Ä‘iá»u khiển chá»n lá»›p ở góc trên phải.\x3cbr\x3e\x3cbr\x3eChắc script thÆ° viện ${layerLib} không được bao gồm đúng kiểu.\x3cbr\x3e\x3cbr\x3e\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eTrợ giúp vá» tính năng này\x3c/a\x3e cho ngÆ°á»i phát triển.",'scale':"Tá»· lệ = 1 : ${scaleDenom}",'W':"T",'E':"Ä",'N':"B",'S':"N",'layerAlreadyAdded':"Bạn muốn thêm lá»›p ${layerName} vào bản đồ, nhÆ°ng lá»›p này đã được thêm",'reprojectDeprecated':"Bạn Ä‘ang áp dụng chế Ä‘á»™ “reproject†vào lá»›p ${layerName}. Chế Ä‘á»™ này đã bị phản đối: nó có mục đích há»— trợ lấp dữ liệu trên các ná»n bản đồ thÆ°Æ¡ng mại; nên thá»±c hiện hiệu ứng đó dùng tính năng Mercator Hình cầu. Có sẵn thêm chi tiết tại http://trac.openlayers.org/wiki/SphericalMercator .",'methodDeprecated':"PhÆ°Æ¡ng thức này đã bị phản đối và sẽ bị dá»i vào phiên bản 3.0. Xin hãy sá»­ dụng ${newMethod} thay thế.",'boundsAddError':"Cần phải cho cả giá trị x và y vào hàm add.",'lonlatAddError':"Cần phải cho cả giá trị lon và lat vào hàm add.",'pixelAddError':"Cần phải cho cả giá trị x và y vào hàm add.",'unsupportedGeometryType':"Không há»— trợ kiểu địa lý: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition bị thất bại: nguyên tố vá»›i ID ${elemId} có thể ở chá»— sai.",'filterEvaluateNotImplemented':"chÆ°a há»— trợ evaluate cho loại bá»™ lá»c này."});OpenLayers.Popup.AnchoredBubble=OpenLayers.Class(OpenLayers.Popup.Anchored,{rounded:false,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){this.padding=new OpenLayers.Bounds(0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE,0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE);OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments);},draw:function(px){OpenLayers.Popup.Anchored.prototype.draw.apply(this,arguments);this.setContentHTML();this.setBackgroundColor();this.setOpacity();return this.div;},updateRelativePosition:function(){this.setRicoCorners();},setSize:function(contentSize){OpenLayers.Popup.Anchored.prototype.setSize.apply(this,arguments);this.setRicoCorners();},setBackgroundColor:function(color){if(color!=undefined){this.backgroundColor=color;} -if(this.div!=null){if(this.contentDiv!=null){this.div.style.background="transparent";OpenLayers.Rico.Corner.changeColor(this.groupDiv,this.backgroundColor);}}},setOpacity:function(opacity){OpenLayers.Popup.Anchored.prototype.setOpacity.call(this,opacity);if(this.div!=null){if(this.groupDiv!=null){OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,this.opacity);}}},setBorder:function(border){this.border=0;},setRicoCorners:function(){var corners=this.getCornersToRound(this.relativePosition);var options={corners:corners,color:this.backgroundColor,bgColor:"transparent",blend:false};if(!this.rounded){OpenLayers.Rico.Corner.round(this.div,options);this.rounded=true;}else{OpenLayers.Rico.Corner.reRound(this.groupDiv,options);this.setBackgroundColor();this.setOpacity();}},getCornersToRound:function(){var corners=['tl','tr','bl','br'];var corner=OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);OpenLayers.Util.removeItem(corners,corner);return corners.join(" ");},CLASS_NAME:"OpenLayers.Popup.AnchoredBubble"});OpenLayers.Popup.AnchoredBubble.CORNER_SIZE=5;OpenLayers.Popup.Framed=OpenLayers.Class(OpenLayers.Popup.Anchored,{imageSrc:null,imageSize:null,isAlphaImage:false,positionBlocks:null,blocks:null,fixedRelativePosition:false,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments);if(this.fixedRelativePosition){this.updateRelativePosition();this.calculateRelativePosition=function(px){return this.relativePosition;};} -this.contentDiv.style.position="absolute";this.contentDiv.style.zIndex=1;if(closeBox){this.closeDiv.style.zIndex=1;} -this.groupDiv.style.position="absolute";this.groupDiv.style.top="0px";this.groupDiv.style.left="0px";this.groupDiv.style.height="100%";this.groupDiv.style.width="100%";},destroy:function(){this.imageSrc=null;this.imageSize=null;this.isAlphaImage=null;this.fixedRelativePosition=false;this.positionBlocks=null;for(var i=0;i=200&&request.status<300){response.features=this.parseFeatures(request);response.code=OpenLayers.Protocol.Response.SUCCESS;}else{response.code=OpenLayers.Protocol.Response.FAILURE;} -options.callback.call(options.scope,response);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;} -if(!doc||doc.length<=0){return null;} -return(this.readFormat!==null)?this.readFormat.read(doc):this.format.read(doc);},commit:function(features,options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options);var response=new OpenLayers.Protocol.Response({requestType:"commit",reqFeatures:features});response.priv=OpenLayers.Request.POST({url:options.url,data:this.format.write(features,options),callback:this.createCallback(this.handleCommit,response,options)});return response;},handleCommit:function(response,options){if(options.callback){var request=response.priv;var data=request.responseXML;if(!data||!data.documentElement){data=request.responseText;} -var obj=this.format.read(data)||{};response.insertIds=obj.insertIds||[];response.code=(obj.success)?OpenLayers.Protocol.Response.SUCCESS:OpenLayers.Protocol.Response.FAILURE;options.callback.call(options.scope,response);}},filterDelete:function(filter,options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options);var response=new OpenLayers.Protocol.Response({requestType:"commit"});var root=this.format.createElementNSPlus("wfs:Transaction",{attributes:{service:"WFS",version:this.version}});var deleteNode=this.format.createElementNSPlus("wfs:Delete",{attributes:{typeName:(options.featureNS?this.featurePrefix+":":"")+ -options.featureType}});if(options.featureNS){deleteNode.setAttribute("xmlns:"+this.featurePrefix,options.featureNS);} -var filterNode=this.format.writeNode("ogc:Filter",filter);deleteNode.appendChild(filterNode);root.appendChild(deleteNode);var data=OpenLayers.Format.XML.prototype.write.apply(this.format,[root]);return OpenLayers.Request.POST({url:this.url,callback:options.callback||function(){},data:data});},abort:function(response){if(response){response.priv.abort();}},CLASS_NAME:"OpenLayers.Protocol.WFS.v1"});OpenLayers.Renderer.SVG=OpenLayers.Class(OpenLayers.Renderer.Elements,{xmlns:"http://www.w3.org/2000/svg",xlinkns:"http://www.w3.org/1999/xlink",MAX_PIXEL:15000,translationParameters:null,symbolMetrics:null,isGecko:null,supportUse:null,initialize:function(containerID){if(!this.supported()){return;} -OpenLayers.Renderer.Elements.prototype.initialize.apply(this,arguments);this.translationParameters={x:0,y:0};this.supportUse=(navigator.userAgent.toLowerCase().indexOf("applewebkit/5")==-1);this.isGecko=(navigator.userAgent.toLowerCase().indexOf("gecko/")!=-1);this.symbolMetrics={};},destroy:function(){OpenLayers.Renderer.Elements.prototype.destroy.apply(this,arguments);},supported:function(){var svgFeature="http://www.w3.org/TR/SVG11/feature#";return(document.implementation&&(document.implementation.hasFeature("org.w3c.svg","1.0")||document.implementation.hasFeature(svgFeature+"SVG","1.1")||document.implementation.hasFeature(svgFeature+"BasicStructure","1.1")));},inValidRange:function(x,y,xyOnly){var left=x+(xyOnly?0:this.translationParameters.x);var top=y+(xyOnly?0:this.translationParameters.y);return(left>=-this.MAX_PIXEL&&left<=this.MAX_PIXEL&&top>=-this.MAX_PIXEL&&top<=this.MAX_PIXEL);},setExtent:function(extent,resolutionChanged){OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,arguments);var resolution=this.getResolution();var left=-extent.left/resolution;var top=extent.top/resolution;if(resolutionChanged){this.left=left;this.top=top;var extentString="0 0 "+this.size.w+" "+this.size.h;this.rendererRoot.setAttributeNS(null,"viewBox",extentString);this.translate(0,0);return true;}else{var inRange=this.translate(left-this.left,top-this.top);if(!inRange){this.setExtent(extent,true);} -return inRange;}},translate:function(x,y){if(!this.inValidRange(x,y,true)){return false;}else{var transformString="";if(x||y){transformString="translate("+x+","+y+")";} -this.root.setAttributeNS(null,"transform",transformString);this.translationParameters={x:x,y:y};return true;}},setSize:function(size){OpenLayers.Renderer.prototype.setSize.apply(this,arguments);this.rendererRoot.setAttributeNS(null,"width",this.size.w);this.rendererRoot.setAttributeNS(null,"height",this.size.h);},getNodeType:function(geometry,style){var nodeType=null;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.externalGraphic){nodeType="image";}else if(this.isComplexSymbol(style.graphicName)){nodeType=this.supportUse===false?"svg":"use";}else{nodeType="circle";} -break;case"OpenLayers.Geometry.Rectangle":nodeType="rect";break;case"OpenLayers.Geometry.LineString":nodeType="polyline";break;case"OpenLayers.Geometry.LinearRing":nodeType="polygon";break;case"OpenLayers.Geometry.Polygon":case"OpenLayers.Geometry.Curve":case"OpenLayers.Geometry.Surface":nodeType="path";break;default:break;} -return nodeType;},setStyle:function(node,style,options){style=style||node._style;options=options||node._options;var r=parseFloat(node.getAttributeNS(null,"r"));var widthFactor=1;var pos;if(node._geometryClass=="OpenLayers.Geometry.Point"&&r){node.style.visibility="";if(style.graphic===false){node.style.visibility="hidden";}else if(style.externalGraphic){pos=this.getPosition(node);if(style.graphicTitle){node.setAttributeNS(null,"title",style.graphicTitle);} -if(style.graphicWidth&&style.graphicHeight){node.setAttributeNS(null,"preserveAspectRatio","none");} -var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);var opacity=style.graphicOpacity||style.fillOpacity;node.setAttributeNS(null,"x",(pos.x+xOffset).toFixed());node.setAttributeNS(null,"y",(pos.y+yOffset).toFixed());node.setAttributeNS(null,"width",width);node.setAttributeNS(null,"height",height);node.setAttributeNS(this.xlinkns,"href",style.externalGraphic);node.setAttributeNS(null,"style","opacity: "+opacity);}else if(this.isComplexSymbol(style.graphicName)){var offset=style.pointRadius*3;var size=offset*2;var id=this.importSymbol(style.graphicName);pos=this.getPosition(node);widthFactor=this.symbolMetrics[id][0]*3/size;var parent=node.parentNode;var nextSibling=node.nextSibling;if(parent){parent.removeChild(node);} -if(this.supportUse===false){var src=document.getElementById(id);node.firstChild&&node.removeChild(node.firstChild);node.appendChild(src.firstChild.cloneNode(true));node.setAttributeNS(null,"viewBox",src.getAttributeNS(null,"viewBox"));}else{node.setAttributeNS(this.xlinkns,"href","#"+id);} -node.setAttributeNS(null,"width",size);node.setAttributeNS(null,"height",size);node.setAttributeNS(null,"x",pos.x-offset);node.setAttributeNS(null,"y",pos.y-offset);if(nextSibling){parent.insertBefore(node,nextSibling);}else if(parent){parent.appendChild(node);}}else{node.setAttributeNS(null,"r",style.pointRadius);} -var rotation=style.rotation;if((rotation!==undefined||node._rotation!==undefined)&&pos){node._rotation=rotation;rotation|=0;if(node.nodeName!=="svg"){node.setAttributeNS(null,"transform","rotate("+rotation+" "+pos.x+" "+ -pos.y+")");}else{var metrics=this.symbolMetrics[id];node.firstChild.setAttributeNS(null,"transform","rotate("+style.rotation+" "+metrics[1]+" "+metrics[2]+")");}}} -if(options.isFilled){node.setAttributeNS(null,"fill",style.fillColor);node.setAttributeNS(null,"fill-opacity",style.fillOpacity);}else{node.setAttributeNS(null,"fill","none");} -if(options.isStroked){node.setAttributeNS(null,"stroke",style.strokeColor);node.setAttributeNS(null,"stroke-opacity",style.strokeOpacity);node.setAttributeNS(null,"stroke-width",style.strokeWidth*widthFactor);node.setAttributeNS(null,"stroke-linecap",style.strokeLinecap||"round");node.setAttributeNS(null,"stroke-linejoin","round");style.strokeDashstyle&&node.setAttributeNS(null,"stroke-dasharray",this.dashStyle(style,widthFactor));}else{node.setAttributeNS(null,"stroke","none");} -if(style.pointerEvents){node.setAttributeNS(null,"pointer-events",style.pointerEvents);} -if(style.cursor!=null){node.setAttributeNS(null,"cursor",style.cursor);} -return node;},dashStyle:function(style,widthFactor){var w=style.strokeWidth*widthFactor;var str=style.strokeDashstyle;switch(str){case'solid':return'none';case'dot':return[1,4*w].join();case'dash':return[4*w,4*w].join();case'dashdot':return[4*w,4*w,1,4*w].join();case'longdash':return[8*w,4*w].join();case'longdashdot':return[8*w,4*w,1,4*w].join();default:return OpenLayers.String.trim(str).replace(/\s+/g,",");}},createNode:function(type,id){var node=document.createElementNS(this.xmlns,type);if(id){node.setAttributeNS(null,"id",id);} -return node;},nodeTypeCompare:function(node,type){return(type==node.nodeName);},createRenderRoot:function(){return this.nodeFactory(this.container.id+"_svgRoot","svg");},createRoot:function(suffix){return this.nodeFactory(this.container.id+suffix,"g");},createDefs:function(){var defs=this.nodeFactory(this.container.id+"_defs","defs");this.rendererRoot.appendChild(defs);return defs;},drawPoint:function(node,geometry){return this.drawCircle(node,geometry,1);},drawCircle:function(node,geometry,radius){var resolution=this.getResolution();var x=(geometry.x/resolution+this.left);var y=(this.top-geometry.y/resolution);if(this.inValidRange(x,y)){node.setAttributeNS(null,"cx",x);node.setAttributeNS(null,"cy",y);node.setAttributeNS(null,"r",radius);return node;}else{return false;}},drawLineString:function(node,geometry){var componentsResult=this.getComponentsString(geometry.components);if(componentsResult.path){node.setAttributeNS(null,"points",componentsResult.path);return(componentsResult.complete?node:null);}else{return false;}},drawLinearRing:function(node,geometry){var componentsResult=this.getComponentsString(geometry.components);if(componentsResult.path){node.setAttributeNS(null,"points",componentsResult.path);return(componentsResult.complete?node:null);}else{return false;}},drawPolygon:function(node,geometry){var d="";var draw=true;var complete=true;var linearRingResult,path;for(var j=0,len=geometry.components.length;j0){if(this.getShortString(components[i-1])){strings.push(this.clipLine(components[i],components[i-1]));}} -if(imaxX){k=(y2-y1)/(x2-x1);x2=x2<0?-maxX:maxX;y2=y1+(x2-x1)*k;} -if(y2<-maxY||y2>maxY){k=(x2-x1)/(y2-y1);y2=y2<0?-maxY:maxY;x2=x1+(y2-y1)*k;} -return x2+","+y2;},getShortString:function(point){var resolution=this.getResolution();var x=(point.x/resolution+this.left);var y=(this.top-point.y/resolution);if(this.inValidRange(x,y)){return x+","+y;}else{return false;}},getPosition:function(node){return({x:parseFloat(node.getAttributeNS(null,"cx")),y:parseFloat(node.getAttributeNS(null,"cy"))});},importSymbol:function(graphicName){if(!this.defs){this.defs=this.createDefs();} -var id=this.container.id+"-"+graphicName;if(document.getElementById(id)!=null){return id;} -var symbol=OpenLayers.Renderer.symbol[graphicName];if(!symbol){throw new Error(graphicName+' is not a valid symbol name');} -var symbolNode=this.nodeFactory(id,"symbol");var node=this.nodeFactory(null,"polygon");symbolNode.appendChild(node);var symbolExtent=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0);var points=[];var x,y;for(var i=0;i=2*parts[1]){return"longdash";} -return(parts[0]==1||parts[1]==1)?"dot":"dash";}else if(parts.length==4){return(1*parts[0]>=2*parts[1])?"longdashdot":"dashdot";} -return"solid";}},createNode:function(type,id){var node=document.createElement(type);if(id){node.id=id;} -node.unselectable='on';node.onselectstart=OpenLayers.Function.False;return node;},nodeTypeCompare:function(node,type){var subType=type;var splitIndex=subType.indexOf(":");if(splitIndex!=-1){subType=subType.substr(splitIndex+1);} -var nodeName=node.nodeName;splitIndex=nodeName.indexOf(":");if(splitIndex!=-1){nodeName=nodeName.substr(splitIndex+1);} -return(subType==nodeName);},createRenderRoot:function(){return this.nodeFactory(this.container.id+"_vmlRoot","div");},createRoot:function(suffix){return this.nodeFactory(this.container.id+suffix,"olv:group");},drawPoint:function(node,geometry){return this.drawCircle(node,geometry,1);},drawCircle:function(node,geometry,radius){if(!isNaN(geometry.x)&&!isNaN(geometry.y)){var resolution=this.getResolution();node.style.left=(((geometry.x/resolution-this.offset.x)|0)-radius)+"px";node.style.top=(((geometry.y/resolution-this.offset.y)|0)-radius)+"px";var diameter=radius*2;node.style.width=diameter+"px";node.style.height=diameter+"px";return node;} -return false;},drawLineString:function(node,geometry){return this.drawLine(node,geometry,false);},drawLinearRing:function(node,geometry){return this.drawLine(node,geometry,true);},drawLine:function(node,geometry,closeLine){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var numComponents=geometry.components.length;var parts=new Array(numComponents);var comp,x,y;for(var i=0;i0){symbolExtent.bottom=symbolExtent.bottom-diff;symbolExtent.top=symbolExtent.top+diff;}else{symbolExtent.left=symbolExtent.left+diff;symbolExtent.right=symbolExtent.right-diff;} -cache={path:path,size:symbolExtent.getWidth(),left:symbolExtent.left,bottom:symbolExtent.bottom};this.symbolCache[id]=cache;return cache;},CLASS_NAME:"OpenLayers.Renderer.VML"});OpenLayers.Renderer.VML.LABEL_SHIFT={"l":0,"c":.5,"r":1,"t":0,"m":.5,"b":1};OpenLayers.Tile=OpenLayers.Class({EVENT_TYPES:["loadstart","loadend","reload","unload"],events:null,id:null,layer:null,url:null,bounds:null,size:null,position:null,isLoading:false,initialize:function(layer,position,bounds,url,size){this.layer=layer;this.position=position.clone();this.bounds=bounds.clone();this.url=url;this.size=size.clone();this.id=OpenLayers.Util.createUniqueID("Tile_");this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);},unload:function(){if(this.isLoading){this.isLoading=false;this.events.triggerEvent("unload");}},destroy:function(){this.layer=null;this.bounds=null;this.size=null;this.position=null;this.events.destroy();this.events=null;},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile(this.layer,this.position,this.bounds,this.url,this.size);} -OpenLayers.Util.applyDefaults(obj,this);return obj;},draw:function(){var maxExtent=this.layer.maxExtent;var withinMaxExtent=(maxExtent&&this.bounds.intersectsBounds(maxExtent,false));this.shouldDraw=(withinMaxExtent||this.layer.displayOutsideMaxExtent);this.clear();return this.shouldDraw;},moveTo:function(bounds,position,redraw){if(redraw==null){redraw=true;} -this.bounds=bounds.clone();this.position=position.clone();if(redraw){this.draw();}},clear:function(){},getBoundsFromBaseLayer:function(position){var msg=OpenLayers.i18n('reprojectDeprecated',{'layerName':this.layer.name});OpenLayers.Console.warn(msg);var topLeft=this.layer.map.getLonLatFromLayerPx(position);var bottomRightPx=position.clone();bottomRightPx.x+=this.size.w;bottomRightPx.y+=this.size.h;var bottomRight=this.layer.map.getLonLatFromLayerPx(bottomRightPx);if(topLeft.lon>bottomRight.lon){if(topLeft.lon<0){topLeft.lon=-180-(topLeft.lon+180);}else{bottomRight.lon=180+bottomRight.lon+180;}} -var bounds=new OpenLayers.Bounds(topLeft.lon,bottomRight.lat,bottomRight.lon,topLeft.lat);return bounds;},showTile:function(){if(this.shouldDraw){this.show();}},show:function(){},hide:function(){},CLASS_NAME:"OpenLayers.Tile"});OpenLayers.Control.MouseToolbar=OpenLayers.Class(OpenLayers.Control.MouseDefaults,{mode:null,buttons:null,direction:"vertical",buttonClicked:null,initialize:function(position,direction){OpenLayers.Control.prototype.initialize.apply(this,arguments);this.position=new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,OpenLayers.Control.MouseToolbar.Y);if(position){this.position=position;} -if(direction){this.direction=direction;} -this.measureDivs=[];},destroy:function(){for(var btnId in this.buttons){var btn=this.buttons[btnId];btn.map=null;btn.events.destroy();} -OpenLayers.Control.MouseDefaults.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);OpenLayers.Control.MouseDefaults.prototype.draw.apply(this,arguments);this.buttons={};var sz=new OpenLayers.Size(28,28);var centered=new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,0);this._addButton("zoombox","drag-rectangle-off.png","drag-rectangle-on.png",centered,sz,"Shift->Drag to zoom to area");centered=centered.add((this.direction=="vertical"?0:sz.w),(this.direction=="vertical"?sz.h:0));this._addButton("pan","panning-hand-off.png","panning-hand-on.png",centered,sz,"Drag the map to pan.");centered=centered.add((this.direction=="vertical"?0:sz.w),(this.direction=="vertical"?sz.h:0));this.switchModeTo("pan");return this.div;},_addButton:function(id,img,activeImg,xy,sz,title){var imgLocation=OpenLayers.Util.getImagesLocation()+img;var activeImgLocation=OpenLayers.Util.getImagesLocation()+activeImg;var btn=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MouseToolbar_"+id,xy,sz,imgLocation,"absolute");this.div.appendChild(btn);btn.imgLocation=imgLocation;btn.activeImgLocation=activeImgLocation;btn.events=new OpenLayers.Events(this,btn,null,true);btn.events.on({"mousedown":this.buttonDown,"mouseup":this.buttonUp,"dblclick":OpenLayers.Event.stop,scope:this});btn.action=id;btn.title=title;btn.alt=title;btn.map=this.map;this.buttons[id]=btn;return btn;},buttonDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;} -this.buttonClicked=evt.element.action;OpenLayers.Event.stop(evt);},buttonUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;} -if(this.buttonClicked!=null){if(this.buttonClicked==evt.element.action){this.switchModeTo(evt.element.action);} -OpenLayers.Event.stop(evt);this.buttonClicked=null;}},defaultDblClick:function(evt){this.switchModeTo("pan");this.performedDrag=false;var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);OpenLayers.Event.stop(evt);return false;},defaultMouseDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;} -this.mouseDragStart=evt.xy.clone();this.performedDrag=false;this.startViaKeyboard=false;if(evt.shiftKey&&this.mode!="zoombox"){this.switchModeTo("zoombox");this.startViaKeyboard=true;}else if(evt.altKey&&this.mode!="measure"){this.switchModeTo("measure");}else if(!this.mode){this.switchModeTo("pan");} -switch(this.mode){case"zoombox":this.map.div.style.cursor="crosshair";this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.mouseDragStart,null,null,"absolute","2px solid red");this.zoomBox.style.backgroundColor="white";this.zoomBox.style.filter="alpha(opacity=50)";this.zoomBox.style.opacity="0.50";this.zoomBox.style.fontSize="1px";this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);this.performedDrag=true;break;case"measure":var distance="";if(this.measureStart){var measureEnd=this.map.getLonLatFromViewPortPx(this.mouseDragStart);distance=OpenLayers.Util.distVincenty(this.measureStart,measureEnd);distance=Math.round(distance*100)/100;distance=distance+"km";this.measureStartBox=this.measureBox;} -this.measureStart=this.map.getLonLatFromViewPortPx(this.mouseDragStart);;this.measureBox=OpenLayers.Util.createDiv(null,this.mouseDragStart.add(-2-parseInt(this.map.layerContainerDiv.style.left),-2-parseInt(this.map.layerContainerDiv.style.top)),null,null,"absolute");this.measureBox.style.width="4px";this.measureBox.style.height="4px";this.measureBox.style.fontSize="1px";this.measureBox.style.backgroundColor="red";this.measureBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBox);if(distance){this.measureBoxDistance=OpenLayers.Util.createDiv(null,this.mouseDragStart.add(-2-parseInt(this.map.layerContainerDiv.style.left),2-parseInt(this.map.layerContainerDiv.style.top)),null,null,"absolute");this.measureBoxDistance.innerHTML=distance;this.measureBoxDistance.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBoxDistance);this.measureDivs.push(this.measureBoxDistance);} -this.measureBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBox);this.measureDivs.push(this.measureBox);break;default:this.map.div.style.cursor="move";break;} -document.onselectstart=OpenLayers.Function.False;OpenLayers.Event.stop(evt);},switchModeTo:function(mode){if(mode!=this.mode){if(this.mode&&this.buttons[this.mode]){OpenLayers.Util.modifyAlphaImageDiv(this.buttons[this.mode],null,null,null,this.buttons[this.mode].imgLocation);} -if(this.mode=="measure"&&mode!="measure"){for(var i=0,len=this.measureDivs.length;i1){this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);} -if(this.previousStack.length>(this.limit+1)){this.previousStack.pop();} -if(this.nextStack.length>0){this.nextStack=[];this.onNextChange(null,0);}} -return true;},this);}},activate:function(){var activated=false;if(this.map){if(OpenLayers.Control.prototype.activate.apply(this)){if(this.listeners==null){this.setListeners();} -for(var type in this.listeners){this.map.events.register(type,this,this.listeners[type]);} -activated=true;if(this.previousStack.length==0){this.initStack();}}} -return activated;},initStack:function(){if(this.map.getCenter()){this.listeners.moveend();}},deactivate:function(){var deactivated=false;if(this.map){if(OpenLayers.Control.prototype.deactivate.apply(this)){for(var type in this.listeners){this.map.events.unregister(type,this,this.listeners[type]);} -if(this.clearOnDeactivate){this.clear();} -deactivated=true;}} -return deactivated;},CLASS_NAME:"OpenLayers.Control.NavigationHistory"});OpenLayers.Control.PanPanel=OpenLayers.Class(OpenLayers.Control.Panel,{slideFactor:50,initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Pan(OpenLayers.Control.Pan.NORTH,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.SOUTH,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.EAST,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.WEST,{slideFactor:this.slideFactor})]);},CLASS_NAME:"OpenLayers.Control.PanPanel"});OpenLayers.Control.PanZoomBar=OpenLayers.Class(OpenLayers.Control.PanZoom,{zoomStopWidth:18,zoomStopHeight:11,slider:null,sliderEvents:null,zoombarDiv:null,divEvents:null,zoomWorldIcon:false,forceFixedZoomLevel:false,mouseDragStart:null,zoomStart:null,initialize:function(){OpenLayers.Control.PanZoom.prototype.initialize.apply(this,arguments);},destroy:function(){this._removeZoomBar();this.map.events.un({"changebaselayer":this.redraw,scope:this});OpenLayers.Control.PanZoom.prototype.destroy.apply(this,arguments);delete this.mouseDragStart;delete this.zoomStart;},setMap:function(map){OpenLayers.Control.PanZoom.prototype.setMap.apply(this,arguments);this.map.events.register("changebaselayer",this,this.redraw);},redraw:function(){if(this.div!=null){this.removeButtons();this._removeZoomBar();} -this.draw();},draw:function(px){OpenLayers.Control.prototype.draw.apply(this,arguments);px=this.position.clone();this.buttons=[];var sz=new OpenLayers.Size(18,18);var centered=new OpenLayers.Pixel(px.x+sz.w/2,px.y);var wposition=sz.w;if(this.zoomWorldIcon){centered=new OpenLayers.Pixel(px.x+sz.w,px.y);} -this._addButton("panup","north-mini.png",centered,sz);px.y=centered.y+sz.h;this._addButton("panleft","west-mini.png",px,sz);if(this.zoomWorldIcon){this._addButton("zoomworld","zoom-world-mini.png",px.add(sz.w,0),sz);wposition*=2;} -this._addButton("panright","east-mini.png",px.add(wposition,0),sz);this._addButton("pandown","south-mini.png",centered.add(0,sz.h*2),sz);this._addButton("zoomin","zoom-plus-mini.png",centered.add(0,sz.h*3+5),sz);centered=this._addZoomBar(centered.add(0,sz.h*4+5));this._addButton("zoomout","zoom-minus-mini.png",centered,sz);return this.div;},_addZoomBar:function(centered){var imgLocation=OpenLayers.Util.getImagesLocation();var id=this.id+"_"+this.map.id;var zoomsToEnd=this.map.getNumZoomLevels()-1-this.map.getZoom();var slider=OpenLayers.Util.createAlphaImageDiv(id,centered.add(-1,zoomsToEnd*this.zoomStopHeight),new OpenLayers.Size(20,9),imgLocation+"slider.png","absolute");this.slider=slider;this.sliderEvents=new OpenLayers.Events(this,slider,null,true,{includeXY:true});this.sliderEvents.on({"mousedown":this.zoomBarDown,"mousemove":this.zoomBarDrag,"mouseup":this.zoomBarUp,"dblclick":this.doubleClick,"click":this.doubleClick});var sz=new OpenLayers.Size();sz.h=this.zoomStopHeight*this.map.getNumZoomLevels();sz.w=this.zoomStopWidth;var div=null;if(OpenLayers.Util.alphaHack()){var id=this.id+"_"+this.map.id;div=OpenLayers.Util.createAlphaImageDiv(id,centered,new OpenLayers.Size(sz.w,this.zoomStopHeight),imgLocation+"zoombar.png","absolute",null,"crop");div.style.height=sz.h+"px";}else{div=OpenLayers.Util.createDiv('OpenLayers_Control_PanZoomBar_Zoombar'+this.map.id,centered,sz,imgLocation+"zoombar.png");} -this.zoombarDiv=div;this.divEvents=new OpenLayers.Events(this,div,null,true,{includeXY:true});this.divEvents.on({"mousedown":this.divClick,"mousemove":this.passEventToSlider,"dblclick":this.doubleClick,"click":this.doubleClick});this.div.appendChild(div);this.startTop=parseInt(div.style.top);this.div.appendChild(slider);this.map.events.register("zoomend",this,this.moveZoomBar);centered=centered.add(0,this.zoomStopHeight*this.map.getNumZoomLevels());return centered;},_removeZoomBar:function(){this.sliderEvents.un({"mousedown":this.zoomBarDown,"mousemove":this.zoomBarDrag,"mouseup":this.zoomBarUp,"dblclick":this.doubleClick,"click":this.doubleClick});this.sliderEvents.destroy();this.divEvents.un({"mousedown":this.divClick,"mousemove":this.passEventToSlider,"dblclick":this.doubleClick,"click":this.doubleClick});this.divEvents.destroy();this.div.removeChild(this.zoombarDiv);this.zoombarDiv=null;this.div.removeChild(this.slider);this.slider=null;this.map.events.unregister("zoomend",this,this.moveZoomBar);},passEventToSlider:function(evt){this.sliderEvents.handleBrowserEvent(evt);},divClick:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;} -var y=evt.xy.y;var top=OpenLayers.Util.pagePosition(evt.object)[1];var levels=(y-top)/this.zoomStopHeight;if(this.forceFixedZoomLevel||!this.map.fractionalZoom){levels=Math.floor(levels);} -var zoom=(this.map.getNumZoomLevels()-1)-levels;zoom=Math.min(Math.max(zoom,0),this.map.getNumZoomLevels()-1);this.map.zoomTo(zoom);OpenLayers.Event.stop(evt);},zoomBarDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;} -this.map.events.on({"mousemove":this.passEventToSlider,"mouseup":this.passEventToSlider,scope:this});this.mouseDragStart=evt.xy.clone();this.zoomStart=evt.xy.clone();this.div.style.cursor="move";this.zoombarDiv.offsets=null;OpenLayers.Event.stop(evt);},zoomBarDrag:function(evt){if(this.mouseDragStart!=null){var deltaY=this.mouseDragStart.y-evt.xy.y;var offsets=OpenLayers.Util.pagePosition(this.zoombarDiv);if((evt.clientY-offsets[1])>0&&(evt.clientY-offsets[1])0){pieces.push(',');} -pieces.push(this.writeNewline(),this.writeIndent(),json);}} -this.level-=1;pieces.push(this.writeNewline(),this.writeIndent(),']');return pieces.join('');},'string':function(string){var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};if(/["\\\x00-\x1f]/.test(string)){return'"'+string.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c;} -c=b.charCodeAt();return'\\u00'+ -Math.floor(c/16).toString(16)+ -(c%16).toString(16);})+'"';} -return'"'+string+'"';},'number':function(number){return isFinite(number)?String(number):"null";},'boolean':function(bool){return String(bool);},'date':function(date){function format(number){return(number<10)?'0'+number:number;} -return'"'+date.getFullYear()+'-'+ -format(date.getMonth()+1)+'-'+ -format(date.getDate())+'T'+ -format(date.getHours())+':'+ -format(date.getMinutes())+':'+ -format(date.getSeconds())+'"';}},CLASS_NAME:"OpenLayers.Format.JSON"});OpenLayers.Format.WFST=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.WFST.DEFAULTS);var cls=OpenLayers.Format.WFST["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported WFST version: "+options.version;} -return new cls(options);};OpenLayers.Format.WFST.DEFAULTS={"version":"1.0.0"};OpenLayers.Format.XML=OpenLayers.Class(OpenLayers.Format,{namespaces:null,namespaceAlias:null,defaultPrefix:null,readers:{},writers:{},xmldom:null,initialize:function(options){if(window.ActiveXObject){this.xmldom=new ActiveXObject("Microsoft.XMLDOM");} -OpenLayers.Format.prototype.initialize.apply(this,[options]);this.namespaces=OpenLayers.Util.extend({},this.namespaces);this.namespaceAlias={};for(var alias in this.namespaces){this.namespaceAlias[this.namespaces[alias]]=alias;}},destroy:function(){this.xmldom=null;OpenLayers.Format.prototype.destroy.apply(this,arguments);},setNamespace:function(alias,uri){this.namespaces[alias]=uri;this.namespaceAlias[uri]=alias;},read:function(text){var index=text.indexOf('<');if(index>0){text=text.substring(index);} -var node=OpenLayers.Util.Try(OpenLayers.Function.bind((function(){var xmldom;if(window.ActiveXObject&&!this.xmldom){xmldom=new ActiveXObject("Microsoft.XMLDOM");}else{xmldom=this.xmldom;} -xmldom.loadXML(text);return xmldom;}),this),function(){return new DOMParser().parseFromString(text,'text/xml');},function(){var req=new XMLHttpRequest();req.open("GET","data:"+"text/xml"+";charset=utf-8,"+encodeURIComponent(text),false);if(req.overrideMimeType){req.overrideMimeType("text/xml");} -req.send(null);return req.responseXML;});if(this.keepData){this.data=node;} -return node;},write:function(node){var data;if(this.xmldom){data=node.xml;}else{var serializer=new XMLSerializer();if(node.nodeType==1){var doc=document.implementation.createDocument("","",null);if(doc.importNode){node=doc.importNode(node,true);} -doc.appendChild(node);data=serializer.serializeToString(doc);}else{data=serializer.serializeToString(node);}} -return data;},createElementNS:function(uri,name){var element;if(this.xmldom){if(typeof uri=="string"){element=this.xmldom.createNode(1,name,uri);}else{element=this.xmldom.createNode(1,name,"");}}else{element=document.createElementNS(uri,name);} -return element;},createTextNode:function(text){var node;if(typeof text!=="string"){text=String(text);} -if(this.xmldom){node=this.xmldom.createTextNode(text);}else{node=document.createTextNode(text);} -return node;},getElementsByTagNameNS:function(node,uri,name){var elements=[];if(node.getElementsByTagNameNS){elements=node.getElementsByTagNameNS(uri,name);}else{var allNodes=node.getElementsByTagName("*");var potentialNode,fullName;for(var i=0,len=allNodes.length;i0){prefix=name.substring(0,split);local=name.substring(split+1);}else{if(parent){prefix=this.namespaceAlias[parent.namespaceURI];}else{prefix=this.defaultPrefix;} -local=name;} -var child=this.writers[prefix][local].apply(this,[obj]);if(parent){parent.appendChild(child);} -return child;},getChildEl:function(node,name,uri){return node&&this.getThisOrNextEl(node.firstChild,name,uri);},getNextEl:function(node,name,uri){return node&&this.getThisOrNextEl(node.nextSibling,name,uri);},getThisOrNextEl:function(node,name,uri){outer:for(var sibling=node;sibling;sibling=sibling.nextSibling){switch(sibling.nodeType){case 1:if((!name||name===(sibling.localName||sibling.nodeName.split(":").pop()))&&(!uri||uri===sibling.namespaceURI)){break outer;} -sibling=null;break outer;case 3:if(/^\s*$/.test(sibling.nodeValue)){break;} -case 4:case 6:case 12:case 10:case 11:sibling=null;break outer;}} -return sibling||null;},lookupNamespaceURI:function(node,prefix){var uri=null;if(node){if(node.lookupNamespaceURI){uri=node.lookupNamespaceURI(prefix);}else{outer:switch(node.nodeType){case 1:if(node.namespaceURI!==null&&node.prefix===prefix){uri=node.namespaceURI;break outer;} -var len=node.attributes.length;if(len){var attr;for(var i=0;i=0;--i){this.controls[i].destroy();} -this.controls=null;} -if(this.layers!=null){for(var i=this.layers.length-1;i>=0;--i){this.layers[i].destroy(false);} -this.layers=null;} -if(this.viewPortDiv){this.div.removeChild(this.viewPortDiv);} -this.viewPortDiv=null;if(this.eventListeners){this.events.un(this.eventListeners);this.eventListeners=null;} -this.events.destroy();this.events=null;},setOptions:function(options){OpenLayers.Util.extend(this,options);},getTileSize:function(){return this.tileSize;},getBy:function(array,property,match){var test=(typeof match.test=="function");var found=OpenLayers.Array.filter(this[array],function(item){return item[property]==match||(test&&match.test(item[property]));});return found;},getLayersBy:function(property,match){return this.getBy("layers",property,match);},getLayersByName:function(match){return this.getLayersBy("name",match);},getLayersByClass:function(match){return this.getLayersBy("CLASS_NAME",match);},getControlsBy:function(property,match){return this.getBy("controls",property,match);},getControlsByClass:function(match){return this.getControlsBy("CLASS_NAME",match);},getLayer:function(id){var foundLayer=null;for(var i=0,len=this.layers.length;ithis.layers.length){idx=this.layers.length;} -if(base!=idx){this.layers.splice(base,1);this.layers.splice(idx,0,layer);for(var i=0,len=this.layers.length;i=0;--i){this.removePopup(this.popups[i]);}} -popup.map=this;this.popups.push(popup);var popupDiv=popup.draw();if(popupDiv){popupDiv.style.zIndex=this.Z_INDEX_BASE['Popup']+ -this.popups.length;this.layerContainerDiv.appendChild(popupDiv);}},removePopup:function(popup){OpenLayers.Util.removeItem(this.popups,popup);if(popup.div){try{this.layerContainerDiv.removeChild(popup.div);} -catch(e){}} -popup.map=null;},getSize:function(){var size=null;if(this.size!=null){size=this.size.clone();} -return size;},updateSize:function(){var newSize=this.getCurrentSize();if(newSize&&!isNaN(newSize.h)&&!isNaN(newSize.w)){this.events.clearMouseCache();var oldSize=this.getSize();if(oldSize==null){this.size=oldSize=newSize;} -if(!newSize.equals(oldSize)){this.size=newSize;for(var i=0,len=this.layers.length;ithis.restrictedExtent.getWidth()){lonlat=new OpenLayers.LonLat(maxCenter.lon,lonlat.lat);}else if(extent.leftthis.restrictedExtent.right){lonlat=lonlat.add(this.restrictedExtent.right- -extent.right,0);} -if(extent.getHeight()>this.restrictedExtent.getHeight()){lonlat=new OpenLayers.LonLat(lonlat.lon,maxCenter.lat);}else if(extent.bottomthis.restrictedExtent.top){lonlat=lonlat.add(0,this.restrictedExtent.top- -extent.top);}}} -var zoomChanged=forceZoomChange||((this.isValidZoomLevel(zoom))&&(zoom!=this.getZoom()));var centerChanged=(this.isValidLonLat(lonlat))&&(!lonlat.equals(this.center));if(zoomChanged||centerChanged||!dragging){if(!this.dragging&&!noEvent){this.events.triggerEvent("movestart");} -if(centerChanged){if((!zoomChanged)&&(this.center)){this.centerLayerContainer(lonlat);} -this.center=lonlat.clone();} -if((zoomChanged)||(this.layerContainerOrigin==null)){this.layerContainerOrigin=this.center.clone();this.layerContainerDiv.style.left="0px";this.layerContainerDiv.style.top="0px";} -if(zoomChanged){this.zoom=zoom;this.resolution=this.getResolutionForZoom(zoom);this.viewRequestID++;} -var bounds=this.getExtent();if(this.baseLayer.visibility){this.baseLayer.moveTo(bounds,zoomChanged,dragging);if(dragging){this.baseLayer.events.triggerEvent("move");}else{this.baseLayer.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});}} -bounds=this.baseLayer.getExtent();for(var i=0,len=this.layers.length;i=0)&&(zoomLevel0){resolution=this.layers[0].getResolution();} -return resolution;},getUnits:function(){var units=null;if(this.baseLayer!=null){units=this.baseLayer.units;} -return units;},getScale:function(){var scale=null;if(this.baseLayer!=null){var res=this.getResolution();var units=this.baseLayer.units;scale=OpenLayers.Util.getScaleFromResolution(res,units);} -return scale;},getZoomForExtent:function(bounds,closest){var zoom=null;if(this.baseLayer!=null){zoom=this.baseLayer.getZoomForExtent(bounds,closest);} -return zoom;},getResolutionForZoom:function(zoom){var resolution=null;if(this.baseLayer){resolution=this.baseLayer.getResolutionForZoom(zoom);} -return resolution;},getZoomForResolution:function(resolution,closest){var zoom=null;if(this.baseLayer!=null){zoom=this.baseLayer.getZoomForResolution(resolution,closest);} -return zoom;},zoomTo:function(zoom){if(this.isValidZoomLevel(zoom)){this.setCenter(null,zoom);}},zoomIn:function(){this.zoomTo(this.getZoom()+1);},zoomOut:function(){this.zoomTo(this.getZoom()-1);},zoomToExtent:function(bounds,closest){var center=bounds.getCenterLonLat();if(this.baseLayer.wrapDateLine){var maxExtent=this.getMaxExtent();bounds=bounds.clone();while(bounds.right0){var separator=(url.indexOf('?')>-1)?'&':'?';url+=separator+paramString;}} -if(config.proxy&&(url.indexOf("http")==0)){if(typeof config.proxy=="function"){url=config.proxy(url);}else{url=config.proxy+encodeURIComponent(url);}} -request.open(config.method,url,config.async,config.user,config.password);for(var header in config.headers){request.setRequestHeader(header,config.headers[header]);} -var events=this.events;var self=this;request.onreadystatechange=function(){if(request.readyState==OpenLayers.Request.XMLHttpRequest.DONE){var proceed=events.triggerEvent("complete",{request:request,config:config,requestUrl:url});if(proceed!==false){self.runCallbacks({request:request,config:config,requestUrl:url});}}};if(config.async===false){request.send(config.data);}else{window.setTimeout(function(){if(request._aborted!==true){request.send(config.data);}},0);} -return request;},runCallbacks:function(options){var request=options.request;var config=options.config;var complete=(config.scope)?OpenLayers.Function.bind(config.callback,config.scope):config.callback;var success;if(config.success){success=(config.scope)?OpenLayers.Function.bind(config.success,config.scope):config.success;} -var failure;if(config.failure){failure=(config.scope)?OpenLayers.Function.bind(config.failure,config.scope):config.failure;} -complete(request);if(!request.status||(request.status>=200&&request.status<300)){this.events.triggerEvent("success",options);if(success){success(request);}} -if(request.status&&(request.status<200||request.status>=300)){this.events.triggerEvent("failure",options);if(failure){failure(request);}}},GET:function(config){config=OpenLayers.Util.extend(config,{method:"GET"});return OpenLayers.Request.issue(config);},POST:function(config){config=OpenLayers.Util.extend(config,{method:"POST"});config.headers=config.headers?config.headers:{};if(!("CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(config.headers))){config.headers["Content-Type"]="application/xml";} -return OpenLayers.Request.issue(config);},PUT:function(config){config=OpenLayers.Util.extend(config,{method:"PUT"});config.headers=config.headers?config.headers:{};if(!("CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(config.headers))){config.headers["Content-Type"]="application/xml";} -return OpenLayers.Request.issue(config);},DELETE:function(config){config=OpenLayers.Util.extend(config,{method:"DELETE"});return OpenLayers.Request.issue(config);},HEAD:function(config){config=OpenLayers.Util.extend(config,{method:"HEAD"});return OpenLayers.Request.issue(config);},OPTIONS:function(config){config=OpenLayers.Util.extend(config,{method:"OPTIONS"});return OpenLayers.Request.issue(config);}};OpenLayers.Tile.Image=OpenLayers.Class(OpenLayers.Tile,{url:null,imgDiv:null,frame:null,layerAlphaHack:null,isBackBuffer:false,lastRatio:1,isFirstDraw:true,backBufferTile:null,initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.prototype.initialize.apply(this,arguments);this.url=url;this.frame=document.createElement('div');this.frame.style.overflow='hidden';this.frame.style.position='absolute';this.layerAlphaHack=this.layer.alpha&&OpenLayers.Util.alphaHack();},destroy:function(){if(this.imgDiv!=null){if(this.layerAlphaHack){OpenLayers.Event.stopObservingElement(this.imgDiv.childNodes[0]);} -OpenLayers.Event.stopObservingElement(this.imgDiv);if(this.imgDiv.parentNode==this.frame){this.frame.removeChild(this.imgDiv);this.imgDiv.map=null;} -this.imgDiv.urls=null;this.imgDiv.src=OpenLayers.Util.getImagesLocation()+"blank.gif";} -this.imgDiv=null;if((this.frame!=null)&&(this.frame.parentNode==this.layer.div)){this.layer.div.removeChild(this.frame);} -this.frame=null;if(this.backBufferTile){this.backBufferTile.destroy();this.backBufferTile=null;} -this.layer.events.unregister("loadend",this,this.resetBackBuffer);OpenLayers.Tile.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile.Image(this.layer,this.position,this.bounds,this.url,this.size);} -obj=OpenLayers.Tile.prototype.clone.apply(this,[obj]);obj.imgDiv=null;return obj;},draw:function(){if(this.layer!=this.layer.map.baseLayer&&this.layer.reproject){this.bounds=this.getBoundsFromBaseLayer(this.position);} -var drawTile=OpenLayers.Tile.prototype.draw.apply(this,arguments);if((OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,this.layer.transitionEffect)!=-1)||this.layer.singleTile){if(drawTile){if(!this.backBufferTile){this.backBufferTile=this.clone();this.backBufferTile.hide();this.backBufferTile.isBackBuffer=true;this.events.register('loadend',this,this.resetBackBuffer);this.layer.events.register("loadend",this,this.resetBackBuffer);} -this.startTransition();}else{if(this.backBufferTile){this.backBufferTile.clear();}}}else{if(drawTile&&this.isFirstDraw){this.events.register('loadend',this,this.showTile);this.isFirstDraw=false;}} -if(!drawTile){return false;} -if(this.isLoading){this.events.triggerEvent("reload");}else{this.isLoading=true;this.events.triggerEvent("loadstart");} -return this.renderTile();},resetBackBuffer:function(){this.showTile();if(this.backBufferTile&&(this.isFirstDraw||!this.layer.numLoadingTiles)){this.isFirstDraw=false;var maxExtent=this.layer.maxExtent;var withinMaxExtent=(maxExtent&&this.bounds.intersectsBounds(maxExtent,false));if(withinMaxExtent){this.backBufferTile.position=this.position;this.backBufferTile.bounds=this.bounds;this.backBufferTile.size=this.size;this.backBufferTile.imageSize=this.layer.getImageSize(this.bounds)||this.size;this.backBufferTile.imageOffset=this.layer.imageOffset;this.backBufferTile.resolution=this.layer.getResolution();this.backBufferTile.renderTile();} -this.backBufferTile.hide();}},renderTile:function(){if(this.imgDiv==null){this.initImgDiv();} -this.imgDiv.viewRequestID=this.layer.map.viewRequestID;if(this.layer.async){this.layer.getURLasync(this.bounds,this,"url",this.positionImage);}else{if(this.layer.url instanceof Array){this.imgDiv.urls=this.layer.url.slice();} -this.url=this.layer.getURL(this.bounds);this.positionImage();} -return true;},positionImage:function(){if(this.layer===null){return;} -OpenLayers.Util.modifyDOMElement(this.frame,null,this.position,this.size);var imageSize=this.layer.getImageSize(this.bounds);if(this.layerAlphaHack){OpenLayers.Util.modifyAlphaImageDiv(this.imgDiv,null,null,imageSize,this.url);}else{OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,imageSize);this.imgDiv.src=this.url;}},clear:function(){if(this.imgDiv){this.hide();if(OpenLayers.Tile.Image.useBlankTile){this.imgDiv.src=OpenLayers.Util.getImagesLocation()+"blank.gif";}}},initImgDiv:function(){var offset=this.layer.imageOffset;var size=this.layer.getImageSize(this.bounds);if(this.layerAlphaHack){this.imgDiv=OpenLayers.Util.createAlphaImageDiv(null,offset,size,null,"relative",null,null,null,true);}else{this.imgDiv=OpenLayers.Util.createImage(null,offset,size,null,"relative",null,null,true);} -this.imgDiv.className='olTileImage';this.frame.style.zIndex=this.isBackBuffer?0:1;this.frame.appendChild(this.imgDiv);this.layer.div.appendChild(this.frame);if(this.layer.opacity!=null){OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,null,null,null,null,this.layer.opacity);} -this.imgDiv.map=this.layer.map;var onload=function(){if(this.isLoading){this.isLoading=false;this.events.triggerEvent("loadend");}};if(this.layerAlphaHack){OpenLayers.Event.observe(this.imgDiv.childNodes[0],'load',OpenLayers.Function.bind(onload,this));}else{OpenLayers.Event.observe(this.imgDiv,'load',OpenLayers.Function.bind(onload,this));} -var onerror=function(){if(this.imgDiv._attempts>OpenLayers.IMAGE_RELOAD_ATTEMPTS){onload.call(this);}};OpenLayers.Event.observe(this.imgDiv,"error",OpenLayers.Function.bind(onerror,this));},checkImgURL:function(){if(this.layer){var loaded=this.layerAlphaHack?this.imgDiv.firstChild.src:this.imgDiv.src;if(!OpenLayers.Util.isEquivalentUrl(loaded,this.url)){this.hide();}}},startTransition:function(){if(!this.backBufferTile||!this.backBufferTile.imgDiv){return;} -var ratio=1;if(this.backBufferTile.resolution){ratio=this.backBufferTile.resolution/this.layer.getResolution();} -if(ratio!=this.lastRatio){if(this.layer.transitionEffect=='resize'){var upperLeft=new OpenLayers.LonLat(this.backBufferTile.bounds.left,this.backBufferTile.bounds.top);var size=new OpenLayers.Size(this.backBufferTile.size.w*ratio,this.backBufferTile.size.h*ratio);var px=this.layer.map.getLayerPxFromLonLat(upperLeft);OpenLayers.Util.modifyDOMElement(this.backBufferTile.frame,null,px,size);var imageSize=this.backBufferTile.imageSize;imageSize=new OpenLayers.Size(imageSize.w*ratio,imageSize.h*ratio);var imageOffset=this.backBufferTile.imageOffset;if(imageOffset){imageOffset=new OpenLayers.Pixel(imageOffset.x*ratio,imageOffset.y*ratio);} -OpenLayers.Util.modifyDOMElement(this.backBufferTile.imgDiv,null,imageOffset,imageSize);this.backBufferTile.show();}}else{if(this.layer.singleTile){this.backBufferTile.show();}else{this.backBufferTile.hide();}} -this.lastRatio=ratio;},show:function(){this.frame.style.display='';if(OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,this.layer.transitionEffect)!=-1){if(navigator.userAgent.toLowerCase().indexOf("gecko")!=-1){this.frame.scrollLeft=this.frame.scrollLeft;}}},hide:function(){this.frame.style.display='none';},CLASS_NAME:"OpenLayers.Tile.Image"});OpenLayers.Tile.Image.useBlankTile=(OpenLayers.Util.getBrowserName()=="safari"||OpenLayers.Util.getBrowserName()=="opera");OpenLayers.Control.OverviewMap=OpenLayers.Class(OpenLayers.Control,{element:null,ovmap:null,size:new OpenLayers.Size(180,90),layers:null,minRectSize:15,minRectDisplayClass:"RectReplacement",minRatio:8,maxRatio:32,mapOptions:null,autoPan:false,handlers:null,resolutionFactor:1,maximized:false,initialize:function(options){this.layers=[];this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,[options]);},destroy:function(){if(!this.mapDiv){return;} -if(this.handlers.click){this.handlers.click.destroy();} -if(this.handlers.drag){this.handlers.drag.destroy();} -this.mapDiv.removeChild(this.extentRectangle);this.extentRectangle=null;if(this.rectEvents){this.rectEvents.destroy();this.rectEvents=null;} -if(this.ovmap){this.ovmap.destroy();this.ovmap=null;} -this.element.removeChild(this.mapDiv);this.mapDiv=null;this.div.removeChild(this.element);this.element=null;if(this.maximizeDiv){OpenLayers.Event.stopObservingElement(this.maximizeDiv);this.div.removeChild(this.maximizeDiv);this.maximizeDiv=null;} -if(this.minimizeDiv){OpenLayers.Event.stopObservingElement(this.minimizeDiv);this.div.removeChild(this.minimizeDiv);this.minimizeDiv=null;} -this.map.events.un({"moveend":this.update,"changebaselayer":this.baseLayerDraw,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!(this.layers.length>0)){if(this.map.baseLayer){var layer=this.map.baseLayer.clone();this.layers=[layer];}else{this.map.events.register("changebaselayer",this,this.baseLayerDraw);return this.div;}} -this.element=document.createElement('div');this.element.className=this.displayClass+'Element';this.element.style.display='none';this.mapDiv=document.createElement('div');this.mapDiv.style.width=this.size.w+'px';this.mapDiv.style.height=this.size.h+'px';this.mapDiv.style.position='relative';this.mapDiv.style.overflow='hidden';this.mapDiv.id=OpenLayers.Util.createUniqueID('overviewMap');this.extentRectangle=document.createElement('div');this.extentRectangle.style.position='absolute';this.extentRectangle.style.zIndex=1000;this.extentRectangle.className=this.displayClass+'ExtentRectangle';this.mapDiv.appendChild(this.extentRectangle);this.element.appendChild(this.mapDiv);this.div.appendChild(this.element);if(!this.outsideViewport){this.div.className+=" "+this.displayClass+'Container';var imgLocation=OpenLayers.Util.getImagesLocation();var img=imgLocation+'layer-switcher-maximize.png';this.maximizeDiv=OpenLayers.Util.createAlphaImageDiv(this.displayClass+'MaximizeButton',null,new OpenLayers.Size(18,18),img,'absolute');this.maximizeDiv.style.display='none';this.maximizeDiv.className=this.displayClass+'MaximizeButton';OpenLayers.Event.observe(this.maximizeDiv,'click',OpenLayers.Function.bindAsEventListener(this.maximizeControl,this));this.div.appendChild(this.maximizeDiv);var img=imgLocation+'layer-switcher-minimize.png';this.minimizeDiv=OpenLayers.Util.createAlphaImageDiv('OpenLayers_Control_minimizeDiv',null,new OpenLayers.Size(18,18),img,'absolute');this.minimizeDiv.style.display='none';this.minimizeDiv.className=this.displayClass+'MinimizeButton';OpenLayers.Event.observe(this.minimizeDiv,'click',OpenLayers.Function.bindAsEventListener(this.minimizeControl,this));this.div.appendChild(this.minimizeDiv);var eventsToStop=['dblclick','mousedown'];for(var i=0,len=eventsToStop.length;ithis.minRatio)&&(resRatio<=this.maxRatio)&&(this.ovmap.getExtent().containsBounds(testExtent)));},updateOverview:function(){var mapRes=this.map.getResolution();var targetRes=this.ovmap.getResolution();var resRatio=targetRes/mapRes;if(resRatio>this.maxRatio){targetRes=this.minRatio*mapRes;}else if(resRatio<=this.minRatio){targetRes=this.maxRatio*mapRes;} -var center;if(this.ovmap.getProjection()!=this.map.getProjection()){center=this.map.center.clone();center.transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}else{center=this.map.center;} -this.ovmap.setCenter(center,this.ovmap.getZoomForResolution(targetRes*this.resolutionFactor));this.updateRectToMap();},createMap:function(){var options=OpenLayers.Util.extend({controls:[],maxResolution:'auto',fallThrough:false},this.mapOptions);this.ovmap=new OpenLayers.Map(this.mapDiv,options);OpenLayers.Event.stopObserving(window,'unload',this.ovmap.unloadDestroy);this.ovmap.addLayers(this.layers);this.ovmap.zoomToMaxExtent();this.wComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-left-width'))+ -parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-right-width'));this.wComp=(this.wComp)?this.wComp:2;this.hComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-top-width'))+ -parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-bottom-width'));this.hComp=(this.hComp)?this.hComp:2;this.handlers.drag=new OpenLayers.Handler.Drag(this,{move:this.rectDrag,done:this.updateMapToRect},{map:this.ovmap});this.handlers.click=new OpenLayers.Handler.Click(this,{"click":this.mapDivClick},{"single":true,"double":false,"stopSingle":true,"stopDouble":true,"pixelTolerance":1,map:this.ovmap});this.handlers.click.activate();this.rectEvents=new OpenLayers.Events(this,this.extentRectangle,null,true);this.rectEvents.register("mouseover",this,function(e){if(!this.handlers.drag.active&&!this.map.dragging){this.handlers.drag.activate();}});this.rectEvents.register("mouseout",this,function(e){if(!this.handlers.drag.dragging){this.handlers.drag.deactivate();}});if(this.ovmap.getProjection()!=this.map.getProjection()){var sourceUnits=this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units;var targetUnits=this.ovmap.getProjectionObject().getUnits()||this.ovmap.units||this.ovmap.baseLayer.units;this.resolutionFactor=sourceUnits&&targetUnits?OpenLayers.INCHES_PER_UNIT[sourceUnits]/OpenLayers.INCHES_PER_UNIT[targetUnits]:1;}},updateRectToMap:function(){var bounds;if(this.ovmap.getProjection()!=this.map.getProjection()){bounds=this.map.getExtent().transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}else{bounds=this.map.getExtent();} -var pxBounds=this.getRectBoundsFromMapBounds(bounds);if(pxBounds){this.setRectPxBounds(pxBounds);}},updateMapToRect:function(){var lonLatBounds=this.getMapBoundsFromRectBounds(this.rectPxBounds);if(this.ovmap.getProjection()!=this.map.getProjection()){lonLatBounds=lonLatBounds.transform(this.ovmap.getProjectionObject(),this.map.getProjectionObject());} -this.map.panTo(lonLatBounds.getCenterLonLat());},setRectPxBounds:function(pxBounds){var top=Math.max(pxBounds.top,0);var left=Math.max(pxBounds.left,0);var bottom=Math.min(pxBounds.top+Math.abs(pxBounds.getHeight()),this.ovmap.size.h-this.hComp);var right=Math.min(pxBounds.left+pxBounds.getWidth(),this.ovmap.size.w-this.wComp);var width=Math.max(right-left,0);var height=Math.max(bottom-top,0);if(width0){params.format=layerContext.formats[0].value;for(i=0,len=layerContext.formats.length;i0){for(i=0,len=layerContext.styles.length;i0&&tagName.indexOf(criteria)>-1){nodes.push(child);}else{matchNodes=this.getSiblingNodesByTagCriteria(child,criteria);if(matchNodes.length>0){(nodes.length==0)?nodes=matchNodes:nodes.push(matchNodes);}}}} -return nodes;},parseAttributes:function(node){var attributes={};if(node.nodeType==1){var children=node.childNodes;var n=children.length;for(var i=0;ithis.pixelTolerance){passes=false;}} -return passes;},clearTimer:function(){if(this.timerId!=null){window.clearTimeout(this.timerId);this.timerId=null;} -if(this.rightclickTimerId!=null){window.clearTimeout(this.rightclickTimerId);this.rightclickTimerId=null;}},delayedCall:function(evt){this.timerId=null;if(evt){this.callback('click',[evt]);}},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.clearTimer();this.down=null;deactivated=true;} -return deactivated;},CLASS_NAME:"OpenLayers.Handler.Click"});OpenLayers.Handler.Drag=OpenLayers.Class(OpenLayers.Handler,{started:false,stopDown:true,dragging:false,last:null,start:null,oldOnselectstart:null,interval:0,timeoutId:null,documentDrag:false,documentEvents:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);},down:function(evt){},move:function(evt){},up:function(evt){},out:function(evt){},mousedown:function(evt){var propagate=true;this.dragging=false;if(this.checkModifiers(evt)&&OpenLayers.Event.isLeftClick(evt)){this.started=true;this.start=evt.xy;this.last=evt.xy;OpenLayers.Element.addClass(this.map.viewPortDiv,"olDragDown");this.down(evt);this.callback("down",[evt.xy]);OpenLayers.Event.stop(evt);if(!this.oldOnselectstart){this.oldOnselectstart=(document.onselectstart)?document.onselectstart:OpenLayers.Function.True;} -document.onselectstart=OpenLayers.Function.False;propagate=!this.stopDown;}else{this.started=false;this.start=null;this.last=null;} -return propagate;},mousemove:function(evt){if(this.started&&!this.timeoutId&&(evt.xy.x!=this.last.x||evt.xy.y!=this.last.y)){if(this.documentDrag===true&&this.documentEvents){if(evt.element===document){this.adjustXY(evt);this.setEvent(evt);}else{this.destroyDocumentEvents();}} -if(this.interval>0){this.timeoutId=setTimeout(OpenLayers.Function.bind(this.removeTimeout,this),this.interval);} -this.dragging=true;this.move(evt);this.callback("move",[evt.xy]);if(!this.oldOnselectstart){this.oldOnselectstart=document.onselectstart;document.onselectstart=OpenLayers.Function.False;} -this.last=this.evt.xy;} -return true;},removeTimeout:function(){this.timeoutId=null;},mouseup:function(evt){if(this.started){if(this.documentDrag===true&&this.documentEvents){this.adjustXY(evt);this.destroyDocumentEvents();} -var dragged=(this.start!=this.last);this.started=false;this.dragging=false;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.up(evt);this.callback("up",[evt.xy]);if(dragged){this.callback("done",[evt.xy]);} -document.onselectstart=this.oldOnselectstart;} -return true;},mouseout:function(evt){if(this.started&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.documentDrag===true){this.documentEvents=new OpenLayers.Events(this,document,null,null,{includeXY:true});this.documentEvents.on({mousemove:this.mousemove,mouseup:this.mouseup});OpenLayers.Element.addClass(document.body,"olDragDown");}else{var dragged=(this.start!=this.last);this.started=false;this.dragging=false;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.out(evt);this.callback("out",[]);if(dragged){this.callback("done",[evt.xy]);} -if(document.onselectstart){document.onselectstart=this.oldOnselectstart;}}} -return true;},click:function(evt){return(this.start==this.last);},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.dragging=false;activated=true;} -return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.started=false;this.dragging=false;this.start=null;this.last=null;deactivated=true;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");} -return deactivated;},adjustXY:function(evt){var pos=OpenLayers.Util.pagePosition(this.map.div);evt.xy.x-=pos[0];evt.xy.y-=pos[1];},destroyDocumentEvents:function(){OpenLayers.Element.removeClass(document.body,"olDragDown");this.documentEvents.destroy();this.documentEvents=null;},CLASS_NAME:"OpenLayers.Handler.Drag"});OpenLayers.Handler.Feature=OpenLayers.Class(OpenLayers.Handler,{EVENTMAP:{'click':{'in':'click','out':'clickout'},'mousemove':{'in':'over','out':'out'},'dblclick':{'in':'dblclick','out':null},'mousedown':{'in':null,'out':null},'mouseup':{'in':null,'out':null}},feature:null,lastFeature:null,down:null,up:null,clickTolerance:4,geometryTypes:null,stopClick:true,stopDown:true,stopUp:false,initialize:function(control,layer,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,[control,callbacks,options]);this.layer=layer;},mousedown:function(evt){this.down=evt.xy;return this.handle(evt)?!this.stopDown:true;},mouseup:function(evt){this.up=evt.xy;return this.handle(evt)?!this.stopUp:true;},click:function(evt){return this.handle(evt)?!this.stopClick:true;},mousemove:function(evt){if(!this.callbacks['over']&&!this.callbacks['out']){return true;} -this.handle(evt);return true;},dblclick:function(evt){return!this.handle(evt);},geometryTypeMatches:function(feature){return this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)>-1;},handle:function(evt){if(this.feature&&!this.feature.layer){this.feature=null;} -var type=evt.type;var handled=false;var previouslyIn=!!(this.feature);var click=(type=="click"||type=="dblclick");this.feature=this.layer.getFeatureFromEvent(evt);if(this.feature&&!this.feature.layer){this.feature=null;} -if(this.lastFeature&&!this.lastFeature.layer){this.lastFeature=null;} -if(this.feature){var inNew=(this.feature!=this.lastFeature);if(this.geometryTypeMatches(this.feature)){if(previouslyIn&&inNew){if(this.lastFeature){this.triggerCallback(type,'out',[this.lastFeature]);} -this.triggerCallback(type,'in',[this.feature]);}else if(!previouslyIn||click){this.triggerCallback(type,'in',[this.feature]);} -this.lastFeature=this.feature;handled=true;}else{if(this.lastFeature&&(previouslyIn&&inNew||click)){this.triggerCallback(type,'out',[this.lastFeature]);} -this.feature=null;}}else{if(this.lastFeature&&(previouslyIn||click)){this.triggerCallback(type,'out',[this.lastFeature]);}} -return handled;},triggerCallback:function(type,mode,args){var key=this.EVENTMAP[type][mode];if(key){if(type=='click'&&this.up&&this.down){var dpx=Math.sqrt(Math.pow(this.up.x-this.down.x,2)+ -Math.pow(this.up.y-this.down.y,2));if(dpx<=this.clickTolerance){this.callback(key,args);}}else{this.callback(key,args);}}},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.moveLayerToTop();this.map.events.on({"removelayer":this.handleMapEvents,"changelayer":this.handleMapEvents,scope:this});activated=true;} -return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.moveLayerBack();this.feature=null;this.lastFeature=null;this.down=null;this.up=null;this.map.events.un({"removelayer":this.handleMapEvents,"changelayer":this.handleMapEvents,scope:this});deactivated=true;} -return deactivated;},handleMapEvents:function(evt){if(!evt.property||evt.property=="order"){this.moveLayerToTop();}},moveLayerToTop:function(){var index=Math.max(this.map.Z_INDEX_BASE['Feature']-1,this.layer.getZIndex())+1;this.layer.setZIndex(index);},moveLayerBack:function(){var index=this.layer.getZIndex()-1;if(index>=this.map.Z_INDEX_BASE['Feature']){this.layer.setZIndex(index);}else{this.map.setLayerZIndex(this.layer,this.map.getLayerIndex(this.layer));}},CLASS_NAME:"OpenLayers.Handler.Feature"});OpenLayers.Handler.Hover=OpenLayers.Class(OpenLayers.Handler,{delay:500,pixelTolerance:null,stopMove:false,px:null,timerId:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);},mousemove:function(evt){if(this.passesTolerance(evt.xy)){this.clearTimer();this.callback('move',[evt]);this.px=evt.xy;evt=OpenLayers.Util.extend({},evt);this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall,this,evt),this.delay);} -return!this.stopMove;},mouseout:function(evt){if(OpenLayers.Util.mouseLeft(evt,this.map.div)){this.clearTimer();this.callback('move',[evt]);} -return true;},passesTolerance:function(px){var passes=true;if(this.pixelTolerance&&this.px){var dpx=Math.sqrt(Math.pow(this.px.x-px.x,2)+ -Math.pow(this.px.y-px.y,2));if(dpx=0){this.initResolutions();break;}}}},onMapResize:function(){},redraw:function(){var redrawn=false;if(this.map){this.inRange=this.calculateInRange();var extent=this.getExtent();if(extent&&this.inRange&&this.visibility){var zoomChanged=true;this.moveTo(extent,zoomChanged,false);this.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});redrawn=true;}} -return redrawn;},moveTo:function(bounds,zoomChanged,dragging){var display=this.visibility;if(!this.isBaseLayer){display=display&&this.inRange;} -this.display(display);},setMap:function(map){if(this.map==null){this.map=map;this.maxExtent=this.maxExtent||this.map.maxExtent;this.minExtent=this.minExtent||this.map.minExtent;this.projection=this.projection||this.map.projection;if(typeof this.projection=="string"){this.projection=new OpenLayers.Projection(this.projection);} -this.units=this.projection.getUnits()||this.units||this.map.units;this.initResolutions();if(!this.isBaseLayer){this.inRange=this.calculateInRange();var show=((this.visibility)&&(this.inRange));this.div.style.display=show?"":"none";} -this.setTileSize();}},afterAdd:function(){},removeMap:function(map){},getImageSize:function(bounds){return(this.imageSize||this.tileSize);},setTileSize:function(size){var tileSize=(size)?size:((this.tileSize)?this.tileSize:this.map.getTileSize());this.tileSize=tileSize;if(this.gutter){this.imageOffset=new OpenLayers.Pixel(-this.gutter,-this.gutter);this.imageSize=new OpenLayers.Size(tileSize.w+(2*this.gutter),tileSize.h+(2*this.gutter));}},getVisibility:function(){return this.visibility;},setVisibility:function(visibility){if(visibility!=this.visibility){this.visibility=visibility;this.display(visibility);this.redraw();if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"visibility"});} -this.events.triggerEvent("visibilitychanged");}},display:function(display){if(display!=(this.div.style.display!="none")){this.div.style.display=(display&&this.calculateInRange())?"block":"none";}},calculateInRange:function(){var inRange=false;if(this.alwaysInRange){inRange=true;}else{if(this.map){var resolution=this.map.getResolution();inRange=((resolution>=this.minResolution)&&(resolution<=this.maxResolution));}} -return inRange;},setIsBaseLayer:function(isBaseLayer){if(isBaseLayer!=this.isBaseLayer){this.isBaseLayer=isBaseLayer;if(this.map!=null){this.map.events.triggerEvent("changebaselayer",{layer:this});}}},initResolutions:function(){var i,len;var props={},alwaysInRange=true;for(i=0,len=this.RESOLUTION_PROPERTIES.length;i=resolution){highRes=res;lowZoom=i;} -if(res<=resolution){lowRes=res;highZoom=i;break;}} -var dRes=highRes-lowRes;if(dRes>0){zoom=lowZoom+((highRes-resolution)/dRes);}else{zoom=lowZoom;}}else{var diff;var minDiff=Number.POSITIVE_INFINITY;for(var i=0,len=this.resolutions.length;iminDiff){break;} -minDiff=diff;}else{if(this.resolutions[i]4) -this._object.open(sMethod,sUrl,bAsync,sUser,sPassword);else -if(arguments.length>3) -this._object.open(sMethod,sUrl,bAsync,sUser);else -this._object.open(sMethod,sUrl,bAsync);if(!bGecko&&!bIE){this.readyState=cXMLHttpRequest.OPENED;fReadyStateChange(this);} -this._object.onreadystatechange=function(){if(bGecko&&!bAsync) -return;oRequest.readyState=oRequest._object.readyState;fSynchronizeValues(oRequest);if(oRequest._aborted){oRequest.readyState=cXMLHttpRequest.UNSENT;return;} -if(oRequest.readyState==cXMLHttpRequest.DONE){fCleanTransport(oRequest);if(bIE&&bAsync) -window.detachEvent("onunload",fOnUnload);} -if(nState!=oRequest.readyState) -fReadyStateChange(oRequest);nState=oRequest.readyState;}};cXMLHttpRequest.prototype.send=function(vData){if(cXMLHttpRequest.onsend) -cXMLHttpRequest.onsend.apply(this,arguments);if(vData&&vData.nodeType){vData=window.XMLSerializer?new window.XMLSerializer().serializeToString(vData):vData.xml;if(!this._headers["Content-Type"]) -this._object.setRequestHeader("Content-Type","application/xml");} -this._object.send(vData);if(bGecko&&!this._async){this.readyState=cXMLHttpRequest.OPENED;fSynchronizeValues(this);while(this.readyStatecXMLHttpRequest.UNSENT) -this._aborted=true;this._object.abort();fCleanTransport(this);};cXMLHttpRequest.prototype.getAllResponseHeaders=function(){return this._object.getAllResponseHeaders();};cXMLHttpRequest.prototype.getResponseHeader=function(sName){return this._object.getResponseHeader(sName);};cXMLHttpRequest.prototype.setRequestHeader=function(sName,sValue){if(!this._headers) -this._headers={};this._headers[sName]=sValue;return this._object.setRequestHeader(sName,sValue);};cXMLHttpRequest.prototype.addEventListener=function(sName,fHandler,bUseCapture){for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++) -if(oListener[0]==sName&&oListener[1]==fHandler&&oListener[2]==bUseCapture) -return;this._listeners.push([sName,fHandler,bUseCapture]);};cXMLHttpRequest.prototype.removeEventListener=function(sName,fHandler,bUseCapture){for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++) -if(oListener[0]==sName&&oListener[1]==fHandler&&oListener[2]==bUseCapture) -break;if(oListener) -this._listeners.splice(nIndex,1);};cXMLHttpRequest.prototype.dispatchEvent=function(oEvent){var oEventPseudo={'type':oEvent.type,'target':this,'currentTarget':this,'eventPhase':2,'bubbles':oEvent.bubbles,'cancelable':oEvent.cancelable,'timeStamp':oEvent.timeStamp,'stopPropagation':function(){},'preventDefault':function(){},'initEvent':function(){}};if(oEventPseudo.type=="readystatechange"&&this.onreadystatechange) -(this.onreadystatechange.handleEvent||this.onreadystatechange).apply(this,[oEventPseudo]);for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++) -if(oListener[0]==oEventPseudo.type&&!oListener[2]) -(oListener[1].handleEvent||oListener[1]).apply(this,[oEventPseudo]);};cXMLHttpRequest.prototype.toString=function(){return'['+"object"+' '+"XMLHttpRequest"+']';};cXMLHttpRequest.toString=function(){return'['+"XMLHttpRequest"+']';};function fReadyStateChange(oRequest){if(cXMLHttpRequest.onreadystatechange) -cXMLHttpRequest.onreadystatechange.apply(oRequest);oRequest.dispatchEvent({'type':"readystatechange",'bubbles':false,'cancelable':false,'timeStamp':new Date+0});};function fGetDocument(oRequest){var oDocument=oRequest.responseXML,sResponse=oRequest.responseText;if(bIE&&sResponse&&oDocument&&!oDocument.documentElement&&oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)){oDocument=new window.ActiveXObject("Microsoft.XMLDOM");oDocument.async=false;oDocument.validateOnParse=false;oDocument.loadXML(sResponse);} -if(oDocument) -if((bIE&&oDocument.parseError!=0)||!oDocument.documentElement||(oDocument.documentElement&&oDocument.documentElement.tagName=="parsererror")) -return null;return oDocument;};function fSynchronizeValues(oRequest){try{oRequest.responseText=oRequest._object.responseText;}catch(e){} -try{oRequest.responseXML=fGetDocument(oRequest._object);}catch(e){} -try{oRequest.status=oRequest._object.status;}catch(e){} -try{oRequest.statusText=oRequest._object.statusText;}catch(e){}};function fCleanTransport(oRequest){oRequest._object.onreadystatechange=new window.Function;};if(!window.Function.prototype.apply){window.Function.prototype.apply=function(oRequest,oArguments){if(!oArguments) -oArguments=[];oRequest.__func=this;oRequest.__func(oArguments[0],oArguments[1],oArguments[2],oArguments[3],oArguments[4]);delete oRequest.__func;};};OpenLayers.Request.XMLHttpRequest=cXMLHttpRequest;})();OpenLayers.Tile.Image.IFrame=OpenLayers.Class(OpenLayers.Tile.Image,{initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.Image.prototype.initialize.apply(this,arguments);this.layerAlphaHack=false;},destroy:function(){if(this.imgDiv!=null){OpenLayers.Event.stopObservingElement(this.imgDiv.firstChild);} -OpenLayers.Tile.Image.prototype.destroy.apply(this,arguments);},clear:function(){if(this.imgDiv){var iFrame=this.imgDiv.firstChild;OpenLayers.Event.stopObservingElement(iFrame);this.imgDiv.removeChild(iFrame);}},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile.Image.IFrame(this.layer,this.position,this.bounds,this.url,this.size);} -obj=OpenLayers.Tile.Image.prototype.clone.apply(this,[obj]);return obj;},renderTile:function(){if(OpenLayers.Tile.Image.prototype.renderTile.apply(this,arguments)){var form=this.createRequestForm();this.imgDiv.appendChild(form);form.submit();this.imgDiv.removeChild(form);}},initImgDiv:function(){this.imgDiv=this.createImgDiv();OpenLayers.Util.modifyDOMElement(this.imgDiv,this.id,null,this.layer.getImageSize(),"relative");this.imgDiv.className='olTileImage';this.frame.appendChild(this.imgDiv);this.layer.div.appendChild(this.frame);if(this.layer.opacity!=null){OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,null,null,null,null,this.layer.opacity);} -this.imgDiv.map=this.layer.map;},createImgDiv:function(){var eventPane=document.createElement("div");if(OpenLayers.Util.getBrowserName()=="msie"){eventPane.style.backgroundColor='#FFFFFF';eventPane.style.filter='chroma(color=#FFFFFF)';} -OpenLayers.Util.modifyDOMElement(eventPane,null,new OpenLayers.Pixel(0,0),this.layer.getImageSize(),"absolute");var imgDiv=document.createElement("div");imgDiv.appendChild(eventPane);return imgDiv;},createIFrame:function(){var id=this.id+'_iFrame';var iframe;if(OpenLayers.Util.getBrowserName()=="msie"){iframe=document.createElement('